From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from bombadil.infradead.org (bombadil.infradead.org [198.137.202.133]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.lore.kernel.org (Postfix) with ESMTPS id BA572D4336B for ; Fri, 12 Dec 2025 04:12:17 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; d=lists.infradead.org; s=bombadil.20210309; h=Sender:Content-Type: Content-Transfer-Encoding:List-Subscribe:List-Help:List-Post:List-Archive: List-Unsubscribe:List-Id:MIME-Version:In-Reply-To:From:References:Cc:To: Subject:Date:Message-ID:Reply-To:Content-ID:Content-Description:Resent-Date: Resent-From:Resent-Sender:Resent-To:Resent-Cc:Resent-Message-ID:List-Owner; bh=7PJucz46aRp8uWTnUG0zJynpY1NYjZs4fH6jeYgQhYI=; b=TMkJluGYGsPoMrMMZDNE1K5/+J R5f/CdhJENidAUUWsHadr4FusoYG45/iqUaYwTqM3oVGrTzzhfvh2LYX8G9jcGenQgRvndOrEvaoJ sgPFOHXx1Ikl35AVgnmm++aATpDAZdrNGkb/sUxZGG4GLHFe3joiYPk3RCa7q75KbrDltcROHfdJ5 gr4UQJ2KZb4E3mNL90J3LcYPvofO7OA/lJtXxgN20DH73yche2l78zBW9PiLgmqOaAz5RJeZb+FxG cIVotL2HmxyZi+UD17LFc6Htxbv/QLoJv2rWlcZFFLk/QOpqdvXPoD2Ppc8LZO+im2eBHQuFNEgct E+N8GsWw==; Received: from localhost ([::1] helo=bombadil.infradead.org) by bombadil.infradead.org with esmtp (Exim 4.98.2 #2 (Red Hat Linux)) id 1vTuVe-000000003bo-2IhW; Fri, 12 Dec 2025 04:12:04 +0000 Received: from mail-japaneastazlp170130007.outbound.protection.outlook.com ([2a01:111:f403:c405::7] helo=TYDPR03CU002.outbound.protection.outlook.com) by bombadil.infradead.org with esmtps (Exim 4.98.2 #2 (Red Hat Linux)) id 1vTuVa-000000003ba-1gDD; Fri, 12 Dec 2025 04:12:01 +0000 ARC-Seal: i=1; a=rsa-sha256; s=arcselector10001; d=microsoft.com; cv=none; b=FTKVQyQNwDvmN4WMxx8vxcwo1cDCdzZzjfPvNKG/KdmaelGkfPGKz0wjwRKSqS7/R3AHHswcbyNgK3bs63+vxVwAGk5WNLwLRZ6ZyVNaOM0FNbwVPBQXoMgCBsMK1kcKhUzKbCde5z1bG2QhAT9GxunziNLNV4LwdfEa1l8LaqfYznho5pDc9GWXIQbxJe1E9EYQMWl00lg3OMmmPmMcN6tJxdQbQ+LoQHN4yVPMJklpNNkQz12U6kOxGGxjml+LEAkfoTnlricU40H5lBqozX5dI3cpXRbXDpvAMSZf+MVvFFyZnVsEoYUSlhHycQGSxWKyW501CecbAbNgaaxPOA== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=microsoft.com; s=arcselector10001; h=From:Date:Subject:Message-ID:Content-Type:MIME-Version:X-MS-Exchange-AntiSpam-MessageData-ChunkCount:X-MS-Exchange-AntiSpam-MessageData-0:X-MS-Exchange-AntiSpam-MessageData-1; bh=6IJROTgeS+gdBrVdnKeZpbkhDjF77yTC9ofatEtxDvg=; b=XUjybddFBX2aBnb04BSI871MHP+XOvQ69BqdRLRfqAv6tAsBvClGX7wCAObzaMQpC/iDbPfdmZZpbBmk/SaWzgs8iI1GLyLIdOosVRClUXgsGwg/sFwaTonxrrBLt3hp5oknGoE7jY44yPjGxy9DgPKk1+SW8Yb/Enq4N0qv5JVR3IECMcc51b2GROuATGW2segAFxZK0QsafT/n5pxsw3ITyL1ZJjjSlxU2hHNptb9ysxTBUbQKxZanpuXVeHdVgKqU0lBnMlbbr6rLiHT0e0nHbrSXFuMlwUOpC93D0cBuzmeloJZSyy+XAoRTv0pfqVERiBDVGIoSf/mlycKBDg== ARC-Authentication-Results: i=1; mx.microsoft.com 1; spf=pass smtp.mailfrom=amlogic.com; dmarc=pass action=none header.from=amlogic.com; dkim=pass header.d=amlogic.com; arc=none DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=amlogic.com; s=selector1; h=From:Date:Subject:Message-ID:Content-Type:MIME-Version:X-MS-Exchange-SenderADCheck; bh=6IJROTgeS+gdBrVdnKeZpbkhDjF77yTC9ofatEtxDvg=; b=IKUubrJw5nok7vP3nxBlLQMxxewnj2KQ1PuSixlXuz68CTPvHyEEB6ZTACHE2LSr8oF34zrIig0da2rspXWQSIrWYEV0qsSWVfUMcyKJ8MMC0M6K99vAPNfJKFc/yHPLJ0Ef6HbVBoflSvogH7OyPBBVxpmL9QAd3mcAkoBuhpsMtsKA8Cm3HlU3bwhzG3IqineMv7E6pnFADhMTMp0eZE5WE2hiNPPOX8vMPM8CJU+Ar2qTgHkV608cZY14KdnFM2dTBAddcDIpAEv3oYLHD/heVM56Y6ak4a7N0n/LZHLYHA1pLrmLvi34jocF1D0IK2fSxphBhg43ybOU6/C6bg== Authentication-Results: dkim=none (message not signed) header.d=none;dmarc=none action=none header.from=amlogic.com; Received: from KL1PR03MB5521.apcprd03.prod.outlook.com (2603:1096:820:51::12) by SEYPR03MB6628.apcprd03.prod.outlook.com (2603:1096:101:81::9) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384) id 15.20.9412.10; Fri, 12 Dec 2025 04:11:46 +0000 Received: from KL1PR03MB5521.apcprd03.prod.outlook.com ([fe80::f12b:85e:f95c:191e]) by KL1PR03MB5521.apcprd03.prod.outlook.com ([fe80::f12b:85e:f95c:191e%4]) with mapi id 15.20.9412.005; Fri, 12 Dec 2025 04:11:45 +0000 Message-ID: <12f26bf8-409b-4206-a39b-4bb2a14edec0@amlogic.com> Date: Fri, 12 Dec 2025 12:11:42 +0800 User-Agent: Mozilla Thunderbird Subject: Re: [PATCH RFC v2 2/3] decoder: Add V4L2 stateless H.264 decoder driver To: Nicolas Dufresne , Mauro Carvalho Chehab , Rob Herring , Krzysztof Kozlowski , Conor Dooley , Neil Armstrong , Kevin Hilman , Jerome Brunet , Martin Blumenstingl Cc: linux-media@vger.kernel.org, devicetree@vger.kernel.org, linux-kernel@vger.kernel.org, linux-arm-kernel@lists.infradead.org, linux-amlogic@lists.infradead.org References: <20251124-b4-s4-vdec-upstream-v2-0-bdbbce3f11a6@amlogic.com> <20251124-b4-s4-vdec-upstream-v2-2-bdbbce3f11a6@amlogic.com> <9b74086ac938475328904960add2c284b81efd4a.camel@ndufresne.ca> From: Zhentao Guo In-Reply-To: <9b74086ac938475328904960add2c284b81efd4a.camel@ndufresne.ca> X-ClientProxiedBy: SI2P153CA0016.APCP153.PROD.OUTLOOK.COM (2603:1096:4:140::17) To KL1PR03MB5521.apcprd03.prod.outlook.com (2603:1096:820:51::12) MIME-Version: 1.0 X-MS-PublicTrafficType: Email X-MS-TrafficTypeDiagnostic: KL1PR03MB5521:EE_|SEYPR03MB6628:EE_ X-MS-Office365-Filtering-Correlation-Id: ef578a28-a278-4c3e-b7fe-08de39348f9b X-MS-Exchange-SenderADCheck: 1 X-MS-Exchange-AntiSpam-Relay: 0 X-Microsoft-Antispam: BCL:0;ARA:13230040|7416014|366016|376014|4022899009|1800799024; X-Microsoft-Antispam-Message-Info: =?utf-8?B?bEw5TWFlZmFKYVc0M1gvSnBWYVJHTDhTdExZWnRPejFUbTY3b1ZPTUpyQSt6?= =?utf-8?B?UTZnMkR0aEtQTVlSS05YL09WUkNaUTExOFc2eFBURHVvcStoUTZoVVBxUUEx?= =?utf-8?B?a3lXc2NPOFlWd0RZeG9lajRLWDA1TzEwbXBTMFMxSXBxeDRrcXFIbW1lWjhv?= =?utf-8?B?ZHZ0WS9wblYwSmhvN0trTmVIWEkvMysyWUVJQ0p3Sm5tSHhRQVBZKzhUS3ZK?= =?utf-8?B?R1FpNTNsRUFkUHQvMVNsbmxJb0ZZU3FIblFHZ1lBUEFnWUZkblBEN29mQ0tH?= =?utf-8?B?Z01pS0hlQ1Z1VDYya0NNaVI1YldUMGFlWVhYb25NV0l3bzQramRxWmNSeXFv?= =?utf-8?B?STZZbU1RdEpxTE5OOTQ2cnUxbVpYdGtwZ3BHUnZkdGdpVmp3SDlFREpSV3k0?= =?utf-8?B?Y2x0aTVOR0FmajM5YStsdXcwV08zWEhBbXFiZmNnTDk0Nk1TK1d2eXE0RGov?= =?utf-8?B?OGFYYVJkbTZxTUcrRWJTYlJ4OU5CY3FlVFdvTjNRNC9Hb1lBZ1dBdGd5N2t1?= =?utf-8?B?UDdzOTZnVXgrcGVaWDU1dWpBUkluME9IUnduZC9ZWENWR01xRCtTVHNYR2hs?= =?utf-8?B?dG14ZTYydU43cVRpSmszZXBoT1VGZ1JmWGw4eDh2RmppQ0VVdzI1TFUxbEE2?= =?utf-8?B?N2l5U3BMdEFqeWZ2Z2tseUdyTWJqOW80bzFFTjk0Q043Y1FwNjFONHA5d1dX?= =?utf-8?B?WUNMZUNiZ1gxZm84cEVETWJlVUdnZlE1dDI2bS9oZ09rMkU0Z1dGNlR5ZVYv?= =?utf-8?B?QWE4cEZ2Q2owYkJyRHBCSVUyRUFqWGV4aktPelpDZi92RGJWTWJWQUVEUllx?= =?utf-8?B?cHQ5NW5UWkh6Q3ExcDJJYUdLUXdZUGRuUHhWTmVNMlB0WGFGV3hOdi96VjBK?= =?utf-8?B?RVF5eTlPclYyVXNhclY1SGkyTC9Id1ByWHRhZS8xTGFySS94c3ZNVi84Q1hE?= =?utf-8?B?ZGNIaU93VThHVlluVHpFZE1HWkxpMWdnWmt6ZjdyYm42ZWxRZnVBM05zRFpN?= =?utf-8?B?TTQ1Q3czbUgvRzc5blRJa2ZSVEZpcFg0Y3lSWFQ0aTlDTW9DeURUV0RnUEho?= =?utf-8?B?dFdnbEorQWViditWdUdyYlN0bnkrWFRWdWFjbDVlYS9IbzlKOUsza3ZlRGxL?= =?utf-8?B?eGo2SHFUaTdhV21wa2k0UGU5Zm9Dd3FzRG9Kb0M4bHJHZGIzdTJObmIxRFZN?= =?utf-8?B?b0ZGUHZtdUdKZ0loMFJrVW9GUHJPZkVxRDZaN2ptVEs5WkYxeE9JdTlTWWs0?= =?utf-8?B?bmJyRjlOZHBoaW9IUXpRajFwU1hwWjJ3dGtlUS9Uemh1U0VuQ0xNakh5dmg2?= =?utf-8?B?UFhkcCsremRFSFFCOEZJVEVOMWdFeFAyYjVwNjVkemZCSldSVzFZREJRWlNr?= =?utf-8?B?bVpUQUMwdEdlcDVJZ0ZZQzRpc2o1VnNuRmdqRmNhKzhyTVZOQlVSN3dUakdX?= =?utf-8?B?aGpUWGFCbkFmZE5TdC91YzF1dmphU00wMHE5TURMOE5nc05WY2E0dkJiTFU4?= =?utf-8?B?SDlOYzcyRVNSam9iR1hDNnNPcTMwQnpUbk95emRkQmNSenN5a1VmczZDNk1l?= =?utf-8?B?ZnJKS0FnSmN5UjJIL0tGWDMycFdldHlKSnpJQTgvS1pKbnBUZkJldTRqd1lE?= =?utf-8?B?VlZBVUxYL2o2Y0xmTHlqOHFEUUtzSXNyV1NiTTlXbUlPVlJGYXhpbEhCanlO?= =?utf-8?B?S2l4c2xRTnJQYjNKZjhOdzB5bWVRUHc5MUUxeU1RWVlxd01ZWkNOUzRtaGk0?= =?utf-8?B?cXhPT2FIc0lhUU5jOW9Lc2tmcDRrUy9Wd052N20yQnZOWnlJL2MxOGIxUUlK?= =?utf-8?B?UWJuT0FGNHFTcnVLWUtZUjFPRm9mVUFGVGpHaDEyRjd2by9ISnZBWEpIVWly?= =?utf-8?B?dWFUU1AvbkxUTmpHdWlFVHNDR25HK2VvUThlRExiRHYrZGxlalZNbWsvWFFw?= =?utf-8?Q?GgmWNhf/6m7eF12O0Z6wIlF/s6lO0axR?= X-Forefront-Antispam-Report: CIP:255.255.255.255;CTRY:;LANG:en;SCL:1;SRV:;IPV:NLI;SFV:NSPM;H:KL1PR03MB5521.apcprd03.prod.outlook.com;PTR:;CAT:NONE;SFS:(13230040)(7416014)(366016)(376014)(4022899009)(1800799024);DIR:OUT;SFP:1102; X-MS-Exchange-AntiSpam-MessageData-ChunkCount: 1 X-MS-Exchange-AntiSpam-MessageData-0: =?utf-8?B?N09jcFkvanZFK1dOQldsL3I2WmNyZFFJQlpKeTFiVENiTFRCc25zaHlHaXZP?= =?utf-8?B?VktPQTVqclVSLzg2cHRJdVFzMEwrWGZkaXVLMkhqREF1QVpORGEzWjduYzYv?= =?utf-8?B?SE00SjhzR2JMVndKa1ovLzIyZWZPUWJMTVNHSHhaMStWR2RRQnJKMXFmZ1pZ?= =?utf-8?B?SnBkbEIra0FRcU1xV2YvcVE2dUdzckpNZ3ZFaTJsdlpIYm1RT3V4Nm84RU5G?= =?utf-8?B?eFpoQkgyT04zdDl4UGhaNmxYeEozQnhUd1VCSkxZc0lraWZEdDc4MGt4Q3l1?= =?utf-8?B?R001c0trRkw1R1loN2VzL3lBeisxMk5tK1gzMm9qMFFHUmhLWlNnYmpmS1B6?= =?utf-8?B?UW9xcklGWmo2S3VMUWd3YUNKWWdZQXN2SFRsbnl5WXVIUm9ZbG1ZaEFHT1JK?= =?utf-8?B?RnZNZmpYZGFCdmdiQVYyTVlZTU5yL2ZacWdYYUdaZC9EVnhhSEJVWEdCM2RB?= =?utf-8?B?LzdBeG1sWmJOV3JscnBmazdPYXZlcWRuZFJ6dWVFUmthNFJEaUdFbUdOSHYw?= =?utf-8?B?T1dYc1VuM0MrbkQ0MWtudGNYU0NzZlliWmhtdXNTMEQwU1JidEx0K1FCUHNJ?= =?utf-8?B?M0hWdUFnNWZLY2Vqc0xWT2JIeGdWZWNiZ1gvbG00K2NLWVo3Uy93eWFaOEVG?= =?utf-8?B?bU80UHJmSmdpNzZuZmNTVTRWYll2Rk9kbk5HeVg5T1B6QXJ4TjBuKzkvVzBB?= =?utf-8?B?NnN4VWwrQk0wUm16M2RkaUp4c0FzWXZibXNTK2JEck5yNkdZRXZwaVRIS1F4?= =?utf-8?B?eFZMMnpIbzZGMUh6QW1TOWJCem9mNXZwNm9mT2t6SHo0UDBHRzl1QTY1QUt1?= =?utf-8?B?SE5oUXk4aXdhbEZObE1BMHZadlI4cE1zU1ZIK1hTUnU4dWdsbWlJWldZYWM1?= =?utf-8?B?aGZIM2lnRHBCRlo0OStrc1RxRWZSMW9rYi81WDFVUDkzc0hrcjBFM0V3TUFu?= =?utf-8?B?YjllZE45cldKVXlRNGNnSEt4ZTZEL0tKRXJOaFFQVnBiYjVIaGR0MmFIRVV0?= =?utf-8?B?ZWx4aklxMzVHM1A1Mldka3RCekRDMWFhSkRDR0tYN1VWczhHUDNtbHA0eS9H?= =?utf-8?B?SFBNTTA0Y3lOM2g0Y1U5S0dYVkZ3WWZJdmloVmVnNGo2bE9xTXJGbnFyU2x2?= =?utf-8?B?am5mcW5DS21yKzFWckJXelVpWjloZUdFRGZoajN3ZGd5T3h1Um8zY2lranJ2?= =?utf-8?B?QUM1bjVKYndBQmRQWWxWeGR1d1R0WFNpMVBTZ1p1NWlhSEdFNmJEdllPTHpa?= =?utf-8?B?UWwxdTVIdE9kM1dKSmxYRU14eEVtSEp1ZmhFb29lU3dua0FIUzk4VnhBWGxB?= =?utf-8?B?R2h1WFh6MU54SGVBbWdFeUo3ekZzeU9Fb21oRnkwYmxsWDkvdW5sRVYreDVP?= =?utf-8?B?dWFpeGQ3cmpFL2Q2d05VWlhjZWxNd0V6M3VjN3NFQmNXWkI0RlpUeGRDaW1w?= =?utf-8?B?MTNBZDhQOG1kSkp5Z3g2YkNUMDF0QVJZVWVOVjAzR0RZVlBOYUlVNEdJc0dK?= =?utf-8?B?eXEzQm9seVh5Z3loOXlnL3hGRXVZTWtmUnY2YUNEU1pvTVpvYmhSelBaU3JC?= =?utf-8?B?UHlKS2NCSVhTWmZoZ0w2QVk1VXhZNlN3cHByRHl0ZnlGUkk1dWhYZVZhQmRZ?= =?utf-8?B?Mldja0YxMUt1QVRYNm4zR1Z3eFVpdG9Nbm5CbDl2QVVBNjhEaW1OTEhvS1ZM?= =?utf-8?B?aEQ3WGU1K3hBKy81emdCK2E5bHVoNlpGdk13Szh1cVZ1Z25xN1lIem1nRjVR?= =?utf-8?B?TkNJRlJ6Ynh0ek0vQUlyTmdaM29tcGJOaGdxSWQ0dlJ1WU9wQi84Y25pQTRv?= =?utf-8?B?eUtiU0FmMktZbFZ0VWpZeE9RcXdwdW1KS01iZUE1Ymd1aVh5Nis1VEV5QlJz?= =?utf-8?B?cDJJa2VUYnFCNUNtYU1kRzEvdC9MRTZjU25JRnBpQms3aWVNTlplbkZKZjdx?= =?utf-8?B?SGM0blJmYXhBeUE2ekVqRHVmbDFkMUxjYmRlMzJZSTI4UFNlZ0N3andvQzhU?= =?utf-8?B?eGdJczI2UUNsKzZvVmdoTS9OVytEMWx4QS9QeHRwcWJGOHNZTUVYSmJIdWJL?= =?utf-8?B?Z2c0Q3ljSVRzRkU2OENWaCtVdUh6SmIvRUZCcW1Bei9iYnErQTJpOXhuUStZ?= =?utf-8?Q?jc4nKxLJFG/RzJy40K/jdEL25?= X-OriginatorOrg: amlogic.com X-MS-Exchange-CrossTenant-Network-Message-Id: ef578a28-a278-4c3e-b7fe-08de39348f9b X-MS-Exchange-CrossTenant-AuthSource: KL1PR03MB5521.apcprd03.prod.outlook.com X-MS-Exchange-CrossTenant-AuthAs: Internal X-MS-Exchange-CrossTenant-OriginalArrivalTime: 12 Dec 2025 04:11:45.1665 (UTC) X-MS-Exchange-CrossTenant-FromEntityHeader: Hosted X-MS-Exchange-CrossTenant-Id: 0df2add9-25ca-4b3a-acb4-c99ddf0b1114 X-MS-Exchange-CrossTenant-MailboxType: HOSTED X-MS-Exchange-CrossTenant-UserPrincipalName: xNntlKaeRHbv+NgzNYZw1LoAnILD16y9wizW7HmK/GKzRpCu4qHSMv6plJrVcSkgwF6qtJH8oNqIiRVNJlZsfg== X-MS-Exchange-Transport-CrossTenantHeadersStamped: SEYPR03MB6628 X-BeenThere: linux-amlogic@lists.infradead.org X-Mailman-Version: 2.1.34 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Content-Transfer-Encoding: base64 Content-Type: text/plain; charset="utf-8"; Format="flowed" Sender: "linux-amlogic" Errors-To: linux-amlogic-bounces+linux-amlogic=archiver.kernel.org@lists.infradead.org CuWcqCAyMDI1LzEyLzEyIDM6NTMsIE5pY29sYXMgRHVmcmVzbmUg5YaZ6YGTOgpIacKgTmljb2xh cwo+IExlIGx1bmRpIDI0IG5vdmVtYnJlIDIwMjUgw6AgMTE6MzIgKzA4MDAsIFpoZW50YW8gR3Vv IHZpYSBCNCBSZWxheSBhIMOpY3JpdMKgOgo+PiBGcm9tOiBaaGVudGFvIEd1byA8emhlbnRhby5n dW9AYW1sb2dpYy5jb20+Cj4+Cj4+IEFkZCBpbml0aWFsIHN1cHBvcnQgZm9yIFY0TDIgc3RhdGVs ZXNzIHZpZGVvIGRlY29kZXIKPj4gZHJpdmVyIG9uIEFtbG9naWMgUzQoUzgwNVgyKSBwbGF0Zm9y bS4gSW4gcGhhc2UgMSwKPj4gaXQgc3VwcG9ydHMgSC4yNjQgYml0c3RyZWFtcyBkZWNvZGluZy4K PiBQbGVhc2UgcmVmbG93IGluIG5leHQgdmVyc2lvbiwgeW91IGNhbiB1c2Ugc29tZXRoaW5nIGxp a2UgNzIgY2hhci4gU2luY2UgdGhpcyBpcwo+IHN1YnNldCBvZiB3aGF0IHRoZSBIVyBjYW4gZG8s IHNvbWUgZXh0cmEgaW5mb3JtYXRpb24gaXMgYXBwcmVjaWF0ZSwgcGVyaGFwcwo+IHdoaWNoIHBy b2ZpbGVzLCBwaXhlbCBkZXB0aCBldGMuClRoYW5rcywgSSBnb3QgaXQuIEkgd2lsbCBvcHRpbWl6 ZSBpdCBpbiB0aGUgbmV4dCB2ZXJzaW9uIGFjY29yZGluZyB0byAKeW91ciBzdWdnZXN0aW9ucy4K Pj4gU2lnbmVkLW9mZi1ieTogWmhlbnRhbyBHdW8gPHpoZW50YW8uZ3VvQGFtbG9naWMuY29tPgo+ PiAtLS0KPj4gIMKgTUFJTlRBSU5FUlPCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKg wqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqAgfMKgwqDCoCA3ICsK Pj4gIMKgZHJpdmVycy9tZWRpYS9wbGF0Zm9ybS9hbWxvZ2ljL0tjb25maWfCoMKgwqDCoMKgwqDC oMKgwqDCoMKgwqAgfMKgwqDCoCAxICsKPj4gIMKgZHJpdmVycy9tZWRpYS9wbGF0Zm9ybS9hbWxv Z2ljL01ha2VmaWxlwqDCoMKgwqDCoMKgwqDCoMKgwqDCoCB8wqDCoMKgIDEgKwo+PiAgwqBkcml2 ZXJzL21lZGlhL3BsYXRmb3JtL2FtbG9naWMvdmRlYy9LY29uZmlnwqDCoMKgwqDCoMKgwqAgfMKg wqAgMTYgKwo+PiAgwqBkcml2ZXJzL21lZGlhL3BsYXRmb3JtL2FtbG9naWMvdmRlYy9NYWtlZmls ZcKgwqDCoMKgwqDCoCB8wqDCoMKgIDQgKwo+PiAgwqBkcml2ZXJzL21lZGlhL3BsYXRmb3JtL2Ft bG9naWMvdmRlYy9UT0RPwqDCoMKgwqDCoMKgwqDCoMKgwqAgfMKgwqDCoCA3ICsKPj4gIMKgZHJp dmVycy9tZWRpYS9wbGF0Zm9ybS9hbWxvZ2ljL3ZkZWMvYW1sX3ZkZWMuY8KgwqDCoMKgIHzCoCA3 NTYgKysrKysrKysKPj4gIMKgZHJpdmVycy9tZWRpYS9wbGF0Zm9ybS9hbWxvZ2ljL3ZkZWMvYW1s X3ZkZWMuaMKgwqDCoMKgIHzCoMKgIDMxICsKPj4gIMKgZHJpdmVycy9tZWRpYS9wbGF0Zm9ybS9h bWxvZ2ljL3ZkZWMvYW1sX3ZkZWNfZHJ2LmMgfMKgIDIzOSArKysKPj4gIMKgZHJpdmVycy9tZWRp YS9wbGF0Zm9ybS9hbWxvZ2ljL3ZkZWMvYW1sX3ZkZWNfZHJ2LmggfMKgIDE5NiArKwo+PiAgwqBk cml2ZXJzL21lZGlhL3BsYXRmb3JtL2FtbG9naWMvdmRlYy9hbWxfdmRlY19ody5jwqAgfMKgIDU5 NiArKysrKysKPj4gIMKgZHJpdmVycy9tZWRpYS9wbGF0Zm9ybS9hbWxvZ2ljL3ZkZWMvYW1sX3Zk ZWNfaHcuaMKgIHzCoCAxNTggKysKPj4gIMKgLi4uL3BsYXRmb3JtL2FtbG9naWMvdmRlYy9hbWxf dmRlY19wbGF0Zm9ybS5jwqDCoMKgwqDCoCB8wqDCoCAzNyArCj4+ICDCoC4uLi9wbGF0Zm9ybS9h bWxvZ2ljL3ZkZWMvYW1sX3ZkZWNfcGxhdGZvcm0uaMKgwqDCoMKgwqAgfMKgwqAgNjIgKwo+PiAg wqBkcml2ZXJzL21lZGlhL3BsYXRmb3JtL2FtbG9naWMvdmRlYy9oMjY0LmPCoMKgwqDCoMKgwqDC oMKgIHwgMTkzMyArKysrKysrKysrKysrKysrKysrKwo+PiAgwqBkcml2ZXJzL21lZGlhL3BsYXRm b3JtL2FtbG9naWMvdmRlYy9oMjY0LmjCoMKgwqDCoMKgwqDCoMKgIHzCoCAzMDAgKysrCj4+ICDC oGRyaXZlcnMvbWVkaWEvcGxhdGZvcm0vYW1sb2dpYy92ZGVjL3JlZ19kZWZpbmVzLmjCoCB8wqAg MTc3ICsrCj4+ICDCoDE3IGZpbGVzIGNoYW5nZWQsIDQ1MjEgaW5zZXJ0aW9ucygrKQo+Pgo+PiBk aWZmIC0tZ2l0IGEvTUFJTlRBSU5FUlMgYi9NQUlOVEFJTkVSUwo+PiBpbmRleCBlYzYzNTUxNWMw YzQuLjM3MWM4YjgyODM5NCAxMDA2NDQKPj4gLS0tIGEvTUFJTlRBSU5FUlMKPj4gKysrIGIvTUFJ TlRBSU5FUlMKPj4gQEAgLTEzNjUsNiArMTM2NSwxMyBAQCBTOglNYWludGFpbmVkCj4+ICDCoEY6 CURvY3VtZW50YXRpb24vZGV2aWNldHJlZS9iaW5kaW5ncy9zcGkvYW1sb2dpYyxhNC1zcGlzZy55 YW1sCj4+ICDCoEY6CWRyaXZlcnMvc3BpL3NwaS1hbWxvZ2ljLXNwaXNnLmMKPj4gICAKPj4gK0FN TE9HSUMgVkNPREVDIERSSVZFUgo+PiArTToJWmhlbnRhbyBHdW8gPHpoZW50YW8uZ3VvQGFtbG9n aWMuY29tPgo+PiArTDoJbGludXgtbWVkaWFAdmdlci5rZXJuZWwub3JnCj4+ICtTOglNYWludGFp bmVkCj4+ICtGOglEb2N1bWVudGF0aW9uL2RldmljZXRyZWUvYmluZGluZ3MvbWVkaWEvYW1sb2dp YyxzNC12Y29kZWMtZGVjLnlhbWwKPj4gK0Y6CWRyaXZlcnMvbWVkaWEvcGxhdGZvcm0vYW1sb2dp Yy92ZGVjLwo+PiArCj4+ICDCoEFNUEhFTk9MIENISVBDQVAgMiBEUklWRVIKPj4gIMKgTToJSmF2 aWVyIENhcnJhc2NvIDxqYXZpZXIuY2FycmFzY28uY3J1ekBnbWFpbC5jb20+Cj4+ICDCoEw6CWxp bnV4LWh3bW9uQHZnZXIua2VybmVsLm9yZwo+PiBkaWZmIC0tZ2l0IGEvZHJpdmVycy9tZWRpYS9w bGF0Zm9ybS9hbWxvZ2ljL0tjb25maWcgYi9kcml2ZXJzL21lZGlhL3BsYXRmb3JtL2FtbG9naWMv S2NvbmZpZwo+PiBpbmRleCA0NThhY2YzZDVmYTguLjdjNTQxYWMwZDBjMyAxMDA2NDQKPj4gLS0t IGEvZHJpdmVycy9tZWRpYS9wbGF0Zm9ybS9hbWxvZ2ljL0tjb25maWcKPj4gKysrIGIvZHJpdmVy cy9tZWRpYS9wbGF0Zm9ybS9hbWxvZ2ljL0tjb25maWcKPj4gQEAgLTQsMyArNCw0IEBAIGNvbW1l bnQgIkFtbG9naWMgbWVkaWEgcGxhdGZvcm0gZHJpdmVycyIKPj4gICAKPj4gIMKgc291cmNlICJk cml2ZXJzL21lZGlhL3BsYXRmb3JtL2FtbG9naWMvYzMvS2NvbmZpZyIKPj4gIMKgc291cmNlICJk cml2ZXJzL21lZGlhL3BsYXRmb3JtL2FtbG9naWMvbWVzb24tZ2UyZC9LY29uZmlnIgo+PiArc291 cmNlICJkcml2ZXJzL21lZGlhL3BsYXRmb3JtL2FtbG9naWMvdmRlYy9LY29uZmlnIgo+PiBkaWZm IC0tZ2l0IGEvZHJpdmVycy9tZWRpYS9wbGF0Zm9ybS9hbWxvZ2ljL01ha2VmaWxlIGIvZHJpdmVy cy9tZWRpYS9wbGF0Zm9ybS9hbWxvZ2ljL01ha2VmaWxlCj4+IGluZGV4IGM3NDRhZmNkMWI5ZS4u NzQwOWRlNjc0YzBiIDEwMDY0NAo+PiAtLS0gYS9kcml2ZXJzL21lZGlhL3BsYXRmb3JtL2FtbG9n aWMvTWFrZWZpbGUKPj4gKysrIGIvZHJpdmVycy9tZWRpYS9wbGF0Zm9ybS9hbWxvZ2ljL01ha2Vm aWxlCj4+IEBAIC0yLDMgKzIsNCBAQAo+PiAgIAo+PiAgwqBvYmoteSArPSBjMy8KPj4gIMKgb2Jq LXkgKz0gbWVzb24tZ2UyZC8KPj4gK29iai15ICs9IHZkZWMvCj4+IGRpZmYgLS1naXQgYS9kcml2 ZXJzL21lZGlhL3BsYXRmb3JtL2FtbG9naWMvdmRlYy9LY29uZmlnIGIvZHJpdmVycy9tZWRpYS9w bGF0Zm9ybS9hbWxvZ2ljL3ZkZWMvS2NvbmZpZwo+PiBuZXcgZmlsZSBtb2RlIDEwMDY0NAo+PiBp bmRleCAwMDAwMDAwMDAwMDAuLjk1NDI0ZDY0Y2MxZgo+PiAtLS0gL2Rldi9udWxsCj4+ICsrKyBi L2RyaXZlcnMvbWVkaWEvcGxhdGZvcm0vYW1sb2dpYy92ZGVjL0tjb25maWcKPj4gQEAgLTAsMCAr MSwxNiBAQAo+PiArIyBTUERYLUxpY2Vuc2UtSWRlbnRpZmllcjogKEdQTC0yLjAtb25seSBPUiBN SVQpCj4+ICsKPj4gK2NvbmZpZyBWSURFT19BTUxPR0lDX1ZDT0RFQwo+PiArwqDCoMKgIHRyaXN0 YXRlICJBbWxvZ2ljIFZpZGVvIENvZGVjIERyaXZlciIKPj4gK8KgwqDCoCBkZXBlbmRzIG9uIEFS Q0hfTUVTT04gfHwgQ09NUElMRV9URVNUCj4+ICvCoMKgwqAgZGVwZW5kcyBvbiBWSURFT19ERVYK Pj4gK8KgwqDCoCBkZXBlbmRzIG9uIFY0TF9NRU0yTUVNX0RSSVZFUlMKPj4gK8KgwqDCoCBzZWxl Y3QgVklERU9CVUYyX0RNQV9DT05USUcKPj4gK8KgwqDCoCBzZWxlY3QgVjRMMl9IMjY0Cj4+ICvC oMKgwqAgc2VsZWN0IFY0TDJfTUVNMk1FTV9ERVYKPj4gK8KgwqDCoCBzZWxlY3QgTUVTT05fQ0FO VkFTCj4+ICvCoMKgwqAgaGVscAo+PiArwqDCoMKgwqDCoCBUaGlzIGlzIGEgdjRsMiBkcml2ZXIg Zm9yIEFtbG9naWMgdmlkZW8gY29kZWMgZHJpdmVyLgo+PiArCcKgIFRoaXMgZHJpdmVyIGlzIGRl c2lnbmVkIHRvIHN1cHBvcnQgVjRMMiBNMk0gU1RBVEVMRVNTCj4+ICsJwqAgaW50ZXJmYWNlLgo+ PiArwqDCoMKgwqDCoCBUbyBjb21waWxlIHRoaXMgZHJpdmVyIGFzIGEgbW9kdWxlIGNob29zZSBt IGhlcmUuCj4+IGRpZmYgLS1naXQgYS9kcml2ZXJzL21lZGlhL3BsYXRmb3JtL2FtbG9naWMvdmRl Yy9NYWtlZmlsZSBiL2RyaXZlcnMvbWVkaWEvcGxhdGZvcm0vYW1sb2dpYy92ZGVjL01ha2VmaWxl Cj4+IG5ldyBmaWxlIG1vZGUgMTAwNjQ0Cj4+IGluZGV4IDAwMDAwMDAwMDAwMC4uMWE3ZGNmMWQ3 NTYyCj4+IC0tLSAvZGV2L251bGwKPj4gKysrIGIvZHJpdmVycy9tZWRpYS9wbGF0Zm9ybS9hbWxv Z2ljL3ZkZWMvTWFrZWZpbGUKPj4gQEAgLTAsMCArMSw0IEBACj4+ICsjIFNQRFgtTGljZW5zZS1J ZGVudGlmaWVyOiBHUEwtMi4wLW9ubHkKPj4gK2FtbC12ZGVjLWRydi1vYmpzIDo9IGFtbF92ZGVj Lm8gYW1sX3ZkZWNfZHJ2Lm8gYW1sX3ZkZWNfaHcubyBhbWxfdmRlY19wbGF0Zm9ybS5vIGgyNjQu b1wKPj4gKwo+PiArb2JqLSQoQ09ORklHX1ZJREVPX0FNTE9HSUNfVkNPREVDKSArPSBhbWwtdmRl Yy1kcnYubwo+PiBkaWZmIC0tZ2l0IGEvZHJpdmVycy9tZWRpYS9wbGF0Zm9ybS9hbWxvZ2ljL3Zk ZWMvVE9ETyBiL2RyaXZlcnMvbWVkaWEvcGxhdGZvcm0vYW1sb2dpYy92ZGVjL1RPRE8KPj4gbmV3 IGZpbGUgbW9kZSAxMDA2NDQKPj4gaW5kZXggMDAwMDAwMDAwMDAwLi41NGM2MDE0NTc3MGUKPj4g LS0tIC9kZXYvbnVsbAo+PiArKysgYi9kcml2ZXJzL21lZGlhL3BsYXRmb3JtL2FtbG9naWMvdmRl Yy9UT0RPCj4+IEBAIC0wLDAgKzEsNyBAQAo+PiArVE9ETyBsaXN0IGZvciBBbWxvZ2ljIFY0TDIg c3RhdGVsZXNzIGRlY29kZXIgZHJpdmVyOgo+PiArCj4+ICsxLiBTdXBwb3J0IGRlY29kaW5nIGZv ciBIRVZDLCBWUDksIEFWMSwgYW5kIE1QRUctMi4KPj4gKzIuIFN1cHBvcnQgbW9yZSBTb0NzLCBp bmNsdWRpbmcgdGhlIG5ldyBUNy9TNyBzZXJpZXMgYW5kIGxlZ2FjeSBTb0NzIChlLmcuLCBHWEws IFNNMSwgRzEyQikuCj4+ICszLiBTdXBwb3J0IDEwLWJpdCBkZWNvZGluZyBhbmQgUDAxMCBvdXRw dXQuCj4+ICvCoMKgIE5vdGU6IFAwMTAgb3V0cHV0IHJlcXVpcmVzIGhhcmR3YXJlIHN1cHBvcnQu Cj4+ICs0LiBTdXBwb3J0IGludGVybGFjZWQgc3RyZWFtIGRlY29kaW5nIGZvciBILjI2NCwgSEVW QywgYW5kIE1QRUctMi4KPj4gZGlmZiAtLWdpdCBhL2RyaXZlcnMvbWVkaWEvcGxhdGZvcm0vYW1s b2dpYy92ZGVjL2FtbF92ZGVjLmMgYi9kcml2ZXJzL21lZGlhL3BsYXRmb3JtL2FtbG9naWMvdmRl Yy9hbWxfdmRlYy5jCj4+IG5ldyBmaWxlIG1vZGUgMTAwNjQ0Cj4+IGluZGV4IDAwMDAwMDAwMDAw MC4uM2VmMmQzMmE3YTczCj4+IC0tLSAvZGV2L251bGwKPj4gKysrIGIvZHJpdmVycy9tZWRpYS9w bGF0Zm9ybS9hbWxvZ2ljL3ZkZWMvYW1sX3ZkZWMuYwo+PiBAQCAtMCwwICsxLDc1NiBAQAo+PiAr Ly8gU1BEWC1MaWNlbnNlLUlkZW50aWZpZXI6IChHUEwtMi4wLW9ubHkgT1IgTUlUKQo+PiArLyoK Pj4gKyAqIENvcHlyaWdodCAoQykgMjAyNSBBbWxvZ2ljLCBJbmMuIEFsbCByaWdodHMgcmVzZXJ2 ZWQKPj4gKyAqLwo+PiArCj4+ICsjaW5jbHVkZSA8bWVkaWEvdjRsMi1tZW0ybWVtLmg+Cj4+ICsj aW5jbHVkZSA8bWVkaWEvdjRsMi1jdHJscy5oPgo+PiArI2luY2x1ZGUgPG1lZGlhL3Y0bDItZXZl bnQuaD4KPj4gKyNpbmNsdWRlIDxtZWRpYS92aWRlb2J1ZjItdjRsMi5oPgo+PiArI2luY2x1ZGUg PG1lZGlhL3ZpZGVvYnVmMi1kbWEtY29udGlnLmg+Cj4+ICsKPj4gKyNpbmNsdWRlICJhbWxfdmRl Yy5oIgo+PiArI2luY2x1ZGUgImFtbF92ZGVjX2h3LmgiCj4+ICsjaW5jbHVkZSAiYW1sX3ZkZWNf cGxhdGZvcm0uaCIKPj4gKwo+PiArI2RlZmluZSBWQ09ERUNfRFJWX05BTUUgImFtbC12ZGVjLWRy diIKPj4gKwo+PiArc3RhdGljIGNvbnN0IHN0cnVjdCBhbWxfdmRlY192NGwyX2N0cmwgY29udHJv bHNbXSA9IHsKPj4gKwl7Cj4+ICsJCS5jb2RlY190eXBlID0gQ09ERUNfVFlQRV9IMjY0LAo+PiAr CQkuY2ZnID0gewo+PiArCQkJLmlkID0gVjRMMl9DSURfU1RBVEVMRVNTX0gyNjRfREVDT0RFX1BB UkFNUywKPj4gKwkJfSwKPj4gKwl9LCB7Cj4+ICsJCS5jb2RlY190eXBlID0gQ09ERUNfVFlQRV9I MjY0LAo+PiArCQkuY2ZnID0gewo+PiArCQkJLmlkID0gVjRMMl9DSURfU1RBVEVMRVNTX0gyNjRf U1BTLAo+PiArCQl9LAo+PiArCX0sIHsKPj4gKwkJLmNvZGVjX3R5cGUgPSBDT0RFQ19UWVBFX0gy NjQsCj4+ICsJCS5jZmcgPSB7Cj4+ICsJCQkuaWQgPSBWNEwyX0NJRF9TVEFURUxFU1NfSDI2NF9Q UFMsCj4+ICsJCX0sCj4+ICsJfSwgewo+PiArCQkuY29kZWNfdHlwZSA9IENPREVDX1RZUEVfSDI2 NCwKPj4gKwkJLmNmZyA9IHsKPj4gKwkJCS5pZCA9IFY0TDJfQ0lEX1NUQVRFTEVTU19IMjY0X1ND QUxJTkdfTUFUUklYLAo+PiArCQl9LAo+PiArCX0sIHsKPj4gKwkJLmNvZGVjX3R5cGUgPSBDT0RF Q19UWVBFX0gyNjQsCj4+ICsJCS5jZmcgPSB7Cj4+ICsJCQkuaWQgPSBWNEwyX0NJRF9TVEFURUxF U1NfSDI2NF9ERUNPREVfTU9ERSwKPj4gKwkJCS5taW4gPSBWNEwyX1NUQVRFTEVTU19IMjY0X0RF Q09ERV9NT0RFX0ZSQU1FX0JBU0VELAo+PiArCQkJLmRlZiA9IFY0TDJfU1RBVEVMRVNTX0gyNjRf REVDT0RFX01PREVfRlJBTUVfQkFTRUQsCj4+ICsJCQkubWF4ID0gVjRMMl9TVEFURUxFU1NfSDI2 NF9ERUNPREVfTU9ERV9GUkFNRV9CQVNFRCwKPj4gKwkJfSwKPj4gKwl9LCB7Cj4+ICsJCS5jb2Rl Y190eXBlID0gQ09ERUNfVFlQRV9IMjY0LAo+PiArCQkuY2ZnID0gewo+PiArCQkJLmlkID0gVjRM Ml9DSURfTVBFR19WSURFT19IMjY0X0xFVkVMLAo+PiArCQl9LAo+PiArCX0sIHsKPj4gKwkJLmNv ZGVjX3R5cGUgPSBDT0RFQ19UWVBFX0gyNjQsCj4+ICsJCS5jZmcgPSB7Cj4+ICsJCQkuaWQgPSBW NEwyX0NJRF9TVEFURUxFU1NfSDI2NF9TVEFSVF9DT0RFLAo+PiArCQkJLm1pbiA9IFY0TDJfU1RB VEVMRVNTX0gyNjRfU1RBUlRfQ09ERV9BTk5FWF9CLAo+PiArCQkJLmRlZiA9IFY0TDJfU1RBVEVM RVNTX0gyNjRfU1RBUlRfQ09ERV9BTk5FWF9CLAo+PiArCQkJLm1heCA9IFY0TDJfU1RBVEVMRVNT X0gyNjRfU1RBUlRfQ09ERV9BTk5FWF9CLAo+PiArCQl9LAo+PiArCX0sIHsKPj4gKwkJLmNvZGVj X3R5cGUgPSBDT0RFQ19UWVBFX0gyNjQsCj4+ICsJCS5jZmcgPSB7Cj4+ICsJCQkuaWQgPSBWNEwy X0NJRF9NUEVHX1ZJREVPX0gyNjRfUFJPRklMRSwKPj4gKwkJCS5taW4gPSBWNEwyX01QRUdfVklE RU9fSDI2NF9QUk9GSUxFX0JBU0VMSU5FLAo+PiArCQkJLm1heCA9IFY0TDJfTVBFR19WSURFT19I MjY0X1BST0ZJTEVfSElHSCwKPj4gKwkJCS5kZWYgPSBWNEwyX01QRUdfVklERU9fSDI2NF9QUk9G SUxFX01BSU4sCj4+ICsJCX0sCj4+ICsJfQo+PiArfTsKPj4gKwo+PiArc3RhdGljIHN0cnVjdCBh bWxfdmlkZW9fZm10IGFtbF92aWRlb19mb3JtYXRzW10gPSB7Cj4+ICsJewo+PiArCQkubmFtZSA9 ICJILjI2NCIsCj4+ICsJCS5mb3VyY2MgPSBWNEwyX1BJWF9GTVRfSDI2NF9TTElDRSwKPj4gKwkJ LnR5cGUgPSBBTUxfRk1UX0RFQywKPj4gKwkJLmNvZGVjX3R5cGUgPSBDT0RFQ19UWVBFX0gyNjQs Cj4+ICsJCS5udW1fcGxhbmVzID0gMSwKPj4gKwkJLnN0ZXB3aXNlID0ge0FNTF9WREVDX01JTl9X LCBBTUxfVkRFQ18xMDgwUF9NQVhfVywgMiwKPj4gKwkJCUFNTF9WREVDX01JTl9ILCBBTUxfVkRF Q18xMDgwUF9NQVhfSCwgMn0sCj4+ICsJfSwKPj4gKwl7Cj4+ICsJCS5uYW1lID0gIk5WMjFNIiwK Pj4gKwkJLmZvdXJjYyA9IFY0TDJfUElYX0ZNVF9OVjIxTSwKPj4gKwkJLnR5cGUgPSBBTUxfRk1U X0ZSQU1FLAo+PiArCQkuY29kZWNfdHlwZSA9IENPREVDX1RZUEVfRlJBTUUsCj4+ICsJCS5udW1f cGxhbmVzID0gMiwKPj4gKwkJLnN0ZXB3aXNlID0ge0FNTF9WREVDX01JTl9XLCBBTUxfVkRFQ18x MDgwUF9NQVhfVywgMiwKPj4gKwkJCUFNTF9WREVDX01JTl9ILCBBTUxfVkRFQ18xMDgwUF9NQVhf SCwgMn0sCj4gWW91IGNhbiBtYWtlIGEgZGVmaW5lIHRvIGluaXRpYWxpemUgdGhpcywgc28geW91 IGRvbid0IHJlcGVhdCBpdCBvdmVyIGFuZCBvdmVyLgo+IEFsc28sIHRyeSB0byB1c2UgcmVhZGFi bGUgc3R5bGUsIHNpbWlsYXIgdG8gdGhlIGNmZyBhYm92ZS4KT0ssIEknbGwgcmVmZXIgdG8gc29t ZSBvdGhlciB1cHN0cmVhbWVkIGRyaXZlcnMgYW5kIGltcG9ydmUgdGhpcy4KPgo+PiArCX0sCj4+ ICsJewo+PiArCQkubmFtZSA9ICJOVjIxIiwKPj4gKwkJLmZvdXJjYyA9IFY0TDJfUElYX0ZNVF9O VjIxLAo+PiArCQkudHlwZSA9IEFNTF9GTVRfRlJBTUUsCj4+ICsJCS5jb2RlY190eXBlID0gQ09E RUNfVFlQRV9GUkFNRSwKPj4gKwkJLm51bV9wbGFuZXMgPSAxLAo+PiArCQkuc3RlcHdpc2UgPSB7 QU1MX1ZERUNfTUlOX1csIEFNTF9WREVDXzEwODBQX01BWF9XLCAyLAo+PiArCQkJQU1MX1ZERUNf TUlOX0gsIEFNTF9WREVDXzEwODBQX01BWF9ILCAyfSwKPj4gKwl9LAo+PiArCXsKPj4gKwkJLm5h bWUgPSAiTlYxMk0iLAo+PiArCQkuZm91cmNjID0gVjRMMl9QSVhfRk1UX05WMTJNLAo+PiArCQku dHlwZSA9IEFNTF9GTVRfRlJBTUUsCj4+ICsJCS5jb2RlY190eXBlID0gQ09ERUNfVFlQRV9GUkFN RSwKPj4gKwkJLm51bV9wbGFuZXMgPSAyLAo+PiArCQkuc3RlcHdpc2UgPSB7QU1MX1ZERUNfTUlO X1csIEFNTF9WREVDXzEwODBQX01BWF9XLCAyLAo+PiArCQkJQU1MX1ZERUNfTUlOX0gsIEFNTF9W REVDXzEwODBQX01BWF9ILCAyfSwKPj4gKwo+PiArCX0sCj4+ICsJewo+PiArCQkubmFtZSA9ICJO VjEyIiwKPj4gKwkJLmZvdXJjYyA9IFY0TDJfUElYX0ZNVF9OVjEyLAo+PiArCQkudHlwZSA9IEFN TF9GTVRfRlJBTUUsCj4+ICsJCS5jb2RlY190eXBlID0gQ09ERUNfVFlQRV9GUkFNRSwKPj4gKwkJ Lm51bV9wbGFuZXMgPSAxLAo+PiArCQkuc3RlcHdpc2UgPSB7QU1MX1ZERUNfTUlOX1csIEFNTF9W REVDXzEwODBQX01BWF9XLCAyLAo+PiArCQkJQU1MX1ZERUNfTUlOX0gsIEFNTF9WREVDXzEwODBQ X01BWF9ILCAyfSwKPj4gKwl9LAo+PiArfTsKPj4gKwo+PiArdm9pZCBhbWxfdmRlY19zZXRfZGVm YXVsdF9wYXJhbXMoc3RydWN0IGFtbF92ZGVjX2N0eCAqY3R4KQo+PiArewo+PiArCXN0cnVjdCBh bWxfcV9kYXRhICpxX2RhdGEgPSBOVUxMOwo+PiArCj4+ICsJY3R4LT5tMm1fY3R4LT5xX2xvY2sg PSAmY3R4LT52NGwyX2ludGZfbG9jazsKPj4gKwo+PiArCWN0eC0+cGljX2luZm8uY29sb3JzcGFj ZSA9IFY0TDJfQ09MT1JTUEFDRV9ERUZBVUxUOwo+PiArCWN0eC0+cGljX2luZm8ueWNiY3JfZW5j ID0gVjRMMl9ZQ0JDUl9FTkNfREVGQVVMVDsKPj4gKwljdHgtPnBpY19pbmZvLnF1YW50aXphdGlv biA9IFY0TDJfUVVBTlRJWkFUSU9OX0RFRkFVTFQ7Cj4+ICsJY3R4LT5waWNfaW5mby54ZmVyX2Z1 bmMgPSBWNEwyX1hGRVJfRlVOQ19ERUZBVUxUOwo+PiArCj4+ICsJcV9kYXRhID0gJmN0eC0+cV9k YXRhW0FNTF9RX0RBVEFfU1JDXTsKPj4gKwltZW1zZXQocV9kYXRhLCAwLCBzaXplb2Yoc3RydWN0 IGFtbF9xX2RhdGEpKTsKPj4gKwlxX2RhdGEtPnZpc2libGVfd2lkdGggPSBBTUxfVkRFQ19NSU5f VzsKPj4gKwlxX2RhdGEtPnZpc2libGVfaGVpZ2h0ID0gQU1MX1ZERUNfTUlOX0g7Cj4+ICsJcV9k YXRhLT5jb2RlZF93aWR0aCA9IEFNTF9WREVDX01JTl9XOwo+PiArCXFfZGF0YS0+Y29kZWRfaGVp Z2h0ID0gQU1MX1ZERUNfTUlOX0g7Cj4+ICsJcV9kYXRhLT5maWxlZF9mbGFnID0gVjRMMl9GSUVM RF9OT05FOwo+PiArCXFfZGF0YS0+Ynl0ZXNwZXJsaW5lWzBdID0gMDsKPj4gKwlxX2RhdGEtPnNp emVpbWFnZVswXSA9ICgxMDI0ICogMTAyNCk7Cj4+ICsJcV9kYXRhLT5mbXQgPSAmYW1sX3ZpZGVv X2Zvcm1hdHNbREVGQVVMVF9PVVRfSURYXTsKPj4gKwo+PiArCXFfZGF0YSA9ICZjdHgtPnFfZGF0 YVtBTUxfUV9EQVRBX0RTVF07Cj4+ICsJbWVtc2V0KHFfZGF0YSwgMCwgc2l6ZW9mKHN0cnVjdCBh bWxfcV9kYXRhKSk7Cj4+ICsJcV9kYXRhLT52aXNpYmxlX3dpZHRoID0gQU1MX1ZERUNfTUlOX1c7 Cj4+ICsJcV9kYXRhLT52aXNpYmxlX2hlaWdodCA9IEFNTF9WREVDX01JTl9IOwo+PiArCXFfZGF0 YS0+Y29kZWRfd2lkdGggPSBBTUxfVkRFQ19NSU5fVzsKPj4gKwlxX2RhdGEtPmNvZGVkX2hlaWdo dCA9IEFNTF9WREVDX01JTl9IOwo+PiArCXFfZGF0YS0+ZmlsZWRfZmxhZyA9IFY0TDJfRklFTERf Tk9ORTsKPj4gKwlxX2RhdGEtPmJ5dGVzcGVybGluZVswXSA9IHFfZGF0YS0+Y29kZWRfd2lkdGg7 Cj4+ICsJcV9kYXRhLT5zaXplaW1hZ2VbMF0gPSBxX2RhdGEtPmNvZGVkX3dpZHRoICogcV9kYXRh LT5jb2RlZF9oZWlnaHQ7Cj4+ICsJcV9kYXRhLT5ieXRlc3BlcmxpbmVbMV0gPSBxX2RhdGEtPmNv ZGVkX3dpZHRoOwo+PiArCXFfZGF0YS0+c2l6ZWltYWdlWzFdID0gcV9kYXRhLT5zaXplaW1hZ2Vb MF0gLyAyOwo+PiArCXFfZGF0YS0+Zm10ID0gJmFtbF92aWRlb19mb3JtYXRzW0RFRkFVTFRfQ0FQ X0lEWF07Cj4gV2h5IGRvIHlvdSBkdXBsaWNhdGVkIHZpc2libGUgYW5kIGNvZGVkIHdpZHRoID8g aG93IGNhbiB5b3UgaG9sZCB0d28gb2YgdGhlc2UgPwoKSW5kZWVkIHRoZSBkZWNvZGVyIGhhcmR3 YXJlIHdpbGwgb25seSB1c2UgY29kZWQgd2lkdGgvaGVpZ2h0LiBUaGV5IGFyZSAKdXNlZCB0byBj YWxjdWxhdGUKdGhlIG9mZnNldCBvZiB0aGUgY2hyb21hIGRhdGEgZnJvbSB0aGUgY2FwdHVyZSBi dWZmZXIuIEknbGwgcmVmZXIgdG8gCnNvbWUgdXBzdHJlYW1lZCBkcml2ZXJzCmFuZCBzZWUgaG93 IHRoZXkgaGFuZGxlIHRoZXNlIHR3byB2YWx1ZXMuCj4gQWxzbywgdG8gYXZvaWQgcG9zc2libGUg ZGV2aWF0ZSBpbiBzaXplaW1hZ2UvYnl0ZXNwZXJsaW5lIGNhbGN1bGF0aW9uLCBpbnRyb2R1Y2UK PiBzb21lIHJlc2V0IGZ1bmN0aW9uLCBhbmQgcGVyaGFwcyBtYWtlIHVzZSBvZiB5b3VyIGludGVy bmFsIGltcGxlbWVudGF0aW9uIG9mCj4gdHJ5X2ZtdC4KT0ssIEknbGwgcmVwbGFjZSB0aGlzIHdp dGggYSBwcm9wZXIgcmVzZXQgZnVuY3Rpb24uCj4+ICt9Cj4+ICsKPj4gK2ludCBhbWxfdmRlY19j dHJsc19zZXR1cChzdHJ1Y3QgYW1sX3ZkZWNfY3R4ICpjdHgpCj4+ICt7Cj4+ICsJaW50IGk7Cj4+ ICsJaW50IGN0cmxzX3NpemUgPSBzaXplb2YoY29udHJvbHMpIC8gc2l6ZW9mKHN0cnVjdCBhbWxf dmRlY192NGwyX2N0cmwpOwo+PiArCj4+ICsJdjRsMl9jdHJsX2hhbmRsZXJfaW5pdCgmY3R4LT5j dHJsX2hhbmRsZXIsIGN0cmxzX3NpemUpOwo+PiArCWZvciAoaSA9IDA7IGkgPCBjdHJsc19zaXpl OyBpKyspIHsKPj4gKwkJdjRsMl9jdHJsX25ld19jdXN0b20oJmN0eC0+Y3RybF9oYW5kbGVyLCAm Y29udHJvbHNbaV0uY2ZnLCBOVUxMKTsKPj4gKwkJaWYgKGN0eC0+Y3RybF9oYW5kbGVyLmVycm9y KSB7Cj4+ICsJCQlkZXZfaW5mbygmY3R4LT5kZXYtPnBsYXRfZGV2LT5kZXYsICJhZGQgY3RybCBm b3IgKCVkKSBmYWlsZWQlZFxuIiwKPj4gKwkJCQkgY29udHJvbHNbaV0uY2ZnLmlkLCBjdHgtPmN0 cmxfaGFuZGxlci5lcnJvcik7Cj4+ICsJCQl2NGwyX2N0cmxfaGFuZGxlcl9mcmVlKCZjdHgtPmN0 cmxfaGFuZGxlcik7Cj4+ICsJCQlyZXR1cm4gY3R4LT5jdHJsX2hhbmRsZXIuZXJyb3I7Cj4+ICsJ CX0KPj4gKwl9Cj4+ICsJY3R4LT5maC5jdHJsX2hhbmRsZXIgPSAmY3R4LT5jdHJsX2hhbmRsZXI7 Cj4+ICsJcmV0dXJuIHY0bDJfY3RybF9oYW5kbGVyX3NldHVwKCZjdHgtPmN0cmxfaGFuZGxlcik7 Cj4+ICt9Cj4+ICsKPj4gK3N0YXRpYyB2b2lkIG0ybW9wc192ZGVjX2RldmljZV9ydW4odm9pZCAq bTJtX3ByaXYpCj4+ICt7Cj4+ICsJc3RydWN0IGFtbF92ZGVjX2N0eCAqY3R4ID0gKHN0cnVjdCBh bWxfdmRlY19jdHggKiltMm1fcHJpdjsKPiBObyBuZWVkIHRvIGNhc3Qgdm9pZCoKR290IGl0IQo+ Cj4+ICsJc3RydWN0IGFtbF92ZGVjX2RldiAqZGV2ID0gY3R4LT5kZXY7Cj4+ICsJc3RydWN0IHZi Ml92NGwyX2J1ZmZlciAqc3JjLCAqZHN0Owo+IG5pdDogc3JjX2J1ZiwgZHN0X2J1ZgpPSywgSSds bCByZW5hbWUgdGhlbS4KPgo+PiArCXN0cnVjdCBtZWRpYV9yZXF1ZXN0ICpzcmNfcmVxOwo+PiAr CWNvbnN0IGNoYXIgKmZ3X3BhdGggPSBkZXYtPnB2ZGVjX2RhdGEtPmZ3X3BhdGhbY3R4LT5jdXJy X2RlY190eXBlXTsKPj4gKwo+PiArCXNyYyA9IHY0bDJfbTJtX25leHRfc3JjX2J1ZihjdHgtPmZo Lm0ybV9jdHgpOwo+PiArCWRzdCA9IHY0bDJfbTJtX25leHRfZHN0X2J1ZihjdHgtPmZoLm0ybV9j dHgpOwo+PiArCWRldl9kYmcoJmRldi0+cGxhdF9kZXYtPmRldiwgImRldmljZSBydW4gOiBzcmMg YnVmIDogJWQgZHN0IGJ1ZiAlZFxuIiwKPj4gKwkJc3JjLT52YjJfYnVmLmluZGV4LCBkc3QtPnZi Ml9idWYuaW5kZXgpOwo+PiArCj4+ICsJc3JjX3JlcSA9IHNyYy0+dmIyX2J1Zi5yZXFfb2JqLnJl cTsKPj4gKwlpZiAoc3JjX3JlcSkKPj4gKwkJdjRsMl9jdHJsX3JlcXVlc3Rfc2V0dXAoc3JjX3Jl cSwgJmN0eC0+Y3RybF9oYW5kbGVyKTsKPiBJJ2xsIG5lZWQgdG8gY2hlY2ssIG5vdCBhbGwgZHJp dmVycyBkbyB0aGVzZSBjaGVjaywgeWV0IEkgaGF2ZW4ndCBmb3VuZCBpbiB0aGUKPiBjb3JlIHdo ZXJlIHdlIHByZXZlbnQgdGhpcyBmcm9tIGhhcHBlbmluZy4gSSB3YW50IHRoZSBjb3JlIHRvIHBy ZXZlbnQgdGhpcyBzbyB3ZQo+IGNhbiByZW1vdmUgYWxsIHRoZXNlIGNoZWNrcywgYnV0IEknbSBh IGJpdCB1bnN1cmUgbm93LgpHb3QgaXQuIElmIHlvdSB0aGluayB0aGlzIGNhbiBiZSByZW1vdmVk LCBwbGVhc2UgZmVlbCBmcmVlIHRvIGluZm9ybSBtZSwgCnRoYW5rcyEKPj4gKwo+PiArCWRvc19l bmFibGUoZGV2LT5kZWNfaHcpOwo+PiArCS8qIGluY2FzZSBvZiBidXMgaGFuZyBpbiBzdG9wX3N0 cmVhbWluZyAqLwo+PiArCWN0eC0+ZG9zX2Nsa19lbiA9IDE7Cj4+ICsJYW1sX3ZkZWNfcmVzZXRf Y29yZShkZXYtPmRlY19odyk7Cj4+ICsJbG9hZF9maXJtd2FyZShkZXYtPmRlY19odywgZndfcGF0 aCk7Cj4+ICsKPj4gKwlpZiAoY3R4LT5jb2RlY19vcHMtPnJ1bikKPj4gKwkJY3R4LT5jb2RlY19v cHMtPnJ1bihjdHgpOwo+IHVzZSBpZiAoIUJVR19PTihjdHgtPmNvZGVjX29wcy0+cnVuID09IE5V TEwpKSwgaXQgd291bGQgYmUgZHJpdmVyIHByb2dyYW1taW5nCj4gZXJyb3IgdG8gbm90IGhhdmUg YSBmdW4gZnVuY3Rpb24uClllcywgSSdsbCBhZGQgdGhlIEJVR19PTiBoZXJlLgo+Cj4+ICsKPj4g Kwl2NGwyX20ybV9idWZfY29weV9tZXRhZGF0YShzcmMsIGRzdCk7Cj4+ICsJaWYgKHNyY19yZXEp Cj4+ICsJCXY0bDJfY3RybF9yZXF1ZXN0X2NvbXBsZXRlKHNyY19yZXEsICZjdHgtPmN0cmxfaGFu ZGxlcik7Cj4+ICsKPj4gKwl2NGwyX20ybV9idWZfZG9uZV9hbmRfam9iX2ZpbmlzaChkZXYtPm0y bV9kZXZfZGVjLCBjdHgtPm0ybV9jdHgsIFZCMl9CVUZfU1RBVEVfRE9ORSk7Cj4gVGhpcyBpcyBh dHlwaWNhbCwgbm9ybWFsbHkgd2UgY2FsbCB0aGlzIHdoZW4gd2UgcmVjZWl2ZSB0aGUgSVJRLCB0 aGF0IGF2b2lkCj4gaGF2aW5nIHRvIHBvbGwsIGFuZCByZW1vdmUgYSB1c2VsZXNzIGNvbnRleHQg c3dpdGNoLgpPSywgSSdsbCBtb3ZlIGl0IHRvIHRoZSBJUlEgZnVuY3Rpb24uIEluIGZhY3QsIEkg aGF2ZW4ndCBsb29rZWQgaW50byB0aGUgCmltcGxlbWVudGF0aW9uIGRldGFpbHMgb2YgdGhpcyBm dW5jdGlvbiB5ZXQuwqBJJ2xsIGdvIGFuZCBzdHVkeSBpdC4KPj4gK30KPj4gKwo+PiArY29uc3Qg c3RydWN0IHY0bDJfbTJtX29wcyBhbWxfdmRlY19tMm1fb3BzID0gewo+PiArCS5kZXZpY2VfcnVu ID0gbTJtb3BzX3ZkZWNfZGV2aWNlX3J1biwKPj4gK307Cj4+ICsKPj4gK3N0YXRpYyBpbnQgdmlk aW9jX3ZkZWNfcXVlcnljYXAoc3RydWN0IGZpbGUgKmZpbGUsIHZvaWQgKnByaXYsCj4+ICsJCQkJ c3RydWN0IHY0bDJfY2FwYWJpbGl0eSAqY2FwKQo+PiArewo+PiArCXN0cnNjcHkoY2FwLT5kcml2 ZXIsIFZDT0RFQ19EUlZfTkFNRSwgc2l6ZW9mKGNhcC0+ZHJpdmVyKSk7Cj4+ICsJc3Ryc2NweShj YXAtPmNhcmQsICJwbGF0Zm9ybToiIFZDT0RFQ19EUlZfTkFNRSwgc2l6ZW9mKGNhcC0+Y2FyZCkp Owo+PiArCj4+ICsJcmV0dXJuIDA7Cj4+ICt9Cj4+ICsKPj4gK3N0YXRpYyBpbnQgdmlkaW9jX3Zk ZWNfZW51bV9mbXQoc3RydWN0IHY0bDJfZm10ZGVzYyAqZiwgYm9vbCBpc19vdXRwdXQpCj4+ICt7 Cj4+ICsJc3RydWN0IGFtbF92aWRlb19mbXQgKmZtdDsKPj4gKwlpbnQgZm10X3NpemUgPSBzaXpl b2YoYW1sX3ZpZGVvX2Zvcm1hdHMpIC8gc2l6ZW9mKHN0cnVjdCBhbWxfdmlkZW9fZm10KTsKPj4g KwlpbnQgaSA9IDAsIGogPSAwOwo+PiArCj4+ICsJZm9yICg7IGkgPCBmbXRfc2l6ZTsgaSsrKSB7 Cj4+ICsJCWZtdCA9ICZhbWxfdmlkZW9fZm9ybWF0c1tpXTsKPj4gKwkJaWYgKGlzX291dHB1dCAm JiBmbXQtPnR5cGUgIT0gQU1MX0ZNVF9ERUMpCj4+ICsJCQljb250aW51ZTsKPj4gKwkJaWYgKCFp c19vdXRwdXQgJiYgZm10LT50eXBlICE9IEFNTF9GTVRfRlJBTUUpCj4+ICsJCQljb250aW51ZTsK Pj4gKwo+PiArCQlpZiAoaiA9PSBmLT5pbmRleCkgewo+PiArCQkJZi0+cGl4ZWxmb3JtYXQgPSBm bXQtPmZvdXJjYzsKPj4gKwkJCXN0cnNjcHkoZi0+ZGVzY3JpcHRpb24sIGZtdC0+bmFtZSwKPj4g KwkJCQlzaXplb2YoZi0+ZGVzY3JpcHRpb24pKTsKPiBUaGVyZSBpcyBhIG1lbW9yeSBib3VuZGVk IHZlcnNpb24gb2YgdGhpcywgYW5kIHRoZXNlIGFyZSBmaXhlZCBzaXplIGNoYXIgYXJyYXksCj4g cGxlYXNlIHVzZSB0aGVzZS4KR290IGl0Lgo+PiArCQkJaWYgKHN0cmxlbihmbXQtPm5hbWUpID49 IHNpemVvZihmLT5kZXNjcmlwdGlvbikpCj4+ICsJCQkJZi0+ZGVzY3JpcHRpb25bc2l6ZW9mKGYt PmRlc2NyaXB0aW9uKSAtIDFdID0gJ1wwJzsKPiBzdHJjcHkoKSB3b3VsZCBiZSB0aGUgcHJlZmVy cmVkIGhlbHBlciBmb3IgdGhpcywgbm8gbmVlZCB0byBmaWxsIHRoZSBsZWFkaW5nCj4gemVybyBs aWVrIHRoaXMsIHNlZSBpbmNsdWRlL2xpbnV4L3N0cmluZy5oCk9rLCBpdCBzaG91bGQgYmUgbW9y ZSBzdWl0YWJsZSB0byB1c2Ugc3RyY3B5Lgo+Cj4+ICsJCQlyZXR1cm4gMDsKPj4gKwkJfQo+PiAr CQkrK2o7Cj4+ICsJfQo+PiArCXJldHVybiAtRUlOVkFMOwo+PiArfQo+PiArCj4+ICtzdGF0aWMg c3RydWN0IGFtbF9xX2RhdGEgKmFtbF92ZGVjX2dldF9xZGF0YV9ieV90eXBlKHN0cnVjdCBhbWxf dmRlY19jdHggKmN0eCwKPj4gKwkJCQkJCcKgwqDCoMKgIGVudW0gdjRsMl9idWZfdHlwZSB0eXBl KQo+PiArewo+PiArCWlmIChWNEwyX1RZUEVfSVNfT1VUUFVUKHR5cGUpKQo+PiArCQlyZXR1cm4g JmN0eC0+cV9kYXRhW0FNTF9RX0RBVEFfU1JDXTsKPj4gKwo+PiArCXJldHVybiAmY3R4LT5xX2Rh dGFbQU1MX1FfREFUQV9EU1RdOwo+PiArfQo+PiArCj4+ICtzdGF0aWMgc3RydWN0IGFtbF92aWRl b19mbXQgKmFtbF92ZGVjX2dldF92aWRlb19mbXQodTMyIGZvcm1hdCkKPj4gK3sKPj4gKwlzdHJ1 Y3QgYW1sX3ZpZGVvX2ZtdCAqZm10Owo+PiArCXVuc2lnbmVkIGludCBrOwo+PiArCj4+ICsJZm9y IChrID0gMDsgayA8IChzaXplb2YoYW1sX3ZpZGVvX2Zvcm1hdHMpIC8gc2l6ZW9mKHN0cnVjdCBh bWxfdmlkZW9fZm10KSk7IGsrKykgewo+IEFSUkFZX1NJWkUgZ2FpbiwgcGxlYXNlIGFwcGx5IHRo cm91Z2ggdGhlIGVudGlyZSBwYXRjaC4KT0ssIHRoaXMgc2hvdWxkIGJlIHJlcGxhY2VkIHdpdGgg QVJSQVJfU0laRS4KPj4gKwkJZm10ID0gJmFtbF92aWRlb19mb3JtYXRzW2tdOwo+PiArCQlpZiAo Zm10LT5mb3VyY2MgPT0gZm9ybWF0KQo+PiArCQkJcmV0dXJuIGZtdDsKPj4gKwl9Cj4+ICsKPj4g KwlyZXR1cm4gTlVMTDsKPj4gK30KPj4gKwo+PiArc3RhdGljIGludCBhbWxfdmRlY19pbml0X2Rl Y19pbnN0KHN0cnVjdCBhbWxfdmRlY19jdHggKmN0eCwKPj4gKwkJCQnCoCBzdHJ1Y3QgYW1sX3Zp ZGVvX2ZtdCAqZm10X291dCkKPj4gK3sKPj4gKwlzdHJ1Y3QgYW1sX3ZkZWNfZGV2ICpkZXYgPSBj dHgtPmRldjsKPj4gKwlpbnQgcmV0ID0gLTE7Cj4+ICsKPj4gKwlpZiAoIWZtdF9vdXQpCj4+ICsJ CXJldHVybiByZXQ7Cj4+ICsKPj4gKwlpZiAoZm10X291dC0+Y29kZWNfdHlwZSA9PSBDT0RFQ19U WVBFX0ZSQU1FKSB7Cj4+ICsJCWRldl9kYmcoJmRldi0+cGxhdF9kZXYtPmRldiwgImNhcHR1cmUg dHlwZSBubyBuZWVkIHRvIHNldFxuIik7Cj4+ICsJCXJldHVybiAwOwo+PiArCX0KPj4gKwo+PiAr CWN0eC0+Y29kZWNfb3BzID0gJmRldi0+cHZkZWNfZGF0YS0+Y29kZWNfb3BzW2ZtdF9vdXQtPmNv ZGVjX3R5cGVdOwo+PiArCWlmIChjdHgtPmNvZGVjX29wcy0+aW5pdCkgewo+PiArCQlyZXQgPSBj dHgtPmNvZGVjX29wcy0+aW5pdChjdHgpOwo+PiArCQlpZiAocmV0IDwgMCkKPj4gKwkJCXJldHVy biByZXQ7Cj4+ICsJfQo+PiArCWN0eC0+Y3Vycl9kZWNfdHlwZSA9IGZtdF9vdXQtPmNvZGVjX3R5 cGU7Cj4+ICsJZGV2X2luZm8oJmRldi0+cGxhdF9kZXYtPmRldiwgIiVzIHNldCBjdXJyX2RlY190 eXBlID0gJWRcbiIsIF9fZnVuY19fLCBjdHgtPmN1cnJfZGVjX3R5cGUpOwo+IEkgbm90IHN1cmUg SSB3YW50IHRvIHNlZSBhIG51bWVyaWNhbCB2YWx1ZSBvZiBhbiByYW5kb20gZW51bSBmcm9tIHRo ZSBjb2RlIGZyb20KPiBhIGRldl9pbmZvKCksIHBsZWFzZSB1c2UgZGV2X2luZm8oKSB3aXRoIHRo ZSBtaW5kc2V0IHRoYXQgaWYgeW91IG5lZWQgdG8gY2hlY2sKPiB0aGUgY29kZSB0byBzZWUgd2hh dCBpdCBtZWFucywgaXRzIG5vdCBhIGRldl9pbmZvKCkuClllcywgSSdsbCBhZGQgZm9ybWF0IHN0 cmluZ3MgdG8gdGhpcyBtZXNzYWdlLiBJdCBjYW4gaGVscCBvdGhlcnMgdG8gCnVuZGVyc3RhbmQg d2hhdCBpcyBoYXBwZW5pbmcuCj4KPj4gKwo+PiArCXJldHVybiByZXQ7Cj4+ICt9Cj4+ICsKPj4g K3N0YXRpYyB2b2lkIHNldF9waWNfaW5mbyhzdHJ1Y3QgYW1sX3ZkZWNfY3R4ICpjdHgsCj4+ICsJ CQkgc3RydWN0IHY0bDJfcGl4X2Zvcm1hdF9tcGxhbmUgKnBpeF9tcCwKPj4gKwkJCSBlbnVtIHY0 bDJfYnVmX3R5cGUgdHlwZSkKPj4gK3sKPj4gKwlzdHJ1Y3QgYW1sX3FfZGF0YSAqcV9kYXRhOwo+ PiArCj4+ICsJcV9kYXRhID0gYW1sX3ZkZWNfZ2V0X3FkYXRhX2J5X3R5cGUoY3R4LCB0eXBlKTsK Pj4gKwo+PiArCWN0eC0+cGljX2luZm8uY29sb3JzcGFjZSA9IHBpeF9tcC0+Y29sb3JzcGFjZTsK Pj4gKwljdHgtPnBpY19pbmZvLnljYmNyX2VuYyA9IHBpeF9tcC0+eWNiY3JfZW5jOwo+PiArCWN0 eC0+cGljX2luZm8ucXVhbnRpemF0aW9uID0gcGl4X21wLT5xdWFudGl6YXRpb247Cj4+ICsJY3R4 LT5waWNfaW5mby54ZmVyX2Z1bmMgPSBwaXhfbXAtPnhmZXJfZnVuYzsKPj4gKwo+PiArCWlmIChW NEwyX1RZUEVfSVNfT1VUUFVUKHR5cGUpKSB7Cj4+ICsJCXFfZGF0YS0+c2l6ZWltYWdlWzBdID0g cGl4X21wLT5wbGFuZV9mbXRbMF0uc2l6ZWltYWdlOwo+PiArCQljdHgtPnBpY19pbmZvLm91dHB1 dF9waXhfZm10ID0gcGl4X21wLT5waXhlbGZvcm1hdDsKPj4gKwkJY3R4LT5waWNfaW5mby5jb2Rl ZF93aWR0aCA9IEFMSUdOKHBpeF9tcC0+d2lkdGgsIDY0KTsKPj4gKwkJY3R4LT5waWNfaW5mby5j b2RlZF9oZWlnaHQgPSBBTElHTihwaXhfbXAtPmhlaWdodCwgNjQpOwo+PiArCQljdHgtPnBpY19p bmZvLmZiX3NpemVbMF0gPQo+PiArCQnCoMKgwqAgY3R4LT5waWNfaW5mby5jb2RlZF93aWR0aCAq IGN0eC0+cGljX2luZm8uY29kZWRfaGVpZ2h0Owo+PiArCQljdHgtPnBpY19pbmZvLmZiX3NpemVb MV0gPSBjdHgtPnBpY19pbmZvLmZiX3NpemVbMF0gLyAyOwo+PiArCQljdHgtPnBpY19pbmZvLnBs YW5lX251bSA9IDE7Cj4+ICsJfSBlbHNlIHsKPj4gKwkJY3R4LT5waWNfaW5mby5wbGFuZV9udW0g PSBxX2RhdGEtPmZtdC0+bnVtX3BsYW5lczsKPj4gKwkJY3R4LT5waWNfaW5mby5jYXBfcGl4X2Zt dCA9IHBpeF9tcC0+cGl4ZWxmb3JtYXQ7Cj4+ICsJCXFfZGF0YS0+Y29kZWRfd2lkdGggPSBjdHgt PnBpY19pbmZvLmNvZGVkX3dpZHRoOwo+PiArCQlxX2RhdGEtPmNvZGVkX2hlaWdodCA9IGN0eC0+ cGljX2luZm8uY29kZWRfaGVpZ2h0Owo+PiArCQlxX2RhdGEtPnNpemVpbWFnZVswXSA9IGN0eC0+ cGljX2luZm8uZmJfc2l6ZVswXTsKPj4gKwkJcV9kYXRhLT5ieXRlc3BlcmxpbmVbMF0gPSBjdHgt PnBpY19pbmZvLmNvZGVkX3dpZHRoOwo+PiArCQlpZiAocV9kYXRhLT5mbXQtPm51bV9wbGFuZXMg PiAxKSB7Cj4+ICsJCQlxX2RhdGEtPnNpemVpbWFnZVsxXSA9IGN0eC0+cGljX2luZm8uZmJfc2l6 ZVsxXTsKPj4gKwkJCXFfZGF0YS0+Ynl0ZXNwZXJsaW5lWzFdID0gY3R4LT5waWNfaW5mby5jb2Rl ZF93aWR0aDsKPj4gKwkJfSBlbHNlIHsKPj4gKwkJCXFfZGF0YS0+c2l6ZWltYWdlWzBdICs9IGN0 eC0+cGljX2luZm8uZmJfc2l6ZVsxXTsKPj4gKwkJfQo+PiArCX0KPgo+IFdoeSBkb24ndCB5b3Ug c2ltcGx5IHN0b3JlIHRoZSBmb3JtYXQgc3RydWN0dXJlID8gd2lkdGgvaGVpZ2h0IGFsaWdubWVu dCBpcyB3ZWxsCj4gY292ZXJlZCBpbiB2NGwyLWNvbW1vbiwgdXNlIHRoZSBoZWxwZXJzLiBSZS11 c2UgeW91ciB0cnlfZm10IGltcGxlbWVudGF0aW9uIGZvcgo+IHRoaXMgdG9vLCBhbmQgbWFrZXMg c3VyZSB0aGUgY2hhbmdlcyBhcmUgcmVmbGVjdGVkIHRvIHVzZXJzLgpZZXMsIHRoaXMgc2VlbXMg dG9vIGNvbXBsaWNhdGUgYW5kIHN1cGVyZmx1b3VzLiBJJ2xsIHNpbXBsaWZ5IHRoaXMuCj4gRmlu YWxseSwgZG9uJ3QgZHVwbGljYXRlIHRoZSBkYXRhLCBpdHMgYWxsIHZlcnkgZXJyb3IgcHJvbmUu IFlvdSBoYXZlIHBpY19pbmZvCj4gc3RvcmVkIGluIDMgcGxhY2VzIG5vdy4KT0ssIEknbGwgZml4 IHRoaXMgcHJvYmxlbS4KPgo+PiArfQo+PiArCj4+ICtzdGF0aWMgaW50IHZpZGlvY192ZGVjX2Vu dW1fZnJhbWVzaXplcyhzdHJ1Y3QgZmlsZSAqZmlsZSwgdm9pZCAqcHJpdiwKPj4gKwkJCQnCoMKg wqDCoMKgwqAgc3RydWN0IHY0bDJfZnJtc2l6ZWVudW0gKmZzaXplKQo+PiArewo+PiArCXN0cnVj dCBhbWxfdmlkZW9fZm10ICpmbXQ7Cj4+ICsJc3RydWN0IGFtbF92ZGVjX2RldiAqZGV2ID0gdmlk ZW9fZHJ2ZGF0YShmaWxlKTsKPj4gKwl1MzIgbWF4X2gsIG1heF93Owo+PiArCj4+ICsJaWYgKGZz aXplLT5pbmRleCAhPSAwKQo+PiArCQlyZXR1cm4gLUVJTlZBTDsKPj4gKwo+PiArCW1heF9oID0g ZGV2LT5wdmRlY19kYXRhLT5kZWNfZm10LT5tYXhfaGVpZ2h0Owo+PiArCW1heF93ID0gZGV2LT5w dmRlY19kYXRhLT5kZWNfZm10LT5tYXhfd2lkdGg7Cj4+ICsKPj4gKwlmbXQgPSBhbWxfdmRlY19n ZXRfdmlkZW9fZm10KGZzaXplLT5waXhlbF9mb3JtYXQpOwo+PiArCWlmICghZm10KQo+PiArCQly ZXR1cm4gLUVJTlZBTDsKPj4gKwo+PiArCWZzaXplLT50eXBlID0gVjRMMl9GUk1TSVpFX1RZUEVf U1RFUFdJU0U7Cj4+ICsJZnNpemUtPnN0ZXB3aXNlID0gZm10LT5zdGVwd2lzZTsKPj4gKwlmc2l6 ZS0+c3RlcHdpc2UubWF4X2hlaWdodCA9IG1heF9oOwo+PiArCWZzaXplLT5zdGVwd2lzZS5tYXhf d2lkdGggPSBtYXhfdzsKPiBubyBtaW4gPyBOb3JtYWxseSB1bmRlciAxeDEgaXMgbm90IGFsbG93 ZWQuClRoZSBtaW4gd2lkdGggeCBoZWlnaHQgc2hvdWxkIGJlIDY0IHggNjQgZm9yIFM4MDVYMiBw bGF0Zm9ybS4gVGhpcyAKc2hvdWxkIGJlIGFkZGVkLgo+PiArCj4+ICsJcmV0dXJuIDA7Cj4+ICt9 Cj4+ICsKPj4gK3N0YXRpYyBpbnQgdmRlY190cnlfZm10X21wKHN0cnVjdCBhbWxfdmRlY19jdHgg KmN0eCwgc3RydWN0IHY0bDJfZm9ybWF0ICpmLAo+PiArCQkJwqDCoCBjb25zdCBzdHJ1Y3QgYW1s X3ZpZGVvX2ZtdCAqZm10X21wKQo+PiArewo+PiArCXN0cnVjdCB2NGwyX3BpeF9mb3JtYXRfbXBs YW5lICpwaXhfbXAgPSAmZi0+Zm10LnBpeF9tcDsKPj4gKwlzdHJ1Y3QgYW1sX3FfZGF0YSAqcV9k YXRhOwo+PiArCXN0cnVjdCBhbWxfdmRlY19kZXYgKmRldiA9IGN0eC0+ZGV2Owo+PiArCXUzMiBt YXhfaCwgbWF4X3c7Cj4+ICsJaW50IGk7Cj4+ICsKPj4gKwltYXhfaCA9IGRldi0+cHZkZWNfZGF0 YS0+ZGVjX2ZtdC0+bWF4X2hlaWdodDsKPj4gKwltYXhfdyA9IGRldi0+cHZkZWNfZGF0YS0+ZGVj X2ZtdC0+bWF4X3dpZHRoOwo+PiArCj4+ICsJcGl4X21wLT5maWVsZCA9IFY0TDJfRklFTERfTk9O RTsKPj4gKwlxX2RhdGEgPSBhbWxfdmRlY19nZXRfcWRhdGFfYnlfdHlwZShjdHgsIGYtPnR5cGUp Owo+IEknbSBub3Qgc3VyZSBpdCBoZWxwcyBhbnl0aGluZyB0byB1c2UgcWRhdGEuCgpJdCB3YXMg aW5oZXJpdGVkIGZyb20gdGhlIGxlZ2FjeSBjb2RlIGFjdHVhbGx5LCB1c2VkIGZvciB0aGUgZGVm YXVsdCAKZGF0YSBzdG9yYWdlLiBJJ2xsIHRyeSB0byB1c2Ugc29tZSBvdGhlciBtZXRob2RzIHRv IGltcHJvdmUgdGhpcy4KCj4+ICsKPj4gKwlwaXhfbXAtPmhlaWdodCA9IGNsYW1wKHBpeF9tcC0+ aGVpZ2h0LCBBTUxfVkRFQ19NSU5fSCwgbWF4X2gpOwo+PiArCXBpeF9tcC0+d2lkdGggPSBjbGFt cChwaXhfbXAtPndpZHRoLCBBTUxfVkRFQ19NSU5fSCwgbWF4X3cpOwo+PiArCj4+ICsJaWYgKFY0 TDJfVFlQRV9JU19PVVRQVVQoZi0+dHlwZSkpIHsKPj4gKwkJcGl4X21wLT5udW1fcGxhbmVzID0g cV9kYXRhLT5mbXQtPm51bV9wbGFuZXM7Cj4+ICsJCXBpeF9tcC0+cGl4ZWxmb3JtYXQgPSBxX2Rh dGEtPmZtdC0+Zm91cmNjOwo+PiArCQlwaXhfbXAtPnBsYW5lX2ZtdFswXS5ieXRlc3BlcmxpbmUg PSBxX2RhdGEtPmJ5dGVzcGVybGluZVswXTsKPiBXaGF0IHdvdWxkIHlvdSB1c2UgYnl0ZXNwZXJs aW5lIChzdHJpZGUpIGZvciBvbiBhIGJpdHN0cnJlYW0gYnVmZmVyID8gUmVzZXQgdGhpcwo+IHRv IHplcm8gYXQgYmVzdC4KWWVzLCB0aGlzIGNhbiBiZSByZXNldCB0byAwLgo+Cj4+ICsJCXBpeF9t cC0+cGxhbmVfZm10WzBdLnNpemVpbWFnZSA9IHFfZGF0YS0+c2l6ZWltYWdlWzBdOwo+IEFwcGxp Y2F0aW9uIHNob3VsZCBiZSBhYmxlIHRvIGNob3NlIGEgc2l6ZSBoZXJlLiBBbHNvIGl0IG1ha2Ug bm8gc2Vuc2UgdG8gdXNlZAo+IGFueSBjYWNoZWQgdmFsdWUuIEJhc2ljYWxseToKPgo+IDEuIElm IGl0cyB6ZXJvLCBjb21wdXRlIGEgc2l6ZSwgY2hlY2sgd2hhdCBvdGhlciBkcml2ZXJzIGRvCj4g Mi4gT3RoZXJ3aXNlIGtlZXAgYXBwbGljYXRpb24gcHJvdmlkZWQgc2l6ZSwgYnV0IGFsaWduIGl0 IGZvciB5b3VyIEhXCkdvdCBpdCEgSSBzaG91bGQgbm90IGJlIGdpdmVuIGEgY2FjYWhlZCB2YWx1 ZS4gSXQgc2hvdWxkIGJlIGdpdmVuIHZhbHVlIApieSB0aGUgdXNlci4gSSdsbCBmaXggdGhpcy4K PiBJbiBTX0ZNVCwgaWYgdGhhdCBjYWxsIHN1Y2NlZWQsIGFuZCB0aGUgcXVldWUgaXNuJ3QgYnVz eSwgeW91IHdpbGwgcmVzZXQgdGhlCj4gQ0FQVFVSRSBmb3JtYXQgdG8ga2VlcCBpdCBtYXRjaGlu Zy4KR290IGl0Lgo+Cj4+ICsJfSBlbHNlIHsKPj4gKwkJdjRsMl9maWxsX3BpeGZtdF9tcChwaXhf bXAsIGZtdF9tcC0+Zm91cmNjLCBwaXhfbXAtPndpZHRoLAo+PiArCQkJCcKgwqDCoCBwaXhfbXAt PmhlaWdodCk7Cj4gV2l0aCBhIHByb3BlciByZXNldCwgeW91IHdpbGwgc2ltcGx5IGNvcHkgdGhl IGZtdCB5b3UgaGF2ZSBzdG9yZWQgYWxyZWFkeS4KT0ssIEknbGwgY2hlY2sgbXkgY29kZSBjYXJl ZnVsbHkgYW5kIHNlZSBpZiB0aGlzIGNhbiBiZSBpbXByb3ZlZC4KPgo+PiArCX0KPj4gKwo+PiAr CWZvciAoaSA9IDA7IGkgPCBwaXhfbXAtPm51bV9wbGFuZXM7IGkrKykKPj4gKwkJbWVtc2V0KCZw aXhfbXAtPnBsYW5lX2ZtdFtpXS5yZXNlcnZlZFswXSwgMHgwLAo+PiArCQnCoMKgwqDCoMKgwqAg c2l6ZW9mKHBpeF9tcC0+cGxhbmVfZm10WzBdLnJlc2VydmVkKSk7Cj4+ICsKPj4gKwltZW1zZXQo cGl4X21wLT5yZXNlcnZlZCwgMHgwLCBzaXplb2YocGl4X21wLT5yZXNlcnZlZCkpOwo+PiArCXBp eF9tcC0+ZmxhZ3MgPSAwOwo+IFRoZSBjb3JlIGlzIHN1cHBvc2UgdG8gdGFrZSBjYXJlLgpZb3Ug bWVhbiB0aGUgVjRMMiBjb3JlPyBUaGVuIEkgd2lsbCByZW1vdmUgdGhpcy4KPgo+PiArCj4+ICsJ cmV0dXJuIDA7Cj4+ICt9Cj4+ICsKPj4gK3N0YXRpYyBpbnQgdmRlY19zX2ZtdChzdHJ1Y3QgYW1s X3ZkZWNfY3R4ICpjdHgsIHN0cnVjdCB2NGwyX2Zvcm1hdCAqZikKPj4gK3sKPj4gKwlzdHJ1Y3Qg YW1sX3FfZGF0YSAqcV9kYXRhOwo+PiArCXN0cnVjdCB2NGwyX3BpeF9mb3JtYXRfbXBsYW5lICpw aXhfbXAgPSAmZi0+Zm10LnBpeF9tcDsKPj4gKwlzdHJ1Y3QgYW1sX3ZpZGVvX2ZtdCAqZm10ID0K Pj4gKwnCoMKgwqAgYW1sX3ZkZWNfZ2V0X3ZpZGVvX2ZtdChmLT5mbXQucGl4X21wLnBpeGVsZm9y bWF0KTsKPj4gKwo+PiArCXFfZGF0YSA9IGFtbF92ZGVjX2dldF9xZGF0YV9ieV90eXBlKGN0eCwg Zi0+dHlwZSk7Cj4+ICsKPj4gKwlpZiAoZm10KQkvKiBkZWZhdWx0IGZtdCB3YXMgc2V0IGluIGZv cGVuICovCj4+ICsJCXFfZGF0YS0+Zm10ID0gZm10Owo+IFlvdSBzaG91bGQgbm90IHdyaXRlIGlu dG8gdGhlIHN0YXRlIGJlZm9yZSB0cnlfZm10LCBhbmQgd2l0aG91dCBjaGVja2luZyBpZiB0aGUK PiBxdWV1ZXMgYXJlIGJ1c3kgb3Igbm90LiBBbHMsIFNfRk1UKE9VVFBVVCkgd2lsbCByZXNldCB0 aGUgY2FwdHVyZSBmb3JtYXQgdG8KPiBtYXRjaCwgc28gaXQgcmVxdWlyZXMgYm90aCBxdWV1ZXMg dG8gbm90IGJlIGFjdGl2ZS4gQ2hlY2sgb3RoZXIgZHJpdmVycyBwbGVhc2UuCk9LLCBJIHdhbnNu J3QgdmVyeSBjbGVhciBhYm91dCB0aGUgYmVoYXZpb3VyIGJlZm9yZS4gSSAnbGwgcmVmZXIgdG8g Cm90aGVyIHVwc3RyZWFtZWQgZHJpdmVycyBhbmQgaW1wcm92ZSB0aGlzLgo+Cj4gSSdsbCBzdG9w IGhlcmUsIEkgdGhpbmsgeW91IHNob3VsZCByZXdvcmsgeW91ciBzcmMvZHN0IGZvcm1hdCBzdG9y YWdlLiBNYWtlIHVzZQo+IG9mIHY0bDItY29tbW9uLiBTaW5jZSB5b3UgcGxhbiB0byBtYWtlIHRo aXMgbXVsdGktdmFyaWFudCwgYWRkIHN0cnVjdHVyZSB0bwo+IHN0b3JlIHRoI2UgYWxpZ25tZW50 IHBlci1zb2MvcGVyLWNvZGVjIGV0Yy4KVGhhbmsgeW91IHNvIG11Y2ggZm9yIHBvaW50aW5nIG91 dCBhbGwgdGhlc2UgaXNzdWVzICEgSSdsbCBpbXByb3ZlIGFsbCAKdGhlIHBvaW50cyB5b3UgbWVu dGlvbmVkIGluIHRoZSBuZXh0IHBhdGNoIHZlcnNpb24uCj4KPiByZWdhcmRzLAo+IE5pY29sYXMK CkJlc3QgcmVnYXJkcwoKWmhlbnRhbwoKPj4gKwo+PiArCXZkZWNfdHJ5X2ZtdF9tcChjdHgsIGYs IHFfZGF0YS0+Zm10KTsKPj4gKwlzZXRfcGljX2luZm8oY3R4LCBwaXhfbXAsIGYtPnR5cGUpOwo+ PiArCj4+ICsJcmV0dXJuIDA7Cj4+ICt9Cj4+ICsKPj4gK3N0YXRpYyBpbnQgdmRlY19nX2ZtdChz dHJ1Y3QgYW1sX3ZkZWNfY3R4ICpjdHgsIHN0cnVjdCB2NGwyX2Zvcm1hdCAqZikKPj4gK3sKPj4g KwlzdHJ1Y3QgdjRsMl9waXhfZm9ybWF0X21wbGFuZSAqcGl4X21wID0gJmYtPmZtdC5waXhfbXA7 Cj4+ICsJc3RydWN0IGFtbF9xX2RhdGEgKnFfZGF0YTsKPj4gKwo+PiArCXFfZGF0YSA9IGFtbF92 ZGVjX2dldF9xZGF0YV9ieV90eXBlKGN0eCwgZi0+dHlwZSk7Cj4+ICsKPj4gKwlwaXhfbXAtPmZp ZWxkID0gVjRMMl9GSUVMRF9OT05FOwo+PiArCXBpeF9tcC0+Y29sb3JzcGFjZSA9IGN0eC0+cGlj X2luZm8uY29sb3JzcGFjZTsKPj4gKwlwaXhfbXAtPnljYmNyX2VuYyA9IGN0eC0+cGljX2luZm8u eWNiY3JfZW5jOwo+PiArCXBpeF9tcC0+cXVhbnRpemF0aW9uID0gY3R4LT5waWNfaW5mby5xdWFu dGl6YXRpb247Cj4+ICsJcGl4X21wLT54ZmVyX2Z1bmMgPSBjdHgtPnBpY19pbmZvLnhmZXJfZnVu YzsKPj4gKwo+PiArCWlmIChWNEwyX1RZUEVfSVNfT1VUUFVUKGYtPnR5cGUpKSB7Cj4+ICsJCXBp eF9tcC0+aGVpZ2h0ID0gcV9kYXRhLT5jb2RlZF9oZWlnaHQ7Cj4+ICsJCXBpeF9tcC0+d2lkdGgg PSBxX2RhdGEtPmNvZGVkX3dpZHRoOwo+PiArCQlwaXhfbXAtPnBpeGVsZm9ybWF0ID0gcV9kYXRh LT5mbXQtPmZvdXJjYzsKPj4gKwkJcGl4X21wLT5udW1fcGxhbmVzID0gcV9kYXRhLT5mbXQtPm51 bV9wbGFuZXM7Cj4+ICsJCXBpeF9tcC0+cGxhbmVfZm10WzBdLmJ5dGVzcGVybGluZSA9IHFfZGF0 YS0+Ynl0ZXNwZXJsaW5lWzBdOwo+PiArCQlwaXhfbXAtPnBsYW5lX2ZtdFswXS5zaXplaW1hZ2Ug PSBxX2RhdGEtPnNpemVpbWFnZVswXTsKPj4gKwl9IGVsc2Ugewo+PiArCQlpZiAoY3R4LT5waWNf aW5mby5jb2RlZF93aWR0aCAhPSAwICYmIGN0eC0+cGljX2luZm8uY29kZWRfaGVpZ2h0ICE9IDAp IHsKPj4gKwkJCXBpeF9tcC0+d2lkdGggPSBjdHgtPnBpY19pbmZvLmNvZGVkX3dpZHRoOwo+PiAr CQkJcGl4X21wLT5oZWlnaHQgPSBjdHgtPnBpY19pbmZvLmNvZGVkX2hlaWdodDsKPj4gKwkJfSBl bHNlIHsKPj4gKwkJCXBpeF9tcC0+aGVpZ2h0ID0gcV9kYXRhLT5jb2RlZF9oZWlnaHQ7Cj4+ICsJ CQlwaXhfbXAtPndpZHRoID0gcV9kYXRhLT5jb2RlZF9oZWlnaHQ7Cj4+ICsJCX0KPj4gKwkJdjRs Ml9maWxsX3BpeGZtdF9tcChwaXhfbXAsIHFfZGF0YS0+Zm10LT5mb3VyY2MsIHBpeF9tcC0+d2lk dGgsCj4+ICsJCQkJwqDCoMKgIHBpeF9tcC0+aGVpZ2h0KTsKPj4gKwl9Cj4+ICsKPj4gKwlyZXR1 cm4gMDsKPj4gK30KPj4gKwo+PiArc3RhdGljIGludCB2aWRpb2NfdHJ5X2ZtdF9jYXBfbXBsYW5l KHN0cnVjdCBmaWxlICpmaWxlLCB2b2lkICpwcml2LAo+PiArCQkJCcKgwqDCoMKgIHN0cnVjdCB2 NGwyX2Zvcm1hdCAqZikKPj4gK3sKPj4gKwlzdHJ1Y3QgYW1sX3ZkZWNfY3R4ICpjdHggPSBmaF90 b19kZWNfY3R4KGZpbGUpOwo+PiArCWNvbnN0IHN0cnVjdCBhbWxfdmlkZW9fZm10ICpmbXRfbXA7 Cj4+ICsJc3RydWN0IGFtbF9xX2RhdGEgKnFfZGF0YTsKPj4gKwo+PiArCXFfZGF0YSA9IGFtbF92 ZGVjX2dldF9xZGF0YV9ieV90eXBlKGN0eCwgVjRMMl9CVUZfVFlQRV9WSURFT19DQVBUVVJFX01Q TEFORSk7Cj4+ICsKPj4gKwlmbXRfbXAgPSBhbWxfdmRlY19nZXRfdmlkZW9fZm10KGYtPmZtdC5w aXhfbXAucGl4ZWxmb3JtYXQpOwo+PiArCWlmICghZm10X21wKQo+PiArCQlmbXRfbXAgPSBxX2Rh dGEtPmZtdDsKPj4gKwo+PiArCXJldHVybiB2ZGVjX3RyeV9mbXRfbXAoY3R4LCBmLCBmbXRfbXAp Owo+PiArfQo+PiArCj4+ICtzdGF0aWMgaW50IHZpZGlvY190cnlfZm10X291dF9tcGxhbmUoc3Ry dWN0IGZpbGUgKmZpbGUsIHZvaWQgKnByaXYsCj4+ICsJCQkJwqDCoMKgwqAgc3RydWN0IHY0bDJf Zm9ybWF0ICpmKQo+PiArewo+PiArCXN0cnVjdCBhbWxfdmRlY19jdHggKmN0eCA9IGZoX3RvX2Rl Y19jdHgoZmlsZSk7Cj4+ICsJY29uc3Qgc3RydWN0IGFtbF92aWRlb19mbXQgKmZtdF9tcDsKPj4g KwlzdHJ1Y3QgYW1sX3FfZGF0YSAqcV9kYXRhID0gYW1sX3ZkZWNfZ2V0X3FkYXRhX2J5X3R5cGUo Y3R4LAo+PiArCQkJCQkJCcKgwqDCoMKgwqDCoCBWNEwyX0JVRl9UWVBFX1ZJREVPX09VVFBVVF9N UExBTkUpOwo+PiArCj4+ICsJZm10X21wID0gYW1sX3ZkZWNfZ2V0X3ZpZGVvX2ZtdChmLT5mbXQu cGl4X21wLnBpeGVsZm9ybWF0KTsKPj4gKwlpZiAoIWZtdF9tcCkKPj4gKwkJZm10X21wID0gcV9k YXRhLT5mbXQ7Cj4+ICsKPj4gKwlyZXR1cm4gdmRlY190cnlfZm10X21wKGN0eCwgZiwgZm10X21w KTsKPj4gK30KPj4gKwo+PiArc3RhdGljIGludCB2aWRpb2NfdmRlY19zX2ZtdF9vdXRfbXBsYW5l KHN0cnVjdCBmaWxlICpmaWxlLCB2b2lkICpwcml2LAo+PiArCQkJCQlzdHJ1Y3QgdjRsMl9mb3Jt YXQgKmYpCj4+ICt7Cj4+ICsJc3RydWN0IGFtbF92ZGVjX2N0eCAqY3R4ID0gZmhfdG9fZGVjX2N0 eChmaWxlKTsKPj4gKwo+PiArCXJldHVybiB2ZGVjX3NfZm10KGN0eCwgZik7Cj4+ICt9Cj4+ICsK Pj4gK3N0YXRpYyBpbnQgdmlkaW9jX3ZkZWNfc19mbXRfY2FwX21wbGFuZShzdHJ1Y3QgZmlsZSAq ZmlsZSwgdm9pZCAqcHJpdiwKPj4gKwkJCQkJc3RydWN0IHY0bDJfZm9ybWF0ICpmKQo+PiArewo+ PiArCXN0cnVjdCBhbWxfdmRlY19jdHggKmN0eCA9IGZoX3RvX2RlY19jdHgoZmlsZSk7Cj4+ICsK Pj4gKwlyZXR1cm4gdmRlY19zX2ZtdChjdHgsIGYpOwo+PiArfQo+PiArCj4+ICtzdGF0aWMgaW50 IHZpZGlvY192ZGVjX2dfZm10X291dF9tcGxhbmUoc3RydWN0IGZpbGUgKmZpbGUsIHZvaWQgKnBy aXYsCj4+ICsJCQkJCXN0cnVjdCB2NGwyX2Zvcm1hdCAqZikKPj4gK3sKPj4gKwlzdHJ1Y3QgYW1s X3ZkZWNfY3R4ICpjdHggPSBmaF90b19kZWNfY3R4KGZpbGUpOwo+PiArCj4+ICsJcmV0dXJuIHZk ZWNfZ19mbXQoY3R4LCBmKTsKPj4gK30KPj4gKwo+PiArc3RhdGljIGludCB2aWRpb2NfdmRlY19n X2ZtdF9jYXBfbXBsYW5lKHN0cnVjdCBmaWxlICpmaWxlLCB2b2lkICpwcml2LAo+PiArCQkJCQlz dHJ1Y3QgdjRsMl9mb3JtYXQgKmYpCj4+ICt7Cj4+ICsJc3RydWN0IGFtbF92ZGVjX2N0eCAqY3R4 ID0gZmhfdG9fZGVjX2N0eChmaWxlKTsKPj4gKwo+PiArCXJldHVybiB2ZGVjX2dfZm10KGN0eCwg Zik7Cj4+ICt9Cj4+ICsKPj4gK3N0YXRpYyBpbnQgdmlkaW9jX3ZkZWNfZW51bV9mbXRfb3V0X21w bGFuZShzdHJ1Y3QgZmlsZSAqZmlsZSwKPj4gKwkJCQkJwqDCoCB2b2lkICpwcml2LCBzdHJ1Y3Qg djRsMl9mbXRkZXNjICpmKQo+PiArewo+PiArCXJldHVybiB2aWRpb2NfdmRlY19lbnVtX2ZtdChm LCAxKTsKPj4gK30KPj4gKwo+PiArc3RhdGljIGludCB2aWRpb2NfdmRlY19lbnVtX2ZtdF9jYXBf bXBsYW5lKHN0cnVjdCBmaWxlICpmaWxlLAo+PiArCQkJCQnCoMKgIHZvaWQgKnByaXYsIHN0cnVj dCB2NGwyX2ZtdGRlc2MgKmYpCj4+ICt7Cj4+ICsJcmV0dXJuIHZpZGlvY192ZGVjX2VudW1fZm10 KGYsIDApOwo+PiArfQo+PiArCj4+ICtjb25zdCBzdHJ1Y3QgdjRsMl9pb2N0bF9vcHMgYW1sX3Zk ZWNfaW9jdGxfb3BzID0gewo+PiArCS52aWRpb2NfcXVlcnljYXAgPSB2aWRpb2NfdmRlY19xdWVy eWNhcCwKPj4gKwkudmlkaW9jX2VudW1fZnJhbWVzaXplcyA9IHZpZGlvY192ZGVjX2VudW1fZnJh bWVzaXplcywKPj4gKwo+PiArCS52aWRpb2NfZW51bV9mbXRfdmlkX2NhcCA9IHZpZGlvY192ZGVj X2VudW1fZm10X2NhcF9tcGxhbmUsCj4+ICsJLnZpZGlvY190cnlfZm10X3ZpZF9jYXBfbXBsYW5l ID0gdmlkaW9jX3RyeV9mbXRfY2FwX21wbGFuZSwKPj4gKwkudmlkaW9jX3NfZm10X3ZpZF9jYXBf bXBsYW5lID0gdmlkaW9jX3ZkZWNfc19mbXRfY2FwX21wbGFuZSwKPj4gKwkudmlkaW9jX2dfZm10 X3ZpZF9jYXBfbXBsYW5lID0gdmlkaW9jX3ZkZWNfZ19mbXRfY2FwX21wbGFuZSwKPj4gKwo+PiAr CS52aWRpb2NfZW51bV9mbXRfdmlkX291dCA9IHZpZGlvY192ZGVjX2VudW1fZm10X291dF9tcGxh bmUsCj4+ICsJLnZpZGlvY190cnlfZm10X3ZpZF9vdXRfbXBsYW5lID0gdmlkaW9jX3RyeV9mbXRf b3V0X21wbGFuZSwKPj4gKwkudmlkaW9jX3NfZm10X3ZpZF9vdXRfbXBsYW5lID0gdmlkaW9jX3Zk ZWNfc19mbXRfb3V0X21wbGFuZSwKPj4gKwkudmlkaW9jX2dfZm10X3ZpZF9vdXRfbXBsYW5lID0g dmlkaW9jX3ZkZWNfZ19mbXRfb3V0X21wbGFuZSwKPj4gKwo+PiArCS52aWRpb2NfcmVxYnVmcyA9 IHY0bDJfbTJtX2lvY3RsX3JlcWJ1ZnMsCj4+ICsJLnZpZGlvY19xdWVyeWJ1ZiA9IHY0bDJfbTJt X2lvY3RsX3F1ZXJ5YnVmLAo+PiArCS52aWRpb2NfcWJ1ZiA9IHY0bDJfbTJtX2lvY3RsX3FidWYs Cj4+ICsJLnZpZGlvY19kcWJ1ZiA9IHY0bDJfbTJtX2lvY3RsX2RxYnVmLAo+PiArCS52aWRpb2Nf cHJlcGFyZV9idWYgPSB2NGwyX20ybV9pb2N0bF9wcmVwYXJlX2J1ZiwKPj4gKwkudmlkaW9jX2Ny ZWF0ZV9idWZzID0gdjRsMl9tMm1faW9jdGxfY3JlYXRlX2J1ZnMsCj4+ICsKPj4gKwkudmlkaW9j X2V4cGJ1ZiA9IHY0bDJfbTJtX2lvY3RsX2V4cGJ1ZiwKPj4gKwo+PiArCS52aWRpb2NfZGVjb2Rl cl9jbWQgPSB2NGwyX20ybV9pb2N0bF9zdGF0ZWxlc3NfZGVjb2Rlcl9jbWQsCj4+ICsJLnZpZGlv Y190cnlfZGVjb2Rlcl9jbWQgPSB2NGwyX20ybV9pb2N0bF9zdGF0ZWxlc3NfdHJ5X2RlY29kZXJf Y21kLAo+PiArCj4+ICsJLnZpZGlvY19zdWJzY3JpYmVfZXZlbnQgPSB2NGwyX2N0cmxfc3Vic2Ny aWJlX2V2ZW50LAo+PiArCS52aWRpb2NfdW5zdWJzY3JpYmVfZXZlbnQgPSB2NGwyX2V2ZW50X3Vu c3Vic2NyaWJlLAo+PiArCj4+ICsJLnZpZGlvY19zdHJlYW1vbiA9IHY0bDJfbTJtX2lvY3RsX3N0 cmVhbW9uLAo+PiArCS52aWRpb2Nfc3RyZWFtb2ZmID0gdjRsMl9tMm1faW9jdGxfc3RyZWFtb2Zm LAo+PiArfTsKPj4gKwo+PiArc3RhdGljIHZvaWQgYW1sX3ZkZWNfcmVsZWFzZV9pbnN0YW5jZShz dHJ1Y3QgYW1sX3ZkZWNfY3R4ICpjdHgpCj4+ICt7Cj4+ICsJaWYgKGN0eC0+Y29kZWNfb3BzICYm IGN0eC0+Y29kZWNfb3BzLT5leGl0KQo+PiArCQljdHgtPmNvZGVjX29wcy0+ZXhpdChjdHgpOwo+ PiArfQo+PiArCj4+ICtzdGF0aWMgaW50IHZiMm9wc192ZGVjX3F1ZXVlX3NldHVwKHN0cnVjdCB2 YjJfcXVldWUgKnZxLAo+PiArCQkJCcKgwqAgdW5zaWduZWQgaW50ICpuYnVmZmVycywKPj4gKwkJ CQnCoMKgIHVuc2lnbmVkIGludCAqbnBsYW5lcywKPj4gKwkJCQnCoMKgIHVuc2lnbmVkIGludCBz aXplc1tdLAo+PiArCQkJCcKgwqAgc3RydWN0IGRldmljZSAqYWxsb2NfZGV2c1tdKQo+PiArewo+ PiArCXN0cnVjdCBhbWxfdmRlY19jdHggKmN0eCA9IHZiMl9nZXRfZHJ2X3ByaXYodnEpOwo+PiAr CXN0cnVjdCBhbWxfcV9kYXRhICpxX2RhdGE7Cj4+ICsJdW5zaWduZWQgaW50IGk7Cj4+ICsKPj4g KwlxX2RhdGEgPSBhbWxfdmRlY19nZXRfcWRhdGFfYnlfdHlwZShjdHgsIHZxLT50eXBlKTsKPj4g KwlpZiAoIXFfZGF0YSkgewo+PiArCQlkZXZfZXJyKCZjdHgtPmRldi0+cGxhdF9kZXYtPmRldiwg Im5vdCBzdXBwb3J0ZWQgdnEgdHlwZVxuIik7Cj4+ICsJCXJldHVybiAtRUlOVkFMOwo+PiArCX0K Pj4gKwo+PiArCWlmICgqbnBsYW5lcykgewo+PiArCQlpZiAoKm5wbGFuZXMgIT0gcV9kYXRhLT5m bXQtPm51bV9wbGFuZXMpCj4+ICsJCQlyZXR1cm4gLUVJTlZBTDsKPj4gKwo+PiArCQlmb3IgKGkg PSAwOyBpIDwgKm5wbGFuZXM7IGkrKykgewo+PiArCQkJaWYgKHNpemVzW2ldIDwgcV9kYXRhLT5z aXplaW1hZ2VbaV0pIHsKPj4gKwkJCQlkZXZfZXJyKCZjdHgtPmRldi0+cGxhdF9kZXYtPmRldiwg Im5vdCBzdXBwb3J0ZWQgc2l6ZWltYWdlXG4iKTsKPj4gKwkJCQlyZXR1cm4gLUVJTlZBTDsKPj4g KwkJCX0KPj4gKwkJCWFsbG9jX2RldnNbaV0gPSAmY3R4LT5kZXYtPnBsYXRfZGV2LT5kZXY7Cj4+ ICsJCX0KPj4gKwl9IGVsc2Ugewo+PiArCQlpZiAodnEtPnR5cGUgPT0gVjRMMl9CVUZfVFlQRV9W SURFT19DQVBUVVJFX01QTEFORSkKPj4gKwkJCSpucGxhbmVzID0gcV9kYXRhLT5mbXQtPm51bV9w bGFuZXM7Cj4+ICsJCWVsc2UgaWYgKHZxLT50eXBlID09IFY0TDJfQlVGX1RZUEVfVklERU9fT1VU UFVUX01QTEFORSkKPj4gKwkJCSpucGxhbmVzID0gMTsKPj4gKwo+PiArCQlmb3IgKGkgPSAwOyBp IDwgKm5wbGFuZXM7IGkrKykgewo+PiArCQkJYWxsb2NfZGV2c1tpXSA9ICZjdHgtPmRldi0+cGxh dF9kZXYtPmRldjsKPj4gKwkJCXNpemVzW2ldID0gcV9kYXRhLT5zaXplaW1hZ2VbaV07Cj4+ICsJ CX0KPj4gKwl9Cj4+ICsKPj4gKwlpZiAoKm5wbGFuZXMpIHsKPj4gKwkJZGV2X2RiZygmY3R4LT5k ZXYtPnBsYXRfZGV2LT5kZXYsICJ0eXBlOiAlZCwgcGxhbmU6ICVkLCBidWYgY250OiAlZCwgc2l6 ZTogW1k6ICV1LCBDOiAldV1cbiIsCj4+ICsJCQl2cS0+dHlwZSwgKm5wbGFuZXMsICpuYnVmZmVy cywgc2l6ZXNbMF0sIHNpemVzWzFdKTsKPj4gKwkJcmV0dXJuIDA7Cj4+ICsJfQo+PiArCj4+ICsJ cmV0dXJuIC1FSU5WQUw7Cj4+ICt9Cj4+ICsKPj4gK3N0YXRpYyBpbnQgdmIyb3BzX3ZkZWNfYnVm X3ByZXBhcmUoc3RydWN0IHZiMl9idWZmZXIgKnZiKQo+PiArewo+PiArCXN0cnVjdCBhbWxfdmRl Y19jdHggKmN0eCA9IHZiMl9nZXRfZHJ2X3ByaXYodmItPnZiMl9xdWV1ZSk7Cj4+ICsJc3RydWN0 IGFtbF9xX2RhdGEgKnFfZGF0YTsKPj4gKwl1bnNpZ25lZCBpbnQgc2l6ZWltYWdlID0gMDsKPj4g KwlpbnQgaTsKPj4gKwo+PiArCXFfZGF0YSA9IGFtbF92ZGVjX2dldF9xZGF0YV9ieV90eXBlKGN0 eCwgdmItPnR5cGUpOwo+PiArCWlmICghcV9kYXRhKQo+PiArCQlyZXR1cm4gLUVJTlZBTDsKPj4g Kwo+PiArCWZvciAoaSA9IDA7IGkgPCBxX2RhdGEtPmZtdC0+bnVtX3BsYW5lczsgaSsrKSB7Cj4+ ICsJCXNpemVpbWFnZSA9IHFfZGF0YS0+c2l6ZWltYWdlW2ldOwo+PiArCQlpZiAodmIyX3BsYW5l X3NpemUodmIsIGkpIDwgc2l6ZWltYWdlKQo+PiArCQkJcmV0dXJuIC1FSU5WQUw7Cj4+ICsKPj4g KwkJaWYgKFY0TDJfVFlQRV9JU19DQVBUVVJFKHZiLT50eXBlKSkKPj4gKwkJCXZiMl9zZXRfcGxh bmVfcGF5bG9hZCh2YiwgaSwgcV9kYXRhLT5zaXplaW1hZ2VbaV0pOwo+PiArCX0KPj4gKwo+PiAr CXJldHVybiAwOwo+PiArfQo+PiArCj4+ICtzdGF0aWMgaW50IHZiMl9vcHNfdmRlY19idWZfaW5p dChzdHJ1Y3QgdmIyX2J1ZmZlciAqdmIpCj4+ICt7Cj4+ICsJcmV0dXJuIDA7Cj4+ICt9Cj4+ICsK Pj4gK3N0YXRpYyB2b2lkIHZiMl9vcHNfdmRlY19idWZfcXVldWUoc3RydWN0IHZiMl9idWZmZXIg KnZiKQo+PiArewo+PiArCXN0cnVjdCBhbWxfdmRlY19jdHggKmN0eCA9IHZiMl9nZXRfZHJ2X3By aXYodmItPnZiMl9xdWV1ZSk7Cj4+ICsJc3RydWN0IHZiMl92NGwyX2J1ZmZlciAqdmIyX3Y0bDIg PSB0b192YjJfdjRsMl9idWZmZXIodmIpOwo+PiArCj4+ICsJdjRsMl9tMm1fYnVmX3F1ZXVlKGN0 eC0+ZmgubTJtX2N0eCwgdmIyX3Y0bDIpOwo+PiArfQo+PiArCj4+ICtzdGF0aWMgdm9pZCB2YjJf b3BzX3ZkZWNfYnVmX2ZpbmlzaChzdHJ1Y3QgdmIyX2J1ZmZlciAqdmIpCj4+ICt7Cj4+ICt9Cj4+ ICsKPj4gK3N0YXRpYyBpbnQgdmIyb3BzX3ZkZWNfc3RhcnRfc3RyZWFtaW5nKHN0cnVjdCB2YjJf cXVldWUgKnEsIHVuc2lnbmVkIGludCBjb3VudCkKPj4gK3sKPj4gKwlzdHJ1Y3QgYW1sX3ZkZWNf Y3R4ICpjdHggPSB2YjJfZ2V0X2Rydl9wcml2KHEpOwo+PiArCXN0cnVjdCBhbWxfcV9kYXRhICpx X2RhdGE7Cj4+ICsKPj4gKwlpZiAoVjRMMl9UWVBFX0lTX09VVFBVVChxLT50eXBlKSkgewo+PiAr CQljdHgtPmlzX291dHB1dF9zdHJlYW1vbiA9IDE7Cj4+ICsJCXFfZGF0YSA9IGFtbF92ZGVjX2dl dF9xZGF0YV9ieV90eXBlKGN0eCwgcS0+dHlwZSk7Cj4+ICsJCWlmIChhbWxfdmRlY19pbml0X2Rl Y19pbnN0KGN0eCwgcV9kYXRhLT5mbXQpIDwgMCkKPj4gKwkJCXJldHVybiAtRUlOVkFMOwo+PiAr CX0gZWxzZSB7Cj4+ICsJCWN0eC0+aXNfY2FwX3N0cmVhbW9uID0gMTsKPj4gKwl9Cj4+ICsKPj4g KwlyZXR1cm4gMDsKPj4gK30KPj4gKwo+PiArc3RhdGljIHZvaWQgdmIyb3BzX3ZkZWNfc3RvcF9z dHJlYW1pbmcoc3RydWN0IHZiMl9xdWV1ZSAqcSkKPj4gK3sKPj4gKwlzdHJ1Y3QgYW1sX3ZkZWNf Y3R4ICpjdHggPSB2YjJfZ2V0X2Rydl9wcml2KHEpOwo+PiArCXN0cnVjdCB2YjJfdjRsMl9idWZm ZXIgKnNyY19idWYgPSBOVUxMLCAqZHN0X2J1ZiA9IE5VTEw7Cj4+ICsKPj4gKwlhbWxfdmRlY19y ZWxlYXNlX2luc3RhbmNlKGN0eCk7Cj4+ICsKPj4gKwlpZiAoVjRMMl9UWVBFX0lTX09VVFBVVChx LT50eXBlKSkgewo+PiArCQl3aGlsZSAoKHNyY19idWYgPSB2NGwyX20ybV9zcmNfYnVmX3JlbW92 ZShjdHgtPm0ybV9jdHgpKSkKPj4gKwkJCXY0bDJfbTJtX2J1Zl9kb25lKHNyY19idWYsIFZCMl9C VUZfU1RBVEVfRVJST1IpOwo+PiArCQljdHgtPmlzX291dHB1dF9zdHJlYW1vbiA9IDA7Cj4+ICsJ fSBlbHNlIHsKPj4gKwkJd2hpbGUgKChkc3RfYnVmID0gdjRsMl9tMm1fZHN0X2J1Zl9yZW1vdmUo Y3R4LT5tMm1fY3R4KSkpCj4+ICsJCQl2NGwyX20ybV9idWZfZG9uZShkc3RfYnVmLCBWQjJfQlVG X1NUQVRFX0VSUk9SKTsKPj4gKwkJY3R4LT5pc19jYXBfc3RyZWFtb24gPSAwOwo+PiArCX0KPj4g K30KPj4gKwo+PiArc3RhdGljIGludCB2YjJvcHNfdmRlY19vdXRfYnVmX3ZhbGlkYXRlKHN0cnVj dCB2YjJfYnVmZmVyICp2YikKPj4gK3sKPj4gKwlzdHJ1Y3QgdmIyX3Y0bDJfYnVmZmVyICp2YnVm ID0gdG9fdmIyX3Y0bDJfYnVmZmVyKHZiKTsKPj4gKwo+PiArCXZidWYtPmZpZWxkID0gVjRMMl9G SUVMRF9OT05FOwo+PiArCXJldHVybiAwOwo+PiArfQo+PiArCj4+ICtzdGF0aWMgdm9pZCB2YjJv cHNfdmRlY19idWZfcmVxdWVzdF9jb21wbGV0ZShzdHJ1Y3QgdmIyX2J1ZmZlciAqdmIpCj4+ICt7 Cj4+ICsJc3RydWN0IGFtbF92ZGVjX2N0eCAqY3R4ID0gdmIyX2dldF9kcnZfcHJpdih2Yi0+dmIy X3F1ZXVlKTsKPj4gKwo+PiArCXY0bDJfY3RybF9yZXF1ZXN0X2NvbXBsZXRlKHZiLT5yZXFfb2Jq LnJlcSwgJmN0eC0+Y3RybF9oYW5kbGVyKTsKPj4gK30KPj4gKwo+PiArc3RhdGljIGNvbnN0IHN0 cnVjdCB2YjJfb3BzIGFtbF92ZGVjX3ZiMl9vcHMgPSB7Cj4+ICsJLnF1ZXVlX3NldHVwID0gdmIy b3BzX3ZkZWNfcXVldWVfc2V0dXAsCj4+ICsJLndhaXRfcHJlcGFyZSA9IHZiMl9vcHNfd2FpdF9w cmVwYXJlLAo+PiArCS53YWl0X2ZpbmlzaCA9IHZiMl9vcHNfd2FpdF9maW5pc2gsCj4+ICsJLnN0 YXJ0X3N0cmVhbWluZyA9IHZiMm9wc192ZGVjX3N0YXJ0X3N0cmVhbWluZywKPj4gKwkuc3RvcF9z dHJlYW1pbmcgPSB2YjJvcHNfdmRlY19zdG9wX3N0cmVhbWluZywKPj4gKwo+PiArCS5idWZfaW5p dCA9IHZiMl9vcHNfdmRlY19idWZfaW5pdCwKPj4gKwkuYnVmX3ByZXBhcmUgPSB2YjJvcHNfdmRl Y19idWZfcHJlcGFyZSwKPj4gKwkuYnVmX291dF92YWxpZGF0ZSA9IHZiMm9wc192ZGVjX291dF9i dWZfdmFsaWRhdGUsCj4+ICsJLmJ1Zl9xdWV1ZSA9IHZiMl9vcHNfdmRlY19idWZfcXVldWUsCj4+ ICsJLmJ1Zl9maW5pc2ggPSB2YjJfb3BzX3ZkZWNfYnVmX2ZpbmlzaCwKPj4gKwkuYnVmX3JlcXVl c3RfY29tcGxldGUgPSB2YjJvcHNfdmRlY19idWZfcmVxdWVzdF9jb21wbGV0ZSwKPj4gK307Cj4+ ICsKPj4gK2ludCBhbWxfdmRlY19xdWV1ZV9pbml0KHZvaWQgKnByaXYsIHN0cnVjdCB2YjJfcXVl dWUgKnNyY192cSwKPj4gKwkJCXN0cnVjdCB2YjJfcXVldWUgKmRzdF92cSkKPj4gK3sKPj4gKwlz dHJ1Y3QgYW1sX3ZkZWNfY3R4ICpjdHggPSAoc3RydWN0IGFtbF92ZGVjX2N0eCAqKXByaXY7Cj4+ ICsJc3RydWN0IGFtbF92ZGVjX2RldiAqZGV2ID0gY3R4LT5kZXY7Cj4+ICsJaW50IHJldCA9IDA7 Cj4+ICsKPj4gKwlzcmNfdnEtPnR5cGUgPSBWNEwyX0JVRl9UWVBFX1ZJREVPX09VVFBVVF9NUExB TkU7Cj4+ICsJc3JjX3ZxLT5pb19tb2RlcyA9IFZCMl9NTUFQIHwgVkIyX0RNQUJVRjsKPj4gKwlz cmNfdnEtPm1lbV9vcHMgPSAmdmIyX2RtYV9jb250aWdfbWVtb3BzOwo+PiArCXNyY192cS0+ZHJ2 X3ByaXYgPSBjdHg7Cj4+ICsJc3JjX3ZxLT5vcHMgPSAmYW1sX3ZkZWNfdmIyX29wczsKPj4gKwlz cmNfdnEtPmxvY2sgPSAmY3R4LT52NGwyX2ludGZfbG9jazsKPj4gKwlzcmNfdnEtPmJ1Zl9zdHJ1 Y3Rfc2l6ZSA9IHNpemVvZihzdHJ1Y3QgdjRsMl9tMm1fYnVmZmVyKTsKPj4gKwlzcmNfdnEtPnN1 cHBvcnRzX3JlcXVlc3RzID0gdHJ1ZTsKPj4gKwlzcmNfdnEtPnRpbWVzdGFtcF9mbGFncyA9IFY0 TDJfQlVGX0ZMQUdfVElNRVNUQU1QX0NPUFk7Cj4+ICsJcmV0ID0gdmIyX3F1ZXVlX2luaXQoc3Jj X3ZxKTsKPj4gKwlpZiAocmV0KSB7Cj4+ICsJCXY0bDJfaW5mbygmZGV2LT52NGwyX2RldiwKPj4g KwkJCcKgICJGYWlsZWQgdG8gaW5pdGlhbGl6ZSB2aWRlb2J1ZjIgcXVldWUob3V0cHV0KSIpOwo+ PiArCQlyZXR1cm4gcmV0Owo+PiArCX0KPj4gKwo+PiArCWRzdF92cS0+dHlwZSA9IFY0TDJfQlVG X1RZUEVfVklERU9fQ0FQVFVSRV9NUExBTkU7Cj4+ICsJZHN0X3ZxLT5pb19tb2RlcyA9IFZCMl9N TUFQIHwgVkIyX0RNQUJVRjsKPj4gKwlkc3RfdnEtPmRydl9wcml2ID0gY3R4Owo+PiArCWRzdF92 cS0+bWVtX29wcyA9ICZ2YjJfZG1hX2NvbnRpZ19tZW1vcHM7Cj4+ICsJZHN0X3ZxLT5vcHMgPSAm YW1sX3ZkZWNfdmIyX29wczsKPj4gKwlkc3RfdnEtPmxvY2sgPSAmY3R4LT52NGwyX2ludGZfbG9j azsKPj4gKwlkc3RfdnEtPmJ1Zl9zdHJ1Y3Rfc2l6ZSA9IHNpemVvZihzdHJ1Y3QgdjRsMl9tMm1f YnVmZmVyKTsKPj4gKwlkc3RfdnEtPnRpbWVzdGFtcF9mbGFncyA9IFY0TDJfQlVGX0ZMQUdfVElN RVNUQU1QX0NPUFk7Cj4+ICsJcmV0ID0gdmIyX3F1ZXVlX2luaXQoZHN0X3ZxKTsKPj4gKwlpZiAo cmV0KSB7Cj4+ICsJCXY0bDJfaW5mbygmZGV2LT52NGwyX2RldiwKPj4gKwkJCcKgICJGYWlsZWQg dG8gaW5pdGlhbGl6ZSB2aWRlb2J1ZjIgcXVldWUoY2FwdHVyZSkiKTsKPj4gKwkJdmIyX3F1ZXVl X3JlbGVhc2Uoc3JjX3ZxKTsKPj4gKwl9Cj4+ICsKPj4gKwlyZXR1cm4gcmV0Owo+PiArfQo+PiBk aWZmIC0tZ2l0IGEvZHJpdmVycy9tZWRpYS9wbGF0Zm9ybS9hbWxvZ2ljL3ZkZWMvYW1sX3ZkZWMu aCBiL2RyaXZlcnMvbWVkaWEvcGxhdGZvcm0vYW1sb2dpYy92ZGVjL2FtbF92ZGVjLmgKPj4gbmV3 IGZpbGUgbW9kZSAxMDA2NDQKPj4gaW5kZXggMDAwMDAwMDAwMDAwLi5hOWZmOTNmMjUwNDMKPj4g LS0tIC9kZXYvbnVsbAo+PiArKysgYi9kcml2ZXJzL21lZGlhL3BsYXRmb3JtL2FtbG9naWMvdmRl Yy9hbWxfdmRlYy5oCj4+IEBAIC0wLDAgKzEsMzEgQEAKPj4gKy8qIFNQRFgtTGljZW5zZS1JZGVu dGlmaWVyOiAoR1BMLTIuMC1vbmx5IE9SIE1JVCkgKi8KPj4gKy8qCj4+ICsgKiBDb3B5cmlnaHQg KEMpIDIwMjUgQW1sb2dpYywgSW5jLiBBbGwgcmlnaHRzIHJlc2VydmVkCj4+ICsgKi8KPj4gKwo+ PiArI2lmbmRlZiBfQU1MX1ZERUNfSF8KPj4gKyNkZWZpbmUgX0FNTF9WREVDX0hfCj4+ICsKPj4g KyNpbmNsdWRlICJhbWxfdmRlY19kcnYuaCIKPj4gKwo+PiArI2RlZmluZSBERUZBVUxUX09VVF9J RFjCoCAwCS8qIHNldCBkZWZhdWx0IG91dHB1dCBmb3JtYXQgdG8gaDI2NCB0eXBlICovCj4+ICsj ZGVmaW5lIERFRkFVTFRfQ0FQX0lEWMKgIDIJLyogc2V0IGRlZmF1bHQgY2FwdHVyZSBmb3JtYXQg dG8gTlYyMSAqLwo+PiArCj4+ICsvKioKPj4gKyAqIHN0cnVjdCBhbWxfdmRlY192NGwyX2N0cmwg LSBoZWxwZXIgdHlwZSB0byBkZWNsYXJlIHN1cHBvcnRlZCBjdHJscwo+PiArICogQGNvZGVjX3R5 cGU6IGNvZGVjIGlkIHRoaXMgY29udHJvbCBiZWxvbmcgdG8gKENPREVDX1RZUEVfSDI2NCwgZXRj LikKPj4gKyAqIEBjZmc6IGNvbnRyb2wgY29uZmlndXJhdGlvbgo+PiArICovCj4+ICtzdHJ1Y3Qg YW1sX3ZkZWNfdjRsMl9jdHJsIHsKPj4gKwl1bnNpZ25lZCBpbnQgY29kZWNfdHlwZTsKPj4gKwlz dHJ1Y3QgdjRsMl9jdHJsX2NvbmZpZyBjZmc7Cj4+ICt9Owo+PiArCj4+ICtleHRlcm4gY29uc3Qg c3RydWN0IHY0bDJfbTJtX29wcyBhbWxfdmRlY19tMm1fb3BzOwo+PiArZXh0ZXJuIGNvbnN0IHN0 cnVjdCB2NGwyX2lvY3RsX29wcyBhbWxfdmRlY19pb2N0bF9vcHM7Cj4+ICsKPj4gK2ludCBhbWxf dmRlY19jdHJsc19zZXR1cChzdHJ1Y3QgYW1sX3ZkZWNfY3R4ICpjdHgpOwo+PiAraW50IGFtbF92 ZGVjX3F1ZXVlX2luaXQodm9pZCAqcHJpdiwgc3RydWN0IHZiMl9xdWV1ZSAqc3JjX3ZxLAo+PiAr CQkJc3RydWN0IHZiMl9xdWV1ZSAqZHN0X3ZxKTsKPj4gK3ZvaWQgYW1sX3ZkZWNfc2V0X2RlZmF1 bHRfcGFyYW1zKHN0cnVjdCBhbWxfdmRlY19jdHggKmN0eCk7Cj4+ICsjZW5kaWYKPj4gZGlmZiAt LWdpdCBhL2RyaXZlcnMvbWVkaWEvcGxhdGZvcm0vYW1sb2dpYy92ZGVjL2FtbF92ZGVjX2Rydi5j IGIvZHJpdmVycy9tZWRpYS9wbGF0Zm9ybS9hbWxvZ2ljL3ZkZWMvYW1sX3ZkZWNfZHJ2LmMKPj4g bmV3IGZpbGUgbW9kZSAxMDA2NDQKPj4gaW5kZXggMDAwMDAwMDAwMDAwLi43NTkxZTI5NThmNDIK Pj4gLS0tIC9kZXYvbnVsbAo+PiArKysgYi9kcml2ZXJzL21lZGlhL3BsYXRmb3JtL2FtbG9naWMv dmRlYy9hbWxfdmRlY19kcnYuYwo+PiBAQCAtMCwwICsxLDIzOSBAQAo+PiArLy8gU1BEWC1MaWNl bnNlLUlkZW50aWZpZXI6IChHUEwtMi4wLW9ubHkgT1IgTUlUKQo+PiArLyoKPj4gKyAqIENvcHly aWdodCAoQykgMjAyNSBBbWxvZ2ljLCBJbmMuIEFsbCByaWdodHMgcmVzZXJ2ZWQKPj4gKyAqLwo+ PiArCj4+ICsjaW5jbHVkZSA8bGludXgvbW9kdWxlLmg+Cj4+ICsjaW5jbHVkZSA8bGludXgvcGxh dGZvcm1fZGV2aWNlLmg+Cj4+ICsjaW5jbHVkZSA8bWVkaWEvdjRsMi1kZXZpY2UuaD4KPj4gKyNp bmNsdWRlIDxtZWRpYS92NGwyLWlvY3RsLmg+Cj4+ICsKPj4gKyNpbmNsdWRlICJhbWxfdmRlYy5o Igo+PiArI2luY2x1ZGUgImFtbF92ZGVjX2h3LmgiCj4+ICsjaW5jbHVkZSAiYW1sX3ZkZWNfcGxh dGZvcm0uaCIKPj4gKwo+PiArI2RlZmluZSBBTUxfVkRFQ19EUlZfTkFNRSAiYW1sLXZkZWMtZHJ2 Igo+PiArCj4+ICtzdGF0aWMgaW50IGZvcHNfdmNvZGVjX29wZW4oc3RydWN0IGZpbGUgKmZpbGUp Cj4+ICt7Cj4+ICsJc3RydWN0IGFtbF92ZGVjX2RldiAqZGVjX2RldiA9IHZpZGVvX2RydmRhdGEo ZmlsZSk7Cj4+ICsJc3RydWN0IGFtbF92ZGVjX2N0eCAqY3R4ID0gTlVMTDsKPj4gKwlpbnQgcmV0 ID0gMDsKPj4gKwo+PiArCWN0eCA9IGt6YWxsb2Moc2l6ZW9mKCpjdHgpLCBHRlBfS0VSTkVMKTsK Pj4gKwlpZiAoIWN0eCkKPj4gKwkJcmV0dXJuIC1FTk9NRU07Cj4+ICsKPj4gKwltdXRleF9sb2Nr KCZkZWNfZGV2LT5kZXZfbXV0ZXgpOwo+PiArCWRlY19kZXYtPmRlY19jdHggPSBjdHg7Cj4+ICsJ Y3R4LT5kZXYgPSBkZWNfZGV2Owo+PiArCXY0bDJfZmhfaW5pdCgmY3R4LT5maCwgdmlkZW9fZGV2 ZGF0YShmaWxlKSk7Cj4+ICsJZmlsZS0+cHJpdmF0ZV9kYXRhID0gJmN0eC0+Zmg7Cj4+ICsJdjRs Ml9maF9hZGQoJmN0eC0+ZmgsIGZpbGUpOwo+PiArCWRlY19kZXYtPmZpbHAgPSBmaWxlOwo+PiAr CW11dGV4X2luaXQoJmN0eC0+djRsMl9pbnRmX2xvY2spOwo+PiArCWluaXRfd2FpdHF1ZXVlX2hl YWQoJmN0eC0+cXVldWUpOwo+PiArCWN0eC0+aW50X2NvbmQgPSAwOwo+PiArCj4+ICsJY3R4LT5t Mm1fY3R4ID0gdjRsMl9tMm1fY3R4X2luaXQoZGVjX2Rldi0+bTJtX2Rldl9kZWMsIGN0eCwKPj4g KwkJCQkJICZhbWxfdmRlY19xdWV1ZV9pbml0KTsKPj4gKwlpZiAoSVNfRVJSKGN0eC0+bTJtX2N0 eCkpIHsKPj4gKwkJcmV0ID0gUFRSX0VSUigoX19mb3JjZSB2b2lkICopY3R4LT5tMm1fY3R4KTsK Pj4gKwkJdjRsMl9lcnIoJmRlY19kZXYtPnY0bDJfZGV2LCAiRmFpbGVkIHRvIHY0bDJfbTJtX2N0 eF9pbml0KCkgKCVkKSIsIHJldCk7Cj4+ICsJCWdvdG8gZXJyX20ybV9jdHhfaW5pdDsKPj4gKwl9 Cj4+ICsKPj4gKwljdHgtPmZoLm0ybV9jdHggPSBjdHgtPm0ybV9jdHg7Cj4+ICsJcmV0ID0gYW1s X3ZkZWNfY3RybHNfc2V0dXAoY3R4KTsKPj4gKwlpZiAocmV0KSB7Cj4+ICsJCXY0bDJfZXJyKCZk ZWNfZGV2LT52NGwyX2RldiwgIkZhaWxlZCB0byBpbml0IGFsbCBjdHJscyAoJWQpIiwgcmV0KTsK Pj4gKwkJZ290byBlcnJfY3RybHNfc2V0dXA7Cj4+ICsJfQo+PiArCj4+ICsJYW1sX3ZkZWNfc2V0 X2RlZmF1bHRfcGFyYW1zKGN0eCk7Cj4+ICsJbXV0ZXhfdW5sb2NrKCZkZWNfZGV2LT5kZXZfbXV0 ZXgpOwo+PiArCj4+ICsJcmV0dXJuIHJldDsKPj4gKwo+PiArZXJyX2N0cmxzX3NldHVwOgo+PiAr CXY0bDJfbTJtX2N0eF9yZWxlYXNlKGN0eC0+bTJtX2N0eCk7Cj4+ICtlcnJfbTJtX2N0eF9pbml0 Ogo+PiArCXY0bDJfZmhfZGVsKCZjdHgtPmZoLCBmaWxlKTsKPj4gKwl2NGwyX2ZoX2V4aXQoJmN0 eC0+ZmgpOwo+PiArCWtmcmVlKGN0eCk7Cj4+ICsJbXV0ZXhfdW5sb2NrKCZkZWNfZGV2LT5kZXZf bXV0ZXgpOwo+PiArCj4+ICsJcmV0dXJuIHJldDsKPj4gK30KPj4gKwo+PiArc3RhdGljIGludCBm b3BzX3Zjb2RlY19yZWxlYXNlKHN0cnVjdCBmaWxlICpmaWxlKQo+PiArewo+PiArCXN0cnVjdCBh bWxfdmRlY19kZXYgKmRlY19kZXYgPSB2aWRlb19kcnZkYXRhKGZpbGUpOwo+PiArCXN0cnVjdCBh bWxfdmRlY19jdHggKmN0eCA9IGZoX3RvX2RlY19jdHgoZmlsZSk7Cj4+ICsKPj4gKwltdXRleF9s b2NrKCZkZWNfZGV2LT5kZXZfbXV0ZXgpOwo+PiArCXY0bDJfY3RybF9oYW5kbGVyX2ZyZWUoJmN0 eC0+Y3RybF9oYW5kbGVyKTsKPj4gKwl2NGwyX20ybV9jdHhfcmVsZWFzZShjdHgtPm0ybV9jdHgp Owo+PiArCXY0bDJfZmhfZGVsKCZjdHgtPmZoLCBmaWxlKTsKPj4gKwl2NGwyX2ZoX2V4aXQoJmN0 eC0+ZmgpOwo+PiArCWtmcmVlKGN0eCk7Cj4+ICsJbXV0ZXhfdW5sb2NrKCZkZWNfZGV2LT5kZXZf bXV0ZXgpOwo+PiArCj4+ICsJcmV0dXJuIDA7Cj4+ICt9Cj4+ICsKPj4gK3N0YXRpYyBjb25zdCBz dHJ1Y3QgdjRsMl9maWxlX29wZXJhdGlvbnMgYW1sX3ZkZWNfZm9wcyA9IHsKPj4gKwkub3duZXLC oMKgwqDCoMKgwqDCoCA9IFRISVNfTU9EVUxFLAo+PiArCS5vcGVuwqDCoMKgwqDCoMKgwqAgPSBm b3BzX3Zjb2RlY19vcGVuLAo+PiArCS5yZWxlYXNlwqDCoMKgID0gZm9wc192Y29kZWNfcmVsZWFz ZSwKPj4gKwkucG9sbMKgwqDCoMKgwqDCoMKgID0gdjRsMl9tMm1fZm9wX3BvbGwsCj4+ICsJLnVu bG9ja2VkX2lvY3RswqDCoMKgID0gdmlkZW9faW9jdGwyLAo+PiArCS5tbWFwwqDCoMKgwqDCoMKg wqAgPSB2NGwyX20ybV9mb3BfbW1hcCwKPj4gK307Cj4+ICsKPj4gK3N0YXRpYyBjb25zdCBzdHJ1 Y3QgdmlkZW9fZGV2aWNlIGRlY19kZXYgPSB7Cj4+ICsJLm5hbWUgPSAiYW1sX2Rldl9kcnYiLAo+ PiArCS5mb3BzID0gJmFtbF92ZGVjX2ZvcHMsCj4+ICsJLmlvY3RsX29wcyA9ICZhbWxfdmRlY19p b2N0bF9vcHMsCj4+ICsJLnJlbGVhc2UgPSB2aWRlb19kZXZpY2VfcmVsZWFzZSwKPj4gKwkudmZs X2RpciA9IFZGTF9ESVJfTTJNLAo+PiArCS5kZXZpY2VfY2FwcyA9IFY0TDJfQ0FQX1ZJREVPX00y TV9NUExBTkUgfCBWNEwyX0NBUF9TVFJFQU1JTkcsCj4+ICt9Owo+PiArCj4+ICtzdGF0aWMgY29u c3Qgc3RydWN0IG1lZGlhX2RldmljZV9vcHMgYW1sX20ybV9tZWRpYV9vcHMgPSB7Cj4+ICsJLnJl cV92YWxpZGF0ZSA9IHZiMl9yZXF1ZXN0X3ZhbGlkYXRlLAo+PiArCS5yZXFfcXVldWUgPSB2NGwy X20ybV9yZXF1ZXN0X3F1ZXVlLAo+PiArfTsKPj4gKwo+PiArc3RhdGljIGludCBhbWxfdmRlY19k cnZfcHJvYmUoc3RydWN0IHBsYXRmb3JtX2RldmljZSAqcGRldikKPj4gK3sKPj4gKwlzdHJ1Y3Qg YW1sX3ZkZWNfZGV2ICpkZXY7Cj4+ICsJc3RydWN0IHZpZGVvX2RldmljZSAqdmZkX2RlYzsKPj4g KwlzdHJ1Y3QgYW1sX3ZkZWNfaHcgKmh3Owo+PiArCWludCByZXQgPSAwOwo+PiArCj4+ICsJZGV2 ID0gZGV2bV9remFsbG9jKCZwZGV2LT5kZXYsIHNpemVvZigqZGV2KSwgR0ZQX0tFUk5FTCk7Cj4+ ICsJaWYgKCFkZXYpCj4+ICsJCXJldHVybiAtRU5PTUVNOwo+PiArCj4+ICsJZGV2LT5wbGF0X2Rl diA9IHBkZXY7Cj4+ICsJbXV0ZXhfaW5pdCgmZGV2LT5kZXZfbXV0ZXgpOwo+PiArCj4+ICsJcmV0 ID0gdjRsMl9kZXZpY2VfcmVnaXN0ZXIoJnBkZXYtPmRldiwgJmRldi0+djRsMl9kZXYpOwo+PiAr CWlmIChyZXQpCj4+ICsJCXJldHVybiBkZXZfZXJyX3Byb2JlKCZwZGV2LT5kZXYsIHJldCwgInY0 bDJfZGV2aWNlX3JlZ2lzdGVyIGVyclxuIik7Cj4+ICsKPj4gKwl2ZmRfZGVjID0gdmlkZW9fZGV2 aWNlX2FsbG9jKCk7Cj4+ICsJaWYgKCF2ZmRfZGVjKSB7Cj4+ICsJCXY0bDJfZXJyKCZkZXYtPnY0 bDJfZGV2LCAiRmFpbGVkIHRvIGFsbG9jYXRlIHZpZGVvIGRldmljZVxuIik7Cj4+ICsJCXJldCA9 IC1FTk9NRU07Cj4+ICsJCWdvdG8gZXJyX2RldmljZV9hbGxvYzsKPj4gKwl9Cj4+ICsJKnZmZF9k ZWMgPSBkZWNfZGV2Owo+PiArCXZmZF9kZWMtPnY0bDJfZGV2ID0gJmRldi0+djRsMl9kZXY7Cj4+ ICsJdmZkX2RlYy0+bG9jayA9ICZkZXYtPmRldl9tdXRleDsKPj4gKwl2aWRlb19zZXRfZHJ2ZGF0 YSh2ZmRfZGVjLCBkZXYpOwo+PiArCWRldi0+dmZkID0gdmZkX2RlYzsKPj4gKwlwbGF0Zm9ybV9z ZXRfZHJ2ZGF0YShwZGV2LCBkZXYpOwo+PiArCj4+ICsJaHcgPSBkZXZtX2t6YWxsb2MoJnBkZXYt PmRldiwgc2l6ZW9mKCpodyksIEdGUF9LRVJORUwpOwo+PiArCWlmICghaHcpIHsKPj4gKwkJcmV0 ID0gLUVOT01FTTsKPj4gKwkJZ290byBlcnJfZGVjX21lbV9pbml0Owo+PiArCX0KPj4gKwlkZXYt PmRlY19odyA9IGh3Owo+PiArCj4+ICsJZGV2LT5wdmRlY19kYXRhID0gb2ZfZGV2aWNlX2dldF9t YXRjaF9kYXRhKCZwZGV2LT5kZXYpOwo+PiArCXJldCA9IGRldi0+cHZkZWNfZGF0YS0+cmVxX2h3 X3Jlc291cmNlKGRldik7Cj4+ICsJaWYgKHJldCA8IDApCj4+ICsJCWdvdG8gZXJyX2h3X2luaXQ7 Cj4+ICsKPj4gKwlkZXYtPm0ybV9kZXZfZGVjID0gdjRsMl9tMm1faW5pdCgmYW1sX3ZkZWNfbTJt X29wcyk7Cj4+ICsJaWYgKElTX0VSUihkZXYtPm0ybV9kZXZfZGVjKSkgewo+PiArCQl2NGwyX2Vy cigmZGV2LT52NGwyX2RldiwgIkZhaWxlZCB0byBpbml0IG1lbTJtZW0gZGVjIGRldmljZVxuIik7 Cj4+ICsJCXJldCA9IFBUUl9FUlIoKF9fZm9yY2Ugdm9pZCAqKWRldi0+bTJtX2Rldl9kZWMpOwo+ PiArCQlnb3RvIGVycl9od19pbml0Owo+PiArCX0KPj4gKwo+PiArCXJldCA9IHZpZGVvX3JlZ2lz dGVyX2RldmljZSh2ZmRfZGVjLCBWRkxfVFlQRV9WSURFTywgLTEpOwo+PiArCWlmIChyZXQpIHsK Pj4gKwkJdjRsMl9lcnIoJmRldi0+djRsMl9kZXYsICJGYWlsZWQgdG8gcmVnaXN0ZXIgdmlkZW8g ZGV2aWNlIik7Cj4+ICsJCWdvdG8gZXJyX3ZpZF9kZXZfcmVnaXN0ZXI7Cj4+ICsJfQo+PiArCj4+ ICsJZGV2LT5tZGV2LmRldiA9ICZwZGV2LT5kZXY7Cj4+ICsJc3Ryc2NweShkZXYtPm1kZXYubW9k ZWwsIEFNTF9WREVDX0RSVl9OQU1FLCBzaXplb2YoZGV2LT5tZGV2Lm1vZGVsKSk7Cj4+ICsJbWVk aWFfZGV2aWNlX2luaXQoJmRldi0+bWRldik7Cj4+ICsJZGV2LT5tZGV2Lm9wcyA9ICZhbWxfbTJt X21lZGlhX29wczsKPj4gKwlkZXYtPnY0bDJfZGV2Lm1kZXYgPSAmZGV2LT5tZGV2Owo+PiArCj4+ ICsJcmV0ID0gdjRsMl9tMm1fcmVnaXN0ZXJfbWVkaWFfY29udHJvbGxlcihkZXYtPm0ybV9kZXZf ZGVjLCB2ZmRfZGVjLAo+PiArCQkJCQkJIE1FRElBX0VOVF9GX1BST0NfVklERU9fREVDT0RFUik7 Cj4+ICsJaWYgKHJldCkgewo+PiArCQl2NGwyX2VycigmZGV2LT52NGwyX2RldiwgIkZhaWxlZCB0 byBpbml0IG1lbTJtZW0gbWVkaWEgY29udHJvbGxlclxuIik7Cj4+ICsJCWdvdG8gZXJyb3JfbTJt X21jX3JlZ2lzdGVyOwo+PiArCX0KPj4gKwo+PiArCXJldCA9IG1lZGlhX2RldmljZV9yZWdpc3Rl cigmZGV2LT5tZGV2KTsKPj4gKwlpZiAocmV0KSB7Cj4+ICsJCXY0bDJfZXJyKCZkZXYtPnY0bDJf ZGV2LCAiRmFpbGVkIHRvIHJlZ2lzdGVyIG1lZGlhIGRldmljZSIpOwo+PiArCQlnb3RvIGVycl9t ZWRpYV9kZXZfcmVnaXN0ZXI7Cj4+ICsJfQo+PiArCXZkZWNfZW5hYmxlKGRldi0+ZGVjX2h3KTsK Pj4gKwlyZXR1cm4gMDsKPj4gKwo+PiArZXJyX21lZGlhX2Rldl9yZWdpc3RlcjoKPj4gKwl2NGwy X20ybV91bnJlZ2lzdGVyX21lZGlhX2NvbnRyb2xsZXIoZGV2LT5tMm1fZGV2X2RlYyk7Cj4+ICtl cnJvcl9tMm1fbWNfcmVnaXN0ZXI6Cj4+ICsJbWVkaWFfZGV2aWNlX2NsZWFudXAoJmRldi0+bWRl dik7Cj4+ICtlcnJfdmlkX2Rldl9yZWdpc3RlcjoKPj4gKwl2NGwyX20ybV9yZWxlYXNlKGRldi0+ bTJtX2Rldl9kZWMpOwo+PiArZXJyX2h3X2luaXQ6Cj4+ICsJZGV2LT5kZWNfaHcgPSBOVUxMOwo+ PiArZXJyX2RlY19tZW1faW5pdDoKPj4gKwl2aWRlb19kZXZpY2VfcmVsZWFzZSh2ZmRfZGVjKTsK Pj4gK2Vycl9kZXZpY2VfYWxsb2M6Cj4+ICsJdjRsMl9kZXZpY2VfdW5yZWdpc3RlcigmZGV2LT52 NGwyX2Rldik7Cj4+ICsJcmV0dXJuIHJldDsKPj4gK30KPj4gKwo+PiArc3RhdGljIHZvaWQgYW1s X3ZkZWNfZHJ2X3JlbW92ZShzdHJ1Y3QgcGxhdGZvcm1fZGV2aWNlICpwZGV2KQo+PiArewo+PiAr CXN0cnVjdCBhbWxfdmRlY19kZXYgKmRldiA9IHBsYXRmb3JtX2dldF9kcnZkYXRhKHBkZXYpOwo+ PiArCj4+ICsJdmRlY19kaXNhYmxlKGRldi0+ZGVjX2h3KTsKPj4gKwo+PiArCWlmIChtZWRpYV9k ZXZub2RlX2lzX3JlZ2lzdGVyZWQoZGV2LT5tZGV2LmRldm5vZGUpKSB7Cj4+ICsJCW1lZGlhX2Rl dmljZV91bnJlZ2lzdGVyKCZkZXYtPm1kZXYpOwo+PiArCQltZWRpYV9kZXZpY2VfY2xlYW51cCgm ZGV2LT5tZGV2KTsKPj4gKwl9Cj4+ICsKPj4gKwlpZiAoZGV2LT5tMm1fZGV2X2RlYykKPj4gKwkJ djRsMl9tMm1fcmVsZWFzZShkZXYtPm0ybV9kZXZfZGVjKTsKPj4gKwlpZiAoZGV2LT52ZmQpCj4+ ICsJCXZpZGVvX3VucmVnaXN0ZXJfZGV2aWNlKGRldi0+dmZkKTsKPj4gKwlpZiAoZGV2LT5kZWNf aHcpIHsKPj4gKwkJZGV2LT5wdmRlY19kYXRhLT5kZXN0cm95X2h3X3Jlc291cmNlKGRldik7Cj4+ ICsJCWRldi0+ZGVjX2h3ID0gTlVMTDsKPj4gKwl9Cj4+ICsJdjRsMl9kZXZpY2VfdW5yZWdpc3Rl cigmZGV2LT52NGwyX2Rldik7Cj4+ICt9Cj4+ICsKPj4gK3N0YXRpYyBjb25zdCBzdHJ1Y3Qgb2Zf ZGV2aWNlX2lkIGFtbF92ZGVjX21hdGNoW10gPSB7Cj4+ICsJey5jb21wYXRpYmxlID0gImFtbG9n aWMsczQtdmNvZGVjLWRlYyIsIC5kYXRhID0gJmFtbF92ZGVjX3M0X3BkYXRhfSwKPj4gKwl7fSwK Pj4gK307Cj4+ICsKPj4gK3N0YXRpYyBzdHJ1Y3QgcGxhdGZvcm1fZHJpdmVyIGFtbF92Y29kZWNf ZGVjX2RyaXZlciA9IHsKPj4gKwkucHJvYmXCoMKgwqAgPSBhbWxfdmRlY19kcnZfcHJvYmUsCj4+ ICsJLnJlbW92ZcKgwqDCoCA9IGFtbF92ZGVjX2Rydl9yZW1vdmUsCj4+ICsJLmRyaXZlcsKgwqDC oCA9IHsKPj4gKwkJLm5hbWXCoMKgwqAgPSBBTUxfVkRFQ19EUlZfTkFNRSwKPj4gKwkJLm9mX21h dGNoX3RhYmxlID0gYW1sX3ZkZWNfbWF0Y2gsCj4+ICsJfSwKPj4gK307Cj4+ICsKPj4gK21vZHVs ZV9wbGF0Zm9ybV9kcml2ZXIoYW1sX3Zjb2RlY19kZWNfZHJpdmVyKTsKPj4gKwo+PiArTU9EVUxF X0RFU0NSSVBUSU9OKCJBbWxvZ2ljIFY0TDIgZGVjb2RlciBkcml2ZXIiKTsKPj4gK01PRFVMRV9M SUNFTlNFKCJHUEwiKTsKPj4gZGlmZiAtLWdpdCBhL2RyaXZlcnMvbWVkaWEvcGxhdGZvcm0vYW1s b2dpYy92ZGVjL2FtbF92ZGVjX2Rydi5oIGIvZHJpdmVycy9tZWRpYS9wbGF0Zm9ybS9hbWxvZ2lj L3ZkZWMvYW1sX3ZkZWNfZHJ2LmgKPj4gbmV3IGZpbGUgbW9kZSAxMDA2NDQKPj4gaW5kZXggMDAw MDAwMDAwMDAwLi4xODY1OWVlZjg3ZWIKPj4gLS0tIC9kZXYvbnVsbAo+PiArKysgYi9kcml2ZXJz L21lZGlhL3BsYXRmb3JtL2FtbG9naWMvdmRlYy9hbWxfdmRlY19kcnYuaAo+PiBAQCAtMCwwICsx LDE5NiBAQAo+PiArLyogU1BEWC1MaWNlbnNlLUlkZW50aWZpZXI6IChHUEwtMi4wLW9ubHkgT1Ig TUlUKSAqLwo+PiArLyoKPj4gKyAqIENvcHlyaWdodCAoQykgMjAyNSBBbWxvZ2ljLCBJbmMuIEFs bCByaWdodHMgcmVzZXJ2ZWQKPj4gKyAqLwo+PiArCj4+ICsjaWZuZGVmIF9BTUxfVkRFQ19EUlZf SF8KPj4gKyNkZWZpbmUgX0FNTF9WREVDX0RSVl9IXwo+PiArCj4+ICsjaW5jbHVkZSA8bGludXgv cGxhdGZvcm1fZGV2aWNlLmg+Cj4+ICsjaW5jbHVkZSA8bGludXgvdmlkZW9kZXYyLmg+Cj4+ICsj aW5jbHVkZSA8bGludXgvY2xrLmg+Cj4+ICsKPj4gKyNpbmNsdWRlIDxtZWRpYS92NGwyLWN0cmxz Lmg+Cj4+ICsjaW5jbHVkZSA8bWVkaWEvdjRsMi1kZXZpY2UuaD4KPj4gKyNpbmNsdWRlIDxtZWRp YS92NGwyLWlvY3RsLmg+Cj4+ICsjaW5jbHVkZSA8bWVkaWEvdjRsMi1tZW0ybWVtLmg+Cj4+ICsj aW5jbHVkZSA8bWVkaWEvdmlkZW9idWYyLWNvcmUuaD4KPj4gKyNpbmNsdWRlIDxtZWRpYS92aWRl b2J1ZjItZG1hLWNvbnRpZy5oPgo+PiArCj4+ICsjZGVmaW5lIEFNTF9WQ09ERUNfTUFYX1BMQU5F UyAzCj4+ICsjZGVmaW5lIEFNTF9WREVDX01JTl9XwqDCoMKgIDY0VQo+PiArI2RlZmluZSBBTUxf VkRFQ19NSU5fSMKgwqDCoCA2NFUKPj4gKyNkZWZpbmUgQU1MX1ZERUNfMTA4MFBfTUFYX0jCoCAx MDg4VQo+PiArI2RlZmluZSBBTUxfVkRFQ18xMDgwUF9NQVhfV8KgIDE5MjBVCj4+ICsKPj4gK3N0 cnVjdCBhbWxfdmRlY19jdHg7Cj4+ICsvKioKPj4gKyAqIGVudW0gYW1sX2ZtdF90eXBlIC0gVHlw ZSBvZiBmb3JtYXQgdHlwZQo+PiArICovCj4+ICtlbnVtIGFtbF9mbXRfdHlwZSB7Cj4+ICsJQU1M X0ZNVF9ERUMgPSAwLAo+PiArCUFNTF9GTVRfRlJBTUUgPSAxLAo+PiArfTsKPj4gKwo+PiArLyoq Cj4+ICsgKiBlbnVtIGFtbF9jb2RlY190eXBlIC0gVHlwZSBvZiBjb2RlYyBmb3JtYXQKPj4gKyAq Lwo+PiArZW51bSBhbWxfY29kZWNfdHlwZSB7Cj4+ICsJQ09ERUNfVFlQRV9IMjY0ID0gMCwKPj4g KwlDT0RFQ19UWVBFX0ZSQU1FLAo+PiArfTsKPj4gKwo+PiArLyoqCj4+ICsgKiBlbnVtIGFtbF9x X3R5cGUgLSBUeXBlIG9mIHF1ZXVlIDogY2FwIG9yIG91dHB1dAo+PiArICovCj4+ICtlbnVtIGFt bF9xX3R5cGUgewo+PiArCUFNTF9RX0RBVEFfU1JDID0gMCwKPj4gKwlBTUxfUV9EQVRBX0RTVCA9 IDEsCj4+ICt9Owo+PiArCj4+ICsvKioKPj4gKyAqIHN0cnVjdCBhbWxfdmlkZW9fZm10IC0gYW1s IHZpZGVvIGRlY29kZXIgZm10IGluZm9ybWF0aW9uCj4+ICsgKiBAZm91cmNjOiBGb3VyQ0MgY29k ZSBvZiB0aGUgZm9ybWF0LiBTZWUgVjRMMl9QSVhfRk1UXyouCj4+ICsgKiBAdHlwZTogQ3VyciBx dWV1ZSB0eXBlOiBjYXB0dXJlIG9yIG91dHB1dC4KPj4gKyAqIEBjb2RlY190eXBlOiBDb2RlYyBt b2RlIHJlbGF0ZWQuIFNlZSBhbWxfY29kZWNfdHlwZS4KPj4gKyAqIEBudW1fcGxhbmVzOiBOdW0g cGxhbmVzIG9mIHRoZSBmb3JtYXQuCj4+ICsgKiBAbmFtZTogTmFtZSBvZiB0aGUgZm9ybWF0Lgo+ PiArICogQHN0ZXB3aXNlOiBTdXBwb3J0ZWQgcmFuZ2Ugb2YgZnJhbWUgc2l6ZXMgKG9ubHkgZm9y IGJpdHN0cmVhbSBmb3JtYXRzKS4KPj4gKyAqLwo+PiArc3RydWN0IGFtbF92aWRlb19mbXQgewo+ PiArCXUzMiBmb3VyY2M7Cj4+ICsJZW51bSBhbWxfZm10X3R5cGUgdHlwZTsKPj4gKwllbnVtIGFt bF9jb2RlY190eXBlIGNvZGVjX3R5cGU7Cj4+ICsJdTMyIG51bV9wbGFuZXM7Cj4+ICsJY29uc3Qg dTggKm5hbWU7Cj4+ICsJc3RydWN0IHY0bDJfZnJtc2l6ZV9zdGVwd2lzZSBzdGVwd2lzZTsKPj4g K307Cj4+ICsKPj4gKy8qKgo+PiArICogc3RydWN0IGFtbF9xX2RhdGEgLSBhbWwgdmlkZW8gcXVl dWUgaW5mb3JtYXRpb24KPj4gKyAqIEB2aXNpYmxlX3dpZHRoOiBXaWR0aCBmb3IgZGlzcGxheS4K Pj4gKyAqIEB2aXNpYmxlX2hlaWdodDogSGVpZ2h0IGZvciBkaXNwbGF5Lgo+PiArICogQGNvZGVk X3dpZHRoOiBXaWR0aCBmb3IgZGVjb2RlLCB3aGljaCBpcyA2NC8zMiBhbGlnbmVkLgo+PiArICog QGNvZGVkX2hlaWdodDogSGVpZ2h0IGZvciBkZWNvZGUsIHdoaWNoIGlzIDY0LzMyIGFsaWduZWQu Cj4+ICsgKiBAZmlsZWRfZmxhZzogRmllbGQgcGljIGZsYWcuCj4+ICsgKiBAYnl0ZXNwZXJsaW5l OiBCeXRlIG51bSBvZiBlYWNoIHBpeGVsIGxpbmUuCj4+ICsgKiBAc2l6ZWltYWdlOiBTaXplIG9m IGZyYW1lIGluIGJ5dGVzLgo+PiArICogQGZtdDogRm9ybWF0IGZvciBjdXJyIHF1ZXVlLiBTZWUg c3RydWN0IGFtbF92aWRlb19mbXQuCj4+ICsgKi8KPj4gK3N0cnVjdCBhbWxfcV9kYXRhIHsKPj4g Kwl1MzIgdmlzaWJsZV93aWR0aDsKPj4gKwl1MzIgdmlzaWJsZV9oZWlnaHQ7Cj4+ICsJdTMyIGNv ZGVkX3dpZHRoOwo+PiArCXUzMiBjb2RlZF9oZWlnaHQ7Cj4+ICsJdTMyIGZpbGVkX2ZsYWc7Cj4+ ICsJdTMyIGJ5dGVzcGVybGluZVtBTUxfVkNPREVDX01BWF9QTEFORVNdOwo+PiArCXUzMiBzaXpl aW1hZ2VbQU1MX1ZDT0RFQ19NQVhfUExBTkVTXTsKPj4gKwlzdHJ1Y3QgYW1sX3ZpZGVvX2ZtdCAq Zm10Owo+PiArfTsKPj4gKwo+PiArLyoqCj4+ICsgKiBzdHJ1Y3QgYW1sX3ZkZWNfZGV2IC0gZHJp dmVyIGRhdGEKPj4gKyAqIEBwbGF0X2RldjogUGxhdGZvcm0gZGV2aWNlIGZvciB0aGUgY3VycmVu dCBkcml2ZXIuCj4+ICsgKiBAdjRsMl9kZXY6IFY0TDIgZGV2aWNlIHRvIHJlZ2lzdGVyIHZpZGVv IGRldmljZXMgZm9yLgo+PiArICogQG0ybV9kZXZfZGVjOiBNZW0ybWVtIGRldmljZSBhc3NvY2lh dGVkIHRvIHRoaXMgZGV2aWNlLgo+PiArICogQHZmZDogVmlkZW9fZGV2aWNlIGFzc29jaWF0ZWQg dG8gdGhpcyBkZXZpY2UuCj4+ICsgKiBAbWRldjogTWVkaWFfZGV2aWNlIGFzc29jaWF0ZWQgdG8g dGhpcyBkZXZpY2UuCj4+ICsgKiBAZGVjX2N0eDogRGVjb2RlciBjb250ZXh0LiBTZWUgc3RydWN0 IGFtbF92ZGVjX2N0eC4KPj4gKyAqIEBkZWNfaHc6IERlY29kZXIgaGFyZHdhcmUgcmVzb3VyY2Vz LiBTZWUgc3RydWN0IGFtbF92ZGVjX2h3Lgo+PiArICogQHB2ZGVjX2RhdGE6IERlY29kZXIgcGxh dGZvcm0gZGF0YS4gU2VlIHN0cnVjdCBhbWxfZGV2X3BsYXRmb3JtX2RhdGEuCj4+ICsgKiBAZGV2 X211dGV4OiB2aWRlb19kZXZpY2UgbG9jay4KPj4gKyAqIEBmaWxwOiB2NGwyIGZpbGUgaGFuZGxl IHBvaW50ZXIuCj4+ICsgKi8KPj4gK3N0cnVjdCBhbWxfdmRlY19kZXYgewo+PiArCXN0cnVjdCBw bGF0Zm9ybV9kZXZpY2UgKnBsYXRfZGV2Owo+PiArCXN0cnVjdCB2NGwyX2RldmljZSB2NGwyX2Rl djsKPj4gKwlzdHJ1Y3QgdjRsMl9tMm1fZGV2ICptMm1fZGV2X2RlYzsKPj4gKwlzdHJ1Y3Qgdmlk ZW9fZGV2aWNlICp2ZmQ7Cj4+ICsJc3RydWN0IG1lZGlhX2RldmljZSBtZGV2Owo+PiArCj4+ICsJ c3RydWN0IGFtbF92ZGVjX2N0eCAqZGVjX2N0eDsKPj4gKwlzdHJ1Y3QgYW1sX3ZkZWNfaHcgKmRl Y19odzsKPj4gKwljb25zdCBzdHJ1Y3QgYW1sX2Rldl9wbGF0Zm9ybV9kYXRhICpwdmRlY19kYXRh Owo+PiArCj4+ICsJc3RydWN0IG11dGV4IGRldl9tdXRleDsKPj4gKwlzdHJ1Y3QgZmlsZSAqZmls cDsKPj4gK307Cj4+ICsKPj4gKy8qKgo+PiArICogc3RydWN0IGRlY19waWNfaW5mbyAtIHBpYyBp bmZvcm1hdGlvbiBkZXNjcmlwdGlvbgo+PiArICogQGNvbG9yc3BhY2U6IGVudW0gdjRsMl9jb2xv cnNwYWNlOyBzdXBwbGVtZW50YWwgdG8gcGl4ZWxmb3JtYXQKPj4gKyAqIEB5Y2Jjcl9lbmM6IGVu dW0gdjRsMl95Y2Jjcl9lbmNvZGluZywgWSdDYkNyIGVuY29kaW5nCj4+ICsgKiBAeGZlcl9mdW5j OiBlbnVtIHY0bDJfeGZlcl9mdW5jLCBjb2xvcnNwYWNlIHRyYW5zZmVyIGZ1bmN0aW9uCj4+ICsg KiBAcXVhbnRpemF0aW9uOiBlbnVtIHY0bDJfcXVhbnRpemF0aW9uLCBjb2xvcnNwYWNlIHF1YW50 aXphdGlvbgo+PiArICogQGNhcF9waXhfZm10OiBQaXhlbCBmb3JtYXQgZm9yIGNhcHR1cmUgcXVl dWUuCj4+ICsgKiBAb3V0cHV0X3BpeF9mbXQ6IFBpeGVsIGZvcm1hdCBmb3Igb3V0cHV0IHF1ZXVl Lgo+PiArICogQGNvZGVkX3dpZHRoOiBXaWR0aCBmb3IgZGVjb2RlLgo+PiArICogQGNvZGVkX2hl aWdodDogSGVpZ2h0IGZvciBkZWNvZGUuCj4+ICsgKiBAZmJfc2l6ZTogRnJhbWUgYnVmZmVyIHNp emUgZm9yIFkgb3IgVVYuCj4+ICsgKiBAcGxhbmVfbnVtOiBOdW0gZm9yIHBsYW5lcyBmb3IgY3Vy ciBmb3JtYXQuCj4+ICsgKi8KPj4gK3N0cnVjdCBkZWNfcGljX2luZm8gewo+PiArCWVudW0gdjRs Ml9jb2xvcnNwYWNlIGNvbG9yc3BhY2U7Cj4+ICsJZW51bSB2NGwyX3ljYmNyX2VuY29kaW5nIHlj YmNyX2VuYzsKPj4gKwllbnVtIHY0bDJfeGZlcl9mdW5jIHhmZXJfZnVuYzsKPj4gKwllbnVtIHY0 bDJfcXVhbnRpemF0aW9uIHF1YW50aXphdGlvbjsKPj4gKwl1MzIgY2FwX3BpeF9mbXQ7Cj4+ICsJ dTMyIG91dHB1dF9waXhfZm10Owo+PiArCXUzMiBjb2RlZF93aWR0aDsKPj4gKwl1MzIgY29kZWRf aGVpZ2h0Owo+PiArCXUzMiBmYl9zaXplWzJdOwo+PiArCXUzMiBwbGFuZV9udW07Cj4+ICt9Owo+ PiArCj4+ICsvKioKPj4gKyAqIHN0cnVjdCBhbWxfdmRlY19jdHggLSBkcml2ZXIgaW5zdGFuY2Ug Y29udGV4dAo+PiArICogQGRldjogcG9pbnRlciB0byB0aGUgYW1sX3ZkZWNfZGV2IG9mIHRoZSBk ZXZpY2UuCj4+ICsgKiBAZmg6IHN0cnVjdCB2NGwyIGZoLgo+PiArICogQG0ybV9jdHg6IHBvaW50 ZXIgdG8gdjRsMl9tMm1fY3R4IGNvbnRleHQuCj4+ICsgKiBAY3RybF9oYW5kbGVyOiBWNEwyIGN0 cmwgaGFuZGxlci4KPj4gKyAqIEB2NGwyX2ludGZfbG9jazogTXV0ZXggbG9jayBmb3IgdjRsMiBp bnRlcmZhY2UuCj4+ICsgKiBAY29kZWNfb3BzOiBDb2RlYyBvcGVyYXRpb24gZnVuY3Rpb25zLiBT ZWUgc3RydWN0IGFtbF9jb2RlY19vcHMuCj4+ICsgKiBAaW50X2NvbmQ6IFZhcmlhYmxlIHVzZWQg YnkgdGhlIHdhaXRxdWV1ZS4KPj4gKyAqIEBxdWV1ZTogV2FpdHF1ZXVlIHRvIHdhaXQgZm9yIHRo ZSBjdXJyZW50IGRlY29kZSBjb250ZXh0IGZpbmlzaC4KPj4gKyAqIEBxX2RhdGE6IGZlYXR1cmUg c3VwcG9ydGVkIGJ5IHRoZSBjdXJyZW50IGRlY29kZXIgaW5zdGFuY2UuCj4+ICsgKiBAaXNfY2Fw X3N0cmVhbW9uOiBpbmRpY2F0ZXMgaWYgdGhlIGN1cnJlbnQgY2FwdHVyZSBzdHJlYW0gaXMgb24u Cj4+ICsgKiBAaXNfb3V0cHV0X3N0cmVhbW9uOiBpbmRpY2F0ZXMgaWYgdGhlIGN1cnJlbnQgb3V0 cHV0IHN0cmVhbSBpcyBvbi4KPj4gKyAqIEBkb3NfY2xrX2VuOiBpbmRpY2F0ZXMgaWYgZG9zIGNs ayBpcyBlbmFibGVkLgo+PiArICogQHBpY19pbmZvOiBQaWMgaW5mb3JtYXRpb24gZm9yIGN1cnIg ZGVjb2RlciBjb250ZXh0LiBTZWUgc3RydWN0IGRlY19waWNfaW5mby4KPj4gKyAqIEBjdXJyX2Rl Y190eXBlOiBDdXJyZW50IGRlY29kZXIgdHlwZS4gKENPREVDX1RZUEVfSDI2NCwgZXRjLikKPj4g KyAqIEBjb2RlY19wcml2OiBQb2ludGVyIHRvIGN1cnJlbnQgZGVjb2RlciBpbnN0YW5jZS4KPj4g KyAqLwo+PiArc3RydWN0IGFtbF92ZGVjX2N0eCB7Cj4+ICsJc3RydWN0IGFtbF92ZGVjX2RldiAq ZGV2Owo+PiArCXN0cnVjdCB2NGwyX2ZoIGZoOwo+PiArCXN0cnVjdCB2NGwyX20ybV9jdHggKm0y bV9jdHg7Cj4+ICsJc3RydWN0IHY0bDJfY3RybF9oYW5kbGVyIGN0cmxfaGFuZGxlcjsKPj4gKwlz dHJ1Y3QgbXV0ZXggdjRsMl9pbnRmX2xvY2s7Cj4+ICsKPj4gKwljb25zdCBzdHJ1Y3QgYW1sX2Nv ZGVjX29wcyAqY29kZWNfb3BzOwo+PiArCWludCBpbnRfY29uZDsKPj4gKwl3YWl0X3F1ZXVlX2hl YWRfdCBxdWV1ZTsKPj4gKwlzdHJ1Y3QgYW1sX3FfZGF0YSBxX2RhdGFbMl07Cj4+ICsKPj4gKwli b29sIGlzX2NhcF9zdHJlYW1vbjsKPj4gKwlib29sIGlzX291dHB1dF9zdHJlYW1vbjsKPj4gKwli b29sIGRvc19jbGtfZW47Cj4+ICsKPj4gKwlzdHJ1Y3QgZGVjX3BpY19pbmZvIHBpY19pbmZvOwo+ PiArCXUzMiBjdXJyX2RlY190eXBlOwo+PiArCXZvaWQgKmNvZGVjX3ByaXY7Cj4+ICt9Owo+PiAr Cj4+ICtzdGF0aWMgaW5saW5lIHN0cnVjdCBhbWxfdmRlY19jdHggKmZoX3RvX2RlY19jdHgoc3Ry dWN0IGZpbGUgKmZpbGUpCj4+ICt7Cj4+ICsJc3RydWN0IHY0bDJfZmggKmZpbGVfZmggPSBmaWxl X3RvX3Y0bDJfZmgoZmlsZSk7Cj4+ICsKPj4gKwlyZXR1cm4gY29udGFpbmVyX29mKGZpbGVfZmgs IHN0cnVjdCBhbWxfdmRlY19jdHgsIGZoKTsKPj4gK30KPj4gKwo+PiArc3RhdGljIGlubGluZSBz dHJ1Y3QgYW1sX3ZkZWNfY3R4ICpjdHJsX3RvX2RlY19jdHgoc3RydWN0IHY0bDJfY3RybF9oYW5k bGVyICpjdHJsKQo+PiArewo+PiArCXJldHVybiBjb250YWluZXJfb2YoY3RybCwgc3RydWN0IGFt bF92ZGVjX2N0eCwgY3RybF9oYW5kbGVyKTsKPj4gK30KPj4gKwo+PiArI2VuZGlmCj4+IGRpZmYg LS1naXQgYS9kcml2ZXJzL21lZGlhL3BsYXRmb3JtL2FtbG9naWMvdmRlYy9hbWxfdmRlY19ody5j IGIvZHJpdmVycy9tZWRpYS9wbGF0Zm9ybS9hbWxvZ2ljL3ZkZWMvYW1sX3ZkZWNfaHcuYwo+PiBu ZXcgZmlsZSBtb2RlIDEwMDY0NAo+PiBpbmRleCAwMDAwMDAwMDAwMDAuLjE3MjkwNzZkZTc2Ywo+ PiAtLS0gL2Rldi9udWxsCj4+ICsrKyBiL2RyaXZlcnMvbWVkaWEvcGxhdGZvcm0vYW1sb2dpYy92 ZGVjL2FtbF92ZGVjX2h3LmMKPj4gQEAgLTAsMCArMSw1OTYgQEAKPj4gKy8vIFNQRFgtTGljZW5z ZS1JZGVudGlmaWVyOiAoR1BMLTIuMC1vbmx5IE9SIE1JVCkKPj4gKy8qCj4+ICsgKiBDb3B5cmln aHQgKEMpIDIwMjUgQW1sb2dpYywgSW5jLiBBbGwgcmlnaHRzIHJlc2VydmVkCj4+ICsgKi8KPj4g Kwo+PiArI2luY2x1ZGUgPGxpbnV4L2ludGVycnVwdC5oPgo+PiArI2luY2x1ZGUgPGxpbnV4L2ly cS5oPgo+PiArI2luY2x1ZGUgPGxpbnV4L29mLmg+Cj4+ICsjaW5jbHVkZSA8bGludXgvb2ZfZGV2 aWNlLmg+Cj4+ICsjaW5jbHVkZSA8bGludXgvb2ZfcGxhdGZvcm0uaD4KPj4gKyNpbmNsdWRlIDxs aW51eC9vZl9hZGRyZXNzLmg+Cj4+ICsjaW5jbHVkZSA8bGludXgvc2xhYi5oPgo+PiArI2luY2x1 ZGUgPGxpbnV4L2Zpcm13YXJlLmg+Cj4+ICsjaW5jbHVkZSA8bGludXgvaW9wb2xsLmg+Cj4+ICsK Pj4gKyNpbmNsdWRlICJhbWxfdmRlY19kcnYuaCIKPj4gKyNpbmNsdWRlICJhbWxfdmRlY19ody5o Igo+PiArI2luY2x1ZGUgImFtbF92ZGVjX3BsYXRmb3JtLmgiCj4+ICsKPj4gKyNkZWZpbmUgTUh6 wqDCoMKgwqAgKDEwMDAwMDApCj4+ICsjZGVmaW5lIE1DX1NJWkUgKDQwOTYgKiAxNikKPj4gKwo+ PiArc3RhdGljIHN0cnVjdCBwbV9wZF9zIHZkZWNfZG9tYWluX2RhdGFbXSA9IHsKPj4gKwlbVkRF Q18xXSA9IHsubmFtZSA9ICJ2ZGVjIiwgfSwKPj4gKwlbVkRFQ19IRVZDXSA9IHsubmFtZSA9ICJo ZXZjIiwgfSwKPj4gK307Cj4+ICsKPj4gK3UzMiByZWFkX2Rvc19yZWcoc3RydWN0IGFtbF92ZGVj X2h3ICpodywgdTMyIGFkZHIpCj4+ICt7Cj4+ICsJdTMyIHJldF92YWw7Cj4+ICsKPj4gKwlyZWdt YXBfcmVhZChody0+bWFwW0RPU19CVVNdLCBhZGRyLCAmcmV0X3ZhbCk7Cj4+ICsKPj4gKwlyZXR1 cm4gcmV0X3ZhbDsKPj4gK30KPj4gKwo+PiArc3RhdGljIHZvaWQgZG9zX3JlZ193cml0ZV9iaXRz KHN0cnVjdCBhbWxfdmRlY19odyAqaHcsIHUzMiByZWcsIHUzMiB2YWwsIGludCBzdGFydCwgaW50 IGxlbikKPj4gK3sKPj4gKwl1MzIgbWFzayA9ICgoKDFMIDw8IChsZW4pKSAtIDEpIDw8IChzdGFy dCkpOwo+PiArCj4+ICsJcmVnbWFwX3VwZGF0ZV9iaXRzKGh3LT5tYXBbRE9TX0JVU10sIHJlZywg bWFzaywgdmFsKTsKPj4gK30KPj4gKwo+PiArdm9pZCBkb3NfZW5hYmxlKHN0cnVjdCBhbWxfdmRl Y19odyAqaHcpCj4+ICt7Cj4+ICsJZG9zX3JlZ193cml0ZV9iaXRzKGh3LCBET1NfR0NMS19FTjAs IDB4M2ZmLCAwLCAxMCk7Cj4+ICsKPj4gKwlyZWdtYXBfd3JpdGUoaHctPm1hcFtET1NfQlVTXSwg R0NMS19FTiwgMHgzZmYpOwo+PiArCj4+ICsJcmVnbWFwX3VwZGF0ZV9iaXRzKGh3LT5tYXBbRE9T X0JVU10sIE1ERUNfUElDX0RDX0NUUkwsICgxIDw8IDMxKSwgMCk7Cj4+ICt9Cj4+ICsKPj4gK3Zv aWQgYW1sX3ZkZWNfcmVzZXRfY29yZShzdHJ1Y3QgYW1sX3ZkZWNfaHcgKmh3KQo+PiArewo+PiAr CXVuc2lnbmVkIGludCBtYXNrID0gMDsKPj4gKwo+PiArCW1hc2sgPSAoMSA8PCAyMSk7Cj4+ICsK Pj4gKwlyZWdtYXBfdXBkYXRlX2JpdHMoaHctPm1hcFtETUNfQlVTXSwgMHgwLCBtYXNrLCAwKTsK Pj4gKwl1c2xlZXBfcmFuZ2UoNjAsIDcwKTsKPj4gKwlyZWdtYXBfd3JpdGUoaHctPm1hcFtET1Nf QlVTXSwgRE9TX1NXX1JFU0VUMCwKPj4gKwkJwqDCoMKgwqAgKDEgPDwgMykgfCAoMSA8PCA0KSB8 ICgxIDw8IDUpIHwgKDEgPDwgNykgfAo+PiArCQnCoMKgwqDCoCAoMSA8PCA4KSB8ICgxIDw8IDkp KTsKPj4gKwlyZWdtYXBfd3JpdGUoaHctPm1hcFtET1NfQlVTXSwgRE9TX1NXX1JFU0VUMCwgMCk7 Cj4+ICsJcmVnbWFwX3VwZGF0ZV9iaXRzKGh3LT5tYXBbRE9TX0JVU10sIFZERUNfQVNTSVNUX01N Q19DVFJMMSwgMSA8PCAzLCAwKTsKPj4gKwlyZWdtYXBfdXBkYXRlX2JpdHMoaHctPm1hcFtET1Nf QlVTXSwgTURFQ19QSUNfRENfTVVYX0NUUkwsIDEgPDwgMzEsIDApOwo+PiArCXJlZ21hcF93cml0 ZShody0+bWFwW0RPU19CVVNdLCBNREVDX0VYVElGX0NGRzEsIDApOwo+PiArCj4+ICsJcmVnbWFw X3VwZGF0ZV9iaXRzKGh3LT5tYXBbRE1DX0JVU10sIDB4MCwgbWFzaywgbWFzayk7Cj4+ICt9Cj4+ ICsKPj4gK3ZvaWQgYW1sX3N0YXJ0X3ZkZWNfaHcoc3RydWN0IGFtbF92ZGVjX2h3ICpodykKPj4g K3sKPj4gKwl1MzIgcmVnX3JlYWRfdmFsOwo+PiArCj4+ICsJcmVnbWFwX3JlYWQoaHctPm1hcFtE T1NfQlVTXSwgRE9TX1NXX1JFU0VUMCwgJnJlZ19yZWFkX3ZhbCk7Cj4+ICsJcmVnbWFwX3JlYWQo aHctPm1hcFtET1NfQlVTXSwgRE9TX1NXX1JFU0VUMCwgJnJlZ19yZWFkX3ZhbCk7Cj4+ICsJcmVn bWFwX3JlYWQoaHctPm1hcFtET1NfQlVTXSwgRE9TX1NXX1JFU0VUMCwgJnJlZ19yZWFkX3ZhbCk7 Cj4+ICsKPj4gKwlyZWdtYXBfd3JpdGUoaHctPm1hcFtET1NfQlVTXSwgRE9TX1NXX1JFU0VUMCwg KDEgPDwgMTIpIHwgKDEgPDwgMTEpKTsKPj4gKwlyZWdtYXBfd3JpdGUoaHctPm1hcFtET1NfQlVT XSwgRE9TX1NXX1JFU0VUMCwgMCk7Cj4+ICsKPj4gKwlyZWdtYXBfcmVhZChody0+bWFwW0RPU19C VVNdLCBET1NfU1dfUkVTRVQwLCAmcmVnX3JlYWRfdmFsKTsKPj4gKwlyZWdtYXBfcmVhZChody0+ bWFwW0RPU19CVVNdLCBET1NfU1dfUkVTRVQwLCAmcmVnX3JlYWRfdmFsKTsKPj4gKwlyZWdtYXBf cmVhZChody0+bWFwW0RPU19CVVNdLCBET1NfU1dfUkVTRVQwLCAmcmVnX3JlYWRfdmFsKTsKPj4g Kwo+PiArCXJlZ21hcF93cml0ZShody0+bWFwW0RPU19CVVNdLCBNUFNSLCAweDAwMDEpOwo+PiAr fQo+PiArCj4+ICt2b2lkIGFtbF9zdG9wX3ZkZWNfaHcoc3RydWN0IGFtbF92ZGVjX2h3ICpodykK Pj4gK3sKPj4gKwl1MzIgcmVnX3ZhbCA9IDA7Cj4+ICsJaW50IHJldDsKPj4gKwo+PiArCXJlZ21h cF93cml0ZShody0+bWFwW0RPU19CVVNdLCBNUFNSLCAwKTsKPj4gKwlyZWdtYXBfd3JpdGUoaHct Pm1hcFtET1NfQlVTXSwgQ1BTUiwgMCk7Cj4+ICsKPj4gKwlyZXQgPSByZWFkX3BvbGxfdGltZW91 dF9hdG9taWMocmVhZF9kb3NfcmVnLCByZWdfdmFsLAo+PiArCQkJCcKgwqDCoMKgwqDCoCAhKHJl Z192YWwgJiAweDgwMDApLAo+PiArCQkJCcKgwqDCoMKgwqDCoCAxMCwgMTAwMDAwLCB0cnVlLAo+ PiArCQkJCcKgwqDCoMKgwqDCoCBodywgSU1FTV9ETUFfQ1RSTCk7Cj4+ICsKPj4gKwlyZXQgPSBy ZWFkX3BvbGxfdGltZW91dF9hdG9taWMocmVhZF9kb3NfcmVnLCByZWdfdmFsLAo+PiArCQkJCcKg wqDCoMKgwqDCoCAhKHJlZ192YWwgJiAweDgwMDApLAo+PiArCQkJCcKgwqDCoMKgwqDCoCAxMCwg MTAwMDAwLCB0cnVlLAo+PiArCQkJCcKgwqDCoMKgwqDCoCBodywgTE1FTV9ETUFfQ1RSTCk7Cj4+ ICsKPj4gKwlyZXQgPSByZWFkX3BvbGxfdGltZW91dF9hdG9taWMocmVhZF9kb3NfcmVnLCByZWdf dmFsLAo+PiArCQkJCcKgwqDCoMKgwqDCoCAhKHJlZ192YWwgJiAweGZmZiksCj4+ICsJCQkJwqDC oMKgwqDCoMKgIDEwLCA4MDAwMDAsIHRydWUsCj4+ICsJCQkJwqDCoMKgwqDCoMKgIGh3LCBXUlJT UF9MTUVNKTsKPj4gKwlpZiAocmV0KQo+PiArCQlkZXZfZXJyKGh3LT5kZXYsICIlcywgY3RybCAl eCwgcnNwICV4LCBwYyAleCBzdGF0dXMgJXgsJXhcbiIsCj4+ICsJCQlfX2Z1bmNfXywgcmVhZF9k b3NfcmVnKGh3LCBMTUVNX0RNQV9DVFJMKSwKPj4gKwkJCXJlYWRfZG9zX3JlZyhodywgV1JSU1Bf TE1FTSksIHJlYWRfZG9zX3JlZyhodywgTVBDX0UpLAo+PiArCQkJcmVhZF9kb3NfcmVnKGh3LCBB Vl9TQ1JBVENIX0opLCByZWFkX2Rvc19yZWcoaHcsIEFWX1NDUkFUQ0hfOSkpOwo+PiArCj4+ICsJ cmVnbWFwX3JlYWQoaHctPm1hcFtET1NfQlVTXSwgRE9TX1NXX1JFU0VUMCwgJnJlZ192YWwpOwo+ PiArCXJlZ21hcF9yZWFkKGh3LT5tYXBbRE9TX0JVU10sIERPU19TV19SRVNFVDAsICZyZWdfdmFs KTsKPj4gKwlyZWdtYXBfcmVhZChody0+bWFwW0RPU19CVVNdLCBET1NfU1dfUkVTRVQwLCAmcmVn X3ZhbCk7Cj4+ICsKPj4gKwlyZWdtYXBfd3JpdGUoaHctPm1hcFtET1NfQlVTXSwgRE9TX1NXX1JF U0VUMCwgKDEgPDwgMTIpIHwgKDEgPDwgMTEpKTsKPj4gKwlyZWdtYXBfd3JpdGUoaHctPm1hcFtE T1NfQlVTXSwgRE9TX1NXX1JFU0VUMCwgMCk7Cj4+ICsKPj4gKwlyZWdtYXBfcmVhZChody0+bWFw W0RPU19CVVNdLCBET1NfU1dfUkVTRVQwLCAmcmVnX3ZhbCk7Cj4+ICsJcmVnbWFwX3JlYWQoaHct Pm1hcFtET1NfQlVTXSwgRE9TX1NXX1JFU0VUMCwgJnJlZ192YWwpOwo+PiArCXJlZ21hcF9yZWFk KGh3LT5tYXBbRE9TX0JVU10sIERPU19TV19SRVNFVDAsICZyZWdfdmFsKTsKPj4gK30KPj4gKwo+ PiAraW50IGxvYWRfZmlybXdhcmUoc3RydWN0IGFtbF92ZGVjX2h3ICpodywgY29uc3QgY2hhciAq cGF0aCkKPj4gK3sKPj4gKwljb25zdCBzdHJ1Y3QgZmlybXdhcmUgKmZ3Owo+PiArCXN0cnVjdCBk ZXZpY2UgKmRldiA9IGh3LT5kZXY7Cj4+ICsJc3RhdGljIHU4ICptY19hZGRyOwo+PiArCXN0YXRp YyBkbWFfYWRkcl90IG1jX2FkZHJfbWFwOwo+PiArCWludCBmd19oZWFkX2xlbjsKPj4gKwl1bG9u ZyB0aW1lb3V0Owo+PiArCWludCByZXQ7Cj4+ICsKPj4gKwlyZXQgPSByZXF1ZXN0X2Zpcm13YXJl KCZmdywgcGF0aCwgZGV2KTsKPj4gKwlpZiAocmV0IDwgMCkgewo+PiArCQlkZXZfaW5mbyhkZXYs ICJyZXF1ZXN0X2Zpcm13YXJlICVzIGZhaWxlZCByZXQgJWRcbiIsIHBhdGgsIHJldCk7Cj4+ICsJ CXJldHVybiAtRUlOVkFMOwo+PiArCX0KPj4gKwo+PiArCWlmIChmdy0+c2l6ZSA+IE1DX1NJWkUp IHsKPj4gKwkJZGV2X2luZm8oZGV2LCAiZncgJXMgb3ZlcnNpemVcbiIsIHBhdGgpOwo+PiArCQly ZXQgPSAtRUlOVkFMOwo+PiArCQlnb3RvIHJlbGVhc2VfZmlybXdhcmU7Cj4+ICsJfQo+PiArCj4+ ICsJZndfaGVhZF9sZW4gPSA1MTI7Cj4+ICsJbWNfYWRkciA9IGRtYV9hbGxvY19jb2hlcmVudChk ZXYsIE1DX1NJWkUsICZtY19hZGRyX21hcCwgR0ZQX0tFUk5FTCk7Cj4+ICsJaWYgKCFtY19hZGRy KSB7Cj4+ICsJCWRldl9pbmZvKGRldiwgIm5vIG1lbSBmb3IgZncgJXNcbiIsIHBhdGgpOwo+PiAr CQlyZXQgPSAtRU5PTUVNOwo+PiArCQlnb3RvIHJlbGVhc2VfZmlybXdhcmU7Cj4+ICsJfQo+PiAr CW1lbXNldChtY19hZGRyLCAwLCBNQ19TSVpFKTsKPj4gKwltZW1jcHkobWNfYWRkciwgKCh1OCAq KWZ3LT5kYXRhICsgZndfaGVhZF9sZW4pLAo+PiArCcKgwqDCoMKgwqDCoCAoZnctPnNpemUgLSBm d19oZWFkX2xlbikpOwo+PiArCj4+ICsJcmVnbWFwX3dyaXRlKGh3LT5tYXBbRE9TX0JVU10sIE1Q U1IsIDApOwo+PiArCXJlZ21hcF93cml0ZShody0+bWFwW0RPU19CVVNdLCBDUFNSLCAwKTsKPj4g Kwo+PiArCXRpbWVvdXQgPSByZWFkX2Rvc19yZWcoaHcsIE1QU1IpOwo+PiArCXRpbWVvdXQgPSBy ZWFkX2Rvc19yZWcoaHcsIE1QU1IpOwo+PiArCj4+ICsJdGltZW91dCA9IGppZmZpZXMgKyBIWjsK Pj4gKwo+PiArCXJlZ21hcF93cml0ZShody0+bWFwW0RPU19CVVNdLCBJTUVNX0RNQV9BRFIsIG1j X2FkZHJfbWFwKTsKPj4gKwlyZWdtYXBfd3JpdGUoaHctPm1hcFtET1NfQlVTXSwgSU1FTV9ETUFf Q09VTlQsIDB4MTAwMCk7Cj4+ICsJcmVnbWFwX3dyaXRlKGh3LT5tYXBbRE9TX0JVU10sIElNRU1f RE1BX0NUUkwsICgweDgwMDAgfCAoNyA8PCAxNikpKTsKPj4gKwo+PiArCXdoaWxlIChyZWFkX2Rv c19yZWcoaHcsIElNRU1fRE1BX0NUUkwpICYgMHg4MDAwKSB7Cj4+ICsJCWlmICh0aW1lX2JlZm9y ZShqaWZmaWVzLCB0aW1lb3V0KSkgewo+PiArCQkJc2NoZWR1bGUoKTsKPj4gKwkJfSBlbHNlIHsK Pj4gKwkJCWRldl9pbmZvKGRldiwgInZkZWMgbG9hZCBtYyBlcnJvclxuIik7Cj4+ICsJCQlyZXQg PSAtRUJVU1k7Cj4+ICsJCQlicmVhazsKPj4gKwkJfQo+PiArCX0KPj4gKwo+PiArCS8qIE9ubHkg aDI2NCBuZWVkcyB0aGlzIHN0ZXAgKi8KPj4gKwlpZiAoaHctPmh3X29wcy5sb2FkX2Zpcm13YXJl X2V4KSB7Cj4+ICsJCXJldCA9IGh3LT5od19vcHMubG9hZF9maXJtd2FyZV9leChody0+Y3Vycl9j dHgsCj4+ICsJCQkJCQnCoCBtY19hZGRyLAo+PiArCQkJCQkJwqAgKGZ3LT5zaXplIC0gZndfaGVh ZF9sZW4pKTsKPj4gKwkJaWYgKHJldCA8IDApIHsKPj4gKwkJCXJldCA9IC1FSU5WQUw7Cj4+ICsJ CQlnb3RvIGZyZWVfZG1hX21lbTsKPj4gKwkJfQo+PiArCX0KPj4gKwo+PiArZnJlZV9kbWFfbWVt Ogo+PiArCWRtYV9mcmVlX2NvaGVyZW50KGRldiwgTUNfU0laRSwgbWNfYWRkciwgbWNfYWRkcl9t YXApOwo+PiArcmVsZWFzZV9maXJtd2FyZToKPj4gKwlyZWxlYXNlX2Zpcm13YXJlKGZ3KTsKPj4g KwlyZXR1cm4gcmV0Owo+PiArfQo+PiArCj4+ICtzdGF0aWMgaW50IHZkZWNfY2xvY2tfZ2F0ZV9p bml0KHN0cnVjdCBhbWxfdmRlY19odyAqaHcpCj4+ICt7Cj4+ICsJaHctPmdhdGVzW1ZERUNdLmlk ID0gInZkZWMiOwo+PiArCWh3LT5nYXRlc1tWREVDX01VWF0uaWQgPSAiY2xrX3ZkZWNfbXV4IjsK Pj4gKwlody0+Z2F0ZXNbSEVWQ0ZfTVVYXS5pZCA9ICJjbGtfaGV2Y2ZfbXV4IjsKPj4gKwo+PiAr CXJldHVybiBkZXZtX2Nsa19idWxrX2dldChody0+ZGV2LCBET1NfQ0xLX01BWCwgaHctPmdhdGVz KTsKPj4gK30KPj4gKwo+PiArc3RhdGljIHN0cnVjdCBjbGtfYnVsa19kYXRhICp2ZGVjX2dldF9j bGtfYnlfbmFtZShzdHJ1Y3QgYW1sX3ZkZWNfaHcgKmh3LAo+PiArCQkJCQkJwqAgY29uc3QgY2hh ciAqbmFtZSkKPj4gK3sKPj4gKwlpbnQgaTsKPj4gKwo+PiArCWZvciAoaSA9IDA7IGkgPCBET1Nf Q0xLX01BWDsgaSsrKSB7Cj4+ICsJCWlmICghc3RyY21wKG5hbWUsIGh3LT5nYXRlc1tpXS5pZCkp IHsKPj4gKwkJCWlmIChody0+Z2F0ZXNbaV0uY2xrKQo+PiArCQkJCXJldHVybiAmaHctPmdhdGVz W2ldOwo+PiArCQl9Cj4+ICsJfQo+PiArCXJldHVybiBOVUxMOwo+PiArfQo+PiArCj4+ICtzdGF0 aWMgaW50IHBtX3ZkZWNfcG93ZXJfZG9tYWluX2luaXQoc3RydWN0IGFtbF92ZGVjX2h3ICpodykK Pj4gK3sKPj4gKwlpbnQgaSwgZXJyOwo+PiArCWNvbnN0IHN0cnVjdCBwb3dlcl9tYW5hZ2VyX3Mg KnBtID0gaHctPnBtOwo+PiArCXN0cnVjdCBwbV9wZF9zICpwZCA9IHBtLT5wZF9kYXRhOwo+PiAr Cj4+ICsJbXV0ZXhfaW5pdCgmaHctPnBtX211dGV4KTsKPj4gKwo+PiArCWZvciAoaSA9IDA7IGkg PCBWREVDX01BWDsgaSsrKSB7Cj4+ICsJCXBkW2ldLmRldiA9IGRldl9wbV9kb21haW5fYXR0YWNo X2J5X25hbWUoaHctPmRldiwgcGRbaV0ubmFtZSk7Cj4+ICsJCWlmIChJU19FUlJfT1JfTlVMTChw ZFtpXS5kZXYpKSB7Cj4+ICsJCQllcnIgPSBQVFJfRVJSKHBkW2ldLmRldik7Cj4+ICsJCQlkZXZf ZGJnKGh3LT5kZXYsICJHZXQgJXMgZmFpbGVkLCBwbS1kb21haW46ICVkXG4iLAo+PiArCQkJCXBk W2ldLm5hbWUsIGVycik7Cj4+ICsJCQljb250aW51ZTsKPj4gKwkJfQo+PiArCj4+ICsJCXBkW2ld LmxpbmsgPSBkZXZpY2VfbGlua19hZGQoaHctPmRldiwgcGRbaV0uZGV2LAo+PiArCQkJCQnCoMKg wqDCoCBETF9GTEFHX1BNX1JVTlRJTUUgfAo+PiArCQkJCQnCoMKgwqDCoCBETF9GTEFHX1NUQVRF TEVTUyk7Cj4+ICsJCWlmIChJU19FUlJfT1JfTlVMTChwZFtpXS5saW5rKSkgewo+PiArCQkJZGV2 X2Vycihody0+ZGV2LCAiQWRkaW5nICVzIGRldmljZSBsaW5rIGZhaWxlZCFcbiIsIHBkW2ldLm5h bWUpOwo+PiArCQkJcmV0dXJuIC1FTk9ERVY7Cj4+ICsJCX0KPj4gKwo+PiArCQlkZXZfZGJnKGh3 LT5kZXYsICJwb3dlciBkb21haW46IG5hbWU6ICVzLCBkZXY6ICVwLCBsaW5rOiAlcFxuIiwKPj4g KwkJCXBkW2ldLm5hbWUsIHBkW2ldLmRldiwgcGRbaV0ubGluayk7Cj4+ICsJfQo+PiArCj4+ICsJ cmV0dXJuIDA7Cj4+ICt9Cj4+ICsKPj4gK3N0YXRpYyB2b2lkIHBtX3ZkZWNfcG93ZXJfZG9tYWlu X3JlbGVhc2Uoc3RydWN0IGFtbF92ZGVjX2h3ICpodykKPj4gK3sKPj4gKwlpbnQgaTsKPj4gKwlj b25zdCBzdHJ1Y3QgcG93ZXJfbWFuYWdlcl9zICpwbSA9IGh3LT5wbTsKPj4gKwlzdHJ1Y3QgcG1f cGRfcyAqcGQgPSBwbS0+cGRfZGF0YTsKPj4gKwo+PiArCWZvciAoaSA9IDA7IGkgPCBWREVDX01B WDsgaSsrKSB7Cj4+ICsJCWlmICghSVNfRVJSX09SX05VTEwocGRbaV0ubGluaykpCj4+ICsJCQlk ZXZpY2VfbGlua19kZWwocGRbaV0ubGluayk7Cj4+ICsKPj4gKwkJaWYgKCFJU19FUlJfT1JfTlVM TChwZFtpXS5kZXYpKQo+PiArCQkJZGV2X3BtX2RvbWFpbl9kZXRhY2gocGRbaV0uZGV2LCB0cnVl KTsKPj4gKwl9Cj4+ICt9Cj4+ICsKPj4gK3N0YXRpYyB2b2lkIGRvc19sb2NhbF9jb25maWcoc3Ry dWN0IGFtbF92ZGVjX2h3ICpodywgYm9vbCBpc19vbiwgaW50IGlkKQo+PiArewo+PiArCWlmIChp c19vbikgewo+PiArCQl1c2xlZXBfcmFuZ2UoMjAsIDEwMCk7Cj4+ICsKPj4gKwkJc3dpdGNoIChp ZCkgewo+PiArCQljYXNlIFZERUNfMToKPj4gKwkJCXJlZ21hcF93cml0ZShody0+bWFwW0RPU19C VVNdLCBET1NfTUVNX1BEX1ZERUMsIDApOwo+PiArCQkJcmVnbWFwX3dyaXRlKGh3LT5tYXBbRE9T X0JVU10sIERPU19TV19SRVNFVDAsIDB4ZmZmZmZmZmMpOwo+PiArCQkJdXNsZWVwX3JhbmdlKDIw LCAxMDApOwo+PiArCQkJcmVnbWFwX3dyaXRlKGh3LT5tYXBbRE9TX0JVU10sIERPU19TV19SRVNF VDAsIDApOwo+PiArCQkJdXNsZWVwX3JhbmdlKDIwLCAxMDApOwo+PiArCQkJcmVnbWFwX3dyaXRl KGh3LT5tYXBbRE9TX0JVU10sIERPU19NRU1fUERfVkRFQywgMCk7Cj4+ICsJCQlicmVhazsKPj4g KwkJY2FzZSBWREVDX0hFVkM6Cj4+ICsJCQlyZWdtYXBfd3JpdGUoaHctPm1hcFtET1NfQlVTXSwg RE9TX01FTV9QRF9IRVZDLCAwKTsKPj4gKwkJCXJlZ21hcF93cml0ZShody0+bWFwW0RPU19CVVNd LCBET1NfU1dfUkVTRVQzLCAweGZmZmZmZmZmKTsKPj4gKwkJCXVzbGVlcF9yYW5nZSgyMCwgMTAw KTsKPj4gKwkJCXJlZ21hcF93cml0ZShody0+bWFwW0RPU19CVVNdLCBET1NfU1dfUkVTRVQzLCAw KTsKPj4gKwkJCXVzbGVlcF9yYW5nZSgyMCwgMTAwKTsKPj4gKwkJCXJlZ21hcF93cml0ZShody0+ bWFwW0RPU19CVVNdLCBET1NfTUVNX1BEX0hFVkMsIDApOwo+PiArCQkJYnJlYWs7Cj4+ICsJCWRl ZmF1bHQ6Cj4+ICsJCQlkZXZfaW5mbyhody0+ZGV2LCAiJXMgb24sIG5vdCBmb3VuZCBpZCAlZFxu IiwgX19mdW5jX18sIGlkKTsKPj4gKwkJCWJyZWFrOwo+PiArCQl9Cj4+ICsJfSBlbHNlIHsKPj4g KwkJc3dpdGNoIChpZCkgewo+PiArCQljYXNlIFZERUNfMToKPj4gKwkJCXJlZ21hcF93cml0ZSho dy0+bWFwW0RPU19CVVNdLCBET1NfU1dfUkVTRVQwLCAweGZmZmZmZmZjKTsKPj4gKwkJCXVzbGVl cF9yYW5nZSgyMCwgMTAwKTsKPj4gKwkJCXJlZ21hcF93cml0ZShody0+bWFwW0RPU19CVVNdLCBE T1NfU1dfUkVTRVQwLCAwKTsKPj4gKwkJCXVzbGVlcF9yYW5nZSgyMCwgMTAwKTsKPj4gKwkJCXJl Z21hcF93cml0ZShody0+bWFwW0RPU19CVVNdLCBET1NfTUVNX1BEX1ZERUMsIDB4ZmZmZmZmZmZV TCk7Cj4+ICsJCQlicmVhazsKPj4gKwkJY2FzZSBWREVDX0hFVkM6Cj4+ICsJCQlyZWdtYXBfd3Jp dGUoaHctPm1hcFtET1NfQlVTXSwgRE9TX1NXX1JFU0VUMywgMHhmZmZmZmZmZik7Cj4+ICsJCQl1 c2xlZXBfcmFuZ2UoMjAsIDEwMCk7Cj4+ICsJCQlyZWdtYXBfd3JpdGUoaHctPm1hcFtET1NfQlVT XSwgRE9TX1NXX1JFU0VUMywgMCk7Cj4+ICsJCQl1c2xlZXBfcmFuZ2UoMjAsIDEwMCk7Cj4+ICsJ CQlyZWdtYXBfd3JpdGUoaHctPm1hcFtET1NfQlVTXSwgRE9TX01FTV9QRF9IRVZDLCAweGZmZmZm ZmZmVUwpOwo+PiArCQkJYnJlYWs7Cj4+ICsJCWRlZmF1bHQ6Cj4+ICsJCQlkZXZfaW5mbyhody0+ ZGV2LCAiJXMgb2ZmLCBub3QgZm91bmQgaWQgJWRcbiIsIF9fZnVuY19fLCBpZCk7Cj4+ICsJCQli cmVhazsKPj4gKwkJfQo+PiArCX0KPj4gKwo+PiArCWRldl9kYmcoaHctPmRldiwgIiVzIGVuZCwg aWQgJWQsIGlzX29uICVkXG4iLCBfX2Z1bmNfXywgaWQsIGlzX29uKTsKPj4gK30KPj4gKwo+PiAr c3RhdGljIHZvaWQgcG1fdmRlY19wb3dlcl9kb21haW5fcG93ZXJfb24oc3RydWN0IGFtbF92ZGVj X2h3ICpodywgaW50IGlkKQo+PiArewo+PiArCWNvbnN0IHN0cnVjdCBwb3dlcl9tYW5hZ2VyX3Mg KnBtID0gaHctPnBtOwo+PiArCXN0cnVjdCBkZXZpY2UgKmRldiA9IHBtLT5wZF9kYXRhW2lkXS5k ZXY7Cj4+ICsJc3RydWN0IGNsa19idWxrX2RhdGEgKmdhdGVfbm9kZTsKPj4gKwo+PiArCWlmIChp ZCA9PSBWREVDXzEpCj4+ICsJCWdhdGVfbm9kZSA9IHZkZWNfZ2V0X2Nsa19ieV9uYW1lKGh3LCAi Y2xrX3ZkZWNfbXV4Iik7Cj4+ICsJZWxzZSBpZiAoaWQgPT0gVkRFQ19IRVZDKQo+PiArCQlnYXRl X25vZGUgPSB2ZGVjX2dldF9jbGtfYnlfbmFtZShodywgImNsa19oZXZjZl9tdXgiKTsKPj4gKwo+ PiArCWlmIChnYXRlX25vZGUpIHsKPj4gKwkJY2xrX3ByZXBhcmVfZW5hYmxlKGdhdGVfbm9kZS0+ Y2xrKTsKPj4gKwkJaWYgKGlkID09IFZERUNfMSkgewo+PiArCQkJY2xrX3NldF9yYXRlKGdhdGVf bm9kZS0+Y2xrLCA0OTk5OTk5OTIpOwo+PiArCQkJZGV2X2RiZyhody0+ZGV2LCAiYWZ0ZXIgc2V0 LCB2ZGVjIG11eCBjbG9jayBpcyAlbHUgSHpcbiIsCj4+ICsJCQkJY2xrX2dldF9yYXRlKGdhdGVf bm9kZS0+Y2xrKSk7Cj4+ICsJCX0KPj4gKwkJZGV2X2RiZyhody0+ZGV2LCAidGhlICUtMTVzIGNs b2NrIG9uXG4iLCBnYXRlX25vZGUtPmlkKTsKPj4gKwl9IGVsc2Ugewo+PiArCQlkZXZfaW5mbyho dy0+ZGV2LCAiY2xrICVkLCB1bnJlYWNoYWJsZVxuIiwgaWQpOwo+PiArCX0KPj4gKwo+PiArCWlm IChkZXYpIHsKPj4gKwkJcG1fcnVudGltZV9nZXRfc3luYyhkZXYpOwo+PiArCQlkZXZfZGJnKGRl diwgImRldjogJXAgbGluayAlcCB0aGUgJS0xNXMgcG93ZXIgb25cbiIsCj4+ICsJCQlkZXYsIHBt LT5wZF9kYXRhW2lkXS5saW5rLCBwbS0+cGRfZGF0YVtpZF0ubmFtZSk7Cj4+ICsJfQo+PiArCj4+ ICsJZG9zX2xvY2FsX2NvbmZpZyhodywgMSwgaWQpOwo+PiArfQo+PiArCj4+ICtzdGF0aWMgdm9p ZCBwbV92ZGVjX3Bvd2VyX2RvbWFpbl9wb3dlcl9vZmYoc3RydWN0IGFtbF92ZGVjX2h3ICpodywg aW50IGlkKQo+PiArewo+PiArCWNvbnN0IHN0cnVjdCBwb3dlcl9tYW5hZ2VyX3MgKnBtID0gaHct PnBtOwo+PiArCXN0cnVjdCBkZXZpY2UgKmRldiA9IHBtLT5wZF9kYXRhW2lkXS5kZXY7Cj4+ICsJ c3RydWN0IGNsa19idWxrX2RhdGEgKmdhdGVfbm9kZTsKPj4gKwo+PiArCWRvc19sb2NhbF9jb25m aWcoaHcsIDAsIGlkKTsKPj4gKwo+PiArCWlmIChkZXYpIHsKPj4gKwkJcG1fcnVudGltZV9wdXRf c3luYyhkZXYpOwo+PiArCQlkZXZfZGJnKGRldiwgImRldjogJXAgbGluayAlcCB0aGUgJS0xNXMg cG93ZXIgb2ZmXG4iLAo+PiArCQkJZGV2LCBwbS0+cGRfZGF0YVtpZF0ubGluaywgcG0tPnBkX2Rh dGFbaWRdLm5hbWUpOwo+PiArCX0KPj4gKwo+PiArCWlmIChpZCA9PSBWREVDXzEpCj4+ICsJCWdh dGVfbm9kZSA9IHZkZWNfZ2V0X2Nsa19ieV9uYW1lKGh3LCAiY2xrX3ZkZWNfbXV4Iik7Cj4+ICsJ ZWxzZSBpZiAoaWQgPT0gVkRFQ19IRVZDKQo+PiArCQlnYXRlX25vZGUgPSB2ZGVjX2dldF9jbGtf YnlfbmFtZShodywgImNsa19oZXZjZl9tdXgiKTsKPj4gKwo+PiArCWlmIChnYXRlX25vZGUpIHsK Pj4gKwkJY2xrX2Rpc2FibGVfdW5wcmVwYXJlKGdhdGVfbm9kZS0+Y2xrKTsKPj4gKwkJZGV2X2Ri Zyhody0+ZGV2LCAidGhlICUtMTVzIGNsb2NrIG9mZlxuIiwgZ2F0ZV9ub2RlLT5pZCk7Cj4+ICsJ fSBlbHNlIHsKPj4gKwkJZGV2X2luZm8oaHctPmRldiwgImNsayAlZCwgdW5yZWFjaGFibGVcbiIs IGlkKTsKPj4gKwl9Cj4+ICt9Cj4+ICsKPj4gK3N0YXRpYyBib29sIHBtX3ZkZWNfcG93ZXJfZG9t YWluX3Bvd2VyX3N0YXRlKHN0cnVjdCBhbWxfdmRlY19odyAqaHcsIGludCBpZCkKPj4gK3sKPj4g KwlpZiAoaHctPnBtLT5wZF9kYXRhW2lkXS5kZXYpCj4+ICsJCXJldHVybiBwbV9ydW50aW1lX2Fj dGl2ZShody0+cG0tPnBkX2RhdGFbaWRdLmRldik7Cj4+ICsJZWxzZQo+PiArCQlyZXR1cm4gZmFs c2U7Cj4+ICt9Cj4+ICsKPj4gK3N0YXRpYyB2b2lkIHZkZWNfcG93ZXJvbihzdHJ1Y3QgYW1sX3Zk ZWNfaHcgKmh3LCBlbnVtIHZkZWNfdHlwZV9lIGNvcmUpCj4+ICt7Cj4+ICsJaWYgKGNvcmUgPj0g VkRFQ19NQVgpCj4+ICsJCXJldHVybjsKPj4gKwo+PiArCW11dGV4X2xvY2soJmh3LT5wbV9tdXRl eCk7Cj4+ICsJaWYgKCFody0+cG0tPnBkX2RhdGFbY29yZV0uZGV2KQo+PiArCQlnb3RvIG91dDsK Pj4gKwo+PiArCWh3LT5wbS0+cGRfZGF0YVtjb3JlXS5yZWZfY291bnQrKzsKPj4gKwlpZiAoaHct PnBtLT5wZF9kYXRhW2NvcmVdLnJlZl9jb3VudCA+IDEpCj4+ICsJCWdvdG8gb3V0Owo+PiArCj4+ ICsJaWYgKGh3LT5wbS0+cG93ZXJfc3RhdGUoaHcsIGNvcmUpKQo+PiArCQlnb3RvIG91dDsKPj4g Kwo+PiArCWh3LT5wbS0+cG93ZXJfb24oaHcsIGNvcmUpOwo+PiArCj4+ICtvdXQ6Cj4+ICsJbXV0 ZXhfdW5sb2NrKCZody0+cG1fbXV0ZXgpOwo+PiArfQo+PiArCj4+ICtzdGF0aWMgdm9pZCB2ZGVj X3Bvd2Vyb2ZmKHN0cnVjdCBhbWxfdmRlY19odyAqaHcsIGVudW0gdmRlY190eXBlX2UgY29yZSkK Pj4gK3sKPj4gKwlpZiAoY29yZSA+PSBWREVDX01BWCkKPj4gKwkJcmV0dXJuOwo+PiArCj4+ICsJ bXV0ZXhfbG9jaygmaHctPnBtX211dGV4KTsKPj4gKwlpZiAoaHctPnBtLT5wZF9kYXRhW2NvcmVd LnJlZl9jb3VudCA9PSAwKQo+PiArCQlnb3RvIG91dDsKPj4gKwo+PiArCWh3LT5wbS0+cGRfZGF0 YVtjb3JlXS5yZWZfY291bnQtLTsKPj4gKwlpZiAoaHctPnBtLT5wZF9kYXRhW2NvcmVdLnJlZl9j b3VudCA+IDApCj4+ICsJCWdvdG8gb3V0Owo+PiArCj4+ICsJaHctPnBtLT5wb3dlcl9vZmYoaHcs IGNvcmUpOwo+PiArCj4+ICtvdXQ6Cj4+ICsJbXV0ZXhfdW5sb2NrKCZody0+cG1fbXV0ZXgpOwo+ PiArfQo+PiArCj4+ICtpbnQgdmRlY19lbmFibGUoc3RydWN0IGFtbF92ZGVjX2h3ICpodykKPj4g K3sKPj4gKwl2ZGVjX3Bvd2Vyb24oaHcsIFZERUNfMSk7Cj4+ICsKPj4gKwlyZXR1cm4gMDsKPj4g K30KPj4gKwo+PiAraW50IHZkZWNfZGlzYWJsZShzdHJ1Y3QgYW1sX3ZkZWNfaHcgKmh3KQo+PiAr ewo+PiArCXZkZWNfcG93ZXJvZmYoaHcsIFZERUNfMSk7Cj4+ICsKPj4gKwlyZXR1cm4gMDsKPj4g K30KPj4gKwo+PiArc3RhdGljIGNvbnN0IHN0cnVjdCBwb3dlcl9tYW5hZ2VyX3MgcG1bXSA9IHsK Pj4gKwlbQU1MX1BNX1BEXSA9IHsKPj4gKwkJLnBkX2RhdGHCoMKgwqAgPSB2ZGVjX2RvbWFpbl9k YXRhLAo+PiArCQkuaW5pdMKgwqDCoMKgwqDCoMKgID0gcG1fdmRlY19wb3dlcl9kb21haW5faW5p dCwKPj4gKwkJLnJlbGVhc2XCoMKgwqAgPSBwbV92ZGVjX3Bvd2VyX2RvbWFpbl9yZWxlYXNlLAo+ PiArCQkucG93ZXJfb27CoMKgwqAgPSBwbV92ZGVjX3Bvd2VyX2RvbWFpbl9wb3dlcl9vbiwKPj4g KwkJLnBvd2VyX29mZsKgwqDCoCA9IHBtX3ZkZWNfcG93ZXJfZG9tYWluX3Bvd2VyX29mZiwKPj4g KwkJLnBvd2VyX3N0YXRlID0gcG1fdmRlY19wb3dlcl9kb21haW5fcG93ZXJfc3RhdGUsCj4+ICsJ fSwKPj4gK307Cj4+ICsKPj4gK3N0YXRpYyBpcnFyZXR1cm5fdCB2ZGVjX2lycV9oYW5kbGVyKGlu dCBpcnEsIHZvaWQgKnByaXYpCj4+ICt7Cj4+ICsJc3RydWN0IGFtbF92ZGVjX2RldiAqZGV2ID0g KHN0cnVjdCBhbWxfdmRlY19kZXYgKilwcml2Owo+PiArCXN0cnVjdCBhbWxfdmRlY19odyAqaHcg PSBkZXYtPmRlY19odzsKPj4gKwlpcnFyZXR1cm5fdCByZXQ7Cj4+ICsKPj4gKwlpZiAoaHctPmh3 X29wcy5pcnFfaGFuZGxlcikKPj4gKwkJcmV0ID0gaHctPmh3X29wcy5pcnFfaGFuZGxlcihpcnEs IHByaXYpOwo+PiArCj4+ICsJcmV0dXJuIHJldDsKPj4gK30KPj4gKwo+PiArc3RhdGljIGlycXJl dHVybl90IHZkZWNfdGhyZWFkZWRfaXNyX2hhbmRsZXIoaW50IGlycSwgdm9pZCAqcHJpdikKPj4g K3sKPj4gKwlzdHJ1Y3QgYW1sX3ZkZWNfZGV2ICpkZXYgPSAoc3RydWN0IGFtbF92ZGVjX2RldiAq KXByaXY7Cj4+ICsJc3RydWN0IGFtbF92ZGVjX2h3ICpodyA9IGRldi0+ZGVjX2h3Owo+PiArCWly cXJldHVybl90IHJldCA9IElSUV9IQU5ETEVEOwo+PiArCj4+ICsJaWYgKGh3LT5od19vcHMuaXJx X3RocmVhZGVkX2Z1bmMpCj4+ICsJCXJldCA9IGh3LT5od19vcHMuaXJxX3RocmVhZGVkX2Z1bmMo aXJxLCBwcml2KTsKPj4gKwo+PiArCXJldHVybiByZXQ7Cj4+ICt9Cj4+ICsKPj4gK3N0cnVjdCBh bWxfdmRlY19odyAqdmRlY19nZXRfaHcodm9pZCAqcHJpdikKPj4gK3sKPj4gKwlzdHJ1Y3QgYW1s X3ZkZWNfZGV2ICpkZXYgPSAoc3RydWN0IGFtbF92ZGVjX2RldiAqKXByaXY7Cj4+ICsKPj4gKwly ZXR1cm4gZGV2LT5kZWNfaHc7Cj4+ICt9Cj4+ICsKPj4gK3N0YXRpYyBjb25zdCBzdHJ1Y3QgcmVn bWFwX2NvbmZpZyBkb3NfcmVnbWFwX2NvbmYgPSB7Cj4+ICsJLnJlZ19iaXRzID0gMzIsCj4+ICsJ LnZhbF9iaXRzID0gMzIsCj4+ICsJLnJlZ19zdHJpZGUgPSA0LAo+PiArCS5tYXhfcmVnaXN0ZXIg PSAweDEwMDAwLAo+PiArfTsKPj4gKwo+PiArc3RhdGljIGNvbnN0IHN0cnVjdCByZWdtYXBfY29u ZmlnIGRtY19yZWdtYXBfY29uZiA9IHsKPj4gKwkucmVnX2JpdHMgPSAzMiwKPj4gKwkudmFsX2Jp dHMgPSAzMiwKPj4gKwkucmVnX3N0cmlkZSA9IDQsCj4+ICsJLm1heF9yZWdpc3RlciA9IDB4MjAs Cj4+ICt9Owo+PiArCj4+ICtpbnQgZGV2X3JlcXVlc3RfaHdfcmVzb3VyY2VzKHZvaWQgKnByaXYp Cj4+ICt7Cj4+ICsJc3RydWN0IGFtbF92ZGVjX2RldiAqZGV2ID0gKHN0cnVjdCBhbWxfdmRlY19k ZXYgKilwcml2Owo+PiArCXN0cnVjdCBhbWxfdmRlY19odyAqaHc7Cj4+ICsJc3RydWN0IHBsYXRm b3JtX2RldmljZSAqcGRldjsKPj4gKwl2b2lkIF9faW9tZW0gKnJlZ19iYXNlW01BWF9SRUdfQlVT XTsKPj4gKwlzdHJ1Y3QgcmVzb3VyY2UgcmVzOwo+PiArCWludCBpOwo+PiArCWludCByZXQgPSAt MTsKPj4gKwo+PiArCWlmICghZGV2IHx8ICFkZXYtPmRlY19odykKPj4gKwkJcmV0dXJuIC0xOwo+ PiArCj4+ICsJcGRldiA9IGRldi0+cGxhdF9kZXY7Cj4+ICsJaHcgPSBkZXYtPmRlY19odzsKPj4g Kwlody0+ZGV2ID0gJnBkZXYtPmRldjsKPj4gKwo+PiArCWh3LT5kZWNfaXJxID0gcGxhdGZvcm1f Z2V0X2lycShwZGV2LCBWREVDX0lSUV8xKTsKPj4gKwlpZiAoaHctPmRlY19pcnEgPCAwKSB7Cj4+ ICsJCWRldl9lcnIoJnBkZXYtPmRldiwgImdldCBpcnEgZmFpbGVkXG4iKTsKPj4gKwkJcmV0dXJu IGh3LT5kZWNfaXJxOwo+PiArCX0KPj4gKwlyZXQgPSBkZXZtX3JlcXVlc3RfdGhyZWFkZWRfaXJx KCZwZGV2LT5kZXYsIGh3LT5kZWNfaXJxLCB2ZGVjX2lycV9oYW5kbGVyLAo+PiArCQkJCQl2ZGVj X3RocmVhZGVkX2lzcl9oYW5kbGVyLCBJUlFGX09ORVNIT1QsCj4+ICsJCQkJCSJ2ZGVjLTEiLCBk ZXYpOwo+PiArCWlmIChyZXQpIHsKPj4gKwkJZGV2X2VycigmcGRldi0+ZGV2LCAiZmFpbGVkIHRv IGluc3RhbGwgaXJxICVkICglZCkiLAo+PiArCQkJaHctPmRlY19pcnEsIHJldCk7Cj4+ICsJCXJl dHVybiAtMTsKPj4gKwl9Cj4+ICsKPj4gKwlmb3IgKGkgPSAwOyBpIDwgTUFYX1JFR19CVVM7IGkr Kykgewo+PiArCQlpZiAob2ZfYWRkcmVzc190b19yZXNvdXJjZShwZGV2LT5kZXYub2Zfbm9kZSwg aSwgJnJlcykpIHsKPj4gKwkJCWRldl9lcnIoJnBkZXYtPmRldiwgIm9mX2FkZHJlc3NfdG9fcmVz b3VyY2UgJWQgZmFpbGVkXG4iLCBpKTsKPj4gKwkJCXJldHVybiAtRUlOVkFMOwo+PiArCQl9Cj4+ ICsJCXJlZ19iYXNlW2ldID0gZGV2bV9pb3JlbWFwX3Jlc291cmNlKCZwZGV2LT5kZXYsICZyZXMp Owo+PiArCj4+ICsJCWlmIChJU19FUlIocmVnX2Jhc2VbaV0pKQo+PiArCQkJcmV0dXJuIFBUUl9F UlIocmVnX2Jhc2VbaV0pOwo+PiArCj4+ICsJCWlmIChpID09IERPU19CVVMpIHsKPj4gKwkJCWh3 LT5tYXBbaV0gPSBkZXZtX3JlZ21hcF9pbml0X21taW8oJnBkZXYtPmRldiwgcmVnX2Jhc2VbaV0s Cj4+ICsJCQkJCQkJwqDCoCAmZG9zX3JlZ21hcF9jb25mKTsKPj4gKwkJfSBlbHNlIGlmIChpID09 IERNQ19CVVMpIHsKPj4gKwkJCWh3LT5tYXBbaV0gPSBkZXZtX3JlZ21hcF9pbml0X21taW8oJnBk ZXYtPmRldiwgcmVnX2Jhc2VbaV0sCj4+ICsJCQkJCQkJwqDCoCAmZG1jX3JlZ21hcF9jb25mKTsK Pj4gKwkJfQo+PiArCj4+ICsJCWlmIChJU19FUlIoaHctPm1hcFtpXSkpCj4+ICsJCQlyZXR1cm4g UFRSX0VSUihody0+bWFwW2ldKTsKPj4gKwo+PiArCQlkZXZfZGJnKCZwZGV2LT5kZXYsICIlcywg cmVzIHN0YXJ0ICVsbHgsIGVuZCAlbGx4LCBpb21hcDogJXBcbiIsCj4+ICsJCQlfX2Z1bmNfXywg KHVuc2lnbmVkIGxvbmcgbG9uZylyZXMuc3RhcnQsCj4+ICsJCQkodW5zaWduZWQgbG9uZyBsb25n KXJlcy5lbmQsIHJlZ19iYXNlW2ldKTsKPj4gKwl9Cj4+ICsJaHctPmNhbnZhcyA9IG1lc29uX2Nh bnZhc19nZXQoJnBkZXYtPmRldik7Cj4+ICsJaWYgKElTX0VSUigmcGRldi0+ZGV2KSkKPj4gKwkJ cmV0dXJuIFBUUl9FUlIoJnBkZXYtPmRldik7Cj4+ICsKPj4gKwlody0+cG0gPSAmcG1bZGV2LT5w dmRlY19kYXRhLT5wb3dlcl90eXBlXTsKPj4gKwlpZiAoaHctPnBtLT5pbml0KSB7Cj4+ICsJCXJl dCA9IGh3LT5wbS0+aW5pdChodyk7Cj4+ICsJCWlmIChyZXQgPCAwKSB7Cj4+ICsJCQlkZXZfZXJy KCZwZGV2LT5kZXYsICJwb3dlciBtZ3IgaW5pdCBmYWlsZWQhXG4iKTsKPj4gKwkJCXJldHVybiBy ZXQ7Cj4+ICsJCX0KPj4gKwl9Cj4+ICsKPj4gKwlyZXQgPSB2ZGVjX2Nsb2NrX2dhdGVfaW5pdCho dyk7Cj4+ICsJaWYgKHJldCkgewo+PiArCQlkZXZfZXJyKCZwZGV2LT5kZXYsICJjbGsgYnVsayBp bml0IGZhaWxlZCFcbiIpOwo+PiArCQlyZXR1cm4gcmV0Owo+PiArCX0KPj4gKwo+PiArCWRldl9k YmcoJnBkZXYtPmRldiwgIiMjQW1sb2dpYyBodyByZXNvdXJjZSBpbml0IE9LIyNcbiIpOwo+PiAr Cj4+ICsJcmV0dXJuIDA7Cj4+ICt9Cj4+ICsKPj4gK3ZvaWQgZGV2X2Rlc3Ryb3lfaHdfcmVzb3Vy Y2VzKHZvaWQgKnByaXYpCj4+ICt7Cj4+ICsJc3RydWN0IGFtbF92ZGVjX2RldiAqZGV2ID0gKHN0 cnVjdCBhbWxfdmRlY19kZXYgKilwcml2Owo+PiArCXN0cnVjdCBhbWxfdmRlY19odyAqaHc7Cj4+ ICsKPj4gKwlpZiAoIWRldiB8fCAhZGV2LT5kZWNfaHcpCj4+ICsJCXJldHVybjsKPj4gKwo+PiAr CWh3ID0gZGV2LT5kZWNfaHc7Cj4+ICsKPj4gKwlpZiAoaHctPnBtLT5yZWxlYXNlKQo+PiArCQlo dy0+cG0tPnJlbGVhc2UoaHcpOwo+PiArCj4+ICsJZGV2X2RiZyhody0+ZGV2LCAiIyNBbWxvZ2lj IGh3IHJlc291cmNlIHJlbGVhc2UgT0sjI1xuIik7Cj4+ICt9Cj4+IGRpZmYgLS1naXQgYS9kcml2 ZXJzL21lZGlhL3BsYXRmb3JtL2FtbG9naWMvdmRlYy9hbWxfdmRlY19ody5oIGIvZHJpdmVycy9t ZWRpYS9wbGF0Zm9ybS9hbWxvZ2ljL3ZkZWMvYW1sX3ZkZWNfaHcuaAo+PiBuZXcgZmlsZSBtb2Rl IDEwMDY0NAo+PiBpbmRleCAwMDAwMDAwMDAwMDAuLjZhYWM4OWE2MzU2Ywo+PiAtLS0gL2Rldi9u dWxsCj4+ICsrKyBiL2RyaXZlcnMvbWVkaWEvcGxhdGZvcm0vYW1sb2dpYy92ZGVjL2FtbF92ZGVj X2h3LmgKPj4gQEAgLTAsMCArMSwxNTggQEAKPj4gKy8qIFNQRFgtTGljZW5zZS1JZGVudGlmaWVy OiAoR1BMLTIuMC1vbmx5IE9SIE1JVCkgKi8KPj4gKy8qCj4+ICsgKiBDb3B5cmlnaHQgKEMpIDIw MjUgQW1sb2dpYywgSW5jLiBBbGwgcmlnaHRzIHJlc2VydmVkCj4+ICsgKi8KPj4gKwo+PiArI2lm bmRlZiBfQU1MX1ZERUNfSFdfSF8KPj4gKyNkZWZpbmUgX0FNTF9WREVDX0hXX0hfCj4+ICsKPj4g KyNpbmNsdWRlIDxsaW51eC9tb2R1bGUuaD4KPj4gKyNpbmNsdWRlIDxsaW51eC9jbGsuaD4KPj4g KyNpbmNsdWRlIDxsaW51eC9wbGF0Zm9ybV9kZXZpY2UuaD4KPj4gKyNpbmNsdWRlIDxsaW51eC9v Zi5oPgo+PiArI2luY2x1ZGUgPGxpbnV4L3BtX2RvbWFpbi5oPgo+PiArI2luY2x1ZGUgPGxpbnV4 L3BtX3J1bnRpbWUuaD4KPj4gKyNpbmNsdWRlIDxsaW51eC9kZWxheS5oPgo+PiArI2luY2x1ZGUg PGxpbnV4L3JlZ21hcC5oPgo+PiArI2luY2x1ZGUgPGxpbnV4L2ludGVycnVwdC5oPgo+PiArI2lu Y2x1ZGUgPGxpbnV4L3NvYy9hbWxvZ2ljL21lc29uLWNhbnZhcy5oPgo+PiArI2luY2x1ZGUgInJl Z19kZWZpbmVzLmgiCj4+ICsKPj4gKyNkZWZpbmUgVkRFQ19GSUZPX0FMSUdOwqDCoMKgwqAgOAo+ PiArI2RlZmluZSBWTERfUEFERElOR19TSVpFwqDCoMKgIDEwMjQKPj4gKwo+PiArLyoqCj4+ICsg KiBzdHJ1Y3QgYW1sX3ZkZWNfaHdfb3BzIC0gY29kZWMgbW9kZSBzcGVjaWZpYyBvcGVyYXRpb25z IGZvciBodwo+PiArICogQGxvYWRfZmlybXdhcmVfZXg6IExvYWQgZmlybXdhcmUgZm9yIGN1cnJl bnQgZGVjIHNwZWNpZmljLgo+PiArICogQGlycV9oYW5kbGVyOiBtYW5kYXRvcnkgY2FsbCB3aGVu IHRoZSBJU1IgdHJpZ2dlcnMKPj4gKyAqIEBpcnFfdGhyZWFkZWRfZnVuYzogbWFuZGF0b3J5IGNh bGwgZm9yIHRoZSB0aHJlYWRlZCBJU1IKPj4gKyAqIEBjYW52YXNfYWxsb2M6IEFsbG9jIGNhbnZh cyBmb3IgY3VyciBmcmFtZQo+PiArICogQGNhbnZhc19mcmVlOiBSZWxlYXNlIGNhbnZhcy4KPj4g KyAqIEBjb25maWdfY2FudmFzOiBDb25maWcgZm9yIGN1cnIgZnJhbWUsIHN1Y2ggYXMgdy9oLCBZ L1VWIHN0YXJ0IGFkZHIgZXRjLgo+PiArICovCj4+ICtzdHJ1Y3QgYW1sX3ZkZWNfaHdfb3BzIHsK Pj4gKwlpbnQgKCpsb2FkX2Zpcm13YXJlX2V4KSh2b2lkICpwcml2LCBjb25zdCB1OCAqZGF0YSwg dTMyIGxlbik7Cj4+ICsJaXJxcmV0dXJuX3QgKCppcnFfaGFuZGxlcikoaW50IGlycSwgdm9pZCAq cHJpdik7Cj4+ICsJaXJxcmV0dXJuX3QgKCppcnFfdGhyZWFkZWRfZnVuYykoaW50IGlycSwgdm9p ZCAqcHJpdik7Cj4+ICsJaW50ICgqY2FudmFzX2FsbG9jKSh1OCAqY2FudmFzX2luZGV4KTsKPj4g Kwl2b2lkICgqY2FudmFzX2ZyZWUpKHU4IGNhbnZhc19pbmRleCk7Cj4+ICsJdm9pZCAoKmNvbmZp Z19jYW52YXMpKHU4IGNhbnZhc19pbmRleCwKPj4gKwkJCcKgwqDCoMKgwqAgdWxvbmcgYWRkciwg dTMyIHdpZHRoLCB1MzIgaGVpZ2h0LAo+PiArCQkJwqDCoMKgwqDCoCB1MzIgd3JhcCwgdTMyIGJs a21vZGUsIHUzMiBlbmRpYW4pOwo+PiArfTsKPj4gKwo+PiArLyoqCj4+ICsgKiBlbnVtIHZkZWNf dHlwZV9lIC0gVHlwZSBvZiBkZWNvZGVyIGhhcmR3YXJlLgo+PiArICovCj4+ICtlbnVtIHZkZWNf dHlwZV9lIHsKPj4gKwlWREVDXzEgPSAwLAo+PiArCVZERUNfSEVWQywKPj4gKwlWREVDX01BWCwK Pj4gK307Cj4+ICsKPj4gKy8qKgo+PiArICogZW51bSB2ZGVjX2lycV9udW0gLSBEZWZpbml0aW9u IG9mIHRoZSBpcnEuCj4+ICsgKi8KPj4gK2VudW0gdmRlY19pcnFfbnVtIHsKPj4gKwlWREVDX0lS UV8wID0gMCwKPj4gKwlWREVDX0lSUV8xLAo+PiArCVZERUNfSVJRXzIsCj4+ICsJVkRFQ19JUlFf TUFYLAo+PiArfTsKPj4gKwo+PiArLyoqCj4+ICsgKiBlbnVtIHZkZWNfdHlwZV9lIC0gVHlwZSBv ZiBkZWNvZGVyIGNsb2NrLgo+PiArICovCj4+ICtlbnVtIGNsa190eXBlX2Ugewo+PiArCVZERUMg PSAwLAo+PiArCVZERUNfTVVYLAo+PiArCUhFVkNGX01VWCwKPj4gKwlET1NfQ0xLX01BWCwKPj4g K307Cj4+ICsKPj4gKy8qKgo+PiArICogZW51bSBhbWxfcG93ZXJfdHlwZV9lIC0gVHlwZSBvZiBk ZWNvZGVyIHBvd2VyLgo+PiArICovCj4+ICtlbnVtIGFtbF9wb3dlcl90eXBlX2Ugewo+PiArCUFN TF9QTV9QRCA9IDAsCj4+ICt9Owo+PiArCj4+ICsvKioKPj4gKyAqIGVudW0gbW1fYnVzX2UgLSBU eXBlIG9mIGRlY29kZXIgaGFyZHdhcmUgYnVzLgo+PiArICovCj4+ICtlbnVtIG1tX2J1c19lIHsK Pj4gKwlET1NfQlVTID0gMCwKPj4gKwlETUNfQlVTLAo+PiArCU1BWF9SRUdfQlVTCj4+ICt9Owo+ PiArCj4+ICsvKioKPj4gKyAqIHN0cnVjdCBwbV9wZF9zIC0gcG93ZXIgZG9tYWluIGRlZmluaXRp b24KPj4gKyAqIEBuYW1lOiBQb3dlciBkb21haW4gbmFtZS4KPj4gKyAqIEBkZXY6IFBvaW50ZXIg dG8gZGV2aWNlIHN0cnVjdHVyZS4KPj4gKyAqIEBtdXRleDogUG9pbnRlciB0byBkZXZpY2VfbGlu ayBzdHJ1Y3R1cmUuCj4+ICsgKiBAcmVmX2NvdW50OiBDdXJyIHBvd2VyIGRvbWFpbiBpbnN0YW5j ZSByZWYgY291bnQuCj4+ICsgKi8KPj4gK3N0cnVjdCBwbV9wZF9zIHsKPj4gKwl1OCAqbmFtZTsK Pj4gKwlzdHJ1Y3QgZGV2aWNlICpkZXY7Cj4+ICsJc3RydWN0IGRldmljZV9saW5rICpsaW5rOwo+ PiArCWludCByZWZfY291bnQ7Cj4+ICt9Owo+PiArCj4+ICsvKioKPj4gKyAqIHN0cnVjdCBhbWxf dmRlY19odyAtIGRlY29kZXIgaGFyZHdhcmUgcmVzb3VyY2VzIGRlZmluaXRpb24KPj4gKyAqIEBw ZGV2OiBQb2ludGVyIHRvIHN0cnVjdCBwbGF0Zm9ybV9kZXZpY2UuCj4+ICsgKiBAZGV2OiBQb2lu dGVyIHRvIHN0cnVjdCBkZXZpY2UuCj4+ICsgKiBAcmVnczogUmVnIGJhc2UgZm9yIGRvcy9kbWMg aGFyZHdhcmUuCj4+ICsgKiBAcG1fbXV0ZXg6IE11dGV4IGZvciBwbS0+cGRfZGF0YS4KPj4gKyAq IEBwbTogUG9pbnRlciB0byBzdHJ1Y3QgcG93ZXJfbWFuYWdlcl9zLgo+PiArICogQGh3X29wczog SGFyZHdhcmUgcmVzb3VyY2Ugb3BlcmF0aW9uIGZ1bmN0aW9ucy4gU2VlIHN0cnVjdCBhbWxfdmRl Y19od19vcHMuCj4+ICsgKiBAZ2F0ZXM6IENsayBpbnN0YW5jZSB1c2VkIGJ5IGN1cnIgZGVjb2Rl ciBjb250ZXh0Lgo+PiArICogQGRlY19pcnE6IElycSByZWdpc3RlcmVkLgo+PiArICogQGN1cnJf Y3R4OiBQb2ludGVyIHRvIGN1cnIgZGVjb2RlciBjb250ZXh0Lgo+PiArICovCj4+ICtzdHJ1Y3Qg YW1sX3ZkZWNfaHcgewo+PiArCXN0cnVjdCBwbGF0Zm9ybV9kZXZpY2UgKnBkZXY7Cj4+ICsJc3Ry dWN0IGRldmljZSAqZGV2Owo+PiArCXN0cnVjdCByZWdtYXAgKm1hcFtNQVhfUkVHX0JVU107Cj4+ ICsJc3RydWN0IG11dGV4IHBtX211dGV4Owo+PiArCXN0cnVjdCBtZXNvbl9jYW52YXMgKmNhbnZh czsKPj4gKwljb25zdCBzdHJ1Y3QgcG93ZXJfbWFuYWdlcl9zICpwbTsKPj4gKwlzdHJ1Y3QgYW1s X3ZkZWNfaHdfb3BzIGh3X29wczsKPj4gKwlzdHJ1Y3QgY2xrX2J1bGtfZGF0YSBnYXRlc1tET1Nf Q0xLX01BWF07Cj4+ICsJaW50IGRlY19pcnE7Cj4+ICsJdm9pZCAqY3Vycl9jdHg7Cj4+ICt9Owo+ PiArCj4+ICsvKioKPj4gKyAqIHN0cnVjdCBwb3dlcl9tYW5hZ2VyX3MgLSBQb3dlciBtYW5hZ2Vy ICYgb3BlcnRpb24gZnVuY3Rpb24KPj4gKyAqIEBwZF9kYXRhOiBQb2ludGVyIHRvIHN0cnVjdCBw bV9wZF9zCj4+ICsgKiBAaW5pdDogUG93ZXIgbWFuYWdlciBpbml0Lgo+PiArICogQHJlbGVhc2U6 IFBvd2VyIG1hbmFnZXIgcmVsZWFzZS4KPj4gKyAqIEBwb3dlcl9vbjogUG93ZXIgb24gZm9yIGRl Y29kZXIgaHcuCj4+ICsgKiBAcG93ZXJfb2ZmOiBQb3dlciBvZmYgZm9yIGRlY29kZXIgaHcuCj4+ ICsgKiBAcG93ZXJfc3RhdGU6IFF1ZXJ5IHRoZSBwb3dlciBzdGF0ZS4KPj4gKyAqLwo+PiArc3Ry dWN0IHBvd2VyX21hbmFnZXJfcyB7Cj4+ICsJc3RydWN0IHBtX3BkX3MgKnBkX2RhdGE7Cj4+ICsJ aW50ICgqaW5pdCkoc3RydWN0IGFtbF92ZGVjX2h3ICpodyk7Cj4+ICsJdm9pZCAoKnJlbGVhc2Up KHN0cnVjdCBhbWxfdmRlY19odyAqaHcpOwo+PiArCXZvaWQgKCpwb3dlcl9vbikoc3RydWN0IGFt bF92ZGVjX2h3ICpodywgaW50IGlkKTsKPj4gKwl2b2lkICgqcG93ZXJfb2ZmKShzdHJ1Y3QgYW1s X3ZkZWNfaHcgKmh3LCBpbnQgaWQpOwo+PiArCWJvb2wgKCpwb3dlcl9zdGF0ZSkoc3RydWN0IGFt bF92ZGVjX2h3ICpodywgaW50IGlkKTsKPj4gK307Cj4+ICsKPj4gK2ludCBkZXZfcmVxdWVzdF9o d19yZXNvdXJjZXModm9pZCAqcHJpdik7Cj4+ICt2b2lkIGRldl9kZXN0cm95X2h3X3Jlc291cmNl cyh2b2lkICpwcml2KTsKPj4gK3N0cnVjdCBhbWxfdmRlY19odyAqdmRlY19nZXRfaHcodm9pZCAq cHJpdik7Cj4+ICt1MzIgcmVhZF9kb3NfcmVnKHN0cnVjdCBhbWxfdmRlY19odyAqaHcsIHUzMiBy ZWdfYWRkcik7Cj4+ICtpbnQgdmRlY19lbmFibGUoc3RydWN0IGFtbF92ZGVjX2h3ICpodyk7Cj4+ ICtpbnQgdmRlY19kaXNhYmxlKHN0cnVjdCBhbWxfdmRlY19odyAqaHcpOwo+PiArdm9pZCBkb3Nf ZW5hYmxlKHN0cnVjdCBhbWxfdmRlY19odyAqaHcpOwo+PiArdm9pZCBhbWxfc3RhcnRfdmRlY19o dyhzdHJ1Y3QgYW1sX3ZkZWNfaHcgKmh3KTsKPj4gK3ZvaWQgYW1sX3N0b3BfdmRlY19odyhzdHJ1 Y3QgYW1sX3ZkZWNfaHcgKmh3KTsKPj4gK2ludCBsb2FkX2Zpcm13YXJlKHN0cnVjdCBhbWxfdmRl Y19odyAqaHcsIGNvbnN0IGNoYXIgKnBhdGgpOwo+PiArdm9pZCBhbWxfdmRlY19yZXNldF9jb3Jl KHN0cnVjdCBhbWxfdmRlY19odyAqaHcpOwo+PiArCj4+ICsjZW5kaWYKPj4gZGlmZiAtLWdpdCBh L2RyaXZlcnMvbWVkaWEvcGxhdGZvcm0vYW1sb2dpYy92ZGVjL2FtbF92ZGVjX3BsYXRmb3JtLmMg Yi9kcml2ZXJzL21lZGlhL3BsYXRmb3JtL2FtbG9naWMvdmRlYy9hbWxfdmRlY19wbGF0Zm9ybS5j Cj4+IG5ldyBmaWxlIG1vZGUgMTAwNjQ0Cj4+IGluZGV4IDAwMDAwMDAwMDAwMC4uZjFmOGJhMWY0 ZmY2Cj4+IC0tLSAvZGV2L251bGwKPj4gKysrIGIvZHJpdmVycy9tZWRpYS9wbGF0Zm9ybS9hbWxv Z2ljL3ZkZWMvYW1sX3ZkZWNfcGxhdGZvcm0uYwo+PiBAQCAtMCwwICsxLDM3IEBACj4+ICsvLyBT UERYLUxpY2Vuc2UtSWRlbnRpZmllcjogKEdQTC0yLjAtb25seSBPUiBNSVQpCj4+ICsvKgo+PiAr ICogQ29weXJpZ2h0IChDKSAyMDI1IEFtbG9naWMsIEluYy4gQWxsIHJpZ2h0cyByZXNlcnZlZAo+ PiArICovCj4+ICsKPj4gKyNpbmNsdWRlICJhbWxfdmRlY19wbGF0Zm9ybS5oIgo+PiArI2luY2x1 ZGUgImFtbF92ZGVjX2Rydi5oIgo+PiArI2luY2x1ZGUgImFtbF92ZGVjX2h3LmgiCj4+ICsjaW5j bHVkZSAiaDI2NC5oIgo+PiArCj4+ICsjZGVmaW5lIFZJREVPX0RFQ19IMjY0wqAgInM0X2gyNjRf bXVsdGkuYmluIgo+PiArCj4+ICtjb25zdCBzdHJ1Y3QgYW1sX2NvZGVjX29wcyBhbWxfUzRfZGVj X29wc1tdID0gewo+PiArCVtDT0RFQ19UWVBFX0gyNjRdID0gewo+PiArCQkuaW5pdCA9IGFtbF9o MjY0X2luaXQsCj4+ICsJCS5leGl0ID0gYW1sX2gyNjRfZXhpdCwKPj4gKwkJLnJ1biA9IGFtbF9o MjY0X2RlY19ydW4sCj4+ICsJfSwKPj4gK307Cj4+ICsKPj4gK3N0YXRpYyBjb25zdCBzdHJ1Y3Qg YW1sX3ZpZGVvX2RlY19mbXQgYW1sX1M0X2RlY19mbXRzID0gewo+PiArCS5tYXhfaGVpZ2h0ID0g QU1MX1ZERUNfMTA4MFBfTUFYX0gsCj4+ICsJLm1heF93aWR0aCA9IEFNTF9WREVDXzEwODBQX01B WF9XLAo+PiArCS5hbGlnbiA9IDMyLAo+PiArCS5pc18xMF9iaXRfc3VwcG9ydCA9IDAsCj4+ICt9 Owo+PiArCj4+ICtjb25zdCBzdHJ1Y3QgYW1sX2Rldl9wbGF0Zm9ybV9kYXRhIGFtbF92ZGVjX3M0 X3BkYXRhID0gewo+PiArCS5kZWNfZm10ID0gJmFtbF9TNF9kZWNfZm10cywKPj4gKwkuY29kZWNf b3BzID0gYW1sX1M0X2RlY19vcHMsCj4+ICsJLnBvd2VyX3R5cGUgPSBBTUxfUE1fUEQsCj4+ICsJ LnJlcV9od19yZXNvdXJjZSA9IGRldl9yZXF1ZXN0X2h3X3Jlc291cmNlcywKPj4gKwkuZGVzdHJv eV9od19yZXNvdXJjZSA9IGRldl9kZXN0cm95X2h3X3Jlc291cmNlcywKPj4gKwkuZndfcGF0aCA9 IHsKPj4gKwkJVklERU9fREVDX0gyNjQsCj4+ICsJfSwKPj4gK307Cj4+IGRpZmYgLS1naXQgYS9k cml2ZXJzL21lZGlhL3BsYXRmb3JtL2FtbG9naWMvdmRlYy9hbWxfdmRlY19wbGF0Zm9ybS5oIGIv ZHJpdmVycy9tZWRpYS9wbGF0Zm9ybS9hbWxvZ2ljL3ZkZWMvYW1sX3ZkZWNfcGxhdGZvcm0uaAo+ PiBuZXcgZmlsZSBtb2RlIDEwMDY0NAo+PiBpbmRleCAwMDAwMDAwMDAwMDAuLmZmMDkzM2Y2ZjA3 NAo+PiAtLS0gL2Rldi9udWxsCj4+ICsrKyBiL2RyaXZlcnMvbWVkaWEvcGxhdGZvcm0vYW1sb2dp Yy92ZGVjL2FtbF92ZGVjX3BsYXRmb3JtLmgKPj4gQEAgLTAsMCArMSw2MiBAQAo+PiArLyogU1BE WC1MaWNlbnNlLUlkZW50aWZpZXI6IChHUEwtMi4wLW9ubHkgT1IgTUlUKSAqLwo+PiArLyoKPj4g KyAqIENvcHlyaWdodCAoQykgMjAyNSBBbWxvZ2ljLCBJbmMuIEFsbCByaWdodHMgcmVzZXJ2ZWQK Pj4gKyAqLwo+PiArCj4+ICsjaWZuZGVmIEFNTF9WREVDX1BMQVRGT1JNX0hfCj4+ICsjZGVmaW5l IEFNTF9WREVDX1BMQVRGT1JNX0hfCj4+ICsKPj4gKyNpbmNsdWRlIDxsaW51eC92aWRlb2RldjIu aD4KPj4gKwo+PiArI2RlZmluZSBNQVhfREVDX0ZPUk1BVCAzCj4+ICsKPj4gKy8qKgo+PiArICog c3RydWN0IGFtbF9jb2RlY19vcHMgLSBjb2RlYyBtb2RlIHNwZWNpZmljIG9wZXJhdGlvbnMKPj4g KyAqIEBpbml0OiBVc2VkIGZvciBkZWNvZGVyIGluaXRpYWxpemF0aW9uLgo+PiArICogQGV4aXQ6 IElmIG5lZWRlZCwgY2FuIGJlIHVzZWQgdG8gdW5kbyB0aGUgLmluaXQgcGhhc2UuCj4+ICsgKiBA cnVuOiBTdGFydCBhIHNpbmdsZSBkZWNvZGluZyBqb2IuIENhbGxlZCBmcm9tIGF0b21pYyBjb250 ZXh0Lgo+PiArICogQ2FsbGVyIHNob3VsZCBlbnN1cmUgdGhhdCBhIHBhaXIgb2YgYnVmZmVycyBp cyByZWFkeSBhbmQgdGhlCj4+ICsgKiBoYXJkd2FyZSBpcyBwb3dlcmVkIG9uIGFuZCBjbGsgaXMg ZW5hYmxlZC4gUmV0dXJucyB6ZXJvIGlmIE9LLAo+PiArICogYSBuZWdhdGl2ZSB2YWx1ZSBpbiBl cnJvciBjYXNlcy4KPj4gKyAqLwo+PiArc3RydWN0IGFtbF9jb2RlY19vcHMgewo+PiArCWludCAo KmluaXQpKHZvaWQgKnByaXYpOwo+PiArCXZvaWQgKCpleGl0KSh2b2lkICpwcml2KTsKPj4gKwlp bnQgKCpydW4pKHZvaWQgKnByaXYpOwo+PiArfTsKPj4gKwo+PiArLyoqCj4+ICsgKiBzdHJ1Y3Qg YW1sX3ZpZGVvX2RlY19mbXQgLSBjb2RlYyBmb3JtYXQgcmVxdWlyZWQgYnkgcGxhdGZvcm0KPj4g KyAqIEBtYXhfaGVpZ2h0OiBNYXggZGVjb2RlIGZyYW1lIGhlaWdodCBvZiBjdXJyZW50IHBsYXRm b3JtLgo+PiArICogQG1heF93aWR0aDogTWF4IGRlY29kZSBmcmFtZSB3aWR0aCBvZiBjdXJyZW50 IHBsYXRmb3JtLgo+PiArICogQGFsaWduOiBBbGlnbiByZXF1aXJlbWVudCBvZiB0aGUgY3VycmVu dCBwbGF0Zm9ybS4KPj4gKyAqIEBpc18xMF9iaXRfc3VwcG9ydDogV2hldGhlciB0aGUgcGxhdGZv cm0gc3VwcG9ydHMgMTAgYml0Lgo+PiArICovCj4+ICtzdHJ1Y3QgYW1sX3ZpZGVvX2RlY19mbXQg ewo+PiArCXUzMiBtYXhfaGVpZ2h0Owo+PiArCXUzMiBtYXhfd2lkdGg7Cj4+ICsJaW50IGFsaWdu Owo+PiArCWludCBpc18xMF9iaXRfc3VwcG9ydDsKPj4gK307Cj4+ICsKPj4gKy8qKgo+PiArICog c3RydWN0IGFtbF9kZXZfcGxhdGZvcm1fZGF0YSAtIGNvbXBhdGlibGUgZGF0YSBmb3IgZWFjaCBj aGlwLgo+PiArICogQGRlY19mbXQ6IFN1cHBvcnQgZGVjIGZvcm1hdC4KPj4gKyAqIEBjb2RlY19v cHM6IENvZGVjIG9wZXJhdGlvbiBmdW5jdGlvbi4KPj4gKyAqIEByZXFfaHdfcmVzb3VyY2U6IE9w ZXJhdGlvbiBmdW5jdGlvbiB0byByZXF1ZXN0IHRoZSBoYXJkd2FyZSByZXNvdXJjZS4KPj4gKyAq IEBkZXN0cm95X2h3X3Jlc291cmNlOiBPcGVyYXRpb24gZnVuY3Rpb24gdG8gcmVsZWFzZSB0aGUg aGFyZHdhcmUgcmVzb3VyY2UuCj4+ICsgKiBAcG93ZXJfdHlwZTogVHlwZSBvZiBwb3dlciB0aGF0 IHRoZSBjdXJyZW50IGNoaXAgbmVlZC4gU2VlIGFtbF9wb3dlcl90eXBlX2UuCj4+ICsgKiBAZndf cGF0aDogUGF0aCBvZiB0aGUgZmlybXdhcmUuYmluLgo+PiArICovCj4+ICtzdHJ1Y3QgYW1sX2Rl dl9wbGF0Zm9ybV9kYXRhIHsKPj4gKwljb25zdCBzdHJ1Y3QgYW1sX3ZpZGVvX2RlY19mbXQgKmRl Y19mbXQ7Cj4+ICsJY29uc3Qgc3RydWN0IGFtbF9jb2RlY19vcHMgKmNvZGVjX29wczsKPj4gKwlp bnQgKCpyZXFfaHdfcmVzb3VyY2UpKHZvaWQgKnByaXYpOwo+PiArCXZvaWQgKCpkZXN0cm95X2h3 X3Jlc291cmNlKSh2b2lkICpwcml2KTsKPj4gKwlpbnQgcG93ZXJfdHlwZTsKPj4gKwljb25zdCBj aGFyICpmd19wYXRoW01BWF9ERUNfRk9STUFUXTsKPj4gK307Cj4+ICsKPj4gK2V4dGVybiBjb25z dCBzdHJ1Y3QgYW1sX2Rldl9wbGF0Zm9ybV9kYXRhIGFtbF92ZGVjX3M0X3BkYXRhOwo+PiArCj4+ ICsjZW5kaWYKPj4gZGlmZiAtLWdpdCBhL2RyaXZlcnMvbWVkaWEvcGxhdGZvcm0vYW1sb2dpYy92 ZGVjL2gyNjQuYyBiL2RyaXZlcnMvbWVkaWEvcGxhdGZvcm0vYW1sb2dpYy92ZGVjL2gyNjQuYwo+ PiBuZXcgZmlsZSBtb2RlIDEwMDY0NAo+PiBpbmRleCAwMDAwMDAwMDAwMDAuLmQ4NjE5ZTE2MGE2 Ygo+PiAtLS0gL2Rldi9udWxsCj4+ICsrKyBiL2RyaXZlcnMvbWVkaWEvcGxhdGZvcm0vYW1sb2dp Yy92ZGVjL2gyNjQuYwo+PiBAQCAtMCwwICsxLDE5MzMgQEAKPj4gKy8vIFNQRFgtTGljZW5zZS1J ZGVudGlmaWVyOiAoR1BMLTIuMC1vbmx5IE9SIE1JVCkKPj4gKy8qCj4+ICsgKiBDb3B5cmlnaHQg KEMpIDIwMjUgQW1sb2dpYywgSW5jLiBBbGwgcmlnaHRzIHJlc2VydmVkCj4+ICsgKi8KPj4gKwo+ PiArI2luY2x1ZGUgPG1lZGlhL3Y0bDItaDI2NC5oPgo+PiArI2luY2x1ZGUgPGxpbnV4L3ZtYWxs b2MuaD4KPj4gKyNpbmNsdWRlICJhbWxfdmRlYy5oIgo+PiArI2luY2x1ZGUgImFtbF92ZGVjX2h3 LmgiCj4+ICsjaW5jbHVkZSAiaDI2NC5oIgo+PiArCj4+ICsjZGVmaW5lIElOVkFMSURfUE9DIDB4 ZmZmZmZmZmYKPj4gKwo+PiArI2RlZmluZSBIMjY0X1NMSUNFX0hFQURFUl9ET05FCQkweDEKPj4g KyNkZWZpbmUgSDI2NF9TTElDRV9EQVRBX0RPTkUJCTB4Mgo+PiArCj4+ICsjZGVmaW5lIEgyNjRf TUFYX0NPTF9CVUYJCQkzMgo+PiArI2RlZmluZSBIMjY0X01BWF9DQU5WQVNfUE9TCQkJMjYKPj4g Kwo+PiArI2RlZmluZSBERUNPREVSX1RJTUVPVVRfTVMJCQk1MDAKPj4gKwo+PiArI2RlZmluZSBD T0xfQlVGRkVSX01BUkdJTgkJCTIKPj4gKyNkZWZpbmUgQ09MX1NJWkVfRk9SX09ORV9NQgkJCTk2 Cj4+ICsKPj4gK3N0cnVjdCB2ZGVjX2gyNjRfc3RhdGVsZXNzX2N0cmxfcmVmIHsKPj4gKwljb25z dCBzdHJ1Y3QgdjRsMl9jdHJsX2gyNjRfZGVjb2RlX3BhcmFtcyAqZGVjb2RlOwo+PiArCWNvbnN0 IHN0cnVjdCB2NGwyX2N0cmxfaDI2NF9zY2FsaW5nX21hdHJpeCAqc2NhbGluZzsKPj4gKwljb25z dCBzdHJ1Y3QgdjRsMl9jdHJsX2gyNjRfc3BzICpzcHM7Cj4+ICsJY29uc3Qgc3RydWN0IHY0bDJf Y3RybF9oMjY0X3BwcyAqcHBzOwo+PiArfTsKPj4gKwo+PiArZW51bSBTbGljZVR5cGUgewo+PiAr CVBfU0xJQ0UgPSAwLAo+PiArCUJfU0xJQ0UgPSAxLAo+PiArCUlfU0xJQ0UgPSAyLAo+PiArCVNQ X1NMSUNFID0gMywKPj4gKwlTSV9TTElDRSA9IDQsCj4+ICsJTUFYX1NMSUNFX1RZUEVTID0gNQo+ PiArfTsKPj4gKwo+PiArLyogVXNlZCBieSBmaXJtd2FyZSAqLwo+PiArdW5pb24gcGFyYW0gewo+ PiArCXN0cnVjdCB7Cj4+ICsJCXVuc2lnbmVkIHNob3J0IGRhdGFbUlBNX0VORCAtIFJQTV9CRUdJ Tl07Cj4+ICsJfSBsOwo+PiArCXN0cnVjdCB7Cj4+ICsJCXVuc2lnbmVkIHNob3J0IGR1bXBbRFBC X09GRlNFVF07Cj4+ICsJCXVuc2lnbmVkIHNob3J0IGRwYl9iYXNlW0ZSQU1FX0lOX0RQQiA8PCAz XTsKPj4gKwo+PiArCQl1bnNpZ25lZCBzaG9ydCBkcGJfbWF4X2J1ZmZlcl9mcmFtZTsKPj4gKwkJ dW5zaWduZWQgc2hvcnQgYWN0dWFsX2RwYl9zaXplOwo+PiArCj4+ICsJCXVuc2lnbmVkIHNob3J0 IGNvbG9jYXRlZF9idWZfc3RhdHVzOwo+PiArCj4+ICsJCXVuc2lnbmVkIHNob3J0IG51bV9mb3J3 YXJkX3Nob3J0X3Rlcm1fcmVmZXJlbmNlX3BpYzsKPj4gKwkJdW5zaWduZWQgc2hvcnQgbnVtX3No b3J0X3Rlcm1fcmVmZXJlbmNlX3BpYzsKPj4gKwkJdW5zaWduZWQgc2hvcnQgbnVtX3JlZmVyZW5j ZV9waWM7Cj4+ICsKPj4gKwkJdW5zaWduZWQgc2hvcnQgY3VycmVudF9kcGJfaW5kZXg7Cj4+ICsJ CXVuc2lnbmVkIHNob3J0IGN1cnJlbnRfZGVjb2RlZF9mcmFtZV9udW07Cj4+ICsJCXVuc2lnbmVk IHNob3J0IGN1cnJlbnRfcmVmZXJlbmNlX2ZyYW1lX251bTsKPj4gKwo+PiArCQl1bnNpZ25lZCBz aG9ydCBsMF9zaXplOwo+PiArCQl1bnNpZ25lZCBzaG9ydCBsMV9zaXplOwo+PiArCQkvKioKPj4g KwkJICogWzY6NV0gOiBuYWxfcmVmX2lkYwo+PiArCQkgKiBbNDowXSA6IG5hbF91bml0X3R5cGUK Pj4gKwkJICovCj4+ICsJCXVuc2lnbmVkIHNob3J0IE5BTF9pbmZvX21tY287Cj4+ICsJCS8qKgo+ PiArCQkgKiBbMTowXSA6IDAwIC0gdG9wIGZpZWxkLCAwMSAtIGJvdHRvbSBmaWVsZCwKPj4gKwkJ ICrCoMKgwqDCoMKgwqDCoMKgIDEwIC0gZnJhbWUsIDExIC0gbWJhZmYgZnJhbWUKPj4gKwkJICov Cj4+ICsJCXVuc2lnbmVkIHNob3J0IHBpY3R1cmVfc3RydWN0dXJlX21tY287Cj4+ICsJCXVuc2ln bmVkIHNob3J0IGZyYW1lX251bTsKPj4gKwkJdW5zaWduZWQgc2hvcnQgcGljX29yZGVyX2NudF9s c2I7Cj4+ICsKPj4gKwkJdW5zaWduZWQgc2hvcnQgbnVtX3JlZl9pZHhfbDBfYWN0aXZlX21pbnVz MTsKPj4gKwkJdW5zaWduZWQgc2hvcnQgbnVtX3JlZl9pZHhfbDFfYWN0aXZlX21pbnVzMTsKPj4g Kwo+PiArCQl1bnNpZ25lZCBzaG9ydCBQcmV2UGljT3JkZXJDbnRMc2I7Cj4+ICsJCXVuc2lnbmVk IHNob3J0IFByZXZpb3VzRnJhbWVOdW07Cj4+ICsKPj4gKwkJLyogMzIgYml0cyB2YXJpYWJsZXMg Ki8KPj4gKwkJdW5zaWduZWQgc2hvcnQgZGVsdGFfcGljX29yZGVyX2NudF9ib3R0b21bMl07Cj4+ ICsJCXVuc2lnbmVkIHNob3J0IGRlbHRhX3BpY19vcmRlcl9jbnRfMFsyXTsKPj4gKwkJdW5zaWdu ZWQgc2hvcnQgZGVsdGFfcGljX29yZGVyX2NudF8xWzJdOwo+PiArCj4+ICsJCXVuc2lnbmVkIHNo b3J0IFByZXZQaWNPcmRlckNudE1zYlsyXTsKPj4gKwkJdW5zaWduZWQgc2hvcnQgUHJldkZyYW1l TnVtT2Zmc2V0WzJdOwo+PiArCj4+ICsJCXVuc2lnbmVkIHNob3J0IGZyYW1lX3BpY19vcmRlcl9j bnRbMl07Cj4+ICsJCXVuc2lnbmVkIHNob3J0IHRvcF9maWVsZF9waWNfb3JkZXJfY250WzJdOwo+ PiArCQl1bnNpZ25lZCBzaG9ydCBib3R0b21fZmllbGRfcGljX29yZGVyX2NudFsyXTsKPj4gKwo+ PiArCQl1bnNpZ25lZCBzaG9ydCBjb2xvY2F0ZWRfbXZfYWRkcl9zdGFydFsyXTsKPj4gKwkJdW5z aWduZWQgc2hvcnQgY29sb2NhdGVkX212X2FkZHJfZW5kWzJdOwo+PiArCQl1bnNpZ25lZCBzaG9y dCBjb2xvY2F0ZWRfbXZfd3JfYWRkclsyXTsKPj4gKwl9IGRwYjsKPj4gKwlzdHJ1Y3Qgewo+PiAr CQl1bnNpZ25lZCBzaG9ydCBkdW1wW01NQ09fT0ZGU0VUXTsKPj4gKwo+PiArCQkvKiBhcnJheSBi YXNlIGFkZHJlc3MgZm9yIG9mZnNldF9mb3JfcmVmX2ZyYW1lICovCj4+ICsJCXVuc2lnbmVkIHNo b3J0IG9mZnNldF9mb3JfcmVmX2ZyYW1lX2Jhc2VbMTI4XTsKPj4gKwo+PiArCQkvKioKPj4gKwkJ ICogMCAtIEluZGV4IGluIERQQgo+PiArCQkgKiAxIC0gUGljdHVyZSBGbGFnCj4+ICsJCSAqwqAg WzJdIDogMCAtIHNob3J0IHRlcm0gcmVmZXJlbmNlLAo+PiArCQkgKgkJCTEgLSBsb25nIHRlcm0g cmVmZXJlbmNlCj4+ICsJCSAqwqAgWzFdIDogYm90dG9tIGZpZWxkCj4+ICsJCSAqwqAgWzBdIDog dG9wIGZpZWxkCj4+ICsJCSAqIDIgLSBQaWN0dXJlIE51bWJlciAoc2hvcnQgdGVybSBvciBsb25n IHRlcm0pIGxvdyAxNiBiaXRzCj4+ICsJCSAqIDMgLSBQaWN0dXJlIE51bWJlciAoc2hvcnQgdGVy bSBvciBsb25nIHRlcm0pIGhpZ2ggMTYgYml0cwo+PiArCQkgKi8KPj4gKwkJdW5zaWduZWQgc2hv cnQgcmVmZXJlbmNlX2Jhc2VbMTI4XTsKPj4gKwo+PiArCQkvKiBjb21tYW5kIGFuZCBwYXJhbWV0 ZXIsIHVudGlsIGNvbW1hbmQgaXMgMyAqLwo+PiArCQl1bnNpZ25lZCBzaG9ydCBsMF9yZW9yZGVy X2NtZFtSRU9SREVSX0NNRF9NQVhdOwo+PiArCQl1bnNpZ25lZCBzaG9ydCBsMV9yZW9yZGVyX2Nt ZFtSRU9SREVSX0NNRF9NQVhdOwo+PiArCj4+ICsJCS8qIGNvbW1hbmQgYW5kIHBhcmFtZXRlciwg dW50aWwgY29tbWFuZCBpcyAwICovCj4+ICsJCXVuc2lnbmVkIHNob3J0IG1tY29fY21kWzQ0XTsK Pj4gKwo+PiArCQl1bnNpZ25lZCBzaG9ydCBsMF9iYXNlWzQwXTsKPj4gKwkJdW5zaWduZWQgc2hv cnQgbDFfYmFzZVs0MF07Cj4+ICsJfSBtbWNvOwo+PiArCXN0cnVjdCB7Cj4+ICsJCS8qIGZyb20g dWNvZGUgbG1lbSwgZG8gbm90IGNoYW5nZSB0aGlzIHN0cnVjdCAqLwo+PiArCX0gcDsKPj4gK307 Cj4+ICsKPj4gK3N0cnVjdCBoMjY0X2RlY29kZV9idWZfc3BlYyB7Cj4+ICsJc3RydWN0IHY0bDJf aDI2NF9kcGJfZW50cnkgKmRwYjsKPj4gKwl1MzIgY2FudmFzX3BvczsKPj4gKwl1MzIgZHBiX2lu ZGV4Owo+PiArCXUzMiBwb2M7Cj4+ICsJaW50IGNvbF9idWZfaW5kZXg7Cj4+ICsJdTggeV9jYW52 YXNfaW5kZXg7Cj4+ICsJdTggdV9jYW52YXNfaW5kZXg7Cj4+ICsJdTggdl9jYW52YXNfaW5kZXg7 Cj4+ICsJdTggdXNlZDsKPj4gKwl1OCBsb25nX3Rlcm1fZmxhZzsKPj4gKwlkbWFfYWRkcl90IHlf ZG1hX2FkZHI7Cj4+ICsJZG1hX2FkZHJfdCBjX2RtYV9hZGRyOwo+PiArfTsKPj4gKwo+PiArI2Rl ZmluZSBSRU9SREVSSU5HX0NPTU1BTkRfTUFYX1NJWkUJMzMKPj4gK3N0cnVjdCBzbGljZSB7Cj4+ ICsJaW50IGZyYW1lX251bTsKPj4gKwkvKm1vZGlmaWNhdGlvbiAqLwo+PiArCWludCBzbGljZV90 eXBlOwo+PiArCWludCBudW1fcmVmX2lkeF9sMDsKPj4gKwlpbnQgbnVtX3JlZl9pZHhfbDE7Cj4+ ICsJaW50IGZpcnN0X21iX2luX3NsaWNlOwo+PiArCWludCByZWZfcGljX2xpc3RfcmVvcmRlcmlu Z19mbGFnWzJdOwo+PiArCWludCBtb2RpZmljYXRpb25fb2ZfcGljX251bXNfaWRjWzJdW1JFT1JE RVJJTkdfQ09NTUFORF9NQVhfU0laRV07Cj4+ICsJaW50IGFic19kaWZmX3BpY19udW1fbWludXMx WzJdW1JFT1JERVJJTkdfQ09NTUFORF9NQVhfU0laRV07Cj4+ICsJaW50IGxvbmdfdGVybV9waWNf aWR4WzJdW1JFT1JERVJJTkdfQ09NTUFORF9NQVhfU0laRV07Cj4+ICsJdW5zaWduZWQgY2hhciBk ZWNfcmVmX3BpY19tYXJraW5nX2J1ZmZlcl92YWxpZDsKPj4gK307Cj4+ICsKPj4gK3N0cnVjdCBh bWxfaDI2NF9jdHggewo+PiArCXN0cnVjdCBhbWxfdmRlY19jdHggKnY0bDJfY3R4Owo+PiArCXU4 IGluaXRfZmxhZzsKPj4gKwl1OCBuZXdfcGljX2ZsYWc7Cj4+ICsJdTggbWNfY3B1X2xvYWRlZDsK Pj4gKwl1OCBwYXJhbV9zZXQ7Cj4+ICsJdTggY29sb2NhdGVkX2J1Zl9udW07Cj4+ICsJdTggcmVn X2lxaWRjdF9jb250cm9sX2luaXRfZmxhZzsKPj4gKwl1MzIgcmVnX2lxaWRjdF9jb250cm9sOwo+ PiArCXUzMiByZWdfdmNvcF9jdHJsX3JlZzsKPj4gKwl1MzIgcmVnX3J2X2FpX21iX2NvdW50Owo+ PiArCXUzMiB2bGRfZGVjX2NvbnRyb2w7Cj4+ICsJdTMyIHNhdmVfYXZzY3JhdGNoX2Y7Cj4+ICsJ dTMyIHNlcV9pbmZvOwo+PiArCXUzMiBkZWNvZGVfcGljX2NvdW50Owo+PiArCXVuaW9uIHBhcmFt IGRwYl9wYXJhbTsKPj4gKwl1MzIgZGVjX3N0YXR1czsKPj4gKwlzdHJ1Y3Qgc2xpY2UgbXNsaWNl Owo+PiArCXN0cnVjdCBoMjY0X2RlY29kZV9idWZfc3BlYyBjdXJyX3NwZWM7Cj4+ICsJc3RydWN0 IGgyNjRfZGVjb2RlX2J1Zl9zcGVjIHJlZl9saXN0MFtWNEwyX0gyNjRfTlVNX0RQQl9FTlRSSUVT ICsgMV07Cj4+ICsJc3RydWN0IGgyNjRfZGVjb2RlX2J1Zl9zcGVjIHJlZl9saXN0MVtWNEwyX0gy NjRfTlVNX0RQQl9FTlRSSUVTICsgMV07Cj4+ICsJc3RydWN0IGgyNjRfZGVjb2RlX2J1Zl9zcGVj IHJlZl9saXN0MF91bnJlb3JkZXJlZFtWNEwyX0gyNjRfTlVNX0RQQl9FTlRSSUVTICsgMV07Cj4+ ICsJc3RydWN0IGgyNjRfZGVjb2RlX2J1Zl9zcGVjIHJlZl9saXN0MV91bnJlb3JkZXJlZFtWNEwy X0gyNjRfTlVNX0RQQl9FTlRSSUVTICsgMV07Cj4+ICsJdTggbGlzdF9zaXplWzJdOwo+PiArCWRt YV9hZGRyX3QgbG1lbV9waHlfYWRkcjsKPj4gKwl2b2lkICpsbWVtX2FkZHI7Cj4+ICsJZG1hX2Fk ZHJfdCBtY19jcHVfcGFkZHI7Cj4+ICsJdm9pZCAqbWNfY3B1X3ZhZGRyOwo+PiArCWRtYV9hZGRy X3QgY21hX2FsbG9jX2FkZHI7Cj4+ICsJdm9pZCAqY21hX2FsbG9jX3ZhZGRyOwo+PiArCWRtYV9h ZGRyX3QgY29sbGF0ZWRfY21hX2FkZHI7Cj4+ICsJZG1hX2FkZHJfdCBjb2xsYXRlZF9jbWFfYWRk cl9lbmQ7Cj4+ICsJdm9pZCAqY29sbGF0ZWRfY21hX3ZhZGRyOwo+PiArCWRtYV9hZGRyX3Qgd29y a3NwYWNlX29mZnNldDsKPj4gKwl2b2lkICp3b3Jrc3BhY2VfdmFkZHI7Cj4+ICsJdTMyIGNvbF9i dWZfYWxsb2Nfc2l6ZTsKPj4gKwl1MzIgb25lX2NvbF9idWZfc2l6ZTsKPj4gKwl1MzIgY29sb2Nh dGVkX2J1Zl9tYXA7Cj4+ICsJaW50IGNvbG9jYXRlZF9idWZfcG9jW0gyNjRfTUFYX0NPTF9CVUZd Owo+PiArCWludCBjYW52YXNfcG9zX3BvY1tIMjY0X01BWF9DQU5WQVNfUE9TXTsKPj4gKwo+PiAr CXUzMiBmcmFtZV93aWR0aDsKPj4gKwl1MzIgZnJhbWVfaGVpZ2h0Owo+PiArCXUzMiBtYl93aWR0 aDsKPj4gKwl1MzIgbWJfaGVpZ2h0Owo+PiArCXUzMiBtYl90b3RhbDsKPj4gKwl1MzIgbWF4X251 bV9yZWZfZnJhbWVzOwo+PiArCj4+ICsJc3RydWN0IHZkZWNfaDI2NF9zdGF0ZWxlc3NfY3RybF9y ZWYgY3RybF9yZWY7Cj4+ICt9Owo+PiArCj4+ICtzdGF0aWMgaW5saW5lIGludCBnZXRfZmxhZyh1 MzIgZmxhZywgdTMyIG1hc2spCj4+ICt7Cj4+ICsJcmV0dXJuIChmbGFnICYgbWFzaykgPyAxIDog MDsKPj4gK30KPj4gKwo+PiArc3RhdGljIGlubGluZSB2b2lkIHdyaXRlX2xtZW0odW5zaWduZWQg c2hvcnQgKmJhc2UsIHUzMiBvZmZzZXQsIHUzMiB2YWx1ZSkKPj4gK3sKPj4gKwliYXNlW29mZnNl dF0gPSB2YWx1ZTsKPj4gK30KPj4gKwo+PiArc3RhdGljIGlubGluZSB1aW50MzJfdCBzcGVjMmNh bnZhcyhzdHJ1Y3QgaDI2NF9kZWNvZGVfYnVmX3NwZWMgKmJ1Zl9zcGVjKQo+PiArewo+PiArCXJl dHVybiAoYnVmX3NwZWMtPnZfY2FudmFzX2luZGV4IDw8IDE2KSB8Cj4+ICsJCShidWZfc3BlYy0+ dV9jYW52YXNfaW5kZXggPDwgOCkgfAo+PiArCQkoYnVmX3NwZWMtPnlfY2FudmFzX2luZGV4IDw8 IDApOwo+PiArfQo+PiArCj4+ICtzdGF0aWMgc3RydWN0IGgyNjRfZGVjb2RlX2J1Zl9zcGVjICpm aW5kX3NwZWNfYnlfZHBiX2luZGV4KHN0cnVjdCBhbWxfaDI2NF9jdHggKmgyNjRfY3R4LCBpbnQg aW5kZXgsCj4+ICsJCQkJCQkJwqDCoCBpbnQgbGlzdCkKPj4gK3sKPj4gKwlpbnQgaTsKPj4gKwlp bnQgc2l6ZTsKPj4gKwlzdHJ1Y3QgaDI2NF9kZWNvZGVfYnVmX3NwZWMgKnJlZl9saXN0Owo+PiAr Cj4+ICsJc2l6ZSA9IGgyNjRfY3R4LT5saXN0X3NpemVbbGlzdF07Cj4+ICsJaWYgKGxpc3QgPT0g MCkKPj4gKwkJcmVmX2xpc3QgPSAmaDI2NF9jdHgtPnJlZl9saXN0MFswXTsKPj4gKwllbHNlCj4+ ICsJCXJlZl9saXN0ID0gJmgyNjRfY3R4LT5yZWZfbGlzdDFbMF07Cj4+ICsKPj4gKwlmb3IgKGkg PSAwOyBpIDwgc2l6ZTsgaSsrKSB7Cj4+ICsJCWlmIChpbmRleCA9PSByZWZfbGlzdFtpXS5kcGJf aW5kZXgpCj4+ICsJCQlyZXR1cm4gJnJlZl9saXN0W2ldOwo+PiArCX0KPj4gKwo+PiArCXJldHVy biBOVUxMOwo+PiArfQo+PiArCj4+ICtzdGF0aWMgaW50IGgyNjRfcHJlcGFyZV9pbnB1dChzdHJ1 Y3QgYW1sX3ZkZWNfY3R4ICpjdHgpCj4+ICt7Cj4+ICsJc3RydWN0IGFtbF92ZGVjX2h3ICpodyA9 IHZkZWNfZ2V0X2h3KGN0eC0+ZGV2KTsKPj4gKwlzdHJ1Y3QgdmIyX3Y0bDJfYnVmZmVyICpzcmM7 Cj4+ICsJc3RydWN0IHZiMl9idWZmZXIgKnZiOwo+PiArCWRtYV9hZGRyX3Qgc3JjX2RtYTsKPj4g Kwl1MzIgcGF5bG9hZF9zaXplOwo+PiArCWludCBkdW1teTsKPj4gKwo+PiArCXNyYyA9IHY0bDJf bTJtX25leHRfc3JjX2J1ZihjdHgtPmZoLm0ybV9jdHgpOwo+PiArCWlmICghc3JjKSB7Cj4+ICsJ CWRldl9pbmZvKGh3LT5kZXYsICJubyBpbnB1dCBidWZmZXIgYXZhaWxhYmxlIVxuIik7Cj4+ICsJ CXJldHVybiAtMTsKPj4gKwl9Cj4+ICsJdmIgPSAmc3JjLT52YjJfYnVmOwo+PiArCXBheWxvYWRf c2l6ZSA9IHZiMl9nZXRfcGxhbmVfcGF5bG9hZCh2YiwgMCk7Cj4+ICsJc3JjX2RtYSA9IHZiMl9k bWFfY29udGlnX3BsYW5lX2RtYV9hZGRyKHZiLCAwKTsKPj4gKwo+PiArCXJlZ21hcF93cml0ZSho dy0+bWFwW0RPU19CVVNdLCBWTERfTUVNX1ZJRklGT19DT05UUk9MLCAwKTsKPj4gKwkvKiByZXNl dCBWTEQgZmlmbyBmb3IgYWxsIHZkZWMgKi8KPj4gKwlyZWdtYXBfd3JpdGUoaHctPm1hcFtET1Nf QlVTXSwgRE9TX1NXX1JFU0VUMCwgKDEgPDwgNSkgfCAoMSA8PCA0KSB8ICgxIDw8IDMpKTsKPj4g KwlyZWdtYXBfd3JpdGUoaHctPm1hcFtET1NfQlVTXSwgRE9TX1NXX1JFU0VUMCwgMCk7Cj4+ICsJ cmVnbWFwX3dyaXRlKGh3LT5tYXBbRE9TX0JVU10sIFBPV0VSX0NUTF9WTEQsIDEgPDwgNCk7Cj4+ ICsKPj4gKwlyZWdtYXBfd3JpdGUoaHctPm1hcFtET1NfQlVTXSwgVkxEX01FTV9WSUZJRk9fU1RB UlRfUFRSLCBzcmNfZG1hKTsKPj4gKwlyZWdtYXBfd3JpdGUoaHctPm1hcFtET1NfQlVTXSwgVkxE X01FTV9WSUZJRk9fRU5EX1BUUiwgKHNyY19kbWEgKyBwYXlsb2FkX3NpemUpKTsKPj4gKwlyZWdt YXBfd3JpdGUoaHctPm1hcFtET1NfQlVTXSwgVkxEX01FTV9WSUZJRk9fQ1VSUl9QVFIsCj4+ICsJ CcKgwqDCoMKgIHJvdW5kX2Rvd24oc3JjX2RtYSwgVkRFQ19GSUZPX0FMSUdOKSk7Cj4+ICsKPj4g KwlyZWdtYXBfd3JpdGUoaHctPm1hcFtET1NfQlVTXSwgVkxEX01FTV9WSUZJRk9fQ09OVFJPTCwg MSk7Cj4+ICsJcmVnbWFwX3dyaXRlKGh3LT5tYXBbRE9TX0JVU10sIFZMRF9NRU1fVklGSUZPX0NP TlRST0wsIDApOwo+PiArCXJlZ21hcF93cml0ZShody0+bWFwW0RPU19CVVNdLCBWTERfTUVNX1ZJ RklGT19CVUZfQ05UTCwgMik7Cj4+ICsKPj4gKwlyZWdtYXBfd3JpdGUoaHctPm1hcFtET1NfQlVT XSwgVkxEX01FTV9WSUZJRk9fUlAsCj4+ICsJCcKgwqDCoMKgIHJvdW5kX2Rvd24oc3JjX2RtYSwg VkRFQ19GSUZPX0FMSUdOKSk7Cj4+ICsJZHVtbXkgPSBwYXlsb2FkX3NpemUgKyBWTERfUEFERElO R19TSVpFOwo+PiArCXJlZ21hcF93cml0ZShody0+bWFwW0RPU19CVVNdLCBWTERfTUVNX1ZJRklG T19XUCwKPj4gKwkJwqDCoMKgwqAgcm91bmRfZG93bigoc3JjX2RtYSArIGR1bW15KSwgVkRFQ19G SUZPX0FMSUdOKSk7Cj4+ICsKPj4gKwlyZWdtYXBfd3JpdGUoaHctPm1hcFtET1NfQlVTXSwgVkxE X01FTV9WSUZJRk9fQlVGX0NOVEwsIDMpOwo+PiArCXJlZ21hcF93cml0ZShody0+bWFwW0RPU19C VVNdLCBWTERfTUVNX1ZJRklGT19CVUZfQ05UTCwgMik7Cj4+ICsKPj4gKwlyZWdtYXBfd3JpdGUo aHctPm1hcFtET1NfQlVTXSwgVkxEX01FTV9WSUZJRk9fQ09OVFJPTCwKPj4gKwkJwqDCoMKgwqAg KDB4MTEgPDwgMTYpIHwgKDEgPDwgMTApIHwgKDcgPDwgMykpOwo+PiArCj4+ICsJcmVnbWFwX3dy aXRlKGh3LT5tYXBbRE9TX0JVU10sIEFWX1NDUkFUQ0hfMSwgMHgwKTsKPj4gKwlyZWdtYXBfd3Jp dGUoaHctPm1hcFtET1NfQlVTXSwgSDI2NF9ERUNPREVfSU5GTywgKDEgPDwgMTMpKTsKPj4gKwly ZWdtYXBfd3JpdGUoaHctPm1hcFtET1NfQlVTXSwgSDI2NF9ERUNPREVfU0laRSwgcGF5bG9hZF9z aXplKTsKPj4gKwlyZWdtYXBfd3JpdGUoaHctPm1hcFtET1NfQlVTXSwgVklGRl9CSVRfQ05ULCBw YXlsb2FkX3NpemUgKiA4KTsKPj4gKwo+PiArCXJldHVybiAwOwo+PiArfQo+PiArCj4+ICtzdGF0 aWMgdm9pZCBjb25maWdfc3BzX3BhcmFtcyhzdHJ1Y3QgYW1sX2gyNjRfY3R4ICpoMjY0X2N0eCwK Pj4gKwkJCcKgwqDCoMKgwqAgdW5zaWduZWQgc2hvcnQgKnNwc19iYXNlLAo+PiArCQkJwqDCoMKg wqDCoCBjb25zdCBzdHJ1Y3QgdjRsMl9jdHJsX2gyNjRfc3BzICpzcHMpCj4+ICt7Cj4+ICsJc3Ry dWN0IGFtbF92ZGVjX2N0eCAqY3R4ID0gaDI2NF9jdHgtPnY0bDJfY3R4Owo+PiArCXN0cnVjdCBh bWxfdmRlY19odyAqaHcgPSB2ZGVjX2dldF9odyhjdHgtPmRldik7Cj4+ICsJdTMyIGNmZ190bXAg PSAwOwo+PiArCXUzMiBmcmFtZV9zaXplOwo+PiArCXUzMiBvZmZzZXQgPSAwOwo+PiArCXVuc2ln bmVkIHNob3J0IGRhdGFfdG1wWzB4MTAwXTsKPj4gKwlpbnQgaSwgaWk7Cj4+ICsKPj4gKwltZW1z ZXQoc3BzX2Jhc2UsIDAsIDB4MTAwKTsKPj4gKwo+PiArCWgyNjRfY3R4LT5mcmFtZV93aWR0aCA9 IChzcHMtPnBpY193aWR0aF9pbl9tYnNfbWludXMxICsgMSkgPDwgNDsKPj4gKwloMjY0X2N0eC0+ ZnJhbWVfaGVpZ2h0ID0gKHNwcy0+cGljX2hlaWdodF9pbl9tYXBfdW5pdHNfbWludXMxICsgMSkg PDwgNDsKPj4gKwo+PiArCWRhdGFfdG1wW29mZnNldF0gPSBQQVJBTV9CQVNFX1ZBTDsKPj4gKwlv ZmZzZXQgKz0gMjsKPj4gKwo+PiArCWRhdGFfdG1wW29mZnNldCsrXSA9IEdFVF9TUFNfUFJPRklM RV9JREMoc3BzLT5wcm9maWxlX2lkYyk7Cj4+ICsKPj4gKwlkYXRhX3RtcFtvZmZzZXQrK10gPSBH RVRfU1BTX1NFUV9QQVJBTV9TRVRfSUQoc3BzLT5zZXFfcGFyYW1ldGVyX3NldF9pZCkgfAo+PiAr CcKgwqDCoCBHRVRfU1BTX0xFVkVMX0lEQyhzcHMtPmxldmVsX2lkYyk7Cj4+ICsKPj4gKwlpZiAo c3BzLT5wcm9maWxlX2lkYyA+PSAxMDApIHsKPj4gKwkJZGF0YV90bXBbb2Zmc2V0KytdID0gR0VU X1NQU19DSFJPTUFfRk9STUFUX0lEQyhzcHMtPmNocm9tYV9mb3JtYXRfaWRjKTsKPj4gKwo+PiAr CQlkYXRhX3RtcFtvZmZzZXQrK10gPSAoKHNwcy0+Y2hyb21hX2Zvcm1hdF9pZGMgXiAxKSA8PCAx KTsKPj4gKwl9Cj4+ICsKPj4gKwlkYXRhX3RtcFtvZmZzZXQrK10gPSBHRVRfU1BTX0xPRzJfTUFY X0ZSQU1FX05VTShzcHMtPmxvZzJfbWF4X2ZyYW1lX251bV9taW51czQpOwo+PiArCWRhdGFfdG1w W29mZnNldCsrXSA9IEdFVF9TUFNfUElDX09SREVSX1RZUEUoc3BzLT5waWNfb3JkZXJfY250X3R5 cGUpOwo+PiArCj4+ICsJaWYgKHNwcy0+cGljX29yZGVyX2NudF90eXBlID09IDApIHsKPj4gKwkJ ZGF0YV90bXBbb2Zmc2V0KytdID0KPj4gKwkJCUdFVF9TUFNfUElDX09SREVSX0NOVF9MU0Ioc3Bz LT5sb2cyX21heF9waWNfb3JkZXJfY250X2xzYl9taW51czQpOwo+PiArCX0gZWxzZSBpZiAoc3Bz LT5waWNfb3JkZXJfY250X3R5cGUgPT0gMSkgewo+PiArCQlkYXRhX3RtcFtvZmZzZXQrK10gPQo+ PiArCQkJZ2V0X2ZsYWcoc3BzLT5mbGFncywKPj4gKwkJCQkgVjRMMl9IMjY0X1NQU19GTEFHX0RF TFRBX1BJQ19PUkRFUl9BTFdBWVNfWkVSTyk7Cj4+ICsJCWRhdGFfdG1wW29mZnNldCsrXSA9Cj4+ ICsJCQlHRVRfU1BTX09GRlNFVF9GT1JfTk9OUkVGX1BJQ19MT1coc3BzLT5vZmZzZXRfZm9yX25v bl9yZWZfcGljKTsKPj4gKwkJZGF0YV90bXBbb2Zmc2V0KytdID0KPj4gKwkJCUdFVF9TUFNfT0ZG U0VUX0ZPUl9OT05SRUZfUElDX0hJR0goc3BzLT5vZmZzZXRfZm9yX25vbl9yZWZfcGljKTsKPj4g KwkJZGF0YV90bXBbb2Zmc2V0KytdID0KPj4gKwkJCUdFVF9TUFNfT0ZGU0VUX0ZPUl9UT1BfQk9U X0ZJRUxEX0xPVyhzcHMtPm9mZnNldF9mb3JfdG9wX3RvX2JvdHRvbV9maWVsZCk7Cj4+ICsJCWRh dGFfdG1wW29mZnNldCsrXSA9Cj4+ICsJCQlHRVRfU1BTX09GRlNFVF9GT1JfVE9QX0JPVF9GSUVM RF9ISUdIKHNwcy0+b2Zmc2V0X2Zvcl90b3BfdG9fYm90dG9tX2ZpZWxkKTsKPj4gKwkJZGF0YV90 bXBbb2Zmc2V0KytdID0gc3BzLT5udW1fcmVmX2ZyYW1lc19pbl9waWNfb3JkZXJfY250X2N5Y2xl Owo+PiArCX0KPj4gKwo+PiArCWRhdGFfdG1wW29mZnNldCsrXSA9IEdFVF9TUFNfTlVNX1JFRl9G UkFNRVMoc3BzLT5tYXhfbnVtX3JlZl9mcmFtZXMpIHwKPj4gKwnCoMKgwqAgR0VUX1NQU19HQVBT X0FMTE9XRURfRkxBRyhnZXRfZmxhZyhzcHMtPmZsYWdzLAo+PiArCQkJCQnCoMKgwqDCoMKgwqAg VjRMMl9IMjY0X1NQU19GTEFHX0dBUFNfSU5fRlJBTUVfTlVNX1ZBTFVFX0FMTE9XRUQpKTsKPj4g Kwo+PiArCWRhdGFfdG1wW29mZnNldCsrXSA9IEdFVF9TUFNfUElDX1dJRFRIX0lOX01CUyhzcHMt PnBpY193aWR0aF9pbl9tYnNfbWludXMxKTsKPj4gKwo+PiArCWRhdGFfdG1wW29mZnNldCsrXSA9 IEdFVF9TUFNfUElDX0hFSUdIVF9JTl9NQlMoc3BzLT5waWNfaGVpZ2h0X2luX21hcF91bml0c19t aW51czEpOwo+PiArCWRhdGFfdG1wW29mZnNldCsrXSA9Cj4+ICsJCUdFVF9TUFNfRElSRUNUXzhY OF9GTEFHUwo+PiArCQkJCShnZXRfZmxhZyhzcHMtPmZsYWdzLAo+PiArCQkJCQnCoCBWNEwyX0gy NjRfU1BTX0ZMQUdfRElSRUNUXzhYOF9JTkZFUkVOQ0UpKSB8Cj4+ICsJCUdFVF9TUFNfTUJfQURB UFRJVkVfRlJBTUVfRklFTERfRkxBR1MKPj4gKwkJCQkoZ2V0X2ZsYWcoc3BzLT5mbGFncywKPj4g KwkJCQkJwqAgVjRMMl9IMjY0X1NQU19GTEFHX01CX0FEQVBUSVZFX0ZSQU1FX0ZJRUxEKSkgfAo+ PiArCQlHRVRfU1BTX0ZSQU1FX01CU19PTkxZX0ZMQUdTCj4+ICsJCQkJKGdldF9mbGFnKHNwcy0+ ZmxhZ3MsCj4+ICsJCQkJCcKgIFY0TDJfSDI2NF9TUFNfRkxBR19GUkFNRV9NQlNfT05MWSkpOwo+ PiArCj4+ICsJZm9yIChpID0gMDsgaSA8IDB4MTAwOyBpICs9IDQpIHsKPj4gKwkJZm9yIChpaSA9 IDA7IGlpIDwgNDsgaWkrKykKPj4gKwkJCXNwc19iYXNlW2kgKyAzIC0gaWldID0gZGF0YV90bXBb aSArIGlpXTsKPj4gKwl9Cj4+ICsKPj4gKwlmcmFtZV9zaXplID0gKHNwcy0+cGljX3dpZHRoX2lu X21ic19taW51czEgKyAxKSAqIChzcHMtPnBpY19oZWlnaHRfaW5fbWFwX3VuaXRzX21pbnVzMSAr IDEpOwo+PiArCWNmZ190bXAgPSAoZ2V0X2ZsYWcoc3BzLT5mbGFncywgVjRMMl9IMjY0X1NQU19G TEFHX0ZSQU1FX01CU19PTkxZKSA8PCAzMSkgfAo+PiArCQkJCShzcHMtPm1heF9udW1fcmVmX2Zy YW1lcyA8PCAyNCkgfCAoZnJhbWVfc2l6ZSA8PCA4KSB8Cj4+ICsJCQkJKHNwcy0+cGljX3dpZHRo X2luX21ic19taW51czEgKyAxKTsKPj4gKwlyZWdtYXBfd3JpdGUoaHctPm1hcFtET1NfQlVTXSwg QVZfU0NSQVRDSF8xLCBjZmdfdG1wKTsKPj4gKwloMjY0X2N0eC0+c2VxX2luZm8gPSBjZmdfdG1w Owo+PiArCj4+ICsJY2ZnX3RtcCA9IDA7Cj4+ICsJY2ZnX3RtcCA9IChnZXRfZmxhZyhzcHMtPmZs YWdzLCBWNEwyX0gyNjRfU1BTX0ZMQUdfRElSRUNUXzhYOF9JTkZFUkVOQ0UpIDw8IDE1KSB8Cj4+ ICsJCQkJKHNwcy0+Y2hyb21hX2Zvcm1hdF9pZGMpOwo+PiArCXJlZ21hcF93cml0ZShody0+bWFw W0RPU19CVVNdLCBBVl9TQ1JBVENIXzIsIGNmZ190bXApOwo+PiArCj4+ICsJY2ZnX3RtcCA9IDA7 Cj4+ICsJY2ZnX3RtcCA9IChzcHMtPm1heF9udW1fcmVmX2ZyYW1lcyA8PCA4KSB8IChzcHMtPmxl dmVsX2lkYyk7Cj4+ICsJcmVnbWFwX3dyaXRlKGh3LT5tYXBbRE9TX0JVU10sIEFWX1NDUkFUQ0hf QiwgY2ZnX3RtcCk7Cj4+ICsKPj4gKwljZmdfdG1wID0gKChzcHMtPmxldmVsX2lkYyAmIDB4ZmYp IDw8IDcpIHwKPj4gKwnCoMKgwqAgKGdldF9mbGFnKHNwcy0+ZmxhZ3MsIFY0TDJfSDI2NF9TUFNf RkxBR19GUkFNRV9NQlNfT05MWSkgPDwgMik7Cj4+ICsJcmVnbWFwX3dyaXRlKGh3LT5tYXBbRE9T X0JVU10sIE5BTF9TRUFSQ0hfQ1RMLAo+PiArCQnCoMKgwqDCoCByZWFkX2Rvc19yZWcoaHcsIE5B TF9TRUFSQ0hfQ1RMKSB8IGNmZ190bXApOwo+PiArCj4+ICsJaDI2NF9jdHgtPm1iX3dpZHRoID0g KHNwcy0+cGljX3dpZHRoX2luX21ic19taW51czEgKyA0KSAmIDB4ZmZmZmZmZmM7Cj4+ICsJaDI2 NF9jdHgtPm1iX2hlaWdodCA9IChzcHMtPnBpY19oZWlnaHRfaW5fbWFwX3VuaXRzX21pbnVzMSAr IDQpICYgMHhmZmZmZmZmYzsKPj4gKwloMjY0X2N0eC0+bWJfdG90YWwgPSBoMjY0X2N0eC0+bWJf d2lkdGggKiBoMjY0X2N0eC0+bWJfaGVpZ2h0Owo+PiArCWgyNjRfY3R4LT5tYXhfbnVtX3JlZl9m cmFtZXMgPSBzcHMtPm1heF9udW1fcmVmX2ZyYW1lczsKPj4gK30KPj4gKwo+PiArc3RhdGljIHZv aWQgY29uZmlnX3Bwc19wYXJhbXMoc3RydWN0IGFtbF9oMjY0X2N0eCAqaDI2NF9jdHgsCj4+ICsJ CQnCoMKgwqDCoMKgIHVuc2lnbmVkIHNob3J0ICpwcHNfYmFzZSwKPj4gKwkJCcKgwqDCoMKgwqAg Y29uc3Qgc3RydWN0IHY0bDJfY3RybF9oMjY0X3BwcyAqcHBzKQo+PiArewo+PiArCXN0cnVjdCBh bWxfdmRlY19jdHggKmN0eCA9IGgyNjRfY3R4LT52NGwyX2N0eDsKPj4gKwlzdHJ1Y3QgYW1sX3Zk ZWNfaHcgKmh3ID0gdmRlY19nZXRfaHcoY3R4LT5kZXYpOwo+PiArCXUzMiBvZmZzZXQgPSAwOwo+ PiArCXVuc2lnbmVkIHNob3J0IGRhdGFfdG1wWzB4MTAwXTsKPj4gKwl1MzIgbWF4X3JlZmVyZW5j ZV9zaXplID0gVjRMMl9IMjY0X05VTV9EUEJfRU5UUklFUzsKPj4gKwl1MzIgbWF4X2xpc3Rfc2l6 ZTsKPj4gKwlpbnQgaSwgaWk7Cj4+ICsKPj4gKwltZW1zZXQocHBzX2Jhc2UsIDAsIDB4MTAwKTsK Pj4gKwo+PiArCWRhdGFfdG1wW29mZnNldCsrXSA9IFBBUkFNX0JBU0VfVkFMOwo+PiArCj4+ICsJ ZGF0YV90bXBbb2Zmc2V0KytdID0KPj4gKwkJR0VUX1BQU19QSUNfUEFSQU1fU0VUX0lEKHBwcy0+ cGljX3BhcmFtZXRlcl9zZXRfaWQpIHwKPj4gKwnCoMKgwqAgR0VUX1BQU19TRVFfUEFSQU1fU0VU X0lEKHBwcy0+c2VxX3BhcmFtZXRlcl9zZXRfaWQpIHwKPj4gKwnCoMKgwqAgR0VUX1BQU19FTlRS T1BZX0NPRElOR19NT0RFX0ZMQUcKPj4gKwkJCShnZXRfZmxhZyhwcHMtPmZsYWdzLAo+PiArCQkJ CcKgIFY0TDJfSDI2NF9QUFNfRkxBR19FTlRST1BZX0NPRElOR19NT0RFKSkgfAo+PiArCcKgwqDC oCBHRVRfUFBTX1BJQ19PUkRFUl9QUkVTRU5UX0ZMQUcKPj4gKwkJCShnZXRfZmxhZyhwcHMtPmZs YWdzLAo+PiArCQkJCcKgIFY0TDJfSDI2NF9QUFNfRkxBR19CT1RUT01fRklFTERfUElDX09SREVS X0lOX0ZSQU1FX1BSRVNFTlQpKTsKPj4gKwo+PiArCWRhdGFfdG1wW29mZnNldCsrXSA9Cj4+ICsJ CUdFVF9QUFNfV0VJR0hURURfQklQUkVEX0lEQyhwcHMtPndlaWdodGVkX2JpcHJlZF9pZGMpIHwK Pj4gKwkJR0VUX1BQU19XRUlHSFRFRF9QUkVEX0ZMQUcoZ2V0X2ZsYWcocHBzLT5mbGFncywKPj4g KwkJCQkJCcKgwqDCoCBWNEwyX0gyNjRfUFBTX0ZMQUdfV0VJR0hURURfUFJFRCkpIHwKPj4gKwkJ R0VUX1BQU19OVU1fSURYX1JFRl9MMV9NSU5VUzEocHBzLT5udW1fcmVmX2lkeF9sMV9kZWZhdWx0 X2FjdGl2ZV9taW51czEpIHwKPj4gKwkJR0VUX1BQU19OVU1fSURYX1JFRl9MMF9NSU5VUzEocHBz LT5udW1fcmVmX2lkeF9sMF9kZWZhdWx0X2FjdGl2ZV9taW51czEpOwo+PiArCj4+ICsJZGF0YV90 bXBbb2Zmc2V0KytdID0gR0VUX1BQU19JTklUX1FTX01JTlVTMjYocHBzLT5waWNfaW5pdF9xc19t aW51czI2KSB8Cj4+ICsJwqDCoMKgIEdFVF9QUFNfSU5JVF9RUF9NSU5VUzI2KHBwcy0+cGljX2lu aXRfcXBfbWludXMyNik7Cj4+ICsKPj4gKwlkYXRhX3RtcFtvZmZzZXRdID0KPj4gKwnCoMKgwqAg R0VUX1BQU19DSFJPTUFfUVBfSU5ERVhfT0ZGU0VUKHBwcy0+Y2hyb21hX3FwX2luZGV4X29mZnNl dCkgfAo+PiArCcKgwqDCoCBHRVRfUFBTX0RFQkxPQ0tfRklMVEVSX0NUUkxfUFJFU0VOVF9GTEFH Cj4+ICsJCQkJKGdldF9mbGFnKHBwcy0+ZmxhZ3MsCj4+ICsJCQkJCcKgIFY0TDJfSDI2NF9QUFNf RkxBR19ERUJMT0NLSU5HX0ZJTFRFUl9DT05UUk9MX1BSRVNFTlQpKSB8Cj4+ICsJwqDCoMKgIEdF VF9QUFNfQ09OU1RSQUlOX0lOVFJBX1BSRURfRkxBRwo+PiArCQkJCShnZXRfZmxhZyhwcHMtPmZs YWdzLAo+PiArCQkJCQnCoCBWNEwyX0gyNjRfUFBTX0ZMQUdfQ09OU1RSQUlORURfSU5UUkFfUFJF RCkpIHwKPj4gKwnCoMKgwqAgR0VUX1BQU19SRURVTkRBTlRfUElDX0NOVF9QUkVTRU5UX0ZMQUcK Pj4gKwkJCQkoZ2V0X2ZsYWcocHBzLT5mbGFncywKPj4gKwkJCQkJwqAgVjRMMl9IMjY0X1BQU19G TEFHX1JFRFVOREFOVF9QSUNfQ05UX1BSRVNFTlQpKTsKPj4gKwlpZiAoZ2V0X2ZsYWcKPj4gKwnC oMKgwqAgKHBwcy0+ZmxhZ3MsCj4+ICsJwqDCoMKgwqAgVjRMMl9IMjY0X1BQU19GTEFHX1RSQU5T Rk9STV84WDhfTU9ERSB8Cj4+ICsJwqDCoMKgwqAgVjRMMl9IMjY0X1BQU19GTEFHX1NDQUxJTkdf TUFUUklYX1BSRVNFTlQpKQo+PiArCQlkYXRhX3RtcFtvZmZzZXRdIHw9ICgxIDw8IDExKTsKPj4g KwlvZmZzZXQrKzsKPj4gKwo+PiArCWRhdGFfdG1wW29mZnNldCsrXSA9Cj4+ICsJwqDCoMKgIEdF VF9QUFNfU0NBTElOR19NQVRSSVhfUFJFU0VOVF9GTEFHKGdldF9mbGFnCj4+ICsJCQkJCQkocHBz LT5mbGFncywKPj4gKwkJCQkJCSBWNEwyX0gyNjRfUFBTX0ZMQUdfU0NBTElOR19NQVRSSVhfUFJF U0VOVCkpIHwKPj4gKwnCoMKgwqAgR0VUX1BQU19UUkFOU0ZPUk1fOFg4X0ZMQUcoZ2V0X2ZsYWcK Pj4gKwkJCQnCoMKgwqDCoMKgwqAgKHBwcy0+ZmxhZ3MsCj4+ICsJCQkJCVY0TDJfSDI2NF9QUFNf RkxBR19UUkFOU0ZPUk1fOFg4X01PREUpKTsKPj4gKwo+PiArCWRhdGFfdG1wW29mZnNldCsrXSA9 Cj4+ICsJCUdFVF9QUFNfR0VUX1NFQ09ORF9DSFJPTUFfUVBfT0ZGU0VUKHBwcy0+c2Vjb25kX2No cm9tYV9xcF9pbmRleF9vZmZzZXQpOwo+PiArCj4+ICsJbWF4X2xpc3Rfc2l6ZSA9IChwcHMtPm51 bV9yZWZfaWR4X2wxX2RlZmF1bHRfYWN0aXZlX21pbnVzMSArIDEpICsKPj4gKwnCoMKgwqAgKHBw cy0+bnVtX3JlZl9pZHhfbDBfZGVmYXVsdF9hY3RpdmVfbWludXMxICsgMSk7Cj4+ICsKPj4gKwlo MjY0X2N0eC0+bWF4X251bV9yZWZfZnJhbWVzID0gbWF4X2xpc3Rfc2l6ZSA+IGgyNjRfY3R4LT5t YXhfbnVtX3JlZl9mcmFtZXMgPwo+PiArCQkJCQkJbWF4X2xpc3Rfc2l6ZSA6IGgyNjRfY3R4LT5t YXhfbnVtX3JlZl9mcmFtZXM7Cj4+ICsKPj4gKwlyZWdtYXBfd3JpdGUoaHctPm1hcFtET1NfQlVT XSwgQVZfU0NSQVRDSF8wLAo+PiArCQnCoMKgwqDCoCAoKGgyNjRfY3R4LT5tYXhfbnVtX3JlZl9m cmFtZXMgKyAxKSA8PCAyNCkgfAo+PiArCQnCoMKgwqDCoCAobWF4X3JlZmVyZW5jZV9zaXplIDw8 IDE2KSB8IChtYXhfcmVmZXJlbmNlX3NpemUgPDwgOCkpOwo+PiArCj4+ICsJZm9yIChpID0gMDsg aSA8IDB4MTAwOyBpICs9IDQpIHsKPj4gKwkJZm9yIChpaSA9IDA7IGlpIDwgNDsgaWkrKykKPj4g KwkJCXBwc19iYXNlW2kgKyAzIC0gaWldID0gZGF0YV90bXBbaSArIGlpXTsKPj4gKwl9Cj4+ICt9 Cj4+ICsKPj4gK3N0YXRpYyB2b2lkIGgyNjRfY29uZmlnX3BhcmFtcyhzdHJ1Y3QgYW1sX3ZkZWNf Y3R4ICpjdHgpCj4+ICt7Cj4+ICsJc3RydWN0IGFtbF9oMjY0X2N0eCAqaDI2NF9jdHggPSAoc3Ry dWN0IGFtbF9oMjY0X2N0eCAqKWN0eC0+Y29kZWNfcHJpdjsKPj4gKwl1bnNpZ25lZCBzaG9ydCAq cF9zcHNfYmFzZSwgKnBfcHBzX2Jhc2U7Cj4+ICsJc3RydWN0IHZkZWNfaDI2NF9zdGF0ZWxlc3Nf Y3RybF9yZWYgKmN0cmxzID0gJmgyNjRfY3R4LT5jdHJsX3JlZjsKPj4gKwljb25zdCBzdHJ1Y3Qg djRsMl9jdHJsX2gyNjRfc3BzICpzcHMgPSBjdHJscy0+c3BzOwo+PiArCWNvbnN0IHN0cnVjdCB2 NGwyX2N0cmxfaDI2NF9wcHMgKnBwcyA9IGN0cmxzLT5wcHM7Cj4+ICsKPj4gKwlwX3Nwc19iYXNl ID0gKHVuc2lnbmVkIHNob3J0ICopKGgyNjRfY3R4LT53b3Jrc3BhY2VfdmFkZHIgKwo+PiArCQlN RU1fU1BTX0JBU0UgKyBzcHMtPnNlcV9wYXJhbWV0ZXJfc2V0X2lkICogMHg0MDApOwo+PiArCXBf cHBzX2Jhc2UgPSAodW5zaWduZWQgc2hvcnQgKikoaDI2NF9jdHgtPndvcmtzcGFjZV92YWRkciAr Cj4+ICsJCU1FTV9QUFNfQkFTRSArIHBwcy0+cGljX3BhcmFtZXRlcl9zZXRfaWQgKiAweDIwMCk7 Cj4+ICsKPj4gKwljb25maWdfc3BzX3BhcmFtcyhoMjY0X2N0eCwgcF9zcHNfYmFzZSwgc3BzKTsK Pj4gKwljb25maWdfcHBzX3BhcmFtcyhoMjY0X2N0eCwgcF9wcHNfYmFzZSwgcHBzKTsKPj4gK30K Pj4gKwo+PiArc3RhdGljIHZvaWQgY29uZmlnX2RlY29kZV9jYW52YXMoc3RydWN0IGFtbF92ZGVj X2h3ICpodywKPj4gKwkJCQkgc3RydWN0IGgyNjRfZGVjb2RlX2J1Zl9zcGVjICpidWZfc3BlYywK Pj4gKwkJCQkgdTMyIG1iX3dpZHRoLCB1MzIgbWJfaGVpZ2h0KQo+PiArewo+PiArCWludCBjYW52 YXNfYWxsb2NfcmVzdWx0ID0gMDsKPj4gKwlpbnQgYmxrbW9kZSA9IDB4MDsKPj4gKwo+PiArCWNh bnZhc19hbGxvY19yZXN1bHQgPSBtZXNvbl9jYW52YXNfYWxsb2MoaHctPmNhbnZhcywgJmJ1Zl9z cGVjLT55X2NhbnZhc19pbmRleCk7Cj4+ICsJY2FudmFzX2FsbG9jX3Jlc3VsdCA9IG1lc29uX2Nh bnZhc19hbGxvYyhody0+Y2FudmFzLCAmYnVmX3NwZWMtPnVfY2FudmFzX2luZGV4KTsKPj4gKwli dWZfc3BlYy0+dl9jYW52YXNfaW5kZXggPSBidWZfc3BlYy0+dV9jYW52YXNfaW5kZXg7Cj4+ICsK Pj4gKwlpZiAoIWNhbnZhc19hbGxvY19yZXN1bHQpIHsKPj4gKwkJLyogY29uZmlnIHkgY2FudmFz ICovCj4+ICsJCW1lc29uX2NhbnZhc19jb25maWcoaHctPmNhbnZhcywKPj4gKwkJCQnCoMKgwqAg YnVmX3NwZWMtPnlfY2FudmFzX2luZGV4LCBidWZfc3BlYy0+eV9kbWFfYWRkciwKPj4gKwkJCQnC oMKgwqAgbWJfd2lkdGggPDwgNCwgbWJfaGVpZ2h0IDw8IDQsCj4+ICsJCQkJwqDCoMKgIE1FU09O X0NBTlZBU19XUkFQX05PTkUsIE1FU09OX0NBTlZBU19CTEtNT0RFX0xJTkVBUiwKPj4gKwkJCQnC oMKgwqAgTUVTT05fQ0FOVkFTX0VORElBTl9TV0FQNjQpOwo+PiArCQlyZWdtYXBfd3JpdGUoaHct Pm1hcFtET1NfQlVTXSwgVkRFQ19BU1NJU1RfQ0FOVkFTX0JMSzMyLAo+PiArCQkJwqDCoMKgwqAg KDEgPDwgMTEpIHwgLyogY2FudmFzX2JsazMyX3dyICovCj4+ICsJCQnCoMKgwqDCoCAoYmxrbW9k ZSA8PCAxMCkgfAkvKiBjYW52YXNfYmxrMzIgKi8KPj4gKwkJCcKgwqDCoMKgICgxIDw8IDgpIHwJ LyogY2FudmFzX2luZGV4X3dyICovCj4+ICsJCQnCoMKgwqDCoCAoYnVmX3NwZWMtPnlfY2FudmFz X2luZGV4IDw8IDApCS8qIGNhbnZhcyBpbmRleCAqLwo+PiArCQnCoMKgwqAgKTsKPj4gKwo+PiAr CQkvKiBjb25maWcgdXYgY2FudmFzICovCj4+ICsJCW1lc29uX2NhbnZhc19jb25maWcoaHctPmNh bnZhcywKPj4gKwkJCQnCoMKgwqAgYnVmX3NwZWMtPnVfY2FudmFzX2luZGV4LCBidWZfc3BlYy0+ Y19kbWFfYWRkciwKPj4gKwkJCQnCoMKgwqAgbWJfd2lkdGggPDwgNCwgbWJfaGVpZ2h0IDw8IDMs Cj4+ICsJCQkJwqDCoMKgIE1FU09OX0NBTlZBU19XUkFQX05PTkUsIE1FU09OX0NBTlZBU19CTEtN T0RFX0xJTkVBUiwKPj4gKwkJCQnCoMKgwqAgTUVTT05fQ0FOVkFTX0VORElBTl9TV0FQNjQpOwo+ PiArCQlyZWdtYXBfd3JpdGUoaHctPm1hcFtET1NfQlVTXSwgVkRFQ19BU1NJU1RfQ0FOVkFTX0JM SzMyLAo+PiArCQkJwqDCoMKgwqAgKDEgPDwgMTEpIHwgLyogY2FudmFzX2JsazMyX3dyICovCj4+ ICsJCQnCoMKgwqDCoCAoYmxrbW9kZSA8PCAxMCkgfAkvKiBjYW52YXNfYmxrMzIgKi8KPj4gKwkJ CcKgwqDCoMKgICgxIDw8IDgpIHwJLyogY2FudmFzX2luZGV4X3dyICovCj4+ICsJCQnCoMKgwqDC oCAoYnVmX3NwZWMtPnVfY2FudmFzX2luZGV4IDw8IDApCS8qIGNhbnZhcyBpbmRleCAqLwo+PiAr CQnCoMKgwqAgKTsKPj4gKwo+PiArCQlyZWdtYXBfd3JpdGUoaHctPm1hcFtET1NfQlVTXSwgQU5D MF9DQU5WQVNfQUREUiArIChidWZfc3BlYy0+Y2FudmFzX3BvcyA8PCAyKSwKPj4gKwkJCcKgwqDC oMKgIHNwZWMyY2FudmFzKGJ1Zl9zcGVjKSk7Cj4+ICsJfQo+PiArfQo+PiArCj4+ICtzdGF0aWMg aW50IGFsbG9jYXRlX2NvbG9jYXRlX2J1ZihzdHJ1Y3QgYW1sX2gyNjRfY3R4ICpoMjY0X2N0eCwg aW50IHBvYykKPj4gK3sKPj4gKwlpbnQgaTsKPj4gKwlzdHJ1Y3QgYW1sX3ZkZWNfY3R4ICpjdHgg PSBoMjY0X2N0eC0+djRsMl9jdHg7Cj4+ICsKPj4gKwlmb3IgKGkgPSAwOyBpIDwgaDI2NF9jdHgt PmNvbG9jYXRlZF9idWZfbnVtOyBpKyspIHsKPj4gKwkJaWYgKCgoaDI2NF9jdHgtPmNvbG9jYXRl ZF9idWZfbWFwID4+IGkpICYgMHgxKSA9PSAwKSB7Cj4+ICsJCQloMjY0X2N0eC0+Y29sb2NhdGVk X2J1Zl9tYXAgfD0gKDEgPDwgaSk7Cj4+ICsJCQlicmVhazsKPj4gKwkJfQo+PiArCX0KPj4gKwo+ PiArCWlmIChpID09IGgyNjRfY3R4LT5jb2xvY2F0ZWRfYnVmX251bSkKPj4gKwkJcmV0dXJuIC0x Owo+PiArCj4+ICsJaDI2NF9jdHgtPmNvbG9jYXRlZF9idWZfcG9jW2ldID0gcG9jOwo+PiArCWRl dl9kYmcoJmN0eC0+ZGV2LT5wbGF0X2Rldi0+ZGV2LCAiJXMgY29sb2NhdGVkX2J1Zl9pbmRleCAl ZCBwb2MgJWRcbiIsIF9fZnVuY19fLCBpLAo+PiArCQloMjY0X2N0eC0+Y29sb2NhdGVkX2J1Zl9w b2NbaV0pOwo+PiArCj4+ICsJcmV0dXJuIGk7Cj4+ICt9Cj4+ICsKPj4gK3N0YXRpYyB2b2lkIHJl bGVhc2VfY29sb2NhdGVfYnVmKHN0cnVjdCBhbWxfaDI2NF9jdHggKmgyNjRfY3R4LCBpbnQgaW5k ZXgpCj4+ICt7Cj4+ICsJc3RydWN0IGFtbF92ZGVjX2N0eCAqY3R4ID0gaDI2NF9jdHgtPnY0bDJf Y3R4Owo+PiArCj4+ICsJaWYgKGluZGV4ID49IDApIHsKPj4gKwkJaWYgKGluZGV4ID49IGgyNjRf Y3R4LT5jb2xvY2F0ZWRfYnVmX251bSkgewo+PiArCQkJZGV2X2RiZwo+PiArCQkJwqDCoMKgICgm Y3R4LT5kZXYtPnBsYXRfZGV2LT5kZXYsCj4+ICsJCQkJICIlcyBlcnJvciwgaW5kZXggJWQgaXMg YmlnZ2VyIHRoYW4gYnVmIGNvdW50ICVkXG4iLAo+PiArCQkJwqDCoMKgwqAgX19mdW5jX18sIGlu ZGV4LCBoMjY0X2N0eC0+bWF4X251bV9yZWZfZnJhbWVzKTsKPj4gKwkJfSBlbHNlIHsKPj4gKwkJ CWlmIChoMjY0X2N0eC0+Y29sb2NhdGVkX2J1Zl9wb2NbaW5kZXhdICE9IElOVkFMSURfUE9DICYm Cj4+ICsJCQnCoMKgwqAgKChoMjY0X2N0eC0+Y29sb2NhdGVkX2J1Zl9tYXAgPj4gaW5kZXgpICYg MHgxKSA9PSAweDEpIHsKPj4gKwkJCQloMjY0X2N0eC0+Y29sb2NhdGVkX2J1Zl9tYXAgJj0gKH4o MSA8PCBpbmRleCkpOwo+PiArCQkJCWRldl9kYmcKPj4gKwkJCQnCoMKgwqAgKCZjdHgtPmRldi0+ cGxhdF9kZXYtPmRldiwKPj4gKwkJCQnCoMKgwqDCoCAiJXMgY29sb2NhdGVkX2J1Zl9pbmRleCAl ZCByZWxlYXNlZCBwb2MgJWRcbiIsCj4+ICsJCQkJwqDCoMKgwqAgX19mdW5jX18sIGluZGV4LAo+ PiArCQkJCcKgwqDCoMKgIGgyNjRfY3R4LT5jb2xvY2F0ZWRfYnVmX3BvY1tpbmRleF0pOwo+PiAr CQkJfQo+PiArCQkJaDI2NF9jdHgtPmNvbG9jYXRlZF9idWZfcG9jW2luZGV4XSA9IElOVkFMSURf UE9DOwo+PiArCQl9Cj4+ICsJfQo+PiArfQo+PiArCj4+ICtzdGF0aWMgaW50IGdldF9jb2xfYnVm X2luZGV4X2J5X3BvYyhzdHJ1Y3QgYW1sX2gyNjRfY3R4ICpoMjY0X2N0eCwgaW50IHBvYykKPj4g K3sKPj4gKwlpbnQgaWR4Owo+PiArCj4+ICsJZm9yIChpZHggPSAwOyBpZHggPCBoMjY0X2N0eC0+ Y29sb2NhdGVkX2J1Zl9udW07IGlkeCsrKSB7Cj4+ICsJCWlmIChoMjY0X2N0eC0+Y29sb2NhdGVk X2J1Zl9wb2NbaWR4XSA9PSBwb2MpCj4+ICsJCQlicmVhazsKPj4gKwl9Cj4+ICsKPj4gKwlpZiAo aWR4ID09IGgyNjRfY3R4LT5jb2xvY2F0ZWRfYnVmX251bSkKPj4gKwkJaWR4ID0gLTE7Cj4+ICsK Pj4gKwlyZXR1cm4gaWR4Owo+PiArfQo+PiArCj4+ICtzdGF0aWMgaW50IGFsbG9jX2NvbG9jYXRl X2NtYShzdHJ1Y3QgYW1sX2gyNjRfY3R4ICpoMjY0X2N0eCwKPj4gKwkJCcKgwqDCoMKgwqAgc3Ry dWN0IGFtbF92ZGVjX2N0eCAqY3R4KQo+PiArewo+PiArCWludCBhbGxvY19zaXplID0gMDsKPj4g KwlpbnQgaTsKPj4gKwlzdHJ1Y3QgYW1sX3ZkZWNfaHcgKmh3Owo+PiArCj4+ICsJaWYgKGgyNjRf Y3R4LT5jb2xsYXRlZF9jbWFfdmFkZHIpCj4+ICsJCXJldHVybiAwOwo+PiArCj4+ICsJaHcgPSB2 ZGVjX2dldF9odyhjdHgtPmRldik7Cj4+ICsJaWYgKCFodykKPj4gKwkJcmV0dXJuIC0xOwo+PiAr Cj4+ICsJLyogOTYgOmNvbCBidWYgc2l6ZSBmb3IgZWFjaCBtYiAqLwo+PiArCWgyNjRfY3R4LT5v bmVfY29sX2J1Zl9zaXplID0gaDI2NF9jdHgtPm1iX3RvdGFsICogOTY7Cj4+ICsJYWxsb2Nfc2l6 ZSA9IFBBR0VfQUxJR04oaDI2NF9jdHgtPm9uZV9jb2xfYnVmX3NpemUgKgo+PiArCQkJKGgyNjRf Y3R4LT5tYXhfbnVtX3JlZl9mcmFtZXMgKyBDT0xfQlVGRkVSX01BUkdJTikpOwo+PiArCWgyNjRf Y3R4LT5jb2xsYXRlZF9jbWFfdmFkZHIgPSBkbWFfYWxsb2NfY29oZXJlbnQoaHctPmRldiwgYWxs b2Nfc2l6ZSwKPj4gKwkJCQkJCQnCoCAmaDI2NF9jdHgtPmNvbGxhdGVkX2NtYV9hZGRyLCBHRlBf S0VSTkVMKTsKPj4gKwlpZiAoIWgyNjRfY3R4LT5jb2xsYXRlZF9jbWFfdmFkZHIpCj4+ICsJCXJl dHVybiAtRU5PTUVNOwo+PiArCj4+ICsJZGV2X2RiZwo+PiArCcKgwqDCoCAoJmN0eC0+ZGV2LT5w bGF0X2Rldi0+ZGV2LAo+PiArCcKgwqDCoCAiY29sbGF0ZWRfY21hX2FkZHIgPSAweCVsbHgsIG9u ZV9jb2xfYnVmX3NpemUgPSAleCBhbGxvY19zaXplID0gJXhcbiIsCj4+ICsJwqDCoMKgwqAgaDI2 NF9jdHgtPmNvbGxhdGVkX2NtYV9hZGRyLCBoMjY0X2N0eC0+b25lX2NvbF9idWZfc2l6ZSwKPj4g KwnCoMKgwqDCoCBhbGxvY19zaXplKTsKPj4gKwloMjY0X2N0eC0+Y29sbGF0ZWRfY21hX2FkZHJf ZW5kID0KPj4gKwnCoMKgwqAgaDI2NF9jdHgtPmNvbGxhdGVkX2NtYV9hZGRyICsgYWxsb2Nfc2l6 ZTsKPj4gKwltZW1zZXQoaDI2NF9jdHgtPmNvbGxhdGVkX2NtYV92YWRkciwgMCwgYWxsb2Nfc2l6 ZSk7Cj4+ICsJaDI2NF9jdHgtPmNvbF9idWZfYWxsb2Nfc2l6ZSA9IGFsbG9jX3NpemU7Cj4+ICsJ aDI2NF9jdHgtPmNvbG9jYXRlZF9idWZfbWFwID0gMDsKPj4gKwloMjY0X2N0eC0+Y29sb2NhdGVk X2J1Zl9udW0gPSBoMjY0X2N0eC0+bWF4X251bV9yZWZfZnJhbWVzICsgQ09MX0JVRkZFUl9NQVJH SU47Cj4+ICsKPj4gKwlmb3IgKGkgPSAwOyBpIDwgSDI2NF9NQVhfQ09MX0JVRjsgaSsrKQo+PiAr CQloMjY0X2N0eC0+Y29sb2NhdGVkX2J1Zl9wb2NbaV0gPSBJTlZBTElEX1BPQzsKPj4gKwo+PiAr CXJldHVybiAwOwo+PiArfQo+PiArCj4+ICtzdGF0aWMgdm9pZCBjb25maWdfcF9yZWZsaXN0KHN0 cnVjdCBhbWxfaDI2NF9jdHggKmgyNjRfY3R4LAo+PiArCQkJwqDCoMKgwqAgc3RydWN0IHY0bDJf aDI2NF9yZWZlcmVuY2UgKnY0bDJfcDBfcmVmbGlzdCwKPj4gKwkJCcKgwqDCoMKgIHUzMiBsaXN0 X3NpemUpCj4+ICt7Cj4+ICsJc3RydWN0IHZkZWNfaDI2NF9zdGF0ZWxlc3NfY3RybF9yZWYgKmN0 cmxzID0gJmgyNjRfY3R4LT5jdHJsX3JlZjsKPj4gKwlzdHJ1Y3QgdjRsMl9jdHJsX2gyNjRfZGVj b2RlX3BhcmFtcyAqZGVjb2RlID0KPj4gKwnCoMKgwqAgKHN0cnVjdCB2NGwyX2N0cmxfaDI2NF9k ZWNvZGVfcGFyYW1zICopY3RybHMtPmRlY29kZTsKPj4gKwlzdHJ1Y3QgdjRsMl9oMjY0X2RwYl9l bnRyeSAqZHBiID0gZGVjb2RlLT5kcGI7Cj4+ICsJdTggaW5kZXg7Cj4+ICsJaW50IGk7Cj4+ICsK Pj4gKwlmb3IgKGkgPSAwOyBpIDwgbGlzdF9zaXplOyBpKyspIHsKPj4gKwkJaW5kZXggPSB2NGwy X3AwX3JlZmxpc3RbaV0uaW5kZXg7Cj4+ICsJCWgyNjRfY3R4LT5yZWZfbGlzdDBbaV0udXNlZCA9 IDE7Cj4+ICsJCWgyNjRfY3R4LT5yZWZfbGlzdDBbaV0uZHBiID0gJmRwYltpbmRleF07Cj4+ICsJ CWgyNjRfY3R4LT5yZWZfbGlzdDBbaV0ucG9jID0gZHBiW2luZGV4XS50b3BfZmllbGRfb3JkZXJf Y250Owo+PiArCQloMjY0X2N0eC0+cmVmX2xpc3QwW2ldLmxvbmdfdGVybV9mbGFnID0KPj4gKwkJ wqDCoMKgIGRwYltpbmRleF0uZmxhZ3MgJiBWNEwyX0gyNjRfRFBCX0VOVFJZX0ZMQUdfTE9OR19U RVJNID8gdHJ1ZSA6IGZhbHNlOwo+PiArCQloMjY0X2N0eC0+cmVmX2xpc3QwW2ldLmRwYl9pbmRl eCA9IGluZGV4Owo+PiArCX0KPj4gKwloMjY0X2N0eC0+bGlzdF9zaXplWzBdID0gaTsKPj4gK30K Pj4gKwo+PiArc3RhdGljIHZvaWQgY29uZmlnX2JfcmVmbGlzdChzdHJ1Y3QgYW1sX2gyNjRfY3R4 ICpoMjY0X2N0eCwKPj4gKwkJCcKgwqDCoMKgIHN0cnVjdCB2NGwyX2gyNjRfcmVmZXJlbmNlICp2 NGwyX2IwX3JlZmxpc3QsCj4+ICsJCQnCoMKgwqDCoCBzdHJ1Y3QgdjRsMl9oMjY0X3JlZmVyZW5j ZSAqdjRsMl9iMV9yZWZsaXN0LAo+PiArCQkJwqDCoMKgwqAgdTMyIGxpc3Rfc2l6ZSkKPj4gK3sK Pj4gKwlzdHJ1Y3QgYW1sX3ZkZWNfY3R4ICpjdHggPSBoMjY0X2N0eC0+djRsMl9jdHg7Cj4+ICsJ c3RydWN0IHZkZWNfaDI2NF9zdGF0ZWxlc3NfY3RybF9yZWYgKmN0cmxzID0gJmgyNjRfY3R4LT5j dHJsX3JlZjsKPj4gKwlzdHJ1Y3QgdjRsMl9jdHJsX2gyNjRfZGVjb2RlX3BhcmFtcyAqZGVjb2Rl ID0KPj4gKwnCoMKgwqAgKHN0cnVjdCB2NGwyX2N0cmxfaDI2NF9kZWNvZGVfcGFyYW1zICopY3Ry bHMtPmRlY29kZTsKPj4gKwlzdHJ1Y3QgdjRsMl9oMjY0X2RwYl9lbnRyeSAqZHBiID0gZGVjb2Rl LT5kcGI7Cj4+ICsJc3RydWN0IHNsaWNlICpjdXJyX3NsaWNlID0gJmgyNjRfY3R4LT5tc2xpY2U7 Cj4+ICsJdTggaW5kZXg7Cj4+ICsJaW50IGksIGo7Cj4+ICsKPj4gKwloMjY0X2N0eC0+bGlzdF9z aXplWzBdID0gY3Vycl9zbGljZS0+bnVtX3JlZl9pZHhfbDA7Cj4+ICsJZm9yIChpID0gMDsgaSA8 IGxpc3Rfc2l6ZSAmJiBpIDwgY3Vycl9zbGljZS0+bnVtX3JlZl9pZHhfbDA7IGkrKykgewo+PiAr CQlpbmRleCA9IHY0bDJfYjBfcmVmbGlzdFtpXS5pbmRleDsKPj4gKwkJaDI2NF9jdHgtPnJlZl9s aXN0MFtpXS51c2VkID0gMTsKPj4gKwkJaDI2NF9jdHgtPnJlZl9saXN0MFtpXS5kcGIgPSAmZHBi W2luZGV4XTsKPj4gKwkJaDI2NF9jdHgtPnJlZl9saXN0MFtpXS5wb2MgPSBkcGJbaW5kZXhdLnRv cF9maWVsZF9vcmRlcl9jbnQ7Cj4+ICsJCWgyNjRfY3R4LT5yZWZfbGlzdDBbaV0ubG9uZ190ZXJt X2ZsYWcgPQo+PiArCQnCoMKgwqAgZHBiW2luZGV4XS5mbGFncyAmIFY0TDJfSDI2NF9EUEJfRU5U UllfRkxBR19MT05HX1RFUk0gPyB0cnVlIDogZmFsc2U7Cj4+ICsJCWgyNjRfY3R4LT5yZWZfbGlz dDBbaV0uY29sX2J1Zl9pbmRleCA9Cj4+ICsJCQlnZXRfY29sX2J1Zl9pbmRleF9ieV9wb2MoaDI2 NF9jdHgsIGRwYltpbmRleF0udG9wX2ZpZWxkX29yZGVyX2NudCk7Cj4+ICsJCWgyNjRfY3R4LT5y ZWZfbGlzdDBbaV0uZHBiX2luZGV4ID0gaW5kZXg7Cj4+ICsJfQo+PiArCj4+ICsJaDI2NF9jdHgt Pmxpc3Rfc2l6ZVsxXSA9IGN1cnJfc2xpY2UtPm51bV9yZWZfaWR4X2wxOwo+PiArCWZvciAoaiA9 IDA7IGogPCBsaXN0X3NpemUgJiYgaiA8IGN1cnJfc2xpY2UtPm51bV9yZWZfaWR4X2wxOyBqKysp IHsKPj4gKwkJaW5kZXggPSB2NGwyX2IxX3JlZmxpc3Rbal0uaW5kZXg7Cj4+ICsJCWgyNjRfY3R4 LT5yZWZfbGlzdDFbal0udXNlZCA9IDE7Cj4+ICsJCWgyNjRfY3R4LT5yZWZfbGlzdDFbal0uZHBi ID0gJmRwYltpbmRleF07Cj4+ICsJCWgyNjRfY3R4LT5yZWZfbGlzdDFbal0ucG9jID0gZHBiW2lu ZGV4XS50b3BfZmllbGRfb3JkZXJfY250Owo+PiArCQloMjY0X2N0eC0+cmVmX2xpc3QxW2pdLmxv bmdfdGVybV9mbGFnID0KPj4gKwkJwqDCoMKgIGRwYltpbmRleF0uZmxhZ3MgJiBWNEwyX0gyNjRf RFBCX0VOVFJZX0ZMQUdfTE9OR19URVJNID8gdHJ1ZSA6IGZhbHNlOwo+PiArCQloMjY0X2N0eC0+ cmVmX2xpc3QxW2pdLmNvbF9idWZfaW5kZXggPQo+PiArCQkJZ2V0X2NvbF9idWZfaW5kZXhfYnlf cG9jKGgyNjRfY3R4LCBkcGJbaW5kZXhdLnRvcF9maWVsZF9vcmRlcl9jbnQpOwo+PiArCQloMjY0 X2N0eC0+cmVmX2xpc3QxW2pdLmRwYl9pbmRleCA9IGluZGV4Owo+PiArCX0KPj4gKwo+PiArCWlm ICgoaDI2NF9jdHgtPmxpc3Rfc2l6ZVsxXSArIGgyNjRfY3R4LT5saXN0X3NpemVbMF0pIDwgbGlz dF9zaXplKQo+PiArCQlkZXZfaW5mbygmY3R4LT5kZXYtPnBsYXRfZGV2LT5kZXYsICJyZWYgbGlz dCBpbmNvcnJlY3QgbGlzdDAgJWQgbGlzdDAgJWQgbGlzdF9zaXplJWRcbiIsCj4+ICsJCQkgaDI2 NF9jdHgtPmxpc3Rfc2l6ZVswXSwgaDI2NF9jdHgtPmxpc3Rfc2l6ZVsxXSwgbGlzdF9zaXplKTsK Pj4gK30KPj4gKwo+PiArc3RhdGljIGludCBwb2NfaXNfaW5fZHBiKGludCBwb2MsIGNvbnN0IHN0 cnVjdCB2NGwyX2gyNjRfZHBiX2VudHJ5ICpkcGIpCj4+ICt7Cj4+ICsJaW50IGk7Cj4+ICsJaW50 IHJldCA9IDA7Cj4+ICsKPj4gKwlmb3IgKGkgPSAwOyBpIDwgVjRMMl9IMjY0X05VTV9EUEJfRU5U UklFUzsgaSsrKSB7Cj4+ICsJCWlmIChwb2MgPT0gZHBiW2ldLnRvcF9maWVsZF9vcmRlcl9jbnQp IHsKPj4gKwkJCXJldCA9IDE7Cj4+ICsJCQlicmVhazsKPj4gKwkJfQo+PiArCX0KPj4gKwo+PiAr CXJldHVybiByZXQ7Cj4+ICt9Cj4+ICsKPj4gK3N0YXRpYyBpbnQgZ2V0X3JlZl9saXN0X3NpemUo c3RydWN0IGFtbF9oMjY0X2N0eCAqaDI2NF9jdHgsIGludCBjdXJfbGlzdCkKPj4gK3sKPj4gKwlz dHJ1Y3QgYW1sX3ZkZWNfY3R4ICpjdHggPSBoMjY0X2N0eC0+djRsMl9jdHg7Cj4+ICsJdW5zaWdu ZWQgc2hvcnQgb3ZlcnJpZGVfZmxhZyA9IGgyNjRfY3R4LT5kcGJfcGFyYW0ubC5kYXRhW1JFRl9J RENfT1ZFUlJJREVfRkxBR107Cj4+ICsJaW50IG51bV9yZWZfaWR4X2x4X2FjdGl2ZV9taW51czE7 Cj4+ICsKPj4gKwlpZiAoY3VyX2xpc3QgPT0gMCkgewo+PiArCQludW1fcmVmX2lkeF9seF9hY3Rp dmVfbWludXMxID0KPj4gKwkJCWgyNjRfY3R4LT5jdHJsX3JlZi5wcHMtPm51bV9yZWZfaWR4X2ww X2RlZmF1bHRfYWN0aXZlX21pbnVzMTsKPj4gKwkJaWYgKG92ZXJyaWRlX2ZsYWcpCj4+ICsJCQlu dW1fcmVmX2lkeF9seF9hY3RpdmVfbWludXMxID0KPj4gKwkJCQloMjY0X2N0eC0+ZHBiX3BhcmFt LmRwYi5udW1fcmVmX2lkeF9sMF9hY3RpdmVfbWludXMxOwo+PiArCX0gZWxzZSB7Cj4+ICsJCW51 bV9yZWZfaWR4X2x4X2FjdGl2ZV9taW51czEgPQo+PiArCQkJaDI2NF9jdHgtPmN0cmxfcmVmLnBw cy0+bnVtX3JlZl9pZHhfbDFfZGVmYXVsdF9hY3RpdmVfbWludXMxOwo+PiArCX0KPj4gKwlkZXZf ZGJnKCZjdHgtPmRldi0+cGxhdF9kZXYtPmRldiwgIiVzIGdldCBsaXN0ICVkIHNpemUgJWRcbiIs Cj4+ICsJCV9fZnVuY19fLCBjdXJfbGlzdCwgbnVtX3JlZl9pZHhfbHhfYWN0aXZlX21pbnVzMSAr IDEpOwo+PiArCj4+ICsJcmV0dXJuIG51bV9yZWZfaWR4X2x4X2FjdGl2ZV9taW51czEgKyAxOwo+ PiArfQo+PiArCj4+ICtzdGF0aWMgaW50IGdldF9yZWZpZHhfYnlfcGljbnVtKHN0cnVjdCBhbWxf aDI2NF9jdHggKmgyNjRfY3R4LCBpbnQgcGljX251bSwKPj4gKwkJCQlpbnQgY3Vycl9saXN0KQo+ PiArewo+PiArCWludCBpOwo+PiArCXN0cnVjdCBoMjY0X2RlY29kZV9idWZfc3BlYyAqcmVmX2xp c3Q7Cj4+ICsKPj4gKwlpZiAoY3Vycl9saXN0ID09IDApCj4+ICsJCXJlZl9saXN0ID0gJmgyNjRf Y3R4LT5yZWZfbGlzdDBbMF07Cj4+ICsJZWxzZQo+PiArCQlyZWZfbGlzdCA9ICZoMjY0X2N0eC0+ cmVmX2xpc3QxWzBdOwo+PiArCj4+ICsJZm9yIChpID0gMDsgcmVmX2xpc3RbaV0uZHBiOyBpKysp IHsKPj4gKwkJaWYgKHBpY19udW0gPT0gcmVmX2xpc3RbaV0uZHBiLT5waWNfbnVtKQo+PiArCQkJ cmV0dXJuIGk7Cj4+ICsJfQo+PiArCj4+ICsJcmV0dXJuIC0xOwo+PiArfQo+PiArCj4+ICtzdGF0 aWMgc3RydWN0IGgyNjRfZGVjb2RlX2J1Zl9zcGVjICpnZXRfc3RfcmVmcGljX2J5X251bShzdHJ1 Y3QgYW1sX2gyNjRfY3R4ICpoMjY0X2N0eCwKPj4gKwkJCQkJCQkgaW50IHBpY19udW0sIGludCBj dXJyX2xpc3QpCj4+ICt7Cj4+ICsJaW50IGk7Cj4+ICsJc3RydWN0IGgyNjRfZGVjb2RlX2J1Zl9z cGVjICpyZWZfbGlzdDsKPj4gKwo+PiArCWlmIChjdXJyX2xpc3QgPT0gMCkKPj4gKwkJcmVmX2xp c3QgPSAmaDI2NF9jdHgtPnJlZl9saXN0MF91bnJlb3JkZXJlZFswXTsKPj4gKwllbHNlCj4+ICsJ CXJlZl9saXN0ID0gJmgyNjRfY3R4LT5yZWZfbGlzdDFfdW5yZW9yZGVyZWRbMF07Cj4+ICsKPj4g Kwlmb3IgKGkgPSAwOyByZWZfbGlzdFtpXS5kcGI7IGkrKykgewo+PiArCQlpZiAocGljX251bSA9 PSByZWZfbGlzdFtpXS5kcGItPnBpY19udW0gJiYgcmVmX2xpc3RbaV0ubG9uZ190ZXJtX2ZsYWcg PT0gMCkKPj4gKwkJCXJldHVybiAmcmVmX2xpc3RbaV07Cj4+ICsJfQo+PiArCj4+ICsJcmV0dXJu IE5VTEw7Cj4+ICt9Cj4+ICsKPj4gK3N0YXRpYyBzdHJ1Y3QgaDI2NF9kZWNvZGVfYnVmX3NwZWMg KmdldF9sdF9yZWZwaWNfYnlfbnVtKHN0cnVjdCBhbWxfaDI2NF9jdHggKmgyNjRfY3R4LAo+PiAr CQkJCQkJCSBpbnQgcGljX251bSwgaW50IGN1cnJfbGlzdCkKPj4gK3sKPj4gKwlpbnQgaTsKPj4g KwlzdHJ1Y3QgaDI2NF9kZWNvZGVfYnVmX3NwZWMgKnJlZl9saXN0Owo+PiArCj4+ICsJaWYgKGN1 cnJfbGlzdCA9PSAwKQo+PiArCQlyZWZfbGlzdCA9ICZoMjY0X2N0eC0+cmVmX2xpc3QwX3VucmVv cmRlcmVkWzBdOwo+PiArCWVsc2UKPj4gKwkJcmVmX2xpc3QgPSAmaDI2NF9jdHgtPnJlZl9saXN0 MV91bnJlb3JkZXJlZFswXTsKPj4gKwo+PiArCWZvciAoaSA9IDA7IHJlZl9saXN0W2ldLmRwYjsg aSsrKSB7Cj4+ICsJCWlmIChwaWNfbnVtID09IHJlZl9saXN0W2ldLmRwYi0+cGljX251bSAmJiBy ZWZfbGlzdFtpXS5sb25nX3Rlcm1fZmxhZyA9PSAxKQo+PiArCQkJcmV0dXJuICZyZWZfbGlzdFtp XTsKPj4gKwl9Cj4+ICsKPj4gKwlyZXR1cm4gTlVMTDsKPj4gK30KPj4gKwo+PiArc3RhdGljIHZv aWQgcmVvcmRlcl9zaG9ydF90ZXJtKHN0cnVjdCBzbGljZSAqY3Vycl9zbGljZSwgaW50IGN1cl9s aXN0LAo+PiArCQkJwqDCoMKgwqDCoMKgIGludCBwaWNfbnVtX2x4LCBpbnQgKnJlZl9pZHhfbHgp Cj4+ICt7Cj4+ICsJc3RydWN0IGFtbF9oMjY0X2N0eCAqaDI2NF9jdHggPSBjb250YWluZXJfb2Yo Y3Vycl9zbGljZSwgc3RydWN0IGFtbF9oMjY0X2N0eCwgbXNsaWNlKTsKPj4gKwlzdHJ1Y3QgYW1s X3ZkZWNfY3R4ICpjdHggPSBoMjY0X2N0eC0+djRsMl9jdHg7Cj4+ICsJaW50IGNfaWR4LCBuX2lk eDsKPj4gKwlpbnQgbnVtX3JlZl9pZHhfbHhfYWN0aXZlOwo+PiArCXN0cnVjdCBoMjY0X2RlY29k ZV9idWZfc3BlYyAqcGljX2x4ID0gTlVMTDsKPj4gKwlzdHJ1Y3QgaDI2NF9kZWNvZGVfYnVmX3Nw ZWMgKnJlZl9saXN0X3Jlb3JkZXJlZDsKPj4gKwo+PiArCWlmIChjdXJfbGlzdCA9PSAwKQo+PiAr CQlyZWZfbGlzdF9yZW9yZGVyZWQgPSAmaDI2NF9jdHgtPnJlZl9saXN0MFswXTsKPj4gKwllbHNl Cj4+ICsJCXJlZl9saXN0X3Jlb3JkZXJlZCA9ICZoMjY0X2N0eC0+cmVmX2xpc3QxWzBdOwo+PiAr Cj4+ICsJbnVtX3JlZl9pZHhfbHhfYWN0aXZlID0gZ2V0X3JlZl9saXN0X3NpemUoaDI2NF9jdHgs IGN1cl9saXN0KTsKPj4gKwo+PiArCS8qIGZpbmQgc2hvcnQtdGVybSByZWYgZnJhbWUgd2l0aCBw aWNfbnVtIGlzIHBpY19udW1fbHggKi8KPj4gKwlwaWNfbHggPSBnZXRfc3RfcmVmcGljX2J5X251 bShoMjY0X2N0eCwgcGljX251bV9seCwgY3VyX2xpc3QpOwo+PiArCWlmICghcGljX2x4KSB7Cj4+ ICsJCWRldl9kYmcoJmN0eC0+ZGV2LT5wbGF0X2Rldi0+ZGV2LCAiY2Fubm90IGZpbmQgc3QgcGlj X2x4IGZvciAlZFxuIiwgcGljX251bV9seCk7Cj4+ICsJCXJldHVybjsKPj4gKwl9Cj4+ICsKPj4g KwlpZiAoKnJlZl9pZHhfbHggPT0gZ2V0X3JlZmlkeF9ieV9waWNudW0oaDI2NF9jdHgsIHBpY19u dW1fbHgsIGN1cl9saXN0KSkgewo+PiArCQlkZXZfZGJnKCZjdHgtPmRldi0+cGxhdF9kZXYtPmRl diwgIm5vIG5lZWQgdG8gbW92ZSBwaWMgbHggJWRcbiIsICpyZWZfaWR4X2x4KTsKPj4gKwkJKnJl Zl9pZHhfbHggPSAqcmVmX2lkeF9seCArIDE7Cj4+ICsJCXJldHVybjsKPj4gKwl9Cj4+ICsKPj4g Kwlmb3IgKGNfaWR4ID0gbnVtX3JlZl9pZHhfbHhfYWN0aXZlOyBjX2lkeCA+ICpyZWZfaWR4X2x4 OyBjX2lkeC0tKQo+PiArCQltZW1jcHkoJnJlZl9saXN0X3Jlb3JkZXJlZFtjX2lkeF0sICZyZWZf bGlzdF9yZW9yZGVyZWRbY19pZHggLSAxXSwKPj4gKwkJwqDCoMKgwqDCoMKgIHNpemVvZihzdHJ1 Y3QgaDI2NF9kZWNvZGVfYnVmX3NwZWMpKTsKPj4gKwo+PiArCW1lbWNweSgmcmVmX2xpc3RfcmVv cmRlcmVkWypyZWZfaWR4X2x4XSwgcGljX2x4LCBzaXplb2Yoc3RydWN0IGgyNjRfZGVjb2RlX2J1 Zl9zcGVjKSk7Cj4+ICsJZGV2X2RiZygmY3R4LT5kZXYtPnBsYXRfZGV2LT5kZXYsICIlcyA6IFJl ZlBpY0xpc3RYWyVkIF0gPSBwaWMgJXAgcGljX251bSglZClcbiIsIF9fZnVuY19fLAo+PiArCQkq cmVmX2lkeF9seCwgcGljX2x4LCByZWZfbGlzdF9yZW9yZGVyZWRbKnJlZl9pZHhfbHhdLmRwYi0+ cGljX251bSk7Cj4+ICsJKnJlZl9pZHhfbHggPSAqcmVmX2lkeF9seCArIDE7Cj4+ICsKPj4gKwlu X2lkeCA9ICpyZWZfaWR4X2x4Owo+PiArCWZvciAoY19pZHggPSAqcmVmX2lkeF9seDsgY19pZHgg PD0gbnVtX3JlZl9pZHhfbHhfYWN0aXZlOyBjX2lkeCsrKSB7Cj4+ICsJCWlmIChyZWZfbGlzdF9y ZW9yZGVyZWRbY19pZHhdLmxvbmdfdGVybV9mbGFnIHx8ICFyZWZfbGlzdF9yZW9yZGVyZWRbY19p ZHhdLmRwYiB8fAo+PiArCQnCoMKgwqAgcmVmX2xpc3RfcmVvcmRlcmVkW2NfaWR4XS5kcGItPnBp Y19udW0gIT0gcGljX251bV9seCkKPj4gKwkJCW1lbWNweSgmcmVmX2xpc3RfcmVvcmRlcmVkW25f aWR4KytdLCAmcmVmX2xpc3RfcmVvcmRlcmVkW2NfaWR4XSwKPj4gKwkJCcKgwqDCoMKgwqDCoCBz aXplb2Yoc3RydWN0IGgyNjRfZGVjb2RlX2J1Zl9zcGVjKSk7Cj4+ICsJfQo+PiArCj4+ICsJaDI2 NF9jdHgtPmxpc3Rfc2l6ZVtjdXJfbGlzdF0gPSBudW1fcmVmX2lkeF9seF9hY3RpdmU7Cj4+ICt9 Cj4+ICsKPj4gK3N0YXRpYyB2b2lkIHJlb3JkZXJfbG9uZ190ZXJtKHN0cnVjdCBzbGljZSAqY3Vy cl9zbGljZSwgaW50IGN1cl9saXN0LAo+PiArCQkJwqDCoMKgwqDCoCBpbnQgbHRfcGljX251bSwg aW50ICpyZWZfaWR4X2x4KQo+PiArewo+PiArCXN0cnVjdCBhbWxfaDI2NF9jdHggKmgyNjRfY3R4 ID0gY29udGFpbmVyX29mKGN1cnJfc2xpY2UsIHN0cnVjdCBhbWxfaDI2NF9jdHgsIG1zbGljZSk7 Cj4+ICsJc3RydWN0IGFtbF92ZGVjX2N0eCAqY3R4ID0gaDI2NF9jdHgtPnY0bDJfY3R4Owo+PiAr CWludCBudW1fcmVmX2lkeF9seF9hY3RpdmU7Cj4+ICsJaW50IGNfaWR4LCBuX2lkeDsKPj4gKwlz dHJ1Y3QgaDI2NF9kZWNvZGVfYnVmX3NwZWMgKnJlZl9saXN0Owo+PiArCXN0cnVjdCBoMjY0X2Rl Y29kZV9idWZfc3BlYyAqcGljX2x0ID0gTlVMTDsKPj4gKwo+PiArCWlmIChjdXJfbGlzdCA9PSAw KQo+PiArCQlyZWZfbGlzdCA9ICZoMjY0X2N0eC0+cmVmX2xpc3QwWzBdOwo+PiArCWVsc2UKPj4g KwkJcmVmX2xpc3QgPSAmaDI2NF9jdHgtPnJlZl9saXN0MVswXTsKPj4gKwo+PiArCW51bV9yZWZf aWR4X2x4X2FjdGl2ZSA9IGdldF9yZWZfbGlzdF9zaXplKGgyNjRfY3R4LCBjdXJfbGlzdCk7Cj4+ ICsKPj4gKwkvKiBmaW5kIGxvbmctdGVybSByZWYgZnJhbWUgd2l0aCBwaWNfbnVtIGlzIGx0X3Bp Y19udW0gKi8KPj4gKwlwaWNfbHQgPSBnZXRfbHRfcmVmcGljX2J5X251bShoMjY0X2N0eCwgbHRf cGljX251bSwgY3VyX2xpc3QpOwo+PiArCWlmICghcGljX2x0KSB7Cj4+ICsJCWRldl9kYmcoJmN0 eC0+ZGV2LT5wbGF0X2Rldi0+ZGV2LCAiY2Fubm90IGZpbmQgbHQgcGljX2x4IGZvciAlZFxuIiwg bHRfcGljX251bSk7Cj4+ICsJCXJldHVybjsKPj4gKwl9Cj4+ICsKPj4gKwlpZiAoKnJlZl9pZHhf bHggPT0gZ2V0X3JlZmlkeF9ieV9waWNudW0oaDI2NF9jdHgsIGx0X3BpY19udW0sIGN1cl9saXN0 KSkgewo+PiArCQlkZXZfZGJnKCZjdHgtPmRldi0+cGxhdF9kZXYtPmRldiwgIm5vIG5lZWQgdG8g bW92ZSBwaWMgbHggJWRcbiIsICpyZWZfaWR4X2x4KTsKPj4gKwkJKnJlZl9pZHhfbHggPSAqcmVm X2lkeF9seCArIDE7Cj4+ICsJCXJldHVybjsKPj4gKwl9Cj4+ICsKPj4gKwlmb3IgKGNfaWR4ID0g bnVtX3JlZl9pZHhfbHhfYWN0aXZlOyBjX2lkeCA+ICpyZWZfaWR4X2x4OyBjX2lkeC0tKQo+PiAr CQltZW1jcHkoJnJlZl9saXN0W2NfaWR4XSwgJnJlZl9saXN0W2NfaWR4IC0gMV0sIHNpemVvZihz dHJ1Y3QgaDI2NF9kZWNvZGVfYnVmX3NwZWMpKTsKPj4gKwo+PiArCW1lbWNweSgmcmVmX2xpc3Rb KnJlZl9pZHhfbHhdLCBwaWNfbHQsIHNpemVvZihzdHJ1Y3QgaDI2NF9kZWNvZGVfYnVmX3NwZWMp KTsKPj4gKwlkZXZfZGJnKCZjdHgtPmRldi0+cGxhdF9kZXYtPmRldiwgIiVzIDogUmVmUGljTGlz dFhbJWQgXSA9IHBpYyAlcCBwaWNfbnVtKCVkKVxuIiwgX19mdW5jX18sCj4+ICsJCSpyZWZfaWR4 X2x4LCBwaWNfbHQsIHJlZl9saXN0WypyZWZfaWR4X2x4XS5kcGItPnBpY19udW0pOwo+PiArCSpy ZWZfaWR4X2x4ID0gKnJlZl9pZHhfbHggKyAxOwo+PiArCj4+ICsJbl9pZHggPSAqcmVmX2lkeF9s eDsKPj4gKwkvKiBQb2ludGVyIGRwYiBpcyBOVUxMIG1lYW5zIHRoaXMgaXMgYSBkdW1teSBmcmFt ZSBzdG9yZSAqLwo+PiArCWZvciAoY19pZHggPSAqcmVmX2lkeF9seDsgY19pZHggPD0gbnVtX3Jl Zl9pZHhfbHhfYWN0aXZlOyBjX2lkeCsrKSB7Cj4+ICsJCWlmICghcmVmX2xpc3RbY19pZHhdLmxv bmdfdGVybV9mbGFnIHx8ICFyZWZfbGlzdFtjX2lkeF0uZHBiIHx8Cj4+ICsJCcKgwqDCoCByZWZf bGlzdFtjX2lkeF0uZHBiLT5waWNfbnVtICE9IGx0X3BpY19udW0pCj4+ICsJCQltZW1jcHkoJnJl Zl9saXN0W25faWR4KytdLCAmcmVmX2xpc3RbY19pZHhdLAo+PiArCQkJwqDCoMKgwqDCoMKgIHNp emVvZihzdHJ1Y3QgaDI2NF9kZWNvZGVfYnVmX3NwZWMpKTsKPj4gKwl9Cj4+ICsKPj4gKwloMjY0 X2N0eC0+bGlzdF9zaXplW2N1cl9saXN0XSA9IG51bV9yZWZfaWR4X2x4X2FjdGl2ZTsKPj4gK30K Pj4gKwo+PiArc3RhdGljIHZvaWQgZ2V0X21vZGlmaWNhdGlvbl9jbWQodW5zaWduZWQgc2hvcnQg KnJlb3JkZXJfY21kLCBzdHJ1Y3Qgc2xpY2UgKmN1cnJfc2xpY2UsIGludCBsaXN0KQo+PiArewo+ PiArCWludCBpLCBqLCB2YWw7Cj4+ICsKPj4gKwl2YWwgPSBjdXJyX3NsaWNlLT5yZWZfcGljX2xp c3RfcmVvcmRlcmluZ19mbGFnW2xpc3RdOwo+PiArCWlmICh2YWwpIHsKPj4gKwkJaSA9IDA7Cj4+ ICsJCWogPSAwOwo+PiArCQlkbyB7Cj4+ICsJCQljdXJyX3NsaWNlLT5tb2RpZmljYXRpb25fb2Zf cGljX251bXNfaWRjW2xpc3RdW2ldID0KPj4gKwkJCQlyZW9yZGVyX2NtZFtqKytdOwo+PiArCQkJ aWYgKGogPj0gUkVPUkRFUl9DTURfTUFYKSB7Cj4+ICsJCQkJY3Vycl9zbGljZS0+bW9kaWZpY2F0 aW9uX29mX3BpY19udW1zX2lkY1tsaXN0XVtpXSA9IDA7Cj4+ICsJCQkJYnJlYWs7Cj4+ICsJCQl9 Cj4+ICsKPj4gKwkJCXZhbCA9IGN1cnJfc2xpY2UtPm1vZGlmaWNhdGlvbl9vZl9waWNfbnVtc19p ZGNbbGlzdF1baV07Cj4+ICsJCQlpZiAodmFsID09IDAgfHwgdmFsID09IDEpCj4+ICsJCQkJY3Vy cl9zbGljZS0+YWJzX2RpZmZfcGljX251bV9taW51czFbbGlzdF1baV0gPSByZW9yZGVyX2NtZFtq KytdOwo+PiArCQkJZWxzZSBpZiAodmFsID09IDIpCj4+ICsJCQkJY3Vycl9zbGljZS0+bG9uZ190 ZXJtX3BpY19pZHhbbGlzdF1baV0gPSByZW9yZGVyX2NtZFtqKytdOwo+PiArCj4+ICsJCQlpKys7 Cj4+ICsKPj4gKwkJCWlmIChpID49IFJFT1JERVJJTkdfQ09NTUFORF9NQVhfU0laRSkgewo+PiAr CQkJCWN1cnJfc2xpY2UtPnJlZl9waWNfbGlzdF9yZW9yZGVyaW5nX2ZsYWdbbGlzdF0gPSAwOwo+ PiArCQkJCWJyZWFrOwo+PiArCQkJfTsKPj4gKwkJCWlmIChqID4gUkVPUkRFUl9DTURfTUFYKSB7 Cj4+ICsJCQkJY3Vycl9zbGljZS0+cmVmX3BpY19saXN0X3Jlb3JkZXJpbmdfZmxhZ1tsaXN0XSA9 IDA7Cj4+ICsJCQkJYnJlYWs7Cj4+ICsJCQl9Owo+PiArCQl9IHdoaWxlICh2YWwgIT0gMyk7Cj4+ ICsJfQo+PiArfQo+PiArCj4+ICtzdGF0aWMgdm9pZCByZW9yZGVyX3BpY3Moc3RydWN0IGFtbF9o MjY0X2N0eCAqaDI2NF9jdHgsIHN0cnVjdCBzbGljZSAqY3Vycl9zbGljZSwgaW50IGN1cl9saXN0 KQo+PiArewo+PiArCXN0cnVjdCBhbWxfdmRlY19jdHggKmN0eCA9IGgyNjRfY3R4LT52NGwyX2N0 eDsKPj4gKwlpbnQgKm1vZGlmaWNhdGlvbl9vZl9waWNfbnVtc19pZGMgPQo+PiArCQljdXJyX3Ns aWNlLT5tb2RpZmljYXRpb25fb2ZfcGljX251bXNfaWRjW2N1cl9saXN0XTsKPj4gKwlpbnQgKmFi c19kaWZmX3BpY19udW1fbWludXMxID0KPj4gKwkJY3Vycl9zbGljZS0+YWJzX2RpZmZfcGljX251 bV9taW51czFbY3VyX2xpc3RdOwo+PiArCWludCAqbG9uZ190ZXJtX3BpY19pZHggPSBjdXJyX3Ns aWNlLT5sb25nX3Rlcm1fcGljX2lkeFtjdXJfbGlzdF07Cj4+ICsJaW50IHBpY19udW1fbHhfbm93 YXJwLCBwaWNfbnVtX2x4X3ByZWQsIHBpY19udW1fbHg7Cj4+ICsJaW50IGN1cnJfcGljX251bSA9 IGN1cnJfc2xpY2UtPmZyYW1lX251bTsKPj4gKwlpbnQgbWF4X3BpY19udW0gPSAxIDw8ICg0ICsg aDI2NF9jdHgtPmN0cmxfcmVmLnNwcy0+bG9nMl9tYXhfZnJhbWVfbnVtX21pbnVzNCk7Cj4+ICsJ aW50IHJlZl9pZHhfbHggPSAwOwo+PiArCWludCBub3dhcnBfdG1wID0gMDsKPj4gKwlpbnQgaTsK Pj4gKwo+PiArCXBpY19udW1fbHhfcHJlZCA9IGN1cnJfcGljX251bTsKPj4gKwlmb3IgKGkgPSAw OyBpIDwgUkVPUkRFUklOR19DT01NQU5EX01BWF9TSVpFICYmIG1vZGlmaWNhdGlvbl9vZl9waWNf bnVtc19pZGNbaV0gIT0gMzsgaSsrKSB7Cj4+ICsJCWlmIChtb2RpZmljYXRpb25fb2ZfcGljX251 bXNfaWRjW2ldID4gMykgewo+PiArCQkJZGV2X2luZm8oJmN0eC0+ZGV2LT5wbGF0X2Rldi0+ZGV2 LCAiZXJyb3IsIEludmFsaWQgbW9kaWZpY2F0aW9uX29mX3BpY19udW1zX2lkYyBjb21tYW5kXG4i KTsKPj4gKwkJCWJyZWFrOwo+PiArCQl9Cj4+ICsKPj4gKwkJaWYgKG1vZGlmaWNhdGlvbl9vZl9w aWNfbnVtc19pZGNbaV0gPCAyKSB7Cj4+ICsJCQlpZiAobW9kaWZpY2F0aW9uX29mX3BpY19udW1z X2lkY1tpXSA9PSAwKSB7Cj4+ICsJCQkJbm93YXJwX3RtcCA9IHBpY19udW1fbHhfcHJlZCAtIChh YnNfZGlmZl9waWNfbnVtX21pbnVzMVtpXSArIDEpOwo+PiArCQkJCXBpY19udW1fbHhfbm93YXJw ID0gbm93YXJwX3RtcCArIChub3dhcnBfdG1wIDwgMCA/IG1heF9waWNfbnVtIDogMCk7Cj4+ICsJ CQl9IGVsc2UgaWYgKG1vZGlmaWNhdGlvbl9vZl9waWNfbnVtc19pZGNbaV0gPT0gMSkgewo+PiAr CQkJCW5vd2FycF90bXAgPSBwaWNfbnVtX2x4X3ByZWQgKyAoYWJzX2RpZmZfcGljX251bV9taW51 czFbaV0gKyAxKTsKPj4gKwkJCQlwaWNfbnVtX2x4X25vd2FycCA9IG5vd2FycF90bXAgLQo+PiAr CQkJCQkobm93YXJwX3RtcCA+IG1heF9waWNfbnVtID8gbWF4X3BpY19udW0gOiAwKTsKPj4gKwkJ CX0KPj4gKwkJCXBpY19udW1fbHhfcHJlZCA9IHBpY19udW1fbHhfbm93YXJwOwo+PiArCQkJaWYg KHBpY19udW1fbHhfbm93YXJwID4gY3Vycl9waWNfbnVtKQo+PiArCQkJCXBpY19udW1fbHggPSBw aWNfbnVtX2x4X25vd2FycCAtIG1heF9waWNfbnVtOwo+PiArCQkJZWxzZQo+PiArCQkJCXBpY19u dW1fbHggPSBwaWNfbnVtX2x4X25vd2FycDsKPj4gKwo+PiArCQkJcmVvcmRlcl9zaG9ydF90ZXJt KGN1cnJfc2xpY2UsIGN1cl9saXN0LCBwaWNfbnVtX2x4LCAmcmVmX2lkeF9seCk7Cj4+ICsJCX0g ZWxzZSB7Cj4+ICsJCQlyZW9yZGVyX2xvbmdfdGVybShjdXJyX3NsaWNlLCBjdXJfbGlzdCwgbG9u Z190ZXJtX3BpY19pZHhbaV0sICZyZWZfaWR4X2x4KTsKPj4gKwkJfQo+PiArCX0KPj4gK30KPj4g Kwo+PiArc3RhdGljIHZvaWQgY29weV9yZWZfbGlzdChzdHJ1Y3QgYW1sX2gyNjRfY3R4ICpoMjY0 X2N0eCwgaW50IGN1cnJfbGlzdCkKPj4gK3sKPj4gKwlpZiAoY3Vycl9saXN0ID09IDApCj4+ICsJ CW1lbWNweShoMjY0X2N0eC0+cmVmX2xpc3QwX3VucmVvcmRlcmVkLCBoMjY0X2N0eC0+cmVmX2xp c3QwLAo+PiArCQnCoMKgwqDCoMKgwqAgc2l6ZW9mKGgyNjRfY3R4LT5yZWZfbGlzdDApKTsKPj4g KwllbHNlCj4+ICsJCW1lbWNweShoMjY0X2N0eC0+cmVmX2xpc3QxX3VucmVvcmRlcmVkLCBoMjY0 X2N0eC0+cmVmX2xpc3QwLAo+PiArCQnCoMKgwqDCoMKgwqAgc2l6ZW9mKGgyNjRfY3R4LT5yZWZf bGlzdDEpKTsKPj4gK30KPj4gKwo+PiArc3RhdGljIHZvaWQgaDI2NF9yZW9yZGVyX3JlZmxpc3Rz KHN0cnVjdCBhbWxfaDI2NF9jdHggKmgyNjRfY3R4KQo+PiArewo+PiArCXVuc2lnbmVkIHNob3J0 ICpyZW9yZGVyX2NtZDsKPj4gKwlzdHJ1Y3Qgc2xpY2UgKmN1cnJfc2xpY2UgPSAmaDI2NF9jdHgt Pm1zbGljZTsKPj4gKwo+PiArCWlmIChjdXJyX3NsaWNlLT5zbGljZV90eXBlICE9IElfU0xJQ0Ug JiYgY3Vycl9zbGljZS0+c2xpY2VfdHlwZSAhPSBTSV9TTElDRSkgewo+PiArCQlyZW9yZGVyX2Nt ZCA9ICZoMjY0X2N0eC0+ZHBiX3BhcmFtLm1tY28ubDBfcmVvcmRlcl9jbWRbMF07Cj4+ICsJCS8q IDM6cGFyc2VkIGJ5IHVjb2RlLCBtZWFucyBubyByZW9yZGVyIG5lZWRlZCAqLwo+PiArCQlpZiAo cmVvcmRlcl9jbWRbMF0gIT0gMykKPj4gKwkJCWN1cnJfc2xpY2UtPnJlZl9waWNfbGlzdF9yZW9y ZGVyaW5nX2ZsYWdbMF0gPSAxOwo+PiArCQllbHNlCj4+ICsJCQljdXJyX3NsaWNlLT5yZWZfcGlj X2xpc3RfcmVvcmRlcmluZ19mbGFnWzBdID0gMDsKPj4gKwo+PiArCQlnZXRfbW9kaWZpY2F0aW9u X2NtZChyZW9yZGVyX2NtZCwgY3Vycl9zbGljZSwgMCk7Cj4+ICsJfQo+PiArCj4+ICsJaWYgKGN1 cnJfc2xpY2UtPnNsaWNlX3R5cGUgPT0gQl9TTElDRSkgewo+PiArCQlyZW9yZGVyX2NtZCA9ICZo MjY0X2N0eC0+ZHBiX3BhcmFtLm1tY28ubDFfcmVvcmRlcl9jbWRbMF07Cj4+ICsJCS8qIDM6cGFy c2VkIGJ5IHVjb2RlLCBtZWFucyBubyByZW9yZGVyIG5lZWRlZCAqLwo+PiArCQlpZiAocmVvcmRl cl9jbWRbMF0gIT0gMykKPj4gKwkJCWN1cnJfc2xpY2UtPnJlZl9waWNfbGlzdF9yZW9yZGVyaW5n X2ZsYWdbMV0gPSAxOwo+PiArCQllbHNlCj4+ICsJCQljdXJyX3NsaWNlLT5yZWZfcGljX2xpc3Rf cmVvcmRlcmluZ19mbGFnWzFdID0gMDsKPj4gKwo+PiArCQlnZXRfbW9kaWZpY2F0aW9uX2NtZChy ZW9yZGVyX2NtZCwgY3Vycl9zbGljZSwgMSk7Cj4+ICsJfQo+PiArCj4+ICsJaWYgKGN1cnJfc2xp Y2UtPnNsaWNlX3R5cGUgIT0gSV9TTElDRSAmJgo+PiArCcKgwqDCoCBjdXJyX3NsaWNlLT5zbGlj ZV90eXBlICE9IFNJX1NMSUNFICYmCj4+ICsJwqDCoMKgIGN1cnJfc2xpY2UtPnJlZl9waWNfbGlz dF9yZW9yZGVyaW5nX2ZsYWdbMF0gIT0gMCkgewo+PiArCQljb3B5X3JlZl9saXN0KGgyNjRfY3R4 LCAwKTsKPj4gKwkJcmVvcmRlcl9waWNzKGgyNjRfY3R4LCBjdXJyX3NsaWNlLCAwKTsKPj4gKwl9 Cj4+ICsKPj4gKwlpZiAoY3Vycl9zbGljZS0+c2xpY2VfdHlwZSA9PSBCX1NMSUNFICYmIGN1cnJf c2xpY2UtPnJlZl9waWNfbGlzdF9yZW9yZGVyaW5nX2ZsYWdbMV0gIT0gMCkgewo+PiArCQljb3B5 X3JlZl9saXN0KGgyNjRfY3R4LCAxKTsKPj4gKwkJcmVvcmRlcl9waWNzKGgyNjRfY3R4LCBjdXJy X3NsaWNlLCAxKTsKPj4gKwl9Cj4+ICt9Cj4+ICsKPj4gK3N0YXRpYyB2b2lkIGgyNjRfY29uZmln X3JlZl9saXN0cyhzdHJ1Y3QgYW1sX3ZkZWNfY3R4ICpjdHgpCj4+ICt7Cj4+ICsJc3RydWN0IGFt bF9oMjY0X2N0eCAqaDI2NF9jdHggPSAoc3RydWN0IGFtbF9oMjY0X2N0eCAqKWN0eC0+Y29kZWNf cHJpdjsKPj4gKwlzdHJ1Y3QgdmRlY19oMjY0X3N0YXRlbGVzc19jdHJsX3JlZiAqY3RybHMgPSAm aDI2NF9jdHgtPmN0cmxfcmVmOwo+PiArCXN0cnVjdCB2NGwyX2N0cmxfaDI2NF9kZWNvZGVfcGFy YW1zICpkZWNvZGUgPQo+PiArCQkoc3RydWN0IHY0bDJfY3RybF9oMjY0X2RlY29kZV9wYXJhbXMg KiljdHJscy0+ZGVjb2RlOwo+PiArCXN0cnVjdCB2NGwyX2N0cmxfaDI2NF9zcHMgKnNwcyA9IChz dHJ1Y3QgdjRsMl9jdHJsX2gyNjRfc3BzICopY3RybHMtPnNwczsKPj4gKwljb25zdCBzdHJ1Y3Qg djRsMl9oMjY0X2RwYl9lbnRyeSAqZHBiID0gZGVjb2RlLT5kcGI7Cj4+ICsJc3RydWN0IHY0bDJf aDI2NF9yZWZsaXN0X2J1aWxkZXIgYnVpbGRlcjsKPj4gKwlzdHJ1Y3QgdjRsMl9oMjY0X3JlZmVy ZW5jZSB2NGwyX3AwX3JlZmxpc3RbVjRMMl9IMjY0X1JFRl9MSVNUX0xFTl07Cj4+ICsJc3RydWN0 IHY0bDJfaDI2NF9yZWZlcmVuY2UgdjRsMl9iMF9yZWZsaXN0W1Y0TDJfSDI2NF9SRUZfTElTVF9M RU5dOwo+PiArCXN0cnVjdCB2NGwyX2gyNjRfcmVmZXJlbmNlIHY0bDJfYjFfcmVmbGlzdFtWNEwy X0gyNjRfUkVGX0xJU1RfTEVOXTsKPj4gKwo+PiArCWlmIChkZWNvZGUtPmZsYWdzID09IFY0TDJf SDI2NF9ERUNPREVfUEFSQU1fRkxBR19JRFJfUElDKQo+PiArCQlyZXR1cm47Cj4+ICsKPj4gKwl2 NGwyX2gyNjRfaW5pdF9yZWZsaXN0X2J1aWxkZXIoJmJ1aWxkZXIsIGRlY29kZSwgc3BzLCBkcGIp Owo+PiArCWRldl9kYmcoJmN0eC0+ZGV2LT5wbGF0X2Rldi0+ZGV2LCAiJXMgbnVtX3ZhbGlkID0g JWQiLCBfX2Z1bmNfXywgYnVpbGRlci5udW1fdmFsaWQpOwo+PiArCj4+ICsJaWYgKGRlY29kZS0+ ZmxhZ3MgJiBWNEwyX0gyNjRfREVDT0RFX1BBUkFNX0ZMQUdfUEZSQU1FKSB7Cj4+ICsJCXY0bDJf aDI2NF9idWlsZF9wX3JlZl9saXN0KCZidWlsZGVyLCB2NGwyX3AwX3JlZmxpc3QpOwo+PiArCQlj b25maWdfcF9yZWZsaXN0KGgyNjRfY3R4LCB2NGwyX3AwX3JlZmxpc3QsIGJ1aWxkZXIubnVtX3Zh bGlkKTsKPj4gKwl9IGVsc2UgaWYgKGRlY29kZS0+ZmxhZ3MgJiBWNEwyX0gyNjRfREVDT0RFX1BB UkFNX0ZMQUdfQkZSQU1FKSB7Cj4+ICsJCXY0bDJfaDI2NF9idWlsZF9iX3JlZl9saXN0cygmYnVp bGRlciwgdjRsMl9iMF9yZWZsaXN0LCB2NGwyX2IxX3JlZmxpc3QpOwo+PiArCQljb25maWdfYl9y ZWZsaXN0KGgyNjRfY3R4LCB2NGwyX2IwX3JlZmxpc3QsIHY0bDJfYjFfcmVmbGlzdCwgYnVpbGRl ci5udW1fdmFsaWQpOwo+PiArCX0KPj4gK30KPj4gKwo+PiArc3RhdGljIHZvaWQgY2xlYXJfdW51 c2VkX2NvbF9idWYoc3RydWN0IGFtbF9oMjY0X2N0eCAqaDI2NF9jdHgsCj4+ICsJCQkJIHN0cnVj dCB2NGwyX2N0cmxfaDI2NF9kZWNvZGVfcGFyYW1zICpkZWNvZGUpCj4+ICt7Cj4+ICsJaW50IGks IGNvbF9wb2M7Cj4+ICsKPj4gKwkvKiBmbHVzaCBhbGwgY29sIGJ1ZmZlcnMgd2hlbiBJRFIgKi8K Pj4gKwlpZiAoZGVjb2RlLT5mbGFncyA9PSBWNEwyX0gyNjRfREVDT0RFX1BBUkFNX0ZMQUdfSURS X1BJQykgewo+PiArCQkvKiAzMiA6IG1heCBpbmRleCBvZiBjby1sb2NhdGUgYnVmZmVyICovCj4+ ICsJCWZvciAoaSA9IDA7IGkgPCAzMjsgaSsrKQo+PiArCQkJcmVsZWFzZV9jb2xvY2F0ZV9idWYo aDI2NF9jdHgsIGkpOwo+PiArCQlyZXR1cm47Cj4+ICsJfQo+PiArCj4+ICsJZm9yIChpID0gMDsg aSA8IGgyNjRfY3R4LT5jb2xvY2F0ZWRfYnVmX251bTsgaSsrKSB7Cj4+ICsJCWNvbF9wb2MgPSBo MjY0X2N0eC0+Y29sb2NhdGVkX2J1Zl9wb2NbaV07Cj4+ICsJCWlmIChjb2xfcG9jICE9IElOVkFM SURfUE9DICYmIChwb2NfaXNfaW5fZHBiKGNvbF9wb2MsIGRlY29kZS0+ZHBiKSAhPSAxKSkKPj4g KwkJCXJlbGVhc2VfY29sb2NhdGVfYnVmKGgyNjRfY3R4LCBpKTsKPj4gKwl9Cj4+ICt9Cj4+ICsK Pj4gK3N0YXRpYyB2b2lkIGgyNjRfY29uZmlnX2RlY29kZV9zcGVjKHN0cnVjdCBhbWxfdmRlY19o dyAqaHcsIHN0cnVjdCBhbWxfdmRlY19jdHggKmN0eCkKPj4gK3sKPj4gKwlzdHJ1Y3QgYW1sX2gy NjRfY3R4ICpoMjY0X2N0eCA9IChzdHJ1Y3QgYW1sX2gyNjRfY3R4ICopaHctPmN1cnJfY3R4Owo+ PiArCXN0cnVjdCB2ZGVjX2gyNjRfc3RhdGVsZXNzX2N0cmxfcmVmICpjdHJscyA9ICZoMjY0X2N0 eC0+Y3RybF9yZWY7Cj4+ICsJc3RydWN0IHY0bDJfY3RybF9oMjY0X2RlY29kZV9wYXJhbXMgKmRl Y29kZSA9Cj4+ICsJCShzdHJ1Y3QgdjRsMl9jdHJsX2gyNjRfZGVjb2RlX3BhcmFtcyAqKWN0cmxz LT5kZWNvZGU7Cj4+ICsJc3RydWN0IGgyNjRfZGVjb2RlX2J1Zl9zcGVjICpidWZfc3BlY19sMCwg KmJ1Zl9zcGVjX2wxOwo+PiArCXN0cnVjdCB2YjJfYnVmZmVyICp2YjsKPj4gKwlzdHJ1Y3QgdmIy X3Y0bDJfYnVmZmVyICp2YjJfdjRsMjsKPj4gKwlzdHJ1Y3QgdmIyX3F1ZXVlICp2cTsKPj4gKwlp bnQgaTsKPj4gKwo+PiArCWNsZWFyX3VudXNlZF9jb2xfYnVmKGgyNjRfY3R4LCBkZWNvZGUpOwo+ PiArCj4+ICsJdmIyX3Y0bDIgPSB2NGwyX20ybV9uZXh0X2RzdF9idWYoY3R4LT5tMm1fY3R4KTsK Pj4gKwl2YiA9ICZ2YjJfdjRsMi0+dmIyX2J1ZjsKPj4gKwo+PiArCWgyNjRfY3R4LT5jdXJyX3Nw ZWMueV9kbWFfYWRkciA9IHZiMl9kbWFfY29udGlnX3BsYW5lX2RtYV9hZGRyKHZiLCAwKTsKPj4g KwlpZiAoY3R4LT5waWNfaW5mby5wbGFuZV9udW0gPiAxKQo+PiArCQloMjY0X2N0eC0+Y3Vycl9z cGVjLmNfZG1hX2FkZHIgPSB2YjJfZG1hX2NvbnRpZ19wbGFuZV9kbWFfYWRkcih2YiwgMSk7Cj4+ ICsJZWxzZQo+PiArCQloMjY0X2N0eC0+Y3Vycl9zcGVjLmNfZG1hX2FkZHIgPQo+PiArCQkJCWgy NjRfY3R4LT5jdXJyX3NwZWMueV9kbWFfYWRkciArIGN0eC0+cGljX2luZm8uZmJfc2l6ZVswXTsK Pj4gKwloMjY0X2N0eC0+Y3Vycl9zcGVjLmNhbnZhc19wb3MgPSAwOwo+PiArCWlmIChkZWNvZGUt Pm5hbF9yZWZfaWRjKQo+PiArCQloMjY0X2N0eC0+Y3Vycl9zcGVjLmNvbF9idWZfaW5kZXggPQo+ PiArCQkJYWxsb2NhdGVfY29sb2NhdGVfYnVmKGgyNjRfY3R4LCBkZWNvZGUtPnRvcF9maWVsZF9v cmRlcl9jbnQpOwo+PiArCWVsc2UKPj4gKwkJaDI2NF9jdHgtPmN1cnJfc3BlYy5jb2xfYnVmX2lu ZGV4ID0gLTE7Cj4+ICsJaDI2NF9jdHgtPmN1cnJfc3BlYy5wb2MgPSBkZWNvZGUtPnRvcF9maWVs ZF9vcmRlcl9jbnQ7Cj4+ICsJY29uZmlnX2RlY29kZV9jYW52YXMoaHcsICZoMjY0X2N0eC0+Y3Vy cl9zcGVjLCBoMjY0X2N0eC0+bWJfd2lkdGgsIGgyNjRfY3R4LT5tYl9oZWlnaHQpOwo+PiArCWgy NjRfY3R4LT5jYW52YXNfcG9zX3BvY1swXSA9IGRlY29kZS0+dG9wX2ZpZWxkX29yZGVyX2NudDsK Pj4gKwo+PiArCWgyNjRfY29uZmlnX3JlZl9saXN0cyhjdHgpOwo+PiArCj4+ICsJdnEgPSB2NGwy X20ybV9nZXRfdnEoY3R4LT5tMm1fY3R4LCBWNEwyX0JVRl9UWVBFX1ZJREVPX0NBUFRVUkVfTVBM QU5FKTsKPj4gKwo+PiArCWZvciAoaSA9IDA7IGkgPCBWNEwyX0gyNjRfTlVNX0RQQl9FTlRSSUVT OyBpKyspIHsKPj4gKwkJc3RydWN0IHY0bDJfaDI2NF9kcGJfZW50cnkgKmRwYiA9ICZkZWNvZGUt PmRwYltpXTsKPj4gKwo+PiArCQlpZiAoIShkcGItPmZsYWdzICYgVjRMMl9IMjY0X0RQQl9FTlRS WV9GTEFHX0FDVElWRSkpCj4+ICsJCQlicmVhazsKPj4gKwo+PiArCQlidWZfc3BlY19sMCA9IGZp bmRfc3BlY19ieV9kcGJfaW5kZXgoaDI2NF9jdHgsIGksIDApOwo+PiArCQlpZiAoYnVmX3NwZWNf bDApIHsKPj4gKwkJCWJ1Zl9zcGVjX2wwLT5jYW52YXNfcG9zID0gaSArIDE7Cj4+ICsJCQl2YiA9 IHZiMl9maW5kX2J1ZmZlcih2cSwgZHBiLT5yZWZlcmVuY2VfdHMpOwo+PiArCQkJaWYgKCF2Yikg ewo+PiArCQkJCWRldl9lcnIoJmN0eC0+ZGV2LT5wbGF0X2Rldi0+ZGV2LAo+PiArCQkJCQkicmVm IHBpYyBmb3IgdHMgJWxsdSBsb3N0XG4iLCBkcGItPnJlZmVyZW5jZV90cyk7Cj4+ICsJCQkJY29u dGludWU7Cj4+ICsJCQl9Cj4+ICsKPj4gKwkJCWJ1Zl9zcGVjX2wwLT55X2RtYV9hZGRyID0KPj4g KwkJCQl2YjJfZG1hX2NvbnRpZ19wbGFuZV9kbWFfYWRkcih2YiwgMCk7Cj4+ICsJCQlpZiAoY3R4 LT5waWNfaW5mby5wbGFuZV9udW0gPiAxKQo+PiArCQkJCWJ1Zl9zcGVjX2wwLT5jX2RtYV9hZGRy ID0gdmIyX2RtYV9jb250aWdfcGxhbmVfZG1hX2FkZHIodmIsIDEpOwo+PiArCQkJZWxzZQo+PiAr CQkJCWJ1Zl9zcGVjX2wwLT5jX2RtYV9hZGRyID0KPj4gKwkJCQkJYnVmX3NwZWNfbDAtPnlfZG1h X2FkZHIgKyBjdHgtPnBpY19pbmZvLmZiX3NpemVbMF07Cj4+ICsJCQljb25maWdfZGVjb2RlX2Nh bnZhcyhodywgYnVmX3NwZWNfbDAsCj4+ICsJCQkJCcKgwqDCoMKgIGgyNjRfY3R4LT5tYl93aWR0 aCwgaDI2NF9jdHgtPm1iX2hlaWdodCk7Cj4+ICsJCQlpZiAoaDI2NF9jdHgtPmNhbnZhc19wb3Nf cG9jW2J1Zl9zcGVjX2wwLT5jYW52YXNfcG9zXSA9PSBJTlZBTElEX1BPQykKPj4gKwkJCQloMjY0 X2N0eC0+Y2FudmFzX3Bvc19wb2NbYnVmX3NwZWNfbDAtPmNhbnZhc19wb3NdID0KPj4gKwkJCQkJ YnVmX3NwZWNfbDAtPmRwYi0+dG9wX2ZpZWxkX29yZGVyX2NudDsKPj4gKwkJCWRldl9kYmcKPj4g KwkJCcKgwqDCoCAoJmN0eC0+ZGV2LT5wbGF0X2Rldi0+ZGV2LAo+PiArCQkJwqDCoMKgwqAgImNv bmZpZyBjYW52YXMgZm9yIHBvYyAlZCBjYW52YXMgJWQgeV9kbWFfYWRkciAweCVsbHhcbiIsCj4+ ICsJCQnCoMKgwqDCoCBidWZfc3BlY19sMC0+ZHBiLT50b3BfZmllbGRfb3JkZXJfY250LAo+PiAr CQkJwqDCoMKgwqAgYnVmX3NwZWNfbDAtPmNhbnZhc19wb3MsIGJ1Zl9zcGVjX2wwLT55X2RtYV9h ZGRyKTsKPj4gKwkJfQo+PiArCj4+ICsJCWJ1Zl9zcGVjX2wxID0gZmluZF9zcGVjX2J5X2RwYl9p bmRleChoMjY0X2N0eCwgaSwgMSk7Cj4+ICsJCWlmICghYnVmX3NwZWNfbDAgJiYgYnVmX3NwZWNf bDEpIHsKPj4gKwkJCWJ1Zl9zcGVjX2wxLT5jYW52YXNfcG9zID0gaSArIDE7Cj4+ICsJCQl2YiA9 IHZiMl9maW5kX2J1ZmZlcih2cSwgZHBiLT5yZWZlcmVuY2VfdHMpOwo+PiArCQkJaWYgKCF2Yikg ewo+PiArCQkJCWRldl9lcnIoJmN0eC0+ZGV2LT5wbGF0X2Rldi0+ZGV2LAo+PiArCQkJCQkicmVm IHBpYyBmb3IgdHMgJWxsdSBsb3N0XG4iLCBkcGItPnJlZmVyZW5jZV90cyk7Cj4+ICsJCQkJY29u dGludWU7Cj4+ICsJCQl9Cj4+ICsKPj4gKwkJCWJ1Zl9zcGVjX2wxLT55X2RtYV9hZGRyID0KPj4g KwkJCQl2YjJfZG1hX2NvbnRpZ19wbGFuZV9kbWFfYWRkcih2YiwgMCk7Cj4+ICsJCQlpZiAoY3R4 LT5waWNfaW5mby5wbGFuZV9udW0gPiAxKQo+PiArCQkJCWJ1Zl9zcGVjX2wxLT5jX2RtYV9hZGRy ID0gdmIyX2RtYV9jb250aWdfcGxhbmVfZG1hX2FkZHIodmIsIDEpOwo+PiArCQkJZWxzZQo+PiAr CQkJCWJ1Zl9zcGVjX2wxLT5jX2RtYV9hZGRyID0KPj4gKwkJCQkJYnVmX3NwZWNfbDEtPnlfZG1h X2FkZHIgKyBjdHgtPnBpY19pbmZvLmZiX3NpemVbMF07Cj4+ICsJCQljb25maWdfZGVjb2RlX2Nh bnZhcyhodywgYnVmX3NwZWNfbDEsIGgyNjRfY3R4LT5tYl93aWR0aCwKPj4gKwkJCQkJwqDCoMKg wqAgaDI2NF9jdHgtPm1iX2hlaWdodCk7Cj4+ICsJCQlpZiAoaDI2NF9jdHgtPmNhbnZhc19wb3Nf cG9jW2J1Zl9zcGVjX2wxLT5jYW52YXNfcG9zXSA9PSBJTlZBTElEX1BPQykKPj4gKwkJCQloMjY0 X2N0eC0+Y2FudmFzX3Bvc19wb2NbYnVmX3NwZWNfbDEtPmNhbnZhc19wb3NdID0KPj4gKwkJCQkJ YnVmX3NwZWNfbDEtPmRwYi0+dG9wX2ZpZWxkX29yZGVyX2NudDsKPj4gKwkJCWRldl9kYmcKPj4g KwkJCcKgwqDCoCAoJmN0eC0+ZGV2LT5wbGF0X2Rldi0+ZGV2LAo+PiArCQkJwqDCoMKgwqAgImNv bmZpZyBjYW52YXMgZm9yIHBvYyAlZCBjYW52YXMgJWQgeV9kbWFfYWRkciAweCVsbHhcbiIsCj4+ ICsJCQnCoMKgwqDCoCBidWZfc3BlY19sMS0+ZHBiLT50b3BfZmllbGRfb3JkZXJfY250LAo+PiAr CQkJwqDCoMKgwqAgYnVmX3NwZWNfbDEtPmNhbnZhc19wb3MsIGJ1Zl9zcGVjX2wxLT55X2RtYV9h ZGRyKTsKPj4gKwkJfSBlbHNlIGlmIChidWZfc3BlY19sMCAmJiBidWZfc3BlY19sMSkgewo+PiAr CQkJbWVtY3B5KGJ1Zl9zcGVjX2wxLCBidWZfc3BlY19sMCwgc2l6ZW9mKHN0cnVjdCBoMjY0X2Rl Y29kZV9idWZfc3BlYykpOwo+PiArCQkJZGV2X2RiZwo+PiArCQkJCSgmY3R4LT5kZXYtPnBsYXRf ZGV2LT5kZXYsCj4+ICsJCQkJICJjb25maWcgY2FudmFzIGZvciBwb2MgJWQgY2FudmFzICVkIHlf ZG1hX2FkZHIgMHglbGx4XG4iLAo+PiArCQkJCSBidWZfc3BlY19sMS0+ZHBiLT50b3BfZmllbGRf b3JkZXJfY250LAo+PiArCQkJCSBidWZfc3BlY19sMS0+Y2FudmFzX3BvcywgYnVmX3NwZWNfbDEt PnlfZG1hX2FkZHIpOwo+PiArCQl9Cj4+ICsJfQo+PiArCj4+ICsJaDI2NF9yZW9yZGVyX3JlZmxp c3RzKGgyNjRfY3R4KTsKPj4gK30KPj4gKwo+PiArc3RhdGljIGludCBoMjY0X2NvbmZpZ19kZWNv ZGVfYnVmKHN0cnVjdCBhbWxfdmRlY19odyAqaHcsIHN0cnVjdCBhbWxfdmRlY19jdHggKmN0eCkK Pj4gK3sKPj4gKwlzdHJ1Y3QgYW1sX2gyNjRfY3R4ICpoMjY0X2N0eCA9IChzdHJ1Y3QgYW1sX2gy NjRfY3R4ICopaHctPmN1cnJfY3R4Owo+PiArCXN0cnVjdCB2ZGVjX2gyNjRfc3RhdGVsZXNzX2N0 cmxfcmVmICpjdHJscyA9ICZoMjY0X2N0eC0+Y3RybF9yZWY7Cj4+ICsJc3RydWN0IHY0bDJfY3Ry bF9oMjY0X2RlY29kZV9wYXJhbXMgKmRlY29kZSA9Cj4+ICsJCShzdHJ1Y3QgdjRsMl9jdHJsX2gy NjRfZGVjb2RlX3BhcmFtcyAqKWN0cmxzLT5kZWNvZGU7Cj4+ICsJdW5zaWduZWQgaW50IGNhbnZh c19hZHI7Cj4+ICsJdW5zaWduZWQgaW50IHJlZl9jZmc7Cj4+ICsJdW5zaWduZWQgaW50IHJlZl9j Zmdfb25jZSA9IDA7Cj4+ICsJc3RydWN0IHNsaWNlICpjdXJyX3NsaWNlID0gJmgyNjRfY3R4LT5t c2xpY2U7Cj4+ICsJdW5zaWduZWQgaW50IHR5cGVfY2ZnID0gMHgzOyAvKiAweDM6IGZyYW1lIHR5 cGUgKi8KPj4gKwl1bnNpZ25lZCBpbnQgY29sb2NhdGVfYWRyX29mZnNldCA9IDA7Cj4+ICsJdW5z aWduZWQgaW50IGNvbG9jYXRlX3dyX2FkcjsKPj4gKwl1bnNpZ25lZCBpbnQgaW5mbzA7Cj4+ICsJ dW5zaWduZWQgaW50IGluZm8xOwo+PiArCXVuc2lnbmVkIGludCBpbmZvMjsKPj4gKwlpbnQgaSwg ajsKPj4gKwlpbnQgaDI2NF9idWZmZXJfaW5mb19kYXRhX3dyaXRlX2NvdW50Owo+PiArCXU4IGNh bnZhc19wb3M7Cj4+ICsJdTggdXNlX21vZGVfOHg4X2ZsYWc7Cj4+ICsJdTMyIHJlZ192YWw7Cj4+ ICsKPj4gKwlyZWdtYXBfd3JpdGUoaHctPm1hcFtET1NfQlVTXSwgSDI2NF9DVVJSRU5UX1BPQ19J RFhfUkVTRVQsIDApOwo+PiArCXJlZ21hcF93cml0ZShody0+bWFwW0RPU19CVVNdLCBIMjY0X0NV UlJFTlRfUE9DLCBkZWNvZGUtPnRvcF9maWVsZF9vcmRlcl9jbnQpOwo+PiArCXJlZ21hcF93cml0 ZShody0+bWFwW0RPU19CVVNdLCBIMjY0X0NVUlJFTlRfUE9DLCBkZWNvZGUtPnRvcF9maWVsZF9v cmRlcl9jbnQpOwo+PiArCXJlZ21hcF93cml0ZShody0+bWFwW0RPU19CVVNdLCBIMjY0X0NVUlJF TlRfUE9DLCBkZWNvZGUtPmJvdHRvbV9maWVsZF9vcmRlcl9jbnQpOwo+PiArCXJlZ21hcF93cml0 ZShody0+bWFwW0RPU19CVVNdLCBDVVJSX0NBTlZBU19DVFJMLCBoMjY0X2N0eC0+Y3Vycl9zcGVj LmNhbnZhc19wb3MgPDwgMjQpOwo+PiArCXJlZ21hcF9yZWFkKGh3LT5tYXBbRE9TX0JVU10sIENV UlJfQ0FOVkFTX0NUUkwsICZjYW52YXNfYWRyKTsKPj4gKwljYW52YXNfYWRyICY9IDB4ZmZmZmZm Owo+PiArCWRldl9kYmcoaHctPmRldiwgImNhbnZhc19wb3MgPSAlZCBjYW52YXNfYWRyIDB4JXhc biIsCj4+ICsJCWgyNjRfY3R4LT5jdXJyX3NwZWMuY2FudmFzX3BvcywgY2FudmFzX2Fkcik7Cj4+ ICsKPj4gKwlyZWdtYXBfd3JpdGUoaHctPm1hcFtET1NfQlVTXSwgUkVDX0NBTlZBU19BRERSLCBj YW52YXNfYWRyKTsKPj4gKwlyZWdtYXBfd3JpdGUoaHctPm1hcFtET1NfQlVTXSwgREJLUl9DQU5W QVNfQUREUiwgY2FudmFzX2Fkcik7Cj4+ICsJcmVnbWFwX3dyaXRlKGh3LT5tYXBbRE9TX0JVU10s IERCS1dfQ0FOVkFTX0FERFIsIGNhbnZhc19hZHIpOwo+PiArCj4+ICsJcmVnbWFwX3dyaXRlKGh3 LT5tYXBbRE9TX0JVU10sIEgyNjRfQlVGRkVSX0lORk9fSU5ERVgsIDE2KTsKPj4gKwlpbmZvMCA9 IDB4ZjQ4MDsKPj4gKwlpbmZvMSA9IGRlY29kZS0+dG9wX2ZpZWxkX29yZGVyX2NudDsKPj4gKwlp bmZvMiA9IGRlY29kZS0+Ym90dG9tX2ZpZWxkX29yZGVyX2NudDsKPj4gKwlpZiAoZGVjb2RlLT5i b3R0b21fZmllbGRfb3JkZXJfY250IDwgZGVjb2RlLT50b3BfZmllbGRfb3JkZXJfY250KQo+PiAr CQlpbmZvMCB8PSAweDEwMDsKPj4gKwo+PiArCXJlZ21hcF93cml0ZShody0+bWFwW0RPU19CVVNd LCBIMjY0X0JVRkZFUl9JTkZPX0RBVEEsIGluZm8wIHwgMHhmKTsKPj4gKwlyZWdtYXBfd3JpdGUo aHctPm1hcFtET1NfQlVTXSwgSDI2NF9CVUZGRVJfSU5GT19EQVRBLCBpbmZvMSk7Cj4+ICsJcmVn bWFwX3dyaXRlKGh3LT5tYXBbRE9TX0JVU10sIEgyNjRfQlVGRkVSX0lORk9fREFUQSwgaW5mbzIp Owo+PiArCj4+ICsJZm9yIChqID0gMDsgaiA8IFY0TDJfSDI2NF9OVU1fRFBCX0VOVFJJRVM7IGor Kykgewo+PiArCQlzdHJ1Y3QgdjRsMl9oMjY0X2RwYl9lbnRyeSAqZHBiID0gJmRlY29kZS0+ZHBi W2pdOwo+PiArCj4+ICsJCWluZm8wID0gMDsKPj4gKwkJaW5mbzEgPSAwOwo+PiArCQlpbmZvMiA9 IDA7Cj4+ICsJCWlmIChkcGItPmZsYWdzICYgVjRMMl9IMjY0X0RQQl9FTlRSWV9GTEFHX0FDVElW RSkgewo+PiArCQkJaW5mbzAgPSAweGY0ODA7Cj4+ICsJCQlpZiAoZHBiLT5ib3R0b21fZmllbGRf b3JkZXJfY250IDwgZHBiLT50b3BfZmllbGRfb3JkZXJfY250KQo+PiArCQkJCWluZm8wIHw9IDB4 MTAwOwo+PiArCQkJaW5mbzEgPSBkcGItPnRvcF9maWVsZF9vcmRlcl9jbnQ7Cj4+ICsJCQlpbmZv MiA9IGRwYi0+Ym90dG9tX2ZpZWxkX29yZGVyX2NudDsKPj4gKwkJCWlmIChkcGItPmZsYWdzICYg VjRMMl9IMjY0X0RQQl9FTlRSWV9GTEFHX0xPTkdfVEVSTSkKPj4gKwkJCQlpbmZvMCB8PSAoKDEg PDwgNSkgfCAoMSA8PCA0KSk7Cj4+ICsJCX0KPj4gKwkJcmVnbWFwX3dyaXRlKGh3LT5tYXBbRE9T X0JVU10sIEgyNjRfQlVGRkVSX0lORk9fREFUQSwgaW5mbzApOwo+PiArCQlyZWdtYXBfd3JpdGUo aHctPm1hcFtET1NfQlVTXSwgSDI2NF9CVUZGRVJfSU5GT19EQVRBLCBpbmZvMSk7Cj4+ICsJCXJl Z21hcF93cml0ZShody0+bWFwW0RPU19CVVNdLCBIMjY0X0JVRkZFUl9JTkZPX0RBVEEsIGluZm8y KTsKPj4gKwl9Cj4+ICsKPj4gKwlyZWdtYXBfd3JpdGUoaHctPm1hcFtET1NfQlVTXSwgSDI2NF9C VUZGRVJfSU5GT19JTkRFWCwgMCk7Cj4+ICsJLyogd2hlbiBmcmFtZSB3aWR0aCA8PSAyNTYsIERp c2FibGUgRERSX0JZVEU2NF9DQUNIRSAqLwo+PiArCWlmIChjdHgtPnBpY19pbmZvLmNvZGVkX3dp ZHRoIDw9IDI1Nikgewo+PiArCQlyZWdtYXBfdXBkYXRlX2JpdHMoaHctPm1hcFtET1NfQlVTXSwg SVFJRENUX0NPTlRST0wsICgxIDw8IDE2KSwgKDEgPDwgMTYpKTsKPj4gKwkJcmVnbWFwX3dyaXRl KGh3LT5tYXBbRE9TX0JVU10sIERDQUNfRERSX0JZVEU2NF9DVEwsCj4+ICsJCQnCoMKgwqDCoCAo cmVhZF9kb3NfcmVnKGh3LCBEQ0FDX0REUl9CWVRFNjRfQ1RMKSAmICh+MHhmKSkgfCAweGEpOwo+ PiArCX0gZWxzZSB7Cj4+ICsJCXJlZ21hcF91cGRhdGVfYml0cyhody0+bWFwW0RPU19CVVNdLCBJ UUlEQ1RfQ09OVFJPTCwgKDEgPDwgMTYpLCAwKTsKPj4gKwkJcmVnbWFwX3dyaXRlKGh3LT5tYXBb RE9TX0JVU10sIERDQUNfRERSX0JZVEU2NF9DVEwsCj4+ICsJCQnCoMKgwqDCoCAocmVhZF9kb3Nf cmVnKGh3LCBEQ0FDX0REUl9CWVRFNjRfQ1RMKSAmICh+MHhmKSkpOwo+PiArCX0KPj4gKwo+PiAr CXJlZl9jZmcgPSAwOwo+PiArCWogPSAwOwo+PiArCj4+ICsJaWYgKGgyNjRfY3R4LT5saXN0X3Np emVbMF0gPiAwKSB7Cj4+ICsJCWZvciAoaSA9IDA7IGkgPCBoMjY0X2N0eC0+bGlzdF9zaXplWzBd OyBpKyspIHsKPj4gKwkJCWNhbnZhc19wb3MgPSBoMjY0X2N0eC0+cmVmX2xpc3QwW2ldLmNhbnZh c19wb3M7Cj4+ICsJCQkvKiBiaXQgMDozIGNhbnZhc19wb3MgYml0IDU6NiBmcmFtZSBzdHJ1Y3Qg Y2ZnICovCj4+ICsJCQlyZWZfY2ZnX29uY2UgPSAoY2FudmFzX3BvcyAmIDB4MWYpIHwgKHR5cGVf Y2ZnIDw8IDUpOwo+PiArCQkJcmVmX2NmZyA8PD0gODsKPj4gKwkJCXJlZl9jZmcgfD0gcmVmX2Nm Z19vbmNlOwo+PiArCQkJaisrOwo+PiArCj4+ICsJCQlpZiAoaiA9PSA0KSB7Cj4+ICsJCQkJcmVn bWFwX3dyaXRlKGh3LT5tYXBbRE9TX0JVU10sIEgyNjRfQlVGRkVSX0lORk9fREFUQSwgcmVmX2Nm Zyk7Cj4+ICsJCQkJZGV2X2RiZyhody0+ZGV2LCAiSDI2NF9CVUZGRVJfSU5GT19EQVRBOiAleFxu IiwgcmVmX2NmZyk7Cj4+ICsJCQkJaDI2NF9idWZmZXJfaW5mb19kYXRhX3dyaXRlX2NvdW50Kys7 Cj4+ICsJCQkJaiA9IDA7Cj4+ICsJCQl9Cj4+ICsJCX0KPj4gKwo+PiArCQlpZiAoaiAhPSAwKSB7 Cj4+ICsJCQl3aGlsZSAoaiAhPSA0KSB7Cj4+ICsJCQkJcmVmX2NmZyA8PD0gODsKPj4gKwkJCQly ZWZfY2ZnIHw9IHJlZl9jZmdfb25jZTsKPj4gKwkJCQlqKys7Cj4+ICsJCQl9Cj4+ICsJCQlyZWdt YXBfd3JpdGUoaHctPm1hcFtET1NfQlVTXSwgSDI2NF9CVUZGRVJfSU5GT19EQVRBLCByZWZfY2Zn KTsKPj4gKwkJCWRldl9kYmcoaHctPmRldiwgIkgyNjRfQlVGRkVSX0lORk9fREFUQTogJXhcbiIs IHJlZl9jZmcpOwo+PiArCQkJaDI2NF9idWZmZXJfaW5mb19kYXRhX3dyaXRlX2NvdW50Kys7Cj4+ ICsJCX0KPj4gKwkJcmVmX2NmZyA9IChyZWZfY2ZnX29uY2UgPDwgMjQpIHwgKHJlZl9jZmdfb25j ZSA8PCAxNikgfAo+PiArCQkJKHJlZl9jZmdfb25jZSA8PCA4KSB8IHJlZl9jZmdfb25jZTsKPj4g KwkJZm9yIChqID0gaDI2NF9idWZmZXJfaW5mb19kYXRhX3dyaXRlX2NvdW50OyBqIDwgODsgaisr KQo+PiArCQkJcmVnbWFwX3dyaXRlKGh3LT5tYXBbRE9TX0JVU10sIEgyNjRfQlVGRkVSX0lORk9f REFUQSwgcmVmX2NmZyk7Cj4+ICsJfQo+PiArCj4+ICsJcmVnbWFwX3dyaXRlKGh3LT5tYXBbRE9T X0JVU10sIEgyNjRfQlVGRkVSX0lORk9fSU5ERVgsIDgpOwo+PiArCWogPSAwOwo+PiArCXJlZl9j ZmcgPSAwOwo+PiArCj4+ICsJaWYgKGgyNjRfY3R4LT5saXN0X3NpemVbMV0gPiAwKSB7Cj4+ICsJ CWZvciAoaSA9IDA7IGkgPCBoMjY0X2N0eC0+bGlzdF9zaXplWzFdOyBpKyspIHsKPj4gKwkJCWNh bnZhc19wb3MgPSBoMjY0X2N0eC0+cmVmX2xpc3QxW2ldLmNhbnZhc19wb3M7Cj4+ICsJCQlyZWZf Y2ZnX29uY2UgPSAoY2FudmFzX3BvcyAmIDB4MWYpIHwgKHR5cGVfY2ZnIDw8IDUpOwo+PiArCQkJ cmVmX2NmZyA8PD0gODsKPj4gKwkJCXJlZl9jZmcgfD0gcmVmX2NmZ19vbmNlOwo+PiArCQkJaisr Owo+PiArCj4+ICsJCQlpZiAoaiA9PSA0KSB7Cj4+ICsJCQkJcmVnbWFwX3dyaXRlKGh3LT5tYXBb RE9TX0JVU10sIEgyNjRfQlVGRkVSX0lORk9fREFUQSwgcmVmX2NmZyk7Cj4+ICsJCQkJZGV2X2Ri Zyhody0+ZGV2LCAiSDI2NF9CVUZGRVJfSU5GT19EQVRBOiAleFxuIiwgcmVmX2NmZyk7Cj4+ICsJ CQkJaiA9IDA7Cj4+ICsJCQl9Cj4+ICsJCX0KPj4gKwl9Cj4+ICsKPj4gKwlpZiAoaiAhPSAwKSB7 Cj4+ICsJCXdoaWxlIChqICE9IDQpIHsKPj4gKwkJCXJlZl9jZmcgPDw9IDg7Cj4+ICsJCQlyZWZf Y2ZnIHw9IHJlZl9jZmdfb25jZTsKPj4gKwkJCWorKzsKPj4gKwkJfQo+PiArCQlkZXZfZGJnKGh3 LT5kZXYsICJIMjY0X0JVRkZFUl9JTkZPX0RBVEE6ICV4XG4iLCByZWZfY2ZnKTsKPj4gKwkJcmVn bWFwX3dyaXRlKGh3LT5tYXBbRE9TX0JVU10sIEgyNjRfQlVGRkVSX0lORk9fREFUQSwgcmVmX2Nm Zyk7Cj4+ICsJfQo+PiArCj4+ICsJaWYgKGdldF9mbGFnKGN0cmxzLT5zcHMtPmZsYWdzLCBWNEwy X0gyNjRfU1BTX0ZMQUdfRlJBTUVfTUJTX09OTFkpICYmCj4+ICsJwqDCoMKgIGdldF9mbGFnKGN0 cmxzLT5zcHMtPmZsYWdzLCBWNEwyX0gyNjRfU1BTX0ZMQUdfRElSRUNUXzhYOF9JTkZFUkVOQ0Up KQo+PiArCQl1c2VfbW9kZV84eDhfZmxhZyA9IDE7Cj4+ICsJZWxzZQo+PiArCQl1c2VfbW9kZV84 eDhfZmxhZyA9IDA7Cj4+ICsKPj4gKwlyZWFkX3BvbGxfdGltZW91dChyZWFkX2Rvc19yZWcsIHJl Z192YWwsCj4+ICsJCQnCoCAhKHJlZ192YWwgJiAweDgwMCksCj4+ICsJCQnCoCAxMCwgMCwgdHJ1 ZSwKPj4gKwkJCcKgIGh3LCBIMjY0X0NPX01CX1JXX0NUTCk7Cj4+ICsKPj4gKwkvKiBjb2wgYnVm IGZvciBjdXJyIGZyYW1lICovCj4+ICsJY29sb2NhdGVfYWRyX29mZnNldCA9IENPTF9TSVpFX0ZP Ul9PTkVfTUI7Cj4+ICsJaWYgKHVzZV9tb2RlXzh4OF9mbGFnKQo+PiArCQljb2xvY2F0ZV9hZHJf b2Zmc2V0ID4+PSAyOwo+PiArCWNvbG9jYXRlX2Fkcl9vZmZzZXQgKj0gY3Vycl9zbGljZS0+Zmly c3RfbWJfaW5fc2xpY2U7Cj4+ICsKPj4gKwlpZiAoaDI2NF9jdHgtPmN1cnJfc3BlYy5jb2xfYnVm X2luZGV4ID49IDAgJiYKPj4gKwnCoMKgwqAgaDI2NF9jdHgtPmN1cnJfc3BlYy5jb2xfYnVmX2lu ZGV4IDwgaDI2NF9jdHgtPmNvbG9jYXRlZF9idWZfbnVtKSB7Cj4+ICsJCWNvbG9jYXRlX3dyX2Fk ciA9IGgyNjRfY3R4LT5jb2xsYXRlZF9jbWFfYWRkciArCj4+ICsJCQkoKGgyNjRfY3R4LT5vbmVf Y29sX2J1Zl9zaXplICogaDI2NF9jdHgtPmN1cnJfc3BlYy5jb2xfYnVmX2luZGV4KSA+Pgo+PiAr CQkJKHVzZV9tb2RlXzh4OF9mbGFnID8gMiA6IDApKTsKPj4gKwkJaWYgKGNvbG9jYXRlX2Fkcl9v ZmZzZXQgPiBoMjY0X2N0eC0+b25lX2NvbF9idWZfc2l6ZSB8fAo+PiArCQnCoMKgwqAgY29sb2Nh dGVfd3JfYWRyICsgaDI2NF9jdHgtPm9uZV9jb2xfYnVmX3NpemUgPgo+PiArCQnCoMKgwqAgaDI2 NF9jdHgtPmNvbGxhdGVkX2NtYV9hZGRyX2VuZCkgewo+PiArCQkJZGV2X2Vycgo+PiArCQkJwqDC oMKgIChody0+ZGV2LCAiRXJyb3IsIGNvbG9jYXRlIGJ1ZiBpcyBub3QgZW5vdWdoLCBpbmRleCBp cyAlZFxuIiwKPj4gKwkJCcKgwqDCoMKgIGgyNjRfY3R4LT5jdXJyX3NwZWMuY29sX2J1Zl9pbmRl eCk7Cj4+ICsJCQlyZXR1cm4gLTE7Cj4+ICsJCX0KPj4gKwkJcmVnbWFwX3dyaXRlKGh3LT5tYXBb RE9TX0JVU10sIEgyNjRfQ09fTUJfV1JfQUREUiwKPj4gKwkJCcKgwqDCoMKgIChjb2xvY2F0ZV93 cl9hZHIgKyBjb2xvY2F0ZV9hZHJfb2Zmc2V0KSk7Cj4+ICsJCWRldl9kYmcoaHctPmRldiwgImNv bCBidWZmZXIgYWRkciA9IDB4JXggY29sX2J1Zl9pbmRleCAlZFxuIiwKPj4gKwkJCShjb2xvY2F0 ZV93cl9hZHIgKyBjb2xvY2F0ZV9hZHJfb2Zmc2V0KSwKPj4gKwkJCWgyNjRfY3R4LT5jdXJyX3Nw ZWMuY29sX2J1Zl9pbmRleCk7Cj4+ICsJfSBlbHNlIHsKPj4gKwkJcmVnbWFwX3dyaXRlKGh3LT5t YXBbRE9TX0JVU10sIEgyNjRfQ09fTUJfV1JfQUREUiwgMHhmZmZmZmZmZik7Cj4+ICsJCWRldl9k YmcoaHctPmRldiwgImNvbCBidWZmZXIgYWRkciA9IDB4ZmZmZmZmZmZcbiIpOwo+PiArCX0KPj4g Kwo+PiArCWlmIChoMjY0X2N0eC0+bGlzdF9zaXplWzFdID4gMCkgewo+PiArCQlzdHJ1Y3QgaDI2 NF9kZWNvZGVfYnVmX3NwZWMgKmNvbG9jYXRlX3BpYyA9ICZoMjY0X2N0eC0+cmVmX2xpc3QxWzBd Owo+PiArCQlzdHJ1Y3QgaDI2NF9kZWNvZGVfYnVmX3NwZWMgKmN1cnJfcGljID0gJmgyNjRfY3R4 LT5jdXJyX3NwZWM7Cj4+ICsJCWludCBsMTBfc3RydWN0dXJlID0gMjsgLyogZm9yIHBpYyBzdHJ1 Y3QgPT0gRlJBTUUsIGRlZmF1bHQgdG8gMiAqLwo+PiArCQlpbnQgY3VyX2NvbG9jYXRlX3JlZl90 eXBlOwo+PiArCQl1bnNpZ25lZCBpbnQgY29sb2NhdGVfcmRfYWRyOwo+PiArCQl1bnNpZ25lZCBp bnQgY29sb2NhdGVfcmRfYWRyX29mZnNldCA9IDA7Cj4+ICsJCXVuc2lnbmVkIGludCB2YWw7Cj4+ ICsKPj4gKwkJY3VyX2NvbG9jYXRlX3JlZl90eXBlID0KPj4gKwkJCShhYnMoY3Vycl9waWMtPnBv YyAtIGNvbG9jYXRlX3BpYy0+ZHBiLT50b3BfZmllbGRfb3JkZXJfY250KSA8Cj4+ICsJCQlhYnMo Y3Vycl9waWMtPnBvYyAtIGNvbG9jYXRlX3BpYy0+ZHBiLT5ib3R0b21fZmllbGRfb3JkZXJfY250 KSkgPwo+PiArCQkJMCA6IDE7Cj4+ICsJCWNvbG9jYXRlX3JkX2Fkcl9vZmZzZXQgPSBDT0xfU0la RV9GT1JfT05FX01COwo+PiArCQlpZiAodXNlX21vZGVfOHg4X2ZsYWcpCj4+ICsJCQljb2xvY2F0 ZV9yZF9hZHJfb2Zmc2V0ID4+PSAyOwo+PiArCj4+ICsJCWNvbG9jYXRlX3JkX2Fkcl9vZmZzZXQg Kj0gY3Vycl9zbGljZS0+Zmlyc3RfbWJfaW5fc2xpY2U7Cj4+ICsJCWlmIChjb2xvY2F0ZV9waWMt PmNvbF9idWZfaW5kZXggPj0gMCAmJgo+PiArCQnCoMKgwqAgY29sb2NhdGVfcGljLT5jb2xfYnVm X2luZGV4IDwgaDI2NF9jdHgtPmNvbG9jYXRlZF9idWZfbnVtKSB7Cj4+ICsJCQljb2xvY2F0ZV9y ZF9hZHIgPSBoMjY0X2N0eC0+Y29sbGF0ZWRfY21hX2FkZHIgKwo+PiArCQkJCSgoaDI2NF9jdHgt Pm9uZV9jb2xfYnVmX3NpemUgKiBjb2xvY2F0ZV9waWMtPmNvbF9idWZfaW5kZXgpID4+Cj4+ICsJ CQkJKHVzZV9tb2RlXzh4OF9mbGFnID8gMiA6IDApKTsKPj4gKwkJCWlmIChjb2xvY2F0ZV9yZF9h ZHIgKyBoMjY0X2N0eC0+b25lX2NvbF9idWZfc2l6ZSA+Cj4+ICsJCQnCoMKgwqAgaDI2NF9jdHgt PmNvbGxhdGVkX2NtYV9hZGRyX2VuZCkgewo+PiArCQkJCWRldl9lcnIKPj4gKwkJCQnCoMKgwqAg KGh3LT5kZXYsICJFcnJvciwgY29sb2NhdGUgcmQgYnVmIGlzIG5vdCBlbm91Z2gsIGluZGV4IGlz ICVkXG4iLAo+PiArCQkJCcKgwqDCoMKgIGNvbG9jYXRlX3BpYy0+Y29sX2J1Zl9pbmRleCk7Cj4+ ICsJCQkJcmV0dXJuIC0xOwo+PiArCQkJfQo+PiArCQkJdmFswqAgPSAoKGNvbG9jYXRlX3JkX2Fk cl9vZmZzZXQgKyBjb2xvY2F0ZV9yZF9hZHIpID4+IDMpIHwKPj4gKwkJCQkoY3VyX2NvbG9jYXRl X3JlZl90eXBlIDw8IDI5KSB8Cj4+ICsJCQkJKGwxMF9zdHJ1Y3R1cmUgPDwgMzApOwo+PiArCQkJ cmVnbWFwX3dyaXRlKGh3LT5tYXBbRE9TX0JVU10sIEgyNjRfQ09fTUJfUkRfQUREUiwgdmFsKTsK Pj4gKwkJfSBlbHNlIHsKPj4gKwkJCWRldl9lcnIKPj4gKwkJCcKgwqDCoCAoaHctPmRldiwgIkVy cm9yLCByZWZlcmVuY2UgcGljIGhhcyBubyBjb2xvY2F0ZWQgYnVmIHBvYyAlZFxuIiwKPj4gKwkJ CcKgwqDCoMKgIGN1cnJfcGljLT5wb2MpOwo+PiArCQkJcmV0dXJuIC0xOwo+PiArCQl9Cj4+ICsJ fQo+PiArCj4+ICsJcmV0dXJuIDA7Cj4+ICt9Cj4+ICsKPj4gK3N0YXRpYyB2b2lkIHJlbGVhc2Vf Y2FudmFzX2luZGV4KHN0cnVjdCBhbWxfdmRlY19odyAqaHcsCj4+ICsJCQkJIHN0cnVjdCBoMjY0 X2RlY29kZV9idWZfc3BlYyAqYnVmKQo+PiArewo+PiArCXN0cnVjdCBhbWxfaDI2NF9jdHggKmgy NjRfY3R4ID0gKHN0cnVjdCBhbWxfaDI2NF9jdHggKilody0+Y3Vycl9jdHg7Cj4+ICsKPj4gKwlp ZiAoaDI2NF9jdHgtPmNhbnZhc19wb3NfcG9jW2J1Zi0+Y2FudmFzX3Bvc10gPT0gSU5WQUxJRF9Q T0MpCj4+ICsJCXJldHVybjsKPj4gKwo+PiArCWlmIChidWYtPnlfY2FudmFzX2luZGV4ID49IDAp IHsKPj4gKwkJbWVzb25fY2FudmFzX2ZyZWUoaHctPmNhbnZhcywgYnVmLT55X2NhbnZhc19pbmRl eCk7Cj4+ICsJCWJ1Zi0+eV9jYW52YXNfaW5kZXggPSAtMTsKPj4gKwl9Cj4+ICsKPj4gKwlpZiAo YnVmLT51X2NhbnZhc19pbmRleCA+PSAwKSB7Cj4+ICsJCW1lc29uX2NhbnZhc19mcmVlKGh3LT5j YW52YXMsIGJ1Zi0+dV9jYW52YXNfaW5kZXgpOwo+PiArCQlidWYtPnVfY2FudmFzX2luZGV4ID0g LTE7Cj4+ICsJCWJ1Zi0+dl9jYW52YXNfaW5kZXggPSAtMTsKPj4gKwl9Cj4+ICsJaDI2NF9jdHgt PmNhbnZhc19wb3NfcG9jW2J1Zi0+Y2FudmFzX3Bvc10gPSBJTlZBTElEX1BPQzsKPj4gK30KPj4g Kwo+PiArc3RhdGljIHZvaWQgaDI2NF9yZWxlYXNlX2RlY29kZV9zcGVjKHN0cnVjdCBhbWxfdmRl Y19odyAqaHcsIHN0cnVjdCBhbWxfdmRlY19jdHggKmN0eCkKPj4gK3sKPj4gKwlzdHJ1Y3QgYW1s X2gyNjRfY3R4ICpoMjY0X2N0eCA9IChzdHJ1Y3QgYW1sX2gyNjRfY3R4ICopaHctPmN1cnJfY3R4 Owo+PiArCWludCBpOwo+PiArCXN0cnVjdCBoMjY0X2RlY29kZV9idWZfc3BlYyAqYnVmOwo+PiAr Cj4+ICsJcmVsZWFzZV9jYW52YXNfaW5kZXgoaHcsICZoMjY0X2N0eC0+Y3Vycl9zcGVjKTsKPj4g Kwo+PiArCWlmIChoMjY0X2N0eC0+bGlzdF9zaXplWzBdID4gMCkgewo+PiArCQlmb3IgKGkgPSAw OyBpIDwgaDI2NF9jdHgtPmxpc3Rfc2l6ZVswXTsgaSsrKSB7Cj4+ICsJCQlidWYgPSAmaDI2NF9j dHgtPnJlZl9saXN0MFtpXTsKPj4gKwkJCWlmIChidWYtPnVzZWQpIHsKPj4gKwkJCQlidWYtPmRw YiA9IE5VTEw7Cj4+ICsJCQkJcmVsZWFzZV9jYW52YXNfaW5kZXgoaHcsIGJ1Zik7Cj4+ICsJCQkJ YnVmLT51c2VkID0gMDsKPj4gKwkJCX0KPj4gKwkJfQo+PiArCQloMjY0X2N0eC0+bGlzdF9zaXpl WzBdID0gMDsKPj4gKwl9Cj4+ICsKPj4gKwlpZiAoaDI2NF9jdHgtPmxpc3Rfc2l6ZVsxXSA+IDAp IHsKPj4gKwkJZm9yIChpID0gMDsgaSA8IGgyNjRfY3R4LT5saXN0X3NpemVbMV07IGkrKykgewo+ PiArCQkJYnVmID0gJmgyNjRfY3R4LT5yZWZfbGlzdDFbaV07Cj4+ICsJCQlpZiAoYnVmLT51c2Vk KSB7Cj4+ICsJCQkJYnVmLT5kcGIgPSBOVUxMOwo+PiArCQkJCXJlbGVhc2VfY2FudmFzX2luZGV4 KGh3LCBidWYpOwo+PiArCQkJCWJ1Zi0+dXNlZCA9IDA7Cj4+ICsJCQl9Cj4+ICsJCX0KPj4gKwkJ aDI2NF9jdHgtPmxpc3Rfc2l6ZVsxXSA9IDA7Cj4+ICsJfQo+PiArfQo+PiArCj4+ICtzdGF0aWMg dm9pZCBzYXZlX3JlZ19zdGF0dXMoc3RydWN0IGFtbF9oMjY0X2N0eCAqaDI2NF9jdHgpCj4+ICt7 Cj4+ICsJc3RydWN0IGFtbF92ZGVjX2N0eCAqY3R4ID0gaDI2NF9jdHgtPnY0bDJfY3R4Owo+PiAr CXN0cnVjdCBhbWxfdmRlY19odyAqaHcgPSB2ZGVjX2dldF9odyhjdHgtPmRldik7Cj4+ICsKPj4g KwlyZWdtYXBfcmVhZChody0+bWFwW0RPU19CVVNdLCBJUUlEQ1RfQ09OVFJPTCwgJmgyNjRfY3R4 LT5yZWdfaXFpZGN0X2NvbnRyb2wpOwo+PiArCWgyNjRfY3R4LT5yZWdfaXFpZGN0X2NvbnRyb2xf aW5pdF9mbGFnID0gMTsKPj4gKwlyZWdtYXBfcmVhZChody0+bWFwW0RPU19CVVNdLCBWQ09QX0NU UkxfUkVHLCAmaDI2NF9jdHgtPnJlZ192Y29wX2N0cmxfcmVnKTsKPj4gKwlyZWdtYXBfcmVhZCho dy0+bWFwW0RPU19CVVNdLCBSVl9BSV9NQl9DT1VOVCwgJmgyNjRfY3R4LT5yZWdfcnZfYWlfbWJf Y291bnQpOwo+PiArCXJlZ21hcF9yZWFkKGh3LT5tYXBbRE9TX0JVU10sIFZMRF9ERUNPREVfQ09O VFJPTCwgJmgyNjRfY3R4LT52bGRfZGVjX2NvbnRyb2wpOwo+PiArfQo+PiArCj4+ICtzdGF0aWMg dm9pZCBoMjY0X2dldF9zbGljZV9wYXJhbXMoc3RydWN0IGFtbF9oMjY0X2N0eCAqaDI2NF9jdHgp Cj4+ICt7Cj4+ICsJc3RydWN0IHNsaWNlICpjdXJyX3NsaWNlID0gJmgyNjRfY3R4LT5tc2xpY2U7 Cj4+ICsKPj4gKwltZW1zZXQoY3Vycl9zbGljZSwgMCwgc2l6ZW9mKHN0cnVjdCBzbGljZSkpOwo+ PiArCS8qIHBhcnNlZCBieSB1Y29kZSAqLwo+PiArCWN1cnJfc2xpY2UtPnNsaWNlX3R5cGUgPSBo MjY0X2N0eC0+ZHBiX3BhcmFtLmwuZGF0YVtTTElDRV9UWVBFXTsKPj4gKwljdXJyX3NsaWNlLT5m aXJzdF9tYl9pbl9zbGljZSA9IGgyNjRfY3R4LT5kcGJfcGFyYW0ubC5kYXRhW0ZJUlNUX01CX0lO X1NMSUNFXTsKPj4gKwljdXJyX3NsaWNlLT5udW1fcmVmX2lkeF9sMCA9IGgyNjRfY3R4LT5kcGJf cGFyYW0uZHBiLm51bV9yZWZfaWR4X2wwX2FjdGl2ZV9taW51czEgKyAxOwo+PiArCWN1cnJfc2xp Y2UtPm51bV9yZWZfaWR4X2wxID0gaDI2NF9jdHgtPmRwYl9wYXJhbS5kcGIubnVtX3JlZl9pZHhf bDFfYWN0aXZlX21pbnVzMSArIDE7Cj4+ICsJY3Vycl9zbGljZS0+ZnJhbWVfbnVtID0gaDI2NF9j dHgtPmN0cmxfcmVmLmRlY29kZS0+ZnJhbWVfbnVtOwo+PiArfQo+PiArCj4+ICtzdGF0aWMgaXJx cmV0dXJuX3QgaDI2NF9pc3IoaW50IGlycSwgdm9pZCAqcHJpdikKPj4gK3sKPj4gKwlzdHJ1Y3Qg YW1sX3ZkZWNfZGV2ICpkZXYgPSAoc3RydWN0IGFtbF92ZGVjX2RldiAqKXByaXY7Cj4+ICsKPj4g KwlyZWdtYXBfd3JpdGUoZGV2LT5kZWNfaHctPm1hcFtET1NfQlVTXSwgVkRFQ19BU1NJU1RfTUJP WDFfQ0xSX1JFRywgMSk7Cj4+ICsKPj4gKwlyZXR1cm4gSVJRX1dBS0VfVEhSRUFEOwo+PiArfQo+ PiArCj4+ICtzdGF0aWMgaXJxcmV0dXJuX3QgaDI2NF90aHJlYWRlZF9pc3JfZnVuYyhpbnQgaXJx LCB2b2lkICpwcml2KQo+PiArewo+PiArCXUzMiBkZWNfc3RhdHVzOwo+PiArCXN0cnVjdCBhbWxf dmRlY19kZXYgKmRldiA9IChzdHJ1Y3QgYW1sX3ZkZWNfZGV2ICopcHJpdjsKPj4gKwlzdHJ1Y3Qg YW1sX2gyNjRfY3R4ICpoMjY0X2N0eCA9IChzdHJ1Y3QgYW1sX2gyNjRfY3R4ICopZGV2LT5kZWNf aHctPmN1cnJfY3R4Owo+PiArCXN0cnVjdCBhbWxfdmRlY19jdHggKmN0eCA9IChzdHJ1Y3QgYW1s X3ZkZWNfY3R4ICopZGV2LT5kZWNfY3R4Owo+PiArCXN0cnVjdCBhbWxfdmRlY19odyAqaHcgPSB2 ZGVjX2dldF9odyhjdHgtPmRldik7Cj4+ICsJdW5zaWduZWQgc2hvcnQgKnAgPSAodW5zaWduZWQg c2hvcnQgKiloMjY0X2N0eC0+bG1lbV9hZGRyOwo+PiArCWludCBpLCBpaTsKPj4gKwo+PiArCXJl Z21hcF9yZWFkKGh3LT5tYXBbRE9TX0JVU10sIERQQl9TVEFUVVNfUkVHLCAmZGVjX3N0YXR1cyk7 Cj4+ICsJaDI2NF9jdHgtPmRlY19zdGF0dXMgPSBkZWNfc3RhdHVzOwo+PiArCWRldl9kYmcKPj4g KwnCoMKgwqAgKCZkZXYtPnBsYXRfZGV2LT5kZXYsCj4+ICsJCSIlcywgZGVjX3N0YXR1cyAweCV4 IFZJRkZfQklUX0NOVCAweCV4IE1CWV9NQlggMHgleCBWTERfU0hJRlRfU1RBVFVTIDB4JXhcbiIs Cj4+ICsJwqDCoMKgIF9fZnVuY19fLCBkZWNfc3RhdHVzLCByZWFkX2Rvc19yZWcoaHcsIFZJRkZf QklUX0NOVCksIHJlYWRfZG9zX3JlZyhodywgTUJZX01CWCksCj4+ICsJwqDCoMKgIHJlYWRfZG9z X3JlZyhodywgVkxEX1NISUZUX1NUQVRVUykpOwo+PiArCj4+ICsJcmVnbWFwX3JlYWQoaHctPm1h cFtET1NfQlVTXSwgRFBCX1NUQVRVU19SRUcsICZoMjY0X2N0eC0+c2F2ZV9hdnNjcmF0Y2hfZik7 Cj4+ICsKPj4gKwlzd2l0Y2ggKGRlY19zdGF0dXMpIHsKPj4gKwljYXNlIEgyNjRfU0xJQ0VfSEVB REVSX0RPTkU6Cj4+ICsJCWZvciAoaSA9IDA7IGkgPCAweDQwMDsgaSArPSA0KQo+PiArCQkJZm9y IChpaSA9IDA7IGlpIDwgNDsgaWkrKykKPj4gKwkJCQloMjY0X2N0eC0+ZHBiX3BhcmFtLmwuZGF0 YVtpICsgaWldID0gcFtpICsgMyAtIGlpXTsKPj4gKwkJc2F2ZV9yZWdfc3RhdHVzKGgyNjRfY3R4 KTsKPj4gKwkJaDI2NF9nZXRfc2xpY2VfcGFyYW1zKGgyNjRfY3R4KTsKPj4gKwkJaWYgKGgyNjRf Y3R4LT5uZXdfcGljX2ZsYWcgPT0gMSkKPj4gKwkJCWgyNjRfY29uZmlnX2RlY29kZV9zcGVjKGh3 LCBjdHgpOwo+PiArCj4+ICsJCWlmIChoMjY0X2NvbmZpZ19kZWNvZGVfYnVmKGh3LCBjdHgpIDwg MCkgewo+PiArCQkJaDI2NF9yZWxlYXNlX2RlY29kZV9zcGVjKGh3LCBjdHgpOwo+PiArCQkJY3R4 LT5pbnRfY29uZCA9IDE7Cj4+ICsJCQl3YWtlX3VwX2ludGVycnVwdGlibGUoJmN0eC0+cXVldWUp Owo+PiArCQkJZ290byBpcnFfaGFuZGxlZDsKPj4gKwkJfQo+PiArCQlpZiAoaDI2NF9jdHgtPm5l d19waWNfZmxhZyA9PSAxKSB7Cj4+ICsJCQlyZWdtYXBfd3JpdGUoaHctPm1hcFtET1NfQlVTXSwg RFBCX1NUQVRVU19SRUcsIEgyNjRfQUNUSU9OX0RFQ09ERV9ORVdQSUMpOwo+PiArCQkJZGV2X2Ri ZygmZGV2LT5wbGF0X2Rldi0+ZGV2LCAiYWN0aW9uIGRlY29kZSBuZXcgcGljXG4iKTsKPj4gKwkJ CWgyNjRfY3R4LT5uZXdfcGljX2ZsYWcgPSAwOwo+PiArCQl9IGVsc2Ugewo+PiArCQkJcmVnbWFw X3dyaXRlKGh3LT5tYXBbRE9TX0JVU10sIERQQl9TVEFUVVNfUkVHLCBIMjY0X0FDVElPTl9ERUNP REVfU0xJQ0UpOwo+PiArCQkJZGV2X2RiZygmZGV2LT5wbGF0X2Rldi0+ZGV2LCAiYWN0aW9uIGRl Y29kZSBuZXcgc2xpY2VcbiIpOwo+PiArCQl9Cj4+ICsJCWJyZWFrOwo+PiArCWNhc2UgSDI2NF9T TElDRV9EQVRBX0RPTkU6Cj4+ICsJCWgyNjRfcmVsZWFzZV9kZWNvZGVfc3BlYyhodywgY3R4KTsK Pj4gKwkJaDI2NF9jdHgtPmRlY29kZV9waWNfY291bnQrKzsKPj4gKwkJY3R4LT5pbnRfY29uZCA9 IDE7Cj4+ICsJCXdha2VfdXBfaW50ZXJydXB0aWJsZSgmY3R4LT5xdWV1ZSk7Cj4+ICsJCWJyZWFr Owo+PiArCWRlZmF1bHQ6Cj4+ICsJCWgyNjRfcmVsZWFzZV9kZWNvZGVfc3BlYyhodywgY3R4KTsK Pj4gKwkJY3R4LT5pbnRfY29uZCA9IDE7Cj4+ICsJCXdha2VfdXBfaW50ZXJydXB0aWJsZSgmY3R4 LT5xdWV1ZSk7Cj4+ICsJCWJyZWFrOwo+PiArCX0KPj4gK2lycV9oYW5kbGVkOgo+PiArCXJldHVy biBJUlFfSEFORExFRDsKPj4gK30KPj4gKwo+PiArc3RhdGljIGludCBoMjY0X3Jlc3RvcmVfaHdf Y3R4KHN0cnVjdCBhbWxfdmRlY19jdHggKmN0eCkKPj4gK3sKPj4gKwlzdHJ1Y3QgYW1sX2gyNjRf Y3R4ICpoMjY0X2N0eCA9Cj4+ICsJCShzdHJ1Y3QgYW1sX2gyNjRfY3R4ICopY3R4LT5jb2RlY19w cml2Owo+PiArCXN0cnVjdCBhbWxfdmRlY19odyAqaHcgPSB2ZGVjX2dldF9odyhjdHgtPmRldik7 Cj4+ICsJaW50IGk7Cj4+ICsKPj4gKwlyZWdtYXBfd3JpdGUoaHctPm1hcFtET1NfQlVTXSwgUE9X RVJfQ1RMX1ZMRCwKPj4gKwkJwqDCoMKgwqAgKHJlYWRfZG9zX3JlZyhodywgUE9XRVJfQ1RMX1ZM RCkKPj4gKwkJwqDCoMKgwqAgfCAoMCA8PCAxMCkgfCAoMSA8PCA5KSB8ICgxIDw8IDYpKSk7Cj4+ ICsKPj4gKwlyZWdtYXBfd3JpdGUoaHctPm1hcFtET1NfQlVTXSwgUFNDQUxFX0NUUkwsIDApOwo+ PiArCj4+ICsJLyogY2xlYXIgbWFpbGJveCBpbnRlcnJ1cHQgKi8KPj4gKwlyZWdtYXBfd3JpdGUo aHctPm1hcFtET1NfQlVTXSwgVkRFQ19BU1NJU1RfTUJPWDFfQ0xSX1JFRywgMSk7Cj4+ICsKPj4g KwkvKiBlbmFibGUgbWFpbGJveCBpbnRlcnJ1cHQgKi8KPj4gKwlyZWdtYXBfd3JpdGUoaHctPm1h cFtET1NfQlVTXSwgVkRFQ19BU1NJU1RfTUJPWDFfTUFTSywgMSk7Cj4+ICsKPj4gKwlyZWdtYXBf dXBkYXRlX2JpdHMoaHctPm1hcFtET1NfQlVTXSwgTURFQ19QSUNfRENfQ1RSTCwgKDEgPDwgMTcp LCAoMSA8PCAxNykpOwo+PiArCWlmIChjdHgtPnFfZGF0YVtBTUxfUV9EQVRBX0RTVF0uZm10LT5m b3VyY2MgPT0gVjRMMl9QSVhfRk1UX05WMjEgfHwKPj4gKwnCoMKgwqAgY3R4LT5xX2RhdGFbQU1M X1FfREFUQV9EU1RdLmZtdC0+Zm91cmNjID09IFY0TDJfUElYX0ZNVF9OVjIxTSkKPj4gKwkJcmVn bWFwX3VwZGF0ZV9iaXRzKGh3LT5tYXBbRE9TX0JVU10sIE1ERUNfUElDX0RDX0NUUkwsCj4+ICsJ CQkJwqDCoCAoMSA8PCAxNiksICgxIDw8IDE2KSk7Cj4+ICsJZWxzZQo+PiArCQlyZWdtYXBfdXBk YXRlX2JpdHMoaHctPm1hcFtET1NfQlVTXSwgTURFQ19QSUNfRENfQ1RSTCwgKDEgPDwgMTYpLCAw KTsKPj4gKwo+PiArCXJlZ21hcF91cGRhdGVfYml0cyhody0+bWFwW0RPU19CVVNdLCBNREVDX1BJ Q19EQ19DVFJMLAo+PiArCQkJwqDCoCAoMHhiZiA8PCAyNCksICgweGJmIDw8IDI0KSk7Cj4+ICsJ cmVnbWFwX3VwZGF0ZV9iaXRzKGh3LT5tYXBbRE9TX0JVU10sIE1ERUNfUElDX0RDX0NUUkwsICgw eGJmIDw8IDI0KSwgMCk7Cj4+ICsJcmVnbWFwX3VwZGF0ZV9iaXRzKGh3LT5tYXBbRE9TX0JVU10s IE1ERUNfUElDX0RDX0NUUkwsICgxIDw8IDMxKSwgMCk7Cj4+ICsKPj4gKwlyZWdtYXBfdXBkYXRl X2JpdHMoaHctPm1hcFtET1NfQlVTXSwgTURFQ19QSUNfRENfTVVYX0NUUkwsICgxIDw8IDMxKSwg MCk7Cj4+ICsJcmVnbWFwX3dyaXRlKGh3LT5tYXBbRE9TX0JVU10sIE1ERUNfRVhUSUZfQ0ZHMSwg MCk7Cj4+ICsJcmVnbWFwX3dyaXRlKGh3LT5tYXBbRE9TX0JVU10sIE1ERUNfUElDX0RDX1RIUkVT SCwgMHg0MDQwMzhhYSk7Cj4+ICsKPj4gKwlyZWdtYXBfd3JpdGUoaHctPm1hcFtET1NfQlVTXSwg RFBCX1NUQVRVU19SRUcsIDApOwo+PiArCj4+ICsJcmVnbWFwX3dyaXRlKGh3LT5tYXBbRE9TX0JV U10sIExNRU1fRFVNUF9BRFIsIGgyNjRfY3R4LT5sbWVtX3BoeV9hZGRyKTsKPj4gKwlyZWdtYXBf d3JpdGUoaHctPm1hcFtET1NfQlVTXSwgRlJBTUVfQ09VTlRFUl9SRUcsIGgyNjRfY3R4LT5kZWNv ZGVfcGljX2NvdW50KTsKPj4gKwlyZWdtYXBfd3JpdGUoaHctPm1hcFtET1NfQlVTXSwgQVZfU0NS QVRDSF84LCBoMjY0X2N0eC0+d29ya3NwYWNlX29mZnNldCk7Cj4+ICsJcmVnbWFwX3dyaXRlKGh3 LT5tYXBbRE9TX0JVU10sIEFWX1NDUkFUQ0hfRywgaDI2NF9jdHgtPm1jX2NwdV9wYWRkcik7Cj4+ ICsKPj4gKwlyZWdtYXBfd3JpdGUoaHctPm1hcFtET1NfQlVTXSwgQVZfU0NSQVRDSF9GLAo+PiAr CQnCoMKgwqDCoCAoKGgyNjRfY3R4LT5zYXZlX2F2c2NyYXRjaF9mICYgMHhmZmZmZmZjMykgfCAo MSA8PCA0KSkpOwo+PiArCXJlZ21hcF91cGRhdGVfYml0cyhody0+bWFwW0RPU19CVVNdLCBBVl9T Q1JBVENIX0YsICgxIDw8IDYpLCAwKTsKPj4gKwo+PiArCXJlZ21hcF93cml0ZShody0+bWFwW0RP U19CVVNdLCBNREVDX1BJQ19EQ19USFJFU0gsIDB4NDA0MDM4YWEpOwo+PiArCj4+ICsJaWYgKGgy NjRfY3R4LT5yZWdfaXFpZGN0X2NvbnRyb2xfaW5pdF9mbGFnID09IDApCj4+ICsJCXJlZ21hcF93 cml0ZShody0+bWFwW0RPU19CVVNdLCBJUUlEQ1RfQ09OVFJPTCwgMHgyMDApOwo+PiArCj4+ICsJ aWYgKGgyNjRfY3R4LT5yZWdfaXFpZGN0X2NvbnRyb2wpCj4+ICsJCXJlZ21hcF93cml0ZShody0+ bWFwW0RPU19CVVNdLCBJUUlEQ1RfQ09OVFJPTCwgaDI2NF9jdHgtPnJlZ19pcWlkY3RfY29udHJv bCk7Cj4+ICsKPj4gKwlpZiAoaDI2NF9jdHgtPnJlZ192Y29wX2N0cmxfcmVnKQo+PiArCQlyZWdt YXBfd3JpdGUoaHctPm1hcFtET1NfQlVTXSwgVkNPUF9DVFJMX1JFRywgaDI2NF9jdHgtPnJlZ192 Y29wX2N0cmxfcmVnKTsKPj4gKwo+PiArCWlmIChoMjY0X2N0eC0+dmxkX2RlY19jb250cm9sKQo+ PiArCQlyZWdtYXBfd3JpdGUoaHctPm1hcFtET1NfQlVTXSwgVkxEX0RFQ09ERV9DT05UUk9MLCBo MjY0X2N0eC0+dmxkX2RlY19jb250cm9sKTsKPj4gKwo+PiArCWRldl9kYmcKPj4gKwnCoMKgwqAg KGh3LT5kZXYsCj4+ICsJwqDCoMKgwqAgIklRSURDVF9DT05UUk9MID0gMHgleCwgVkNPUF9DVFJM X1JFRyAweCV4IFZMRF9ERUNPREVfQ09OVFJPTCAweCV4XG4iLAo+PiArCcKgwqDCoMKgIHJlYWRf ZG9zX3JlZyhodywgSVFJRENUX0NPTlRST0wpLCByZWFkX2Rvc19yZWcoaHcsIFZDT1BfQ1RSTF9S RUcpLAo+PiArCcKgwqDCoMKgIHJlYWRfZG9zX3JlZyhodywgVkxEX0RFQ09ERV9DT05UUk9MKSk7 Cj4+ICsKPj4gKwlmb3IgKGkgPSAwOyBpIDwgSDI2NF9NQVhfQ0FOVkFTX1BPUzsgaSsrKQo+PiAr CQloMjY0X2N0eC0+Y2FudmFzX3Bvc19wb2NbaV0gPSBJTlZBTElEX1BPQzsKPj4gKwo+PiArCXJl dHVybiAwOwo+PiArfQo+PiArCj4+ICtzdGF0aWMgdm9pZCAqYW1sX2gyNjRfZ2V0X2N0cmwoc3Ry dWN0IHY0bDJfY3RybF9oYW5kbGVyICpoZGwsIHUzMiBpZCkKPj4gK3sKPj4gKwlzdHJ1Y3QgdjRs Ml9jdHJsICpjdHJsOwo+PiArCj4+ICsJY3RybCA9IHY0bDJfY3RybF9maW5kKGhkbCwgaWQpOwo+ PiArCXJldHVybiBjdHJsID8gY3RybC0+cF9jdXIucCA6IE5VTEw7Cj4+ICt9Cj4+ICsKPj4gK3N0 YXRpYyBpbnQgYW1sX2gyNjRfZ2V0X3N0YXRlbGVzc19jdHJsX3JlZihzdHJ1Y3QgYW1sX2gyNjRf Y3R4ICpoMjY0X2N0eCkKPj4gK3sKPj4gKwlzdHJ1Y3QgYW1sX3ZkZWNfY3R4ICpjdHggPSBoMjY0 X2N0eC0+djRsMl9jdHg7Cj4+ICsJc3RydWN0IHZkZWNfaDI2NF9zdGF0ZWxlc3NfY3RybF9yZWYg KmN0cmxzID0gJmgyNjRfY3R4LT5jdHJsX3JlZjsKPj4gKwo+PiArCWN0cmxzLT5zcHMgPQo+PiAr CQkoc3RydWN0IHY0bDJfY3RybF9oMjY0X3NwcyAqKWFtbF9oMjY0X2dldF9jdHJsKCZjdHgtPmN0 cmxfaGFuZGxlciwKPj4gKwkJCVY0TDJfQ0lEX1NUQVRFTEVTU19IMjY0X1NQUyk7Cj4+ICsJaWYg KFdBUk5fT04oIWN0cmxzLT5zcHMpKQo+PiArCQlyZXR1cm4gLUVJTlZBTDsKPj4gKwo+PiArCWN0 cmxzLT5wcHMgPQo+PiArCQkoc3RydWN0IHY0bDJfY3RybF9oMjY0X3BwcyAqKWFtbF9oMjY0X2dl dF9jdHJsKCZjdHgtPmN0cmxfaGFuZGxlciwKPj4gKwkJCVY0TDJfQ0lEX1NUQVRFTEVTU19IMjY0 X1BQUyk7Cj4+ICsJaWYgKFdBUk5fT04oIWN0cmxzLT5wcHMpKQo+PiArCQlyZXR1cm4gLUVJTlZB TDsKPj4gKwo+PiArCWN0cmxzLT5kZWNvZGUgPQo+PiArCQkoc3RydWN0IHY0bDJfY3RybF9oMjY0 X2RlY29kZV9wYXJhbXMgKilhbWxfaDI2NF9nZXRfY3RybCgmY3R4LT5jdHJsX2hhbmRsZXIsCj4+ ICsJCQlWNEwyX0NJRF9TVEFURUxFU1NfSDI2NF9ERUNPREVfUEFSQU1TKTsKPj4gKwlpZiAoV0FS Tl9PTighY3RybHMtPmRlY29kZSkpCj4+ICsJCXJldHVybiAtRUlOVkFMOwo+PiArCj4+ICsJY3Ry bHMtPnNjYWxpbmcgPQo+PiArCQkoc3RydWN0IHY0bDJfY3RybF9oMjY0X3NjYWxpbmdfbWF0cml4 ICopYW1sX2gyNjRfZ2V0X2N0cmwoJmN0eC0+Y3RybF9oYW5kbGVyLAo+PiArCQkJVjRMMl9DSURf U1RBVEVMRVNTX0gyNjRfU0NBTElOR19NQVRSSVgpOwo+PiArCWlmIChXQVJOX09OKCFjdHJscy0+ c2NhbGluZykpCj4+ICsJCXJldHVybiAtRUlOVkFMOwo+PiArCj4+ICsJcmV0dXJuIDA7Cj4+ICt9 Cj4+ICsKPj4gK3N0YXRpYyB2b2lkIGNvcHlfbWNfY3B1X2Z3KHZvaWQgKm1jX2NwdV9hZGRyLCBj b25zdCB1OCAqZGF0YSkKPj4gK3sKPj4gKwkvKmhlYWRlciAqLwo+PiArCW1lbWNweSgodTggKilt Y19jcHVfYWRkciArIE1DX09GRlNFVF9IRUFERVIsCj4+ICsJwqDCoMKgwqDCoMKgIGRhdGEgKyAw eDQwMDAsIE1DX1NXQVBfU0laRSk7Cj4+ICsJLypkYXRhICovCj4+ICsJbWVtY3B5KCh1OCAqKW1j X2NwdV9hZGRyICsgTUNfT0ZGU0VUX0RBVEEsCj4+ICsJwqDCoMKgwqDCoMKgIGRhdGEgKyAweDIw MDAsIE1DX1NXQVBfU0laRSk7Cj4+ICsJLyptbWNvICovCj4+ICsJbWVtY3B5KCh1OCAqKW1jX2Nw dV9hZGRyICsgTUNfT0ZGU0VUX01NQ08sCj4+ICsJwqDCoMKgwqDCoMKgIGRhdGEgKyAweDYwMDAs IE1DX1NXQVBfU0laRSk7Cj4+ICsJLypsaXN0ICovCj4+ICsJbWVtY3B5KCh1OCAqKW1jX2NwdV9h ZGRyICsgTUNfT0ZGU0VUX0xJU1QsCj4+ICsJwqDCoMKgwqDCoMKgIGRhdGEgKyAweDMwMDAsIE1D X1NXQVBfU0laRSk7Cj4+ICsJLypzbGljZSAqLwo+PiArCW1lbWNweSgodTggKiltY19jcHVfYWRk ciArIE1DX09GRlNFVF9TTElDRSwKPj4gKwnCoMKgwqDCoMKgwqAgZGF0YSArIDB4NTAwMCwgTUNf U1dBUF9TSVpFKTsKPj4gKwkvKm1haW4gKi8KPj4gKwltZW1jcHkoKHU4ICopbWNfY3B1X2FkZHIg KyBNQ19PRkZTRVRfTUFJTiwgZGF0YSwgMHgyMDAwKTsKPj4gKwkvKmRhdGEgKi8KPj4gKwltZW1j cHkoKHU4ICopbWNfY3B1X2FkZHIgKyBNQ19PRkZTRVRfTUFJTiArIDB4MjAwMCwKPj4gKwnCoMKg wqDCoMKgwqAgZGF0YSArIDB4MjAwMCwgMHgxMDAwKTsKPj4gKwkvKnNsaWNlICovCj4+ICsJbWVt Y3B5KCh1OCAqKW1jX2NwdV9hZGRyICsgTUNfT0ZGU0VUX01BSU4gKyAweDMwMDAsCj4+ICsJwqDC oMKgwqDCoMKgIGRhdGEgKyAweDUwMDAsIDB4MTAwMCk7Cj4+ICt9Cj4+ICsKPj4gK3N0YXRpYyBp bnQgYW1sX2gyNjRfbG9hZF9md19leHQodm9pZCAqcHJpdiwgY29uc3QgdTggKmRhdGEsIHUzMiBs ZW4pCj4+ICt7Cj4+ICsJc3RydWN0IGFtbF9oMjY0X2N0eCAqaDI2NF9jdHggPSAoc3RydWN0IGFt bF9oMjY0X2N0eCAqKXByaXY7Cj4+ICsJc3RydWN0IGFtbF92ZGVjX2N0eCAqY3R4ID0gKHN0cnVj dCBhbWxfdmRlY19jdHggKiloMjY0X2N0eC0+djRsMl9jdHg7Cj4+ICsJc3RydWN0IGFtbF92ZGVj X2h3ICpkZWNfaHc7Cj4+ICsKPj4gKwlpZiAoaDI2NF9jdHgtPm1jX2NwdV9sb2FkZWQpCj4+ICsJ CXJldHVybiAwOwo+PiArCj4+ICsJZGVjX2h3ID0gdmRlY19nZXRfaHcoY3R4LT5kZXYpOwo+PiAr CWlmICghZGVjX2h3KQo+PiArCQlyZXR1cm4gLTE7Cj4+ICsKPj4gKwlpZiAobGVuID4gTUNfVE9U QUxfU0laRSkgewo+PiArCQlkZXZfaW5mbyhkZWNfaHctPmRldiwgInNpemUgb2YgbWNfY3B1X2Z3 IGlkIGludmFsaWRcbiIpOwo+PiArCQlyZXR1cm4gLTE7Cj4+ICsJfQo+PiArCj4+ICsJaDI2NF9j dHgtPm1jX2NwdV92YWRkciA9IGRtYV9hbGxvY19jb2hlcmVudChkZWNfaHctPmRldiwgTUNfVE9U QUxfU0laRSwKPj4gKwkJCQkJCcKgwqDCoCAmaDI2NF9jdHgtPm1jX2NwdV9wYWRkciwKPj4gKwkJ CQkJCcKgwqDCoCBHRlBfS0VSTkVMKTsKPj4gKwlpZiAoIWgyNjRfY3R4LT5tY19jcHVfdmFkZHIp Cj4+ICsJCXJldHVybiAtRU5PTUVNOwo+PiArCj4+ICsJY29weV9tY19jcHVfZncoaDI2NF9jdHgt Pm1jX2NwdV92YWRkciwgZGF0YSk7Cj4+ICsKPj4gKwloMjY0X2N0eC0+bWNfY3B1X2xvYWRlZCA9 IHRydWU7Cj4+ICsKPj4gKwlkZXZfZGJnKGRlY19ody0+ZGV2LCAiaDI2NCBtY2NwdSBmdyBsb2Fk ZWRcbiIpOwo+PiArCj4+ICsJcmV0dXJuIDA7Cj4+ICt9Cj4+ICsKPj4gK2ludCBhbWxfaDI2NF9p bml0KHZvaWQgKnByaXYpCj4+ICt7Cj4+ICsJc3RydWN0IGFtbF92ZGVjX2N0eCAqY3R4ID0gKHN0 cnVjdCBhbWxfdmRlY19jdHggKilwcml2Owo+PiArCXN0cnVjdCBhbWxfdmRlY19odyAqZGVjX2h3 Owo+PiArCXN0cnVjdCBhbWxfaDI2NF9jdHggKmgyNjRfY3R4Owo+PiArCWludCByZXQgPSAwOwo+ PiArCj4+ICsJaDI2NF9jdHggPSBremFsbG9jKHNpemVvZigqaDI2NF9jdHgpLCBHRlBfS0VSTkVM KTsKPj4gKwlpZiAoIWgyNjRfY3R4KQo+PiArCQlyZXR1cm4gLUVOT01FTTsKPj4gKwo+PiArCWgy NjRfY3R4LT52NGwyX2N0eCA9IGN0eDsKPj4gKwlkZWNfaHcgPSB2ZGVjX2dldF9odyhjdHgtPmRl dik7Cj4+ICsJaWYgKCFkZWNfaHcpCj4+ICsJCXJldHVybiAtMTsKPj4gKwo+PiArCWgyNjRfY3R4 LT5tY19jcHVfbG9hZGVkID0gZmFsc2U7Cj4+ICsJZGVjX2h3LT5od19vcHMuaXJxX2hhbmRsZXIg PSBoMjY0X2lzcjsKPj4gKwlkZWNfaHctPmh3X29wcy5pcnFfdGhyZWFkZWRfZnVuYyA9IGgyNjRf dGhyZWFkZWRfaXNyX2Z1bmM7Cj4+ICsJZGVjX2h3LT5od19vcHMubG9hZF9maXJtd2FyZV9leCA9 IGFtbF9oMjY0X2xvYWRfZndfZXh0Owo+PiArCj4+ICsJaDI2NF9jdHgtPmxtZW1fYWRkciA9IGRt YV9hbGxvY19jb2hlcmVudChkZWNfaHctPmRldiwgTE1FTV9EVU1QX1NJWkUsCj4+ICsJCQkJCQkg JmgyNjRfY3R4LT5sbWVtX3BoeV9hZGRyLAo+PiArCQkJCQkJIEdGUF9LRVJORUwpOwo+PiArCWlm ICghaDI2NF9jdHgtPmxtZW1fYWRkcikgewo+PiArCQlyZXQgPSAtRU5PTUVNOwo+PiArCQlnb3Rv IGVycl9hbGxvY19sbWVtOwo+PiArCX0KPj4gKwo+PiArCWgyNjRfY3R4LT5jbWFfYWxsb2NfdmFk ZHIgPQo+PiArCcKgwqDCoCBkbWFfYWxsb2NfY29oZXJlbnQoZGVjX2h3LT5kZXYsIFZfQlVGX0FE RFJfT0ZGU0VULAo+PiArCQkJwqDCoMKgwqDCoMKgICZoMjY0X2N0eC0+Y21hX2FsbG9jX2FkZHIs IEdGUF9LRVJORUwpOwo+PiArCWlmICghaDI2NF9jdHgtPmNtYV9hbGxvY192YWRkcikgewo+PiAr CQlyZXQgPSAtRU5PTUVNOwo+PiArCQlnb3RvIGVycl9hbGxvY193b3Jrc3BhY2U7Cj4+ICsJfQo+ PiArCj4+ICsJaDI2NF9jdHgtPndvcmtzcGFjZV9vZmZzZXQgPSBoMjY0X2N0eC0+Y21hX2FsbG9j X2FkZHIgKyBEQ0FDX1JFQURfTUFSR0lOOwo+PiArCWgyNjRfY3R4LT53b3Jrc3BhY2VfdmFkZHIg PSBoMjY0X2N0eC0+Y21hX2FsbG9jX3ZhZGRyICsgRENBQ19SRUFEX01BUkdJTjsKPj4gKwo+PiAr CWN0eC0+Y29kZWNfcHJpdiA9IGgyNjRfY3R4Owo+PiArCWRlY19ody0+Y3Vycl9jdHggPSBoMjY0 X2N0eDsKPj4gKwloMjY0X2N0eC0+Y29sX2J1Zl9hbGxvY19zaXplID0gMDsKPj4gKwloMjY0X2N0 eC0+aW5pdF9mbGFnID0gMDsKPj4gKwloMjY0X2N0eC0+bmV3X3BpY19mbGFnID0gMDsKPj4gKwlo MjY0X2N0eC0+cGFyYW1fc2V0ID0gMDsKPj4gKwloMjY0X2N0eC0+cmVnX2lxaWRjdF9jb250cm9s X2luaXRfZmxhZyA9IDA7Cj4+ICsJaDI2NF9jdHgtPmRlY29kZV9waWNfY291bnQgPSAwOwo+PiAr Cj4+ICsJcmV0dXJuIDA7Cj4+ICsKPj4gK2Vycl9hbGxvY193b3Jrc3BhY2U6Cj4+ICsJZG1hX2Zy ZWVfY29oZXJlbnQoZGVjX2h3LT5kZXYsIExNRU1fRFVNUF9TSVpFLAo+PiArCQkJwqAgaDI2NF9j dHgtPmxtZW1fYWRkciwgaDI2NF9jdHgtPmxtZW1fcGh5X2FkZHIpOwo+PiArZXJyX2FsbG9jX2xt ZW06Cj4+ICsJa2ZyZWUoaDI2NF9jdHgpOwo+PiArCj4+ICsJcmV0dXJuIHJldDsKPj4gK30KPj4g Kwo+PiArdm9pZCBhbWxfaDI2NF9leGl0KHZvaWQgKnByaXYpCj4+ICt7Cj4+ICsJc3RydWN0IGFt bF92ZGVjX2N0eCAqY3R4ID0gKHN0cnVjdCBhbWxfdmRlY19jdHggKilwcml2Owo+PiArCXN0cnVj dCBhbWxfaDI2NF9jdHggKmgyNjRfY3R4ID0gKHN0cnVjdCBhbWxfaDI2NF9jdHggKiljdHgtPmNv ZGVjX3ByaXY7Cj4+ICsJc3RydWN0IGFtbF92ZGVjX2h3ICpkZWNfaHc7Cj4+ICsKPj4gKwlpZiAo IWgyNjRfY3R4KSB7Cj4+ICsJCWRldl9pbmZvKCZjdHgtPmRldi0+cGxhdF9kZXYtPmRldiwgImgy NjQgZGVjb2RlciBpcyBhbHJlYWR5IGRlc3Ryb3llZCBvciBub3QgY3JlYXRlZCFcbiIpOwo+PiAr CQlyZXR1cm47Cj4+ICsJfQo+PiArCWRlY19odyA9IHZkZWNfZ2V0X2h3KGN0eC0+ZGV2KTsKPj4g KwloMjY0X2N0eC0+cGFyYW1fc2V0ID0gMDsKPj4gKwo+PiArCWlmIChjdHgtPmRvc19jbGtfZW4p Cj4+ICsJCWFtbF9zdG9wX3ZkZWNfaHcoZGVjX2h3KTsKPj4gKwo+PiArCWlmIChoMjY0X2N0eC0+ Y29sbGF0ZWRfY21hX3ZhZGRyKSB7Cj4+ICsJCWRtYV9mcmVlX2NvaGVyZW50KGRlY19ody0+ZGV2 LCBoMjY0X2N0eC0+Y29sX2J1Zl9hbGxvY19zaXplLAo+PiArCQkJCcKgIGgyNjRfY3R4LT5jb2xs YXRlZF9jbWFfdmFkZHIsCj4+ICsJCQkJwqAgaDI2NF9jdHgtPmNvbGxhdGVkX2NtYV9hZGRyKTsK Pj4gKwkJaDI2NF9jdHgtPmNvbF9idWZfYWxsb2Nfc2l6ZSA9IDA7Cj4+ICsJfQo+PiArCj4+ICsJ aWYgKGgyNjRfY3R4LT5tY19jcHVfdmFkZHIpIHsKPj4gKwkJZG1hX2ZyZWVfY29oZXJlbnQoZGVj X2h3LT5kZXYsIE1DX1RPVEFMX1NJWkUsCj4+ICsJCQkJwqAgaDI2NF9jdHgtPm1jX2NwdV92YWRk ciwKPj4gKwkJCQnCoCBoMjY0X2N0eC0+bWNfY3B1X3BhZGRyKTsKPj4gKwkJaDI2NF9jdHgtPm1j X2NwdV9sb2FkZWQgPSBmYWxzZTsKPj4gKwl9Cj4+ICsKPj4gKwlpZiAoaDI2NF9jdHgtPmxtZW1f YWRkcikKPj4gKwkJZG1hX2ZyZWVfY29oZXJlbnQoZGVjX2h3LT5kZXYsIExNRU1fRFVNUF9TSVpF LAo+PiArCQkJCcKgIGgyNjRfY3R4LT5sbWVtX2FkZHIsIGgyNjRfY3R4LT5sbWVtX3BoeV9hZGRy KTsKPj4gKwo+PiArCWlmIChoMjY0X2N0eC0+Y21hX2FsbG9jX3ZhZGRyKQo+PiArCQlkbWFfZnJl ZV9jb2hlcmVudChkZWNfaHctPmRldiwgVl9CVUZfQUREUl9PRkZTRVQsCj4+ICsJCQkJwqAgaDI2 NF9jdHgtPmNtYV9hbGxvY192YWRkciwKPj4gKwkJCQnCoCBoMjY0X2N0eC0+Y21hX2FsbG9jX2Fk ZHIpOwo+PiArCj4+ICsJa2ZyZWUoY3R4LT5jb2RlY19wcml2KTsKPj4gKwlkZWNfaHctPmN1cnJf Y3R4ID0gTlVMTDsKPj4gKwljdHgtPmNvZGVjX3ByaXYgPSBOVUxMOwo+PiArfQo+PiArCj4+ICtz dGF0aWMgdm9pZCBjb25maWdfZGVjb2RlX21vZGUoc3RydWN0IGFtbF92ZGVjX2N0eCAqY3R4KQo+ PiArewo+PiArCXN0cnVjdCBhbWxfaDI2NF9jdHggKmgyNjRfY3R4ID0gKHN0cnVjdCBhbWxfaDI2 NF9jdHggKiljdHgtPmNvZGVjX3ByaXY7Cj4+ICsJc3RydWN0IGFtbF92ZGVjX2h3ICpodyA9IHZk ZWNfZ2V0X2h3KGN0eC0+ZGV2KTsKPj4gKwo+PiArCXJlZ21hcF93cml0ZShody0+bWFwW0RPU19C VVNdLCBIMjY0X0RFQ09ERV9NT0RFLCAweDEpOyAvKmRlY29kZSBtb2RlIGZyYW1lYmFzZSovCj4+ ICsJcmVnbWFwX3dyaXRlKGh3LT5tYXBbRE9TX0JVU10sIEhFQURfUEFERElOR19SRUcsIDApOwo+ PiArCXJlZ21hcF93cml0ZShody0+bWFwW0RPU19CVVNdLCBIMjY0X0RFQ09ERV9TRVFJTkZPLCBo MjY0X2N0eC0+c2VxX2luZm8pOwo+PiArCXJlZ21hcF93cml0ZShody0+bWFwW0RPU19CVVNdLCBJ TklUX0ZMQUdfUkVHLCAxKTsKPj4gK30KPj4gKwo+PiAraW50IGFtbF9oMjY0X2RlY19ydW4odm9p ZCAqcHJpdikKPj4gK3sKPj4gKwlzdHJ1Y3QgYW1sX3ZkZWNfY3R4ICpjdHggPSAoc3RydWN0IGFt bF92ZGVjX2N0eCAqKXByaXY7Cj4+ICsJc3RydWN0IGFtbF9oMjY0X2N0eCAqaDI2NF9jdHggPSAo c3RydWN0IGFtbF9oMjY0X2N0eCAqKWN0eC0+Y29kZWNfcHJpdjsKPj4gKwlzdHJ1Y3QgYW1sX3Zk ZWNfaHcgKmRlY19odyA9IHZkZWNfZ2V0X2h3KGN0eC0+ZGV2KTsKPj4gKwlpbnQgcmV0ID0gLTE7 Cj4+ICsJaW50IGk7Cj4+ICsKPj4gKwlyZXQgPSBhbWxfaDI2NF9nZXRfc3RhdGVsZXNzX2N0cmxf cmVmKGgyNjRfY3R4KTsKPj4gKwlpZiAocmV0IDwgMCkgewo+PiArCQlkZXZfZXJyKCZjdHgtPmRl di0+cGxhdF9kZXYtPmRldiwgIm5vdCBjdHJsIHJlZiBmb3IgaDI2NCBkZWNvZGVyXG4iKTsKPj4g KwkJcmV0dXJuIHJldDsKPj4gKwl9Cj4+ICsKPj4gKwloMjY0X2NvbmZpZ19wYXJhbXMoY3R4KTsK Pj4gKwo+PiArCWlmIChoMjY0X3ByZXBhcmVfaW5wdXQoY3R4KSA8IDApCj4+ICsJCXJldHVybiBy ZXQ7Cj4+ICsKPj4gKwlpZiAoYWxsb2NfY29sb2NhdGVfY21hKGgyNjRfY3R4LCBjdHgpIDwgMCkK Pj4gKwkJcmV0dXJuIHJldDsKPj4gKwo+PiArCWgyNjRfcmVzdG9yZV9od19jdHgoY3R4KTsKPj4g Kwo+PiArCWNvbmZpZ19kZWNvZGVfbW9kZShjdHgpOwo+PiArCS8qIGVuYWJsZSBzdHJlYW0gaW5w dXQgaGFyZHdhcmUgKi8KPj4gKwlyZWdtYXBfdXBkYXRlX2JpdHMoZGVjX2h3LT5tYXBbRE9TX0JV U10sIFZMRF9NRU1fVklGSUZPX0NPTlRST0wsIDB4NiwgMHg2KTsKPj4gKwkvKiBlbmFibGUgaGFy ZHdhcmUgdGltZXIgKi8KPj4gKwlyZWdtYXBfd3JpdGUoZGVjX2h3LT5tYXBbRE9TX0JVU10sIE5B TF9TRUFSQ0hfQ1RMLAo+PiArCQnCoMKgwqDCoCByZWFkX2Rvc19yZWcoZGVjX2h3LCBOQUxfU0VB UkNIX0NUTCkgfCAoMSA8PCAxNikpOwo+PiArCXJlZ21hcF93cml0ZShkZWNfaHctPm1hcFtET1Nf QlVTXSwgTURFQ19FWFRJRl9DRkcyLAo+PiArCQnCoMKgwqDCoCByZWFkX2Rvc19yZWcoZGVjX2h3 LCBNREVDX0VYVElGX0NGRzIpIHwgMHgyMCk7Cj4+ICsJcmVnbWFwX3dyaXRlKGRlY19ody0+bWFw W0RPU19CVVNdLCBOQUxfU0VBUkNIX0NUTCwKPj4gKwkJwqDCoMKgwqAgcmVhZF9kb3NfcmVnKGRl Y19odywgTkFMX1NFQVJDSF9DVEwpICYgKH4weDIpKTsKPj4gKwlyZWdtYXBfdXBkYXRlX2JpdHMo ZGVjX2h3LT5tYXBbRE9TX0JVU10sIFZERUNfQVNTSVNUX01NQ19DVFJMMSwKPj4gKwkJCcKgwqAg KDEgPDwgMyksIDApOwo+PiArCj4+ICsJYW1sX3N0YXJ0X3ZkZWNfaHcoZGVjX2h3KTsKPj4gKwlo MjY0X2N0eC0+aW5pdF9mbGFnID0gMTsKPj4gKwloMjY0X2N0eC0+bmV3X3BpY19mbGFnID0gMTsK Pj4gKwo+PiArCXJlZ21hcF93cml0ZShkZWNfaHctPm1hcFtET1NfQlVTXSwgRFBCX1NUQVRVU19S RUcsIEgyNjRfQUNUSU9OX1NFQVJDSF9IRUFEKTsKPj4gKwo+PiArCXJldCA9IHdhaXRfZXZlbnRf aW50ZXJydXB0aWJsZV90aW1lb3V0KGN0eC0+cXVldWUsIGN0eC0+aW50X2NvbmQsCj4+ICsJCQkJ CcKgwqDCoMKgwqDCoCBtc2Vjc190b19qaWZmaWVzKERFQ09ERVJfVElNRU9VVF9NUykpOwo+PiAr CWN0eC0+aW50X2NvbmQgPSAwOwo+PiArCWlmICghcmV0KSB7Cj4+ICsJCXJldCA9IC0xOwo+PiAr CQlkZXZfZXJyKCZjdHgtPmRldi0+cGxhdF9kZXYtPmRldiwgImRlYyB0aW1lb3V0PSV1XG4iLCBE RUNPREVSX1RJTUVPVVRfTVMpOwo+PiArCQlmb3IgKGkgPSAwOyBpIDwgMTY7IGkrKykgewkvKiAx NiA6IHNob3cgdWNvZGUgUEMgMTYgdGltZXMgd2hlbiB0aW1lb3V0ICovCj4+ICsJCQlkZXZfaW5m bygmY3R4LT5kZXYtPnBsYXRfZGV2LT5kZXYsICJkZWNvZGVyIHRpbWVvdXQsIHBjIDB4JXhcbiIs Cj4+ICsJCQkJIHJlYWRfZG9zX3JlZyhkZWNfaHcsIE1QQ19FKSk7Cj4+ICsJCQl1c2xlZXBfcmFu Z2UoMTAsIDIwKTsKPj4gKwkJfQo+PiArCX0gZWxzZSBpZiAoLUVSRVNUQVJUU1lTID09IHJldCkg ewo+PiArCQlyZXQgPSAtMTsKPj4gKwkJZGV2X2VycigmY3R4LT5kZXYtPnBsYXRfZGV2LT5kZXYs ICJkZWMgaW50ZXIgZmFpbFxuIik7Cj4+ICsJfQo+PiArCj4+ICsJYW1sX3N0b3BfdmRlY19odyhk ZWNfaHcpOwo+PiArCWgyNjRfY3R4LT5pbml0X2ZsYWcgPSAwOwo+PiArCj4+ICsJcmV0dXJuIHJl dDsKPj4gK30KPj4gZGlmZiAtLWdpdCBhL2RyaXZlcnMvbWVkaWEvcGxhdGZvcm0vYW1sb2dpYy92 ZGVjL2gyNjQuaCBiL2RyaXZlcnMvbWVkaWEvcGxhdGZvcm0vYW1sb2dpYy92ZGVjL2gyNjQuaAo+ PiBuZXcgZmlsZSBtb2RlIDEwMDY0NAo+PiBpbmRleCAwMDAwMDAwMDAwMDAuLjNkM2EzNWE2NDFj OQo+PiAtLS0gL2Rldi9udWxsCj4+ICsrKyBiL2RyaXZlcnMvbWVkaWEvcGxhdGZvcm0vYW1sb2dp Yy92ZGVjL2gyNjQuaAo+PiBAQCAtMCwwICsxLDMwMCBAQAo+PiArLyogU1BEWC1MaWNlbnNlLUlk ZW50aWZpZXI6IChHUEwtMi4wLW9ubHkgT1IgTUlUKSAqLwo+PiArLyoKPj4gKyAqIENvcHlyaWdo dCAoQykgMjAyNSBBbWxvZ2ljLCBJbmMuIEFsbCByaWdodHMgcmVzZXJ2ZWQKPj4gKyAqLwo+PiAr I2lmbmRlZiBfSDI2NF9IXwo+PiArI2RlZmluZSBfSDI2NF9IXwo+PiArCj4+ICsjZGVmaW5lIFJQ TV9CRUdJTsKgwqDCoMKgwqDCoMKgwqDCoMKgIDB4MAo+PiArI2RlZmluZSBGUkFNRV9JTl9EUELC oMKgwqDCoMKgwqDCoCAyNAo+PiArI2RlZmluZSBSUE1fRU5EwqDCoMKgwqDCoMKgwqDCoMKgwqDC oMKgIDB4NDAwCj4+ICsjZGVmaW5lIERQQl9PRkZTRVTCoMKgwqDCoMKgwqDCoMKgwqAgMHgxMDAK Pj4gKyNkZWZpbmUgTU1DT19PRkZTRVTCoMKgwqDCoMKgwqDCoMKgIDB4MjAwCj4+ICsjZGVmaW5l IFNQU19PRkZTRVTCoMKgwqDCoMKgwqDCoMKgwqAgMHgxMDAKPj4gKyNkZWZpbmUgUFBTX09GRlNF VMKgwqDCoMKgwqDCoMKgwqDCoCAweDMwMAo+PiArI2RlZmluZSBQQVJBTV9CQVNFX1ZBTMKgwqDC oMKgwqAgMHg0MTRkCj4+ICsjZGVmaW5lIE1FTV9NTUNPX0JBU0XCoMKgwqDCoMKgwqAgMHgwMWMz MDAwCj4+ICsjZGVmaW5lIE1FTV9TUFNfQkFTRcKgwqDCoMKgwqDCoMKgIDB4MDFjM2MwMAo+PiAr I2RlZmluZSBNRU1fUFBTX0JBU0XCoMKgwqDCoMKgwqDCoCAweDAxY2JjMDAKPj4gKyNkZWZpbmUg TUNfVE9UQUxfU0laRcKgwqDCoMKgwqDCoCAoKDIwICsgMTYpICogU1pfMUspCj4+ICsjZGVmaW5l IE1DX1NXQVBfU0laRcKgwqDCoMKgwqDCoMKgICg0ICogU1pfMUspCj4+ICsjZGVmaW5lIExNRU1f RFVNUF9TSVpFwqDCoMKgwqDCoCA0MDk2Cj4+ICsjZGVmaW5lIFZfQlVGX0FERFJfT0ZGU0VUwqDC oCAoMHgyMDAwMDAgKyAweDgwMDAgKyAweDIwMDAwICsgMHgxMDAwKQo+PiArI2RlZmluZSBEQ0FD X1JFQURfTUFSR0lOwqDCoMKgICg2NCAqIDEwMjQpCj4+ICsjZGVmaW5lIE1DX09GRlNFVF9IRUFE RVLCoMKgwqAgMHgwMDAwCj4+ICsjZGVmaW5lIE1DX09GRlNFVF9EQVRBwqDCoMKgwqDCoCAweDEw MDAKPj4gKyNkZWZpbmUgTUNfT0ZGU0VUX01NQ0/CoMKgwqDCoMKgIDB4MjAwMAo+PiArI2RlZmlu ZSBNQ19PRkZTRVRfTElTVMKgwqDCoMKgwqAgMHgzMDAwCj4+ICsjZGVmaW5lIE1DX09GRlNFVF9T TElDRcKgwqDCoMKgIDB4NDAwMAo+PiArI2RlZmluZSBNQ19PRkZTRVRfTUFJTsKgwqDCoMKgwqAg MHg1MDAwCj4+ICsKPj4gKy8qIFJlbmFtZSB0aGUgZG9zIHJlZ3MgKi8KPj4gKyNkZWZpbmUgSDI2 NF9ERUNPREVfSU5GT8KgwqDCoCBNNF9DT05UUk9MX1JFRwo+PiArI2RlZmluZSBJTklUX0ZMQUdf UkVHwqDCoMKgwqDCoMKgIEFWX1NDUkFUQ0hfMgo+PiArI2RlZmluZSBIRUFEX1BBRERJTkdfUkVH wqDCoMKgwqAgQVZfU0NSQVRDSF8zCj4+ICsjZGVmaW5lIFVDT0RFX1dBVENIRE9HX1JFR8KgwqAg QVZfU0NSQVRDSF83Cj4+ICsjZGVmaW5lIExNRU1fRFVNUF9BRFLCoMKgwqDCoMKgwqAgQVZfU0NS QVRDSF9MCj4+ICsjZGVmaW5lIERFQlVHX1JFRzHCoMKgwqDCoMKgwqDCoMKgwqAgQVZfU0NSQVRD SF9NCj4+ICsjZGVmaW5lIERFQlVHX1JFRzLCoMKgwqDCoMKgwqDCoMKgwqAgQVZfU0NSQVRDSF9O Cj4+ICsjZGVmaW5lIEZSQU1FX0NPVU5URVJfUkVHwqDCoMKgwqDCoMKgIEFWX1NDUkFUQ0hfSQo+ PiArI2RlZmluZSBSUE1fQ01EX1JFR8KgwqDCoMKgwqDCoMKgwqDCoCBBVl9TQ1JBVENIX0EKPj4g KyNkZWZpbmUgSDI2NF9ERUNPREVfU0laRcKgwqDCoCBBVl9TQ1JBVENIX0UKPj4gKyNkZWZpbmUg SDI2NF9ERUNPREVfTU9ERcKgwqDCoCBBVl9TQ1JBVENIXzQKPj4gKyNkZWZpbmUgSDI2NF9ERUNP REVfU0VRSU5GT8KgwqDCoCBBVl9TQ1JBVENIXzUKPj4gKy8qKgo+PiArICogTkFMX1NFQVJDSF9D VEw6IGJpdCAwLCBlbmFibGUgaXR1X3QzNQo+PiArICogTkFMX1NFQVJDSF9DVEw6IGJpdCAxLCBl bmFibGUgbW11Cj4+ICsgKiBOQUxfU0VBUkNIX0NUTDogYml0IDIsIGRldGVjdCBmcmFtZV9tYnNf b25seV9mbGFnIHdoZXRoZXIgc3dpdGNoIHJlc29sdXRpb24KPj4gKyAqIE5BTF9TRUFSQ0hfQ1RM OiBiaXQgMywgcmVjb3ZlciB0aGUgY29ycmVjdCBzcHMgcHBzCj4+ICsgKiBOQUxfU0VBUkNIX0NU TDogYml0IDctMTQsbGV2ZWxfaWRjCj4+ICsgKiBOQUxfU0VBUkNIX0NUTDogYml0IDE1LGJpdHN0 cmVhbV9yZXN0cmljdGlvbl9mbGFnCj4+ICsgKi8KPj4gKyNkZWZpbmUgTkFMX1NFQVJDSF9DVEzC oMKgwqDCoMKgIEFWX1NDUkFUQ0hfOQo+PiArI2RlZmluZSBEUEJfU1RBVFVTX1JFR8KgwqDCoMKg wqAgQVZfU0NSQVRDSF9KCj4+ICsjZGVmaW5lIEVSUk9SX1NUQVRVU19SRUfCoMKgwqAgQVZfU0NS QVRDSF85Cj4+ICsKPj4gKyNkZWZpbmUgSDI2NF9CVUZGRVJfSU5GT19JTkRFWMKgwqDCoMKgwqAg UE1WM19YCS8qIDB4YzI0ICovCj4+ICsjZGVmaW5lIEgyNjRfQlVGRkVSX0lORk9fREFUQcKgwqDC oMKgwqDCoCBQTVYyX1gJLyogMHhjMjIgKi8KPj4gKyNkZWZpbmUgSDI2NF9DVVJSRU5UX1BPQ19J RFhfUkVTRVTCoCBMQVNUX1NMSUNFX01WX0FERFIJLyogMHhjMzAgKi8KPj4gKyNkZWZpbmUgSDI2 NF9DVVJSRU5UX1BPQ8KgwqDCoMKgwqDCoMKgwqDCoMKgwqAgTEFTVF9NVlkJLyogMHhjMzIgc2hh cmVkIHdpdGggY29uY2VhbCBNViAqLwo+PiArI2RlZmluZSBIMjY0X0NPX01CX1dSX0FERFLCoMKg wqDCoMKgwqDCoMKgwqAgVkxEX0MzOAo+PiArI2RlZmluZSBIMjY0X0NPX01CX1JEX0FERFLCoMKg wqDCoMKgwqDCoMKgwqAgVkxEX0MzOQo+PiArI2RlZmluZSBIMjY0X0NPX01CX1JXX0NUTMKgwqDC oMKgwqDCoMKgwqDCoMKgIFZMRF9DM0QKPj4gKyNkZWZpbmUgTUJZX01CWMKgwqDCoMKgwqDCoMKg wqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqAgTUJfTU9USU9OX01PREUKPj4gKwo+PiArI2RlZmlu ZSBIMjY0X0FDVElPTl9TRUFSQ0hfSEVBRMKgwqDCoMKgIDB4ZjAKPj4gKyNkZWZpbmUgSDI2NF9B Q1RJT05fREVDT0RFX1NMSUNFwqDCoMKgIDB4ZjEKPj4gKyNkZWZpbmUgSDI2NF9BQ1RJT05fQ09O RklHX0RPTkXCoMKgwqDCoCAweGYyCj4+ICsjZGVmaW5lIEgyNjRfQUNUSU9OX0RFQ09ERV9ORVdQ SUPCoMKgIDB4ZjMKPj4gKyNkZWZpbmUgSDI2NF9BQ1RJT05fREVDT0RFX1NUQVJUwqDCoMKgIDB4 ZmYKPj4gKwo+PiArLyogUlBNIG1lbW9yeSBkZWZpbml0aW9uICovCj4+ICsjZGVmaW5lIEZJWEVE X0ZSQU1FX1JBVEVfRkxBRwkJCQkJCTBYMjEKPj4gKyNkZWZpbmUgT0ZGU0VUX0RFTElNSVRFUl9M TwkJCQkJCTB4MmYKPj4gKyNkZWZpbmUgT0ZGU0VUX0RFTElNSVRFUl9ISQkJCQkJCTB4MzAKPj4g KyNkZWZpbmUgUkVGX0lEQ19PVkVSUklERV9GTEFHCQkJCQkJMHgzNQo+PiArI2RlZmluZSBTTElD RV9JUE9OTFlfQlJFQUsJCQkJCQkwWDVDCj4+ICsjZGVmaW5lIFBSRVZfTUFYX1JFRkVSRU5DRV9G UkFNRV9OVU0JCQkJCTBYNUQKPj4gKyNkZWZpbmUgRU9TCQkJCQkJCQkwWDVFCj4+ICsjZGVmaW5l IEZSQU1FX1BBQ0tJTkdfVFlQRQkJCQkJCTBYNUYKPj4gKyNkZWZpbmUgT0xEX1BPQ19QQVJfMQkJ CQkJCQkwWDYwCj4+ICsjZGVmaW5lIE9MRF9QT0NfUEFSXzIJCQkJCQkJMFg2MQo+PiArI2RlZmlu ZSBQUkVWX01CWAkJCQkJCQkwWDYyCj4+ICsjZGVmaW5lIFBSRVZfTUJZCQkJCQkJCTBYNjMKPj4g KyNkZWZpbmUgRVJST1JfU0tJUF9NQl9OVU0JCQkJCQkwWDY0Cj4+ICsjZGVmaW5lIEVSUk9SX01C X1NUQVRVUwkJCQkJCQkwWDY1Cj4+ICsjZGVmaW5lIEwwX1BJQzBfU1RBVFVTCQkJCQkJCTBYNjYK Pj4gKyNkZWZpbmUgVElNRU9VVF9DT1VOVEVSCQkJCQkJCTBYNjcKPj4gKyNkZWZpbmUgQlVGRkVS X1NJWkUJCQkJCQkJMFg2OAo+PiArI2RlZmluZSBCVUZGRVJfU0laRV9ISQkJCQkJCQkwWDY5Cj4+ ICsjZGVmaW5lIENST1BQSU5HX0xFRlRfUklHSFQJCQkJCQkwWDZBCj4+ICsjZGVmaW5lIENST1BQ SU5HX1RPUF9CT1RUT00JCQkJCQkwWDZCCj4+ICsvKioKPj4gKyAqIHNwc19mbGFnczI6Cj4+ICsg KiBiaXQgMywgYml0c3RyZWFtX3Jlc3RyaWN0aW9uX2ZsYWcKPj4gKyAqIGJpdCAyLCBwaWNfc3Ry dWN0X3ByZXNlbnRfZmxhZwo+PiArICogYml0IDEsIHZjbF9ocmRfcGFyYW1ldGVyc19wcmVzZW50 X2ZsYWcKPj4gKyAqIGJpdCAwLCBuYWxfaHJkX3BhcmFtZXRlcnNfcHJlc2VudF9mbGFnCj4+ICsg Ki8KPj4gKyNkZWZpbmUgU1BTX0ZMQUdTMgkJCQkJCQkweDZDCj4+ICsjZGVmaW5lIE5VTV9SRU9S REVSX0ZSQU1FUwkJCQkJCTB4NkQKPj4gKyNkZWZpbmUgTUFYX0JVRkZFUl9GUkFNRQkJCQkJCTBY NkUKPj4gKwo+PiArI2RlZmluZSBOT05fQ09ORk9STUlOR19TVFJFQU0JCQkJCQkwWDcwCj4+ICsj ZGVmaW5lIFJFQ09WRVJZX1BPSU5UCQkJCQkJCTBYNzEKPj4gKyNkZWZpbmUgUE9TVF9DQU5WQVMJ CQkJCQkJMFg3Mgo+PiArI2RlZmluZSBQT1NUX0NBTlZBU19ICQkJCQkJCTBYNzMKPj4gKyNkZWZp bmUgU0tJUF9QSUNfQ09VTlQJCQkJCQkJMFg3NAo+PiArI2RlZmluZSBUQVJHRVRfTlVNX1NDQUxJ TkdfTElTVAkJCQkJCTBYNzUKPj4gKyNkZWZpbmUgRkZfUE9TVF9PTkVfRlJBTUUJCQkJCQkwWDc2 Cj4+ICsjZGVmaW5lIFBSRVZJT1VTX0JJVF9DTlQJCQkJCQkwWDc3Cj4+ICsjZGVmaW5lIE1CX05P VF9TSElGVF9DT1VOVAkJCQkJCTBYNzgKPj4gKyNkZWZpbmUgUElDX1NUQVRVUwkJCQkJCQkwWDc5 Cj4+ICsjZGVmaW5lIEZSQU1FX0NPVU5URVIJCQkJCQkJMFg3QQo+PiArI2RlZmluZSBORVdfU0xJ Q0VfVFlQRQkJCQkJCQkwWDdCCj4+ICsjZGVmaW5lIE5FV19QSUNUVVJFX1NUUlVDVFVSRQkJCQkJ CTBYN0MKPj4gKyNkZWZpbmUgTkVXX0ZSQU1FX05VTQkJCQkJCQkwWDdECj4+ICsjZGVmaW5lIE5F V19JRFJfUElDX0lECQkJCQkJCTBYN0UKPj4gKyNkZWZpbmUgSURSX1BJQ19JRAkJCQkJCQkwWDdG Cj4+ICsKPj4gKy8qIGgyNjQgTE9DQUwgKi8KPj4gKyNkZWZpbmUgTkFMX1VOSVRfVFlQRQkJCQkJ CQkwWDgwCj4+ICsjZGVmaW5lIE5BTF9SRUZfSURDCQkJCQkJCTBYODEKPj4gKyNkZWZpbmUgU0xJ Q0VfVFlQRQkJCQkJCQkwWDgyCj4+ICsjZGVmaW5lIExPRzJfTUFYX0ZSQU1FX05VTQkJCQkJCTBY ODMKPj4gKyNkZWZpbmUgRlJBTUVfTUJTX09OTFlfRkxBRwkJCQkJCTBYODQKPj4gKyNkZWZpbmUg UElDX09SREVSX0NOVF9UWVBFCQkJCQkJMFg4NQo+PiArI2RlZmluZSBMT0cyX01BWF9QSUNfT1JE RVJfQ05UX0xTQgkJCQkJMFg4Ngo+PiArI2RlZmluZSBQSUNfT1JERVJfUFJFU0VOVF9GTEFHCQkJ CQkJMFg4Nwo+PiArI2RlZmluZSBSRURVTkRBTlRfUElDX0NOVF9QUkVTRU5UX0ZMQUcJCQkJCTBY ODgKPj4gKyNkZWZpbmUgUElDX0lOSVRfUVBfTUlOVVMyNgkJCQkJCTBYODkKPj4gKyNkZWZpbmUg REVCTE9DS0lOR19GSUxURVJfQ09OVFJPTF9QUkVTRU5UX0ZMQUcJCQkJMFg4QQo+PiArI2RlZmlu ZSBOVU1fU0xJQ0VfR1JPVVBTX01JTlVTMQkJCQkJCTBYOEIKPj4gKyNkZWZpbmUgTU9ERV84WDhf RkxBR1MJCQkJCQkJMFg4Qwo+PiArI2RlZmluZSBFTlRST1BZX0NPRElOR19NT0RFX0ZMQUcJCQkJ CTBYOEQKPj4gKyNkZWZpbmUgU0xJQ0VfUVVBTlQJCQkJCQkJMFg4RQo+PiArI2RlZmluZSBUT1RB TF9NQl9IRUlHSFQJCQkJCQkJMFg4Rgo+PiArI2RlZmluZSBQSUNUVVJFX1NUUlVDVFVSRQkJCQkJ CTBYOTAKPj4gKyNkZWZpbmUgVE9QX0lOVFJBX1RZUEUJCQkJCQkJMFg5MQo+PiArI2RlZmluZSBS Vl9BSV9TVEFUVVMJCQkJCQkJMFg5Mgo+PiArI2RlZmluZSBBSV9SRUFEX1NUQVJUCQkJCQkJCTBY OTMKPj4gKyNkZWZpbmUgQUlfV1JJVEVfU1RBUlQJCQkJCQkJMFg5NAo+PiArI2RlZmluZSBBSV9D VVJfQlVGRkVSCQkJCQkJCTBYOTUKPj4gKyNkZWZpbmUgQUlfRE1BX0JVRkZFUgkJCQkJCQkwWDk2 Cj4+ICsjZGVmaW5lIEFJX1JFQURfT0ZGU0VUCQkJCQkJCTBYOTcKPj4gKyNkZWZpbmUgQUlfV1JJ VEVfT0ZGU0VUCQkJCQkJCTBYOTgKPj4gKyNkZWZpbmUgQUlfV1JJVEVfT0ZGU0VUX1NBVkUJCQkJ CQkwWDk5Cj4+ICsjZGVmaW5lIFJWX0FJX0JVRkZfU1RBUlQJCQkJCQkwWDlBCj4+ICsjZGVmaW5l IElfUElDX01CX0NPVU5UCQkJCQkJCTBYOUIKPj4gKyNkZWZpbmUgQUlfV1JfRENBQ19ETUFfQ1RS TAkJCQkJCTBYOUMKPj4gKyNkZWZpbmUgU0xJQ0VfTUJfQ09VTlQJCQkJCQkJMFg5RAo+PiArI2Rl ZmluZSBQSUNUWVBFCQkJCQkJCQkwWDlFCj4+ICsjZGVmaW5lIFNMSUNFX0dST1VQX01BUF9UWVBF CQkJCQkJMFg5Rgo+PiArI2RlZmluZSBNQl9UWVBFCQkJCQkJCQkwWEEwCj4+ICsjZGVmaW5lIE1C X0FGRl9BRERFRF9ETUEJCQkJCQkwWEExCj4+ICsjZGVmaW5lIFBSRVZJT1VTX01CX1RZUEUJCQkJ CQkwWEEyCj4+ICsjZGVmaW5lIFdFSUdIVEVEX1BSRURfRkxBRwkJCQkJCTBYQTMKPj4gKyNkZWZp bmUgV0VJR0hURURfQklQUkVEX0lEQwkJCQkJCTBYQTQKPj4gKy8qIGJpdCAzOjIgLSBQSUNUVVJF X1NUUlVDVFVSRQo+PiArICogYml0IDEgLSBNQl9BREFQVElWRV9GUkFNRV9GSUVMRF9GTEFHCj4+ ICsgKiBiaXQgMCAtIEZSQU1FX01CU19PTkxZX0ZMQUcKPj4gKyAqLwo+PiArI2RlZmluZSBNQkZG X0lORk8JCQkJCQkJMFhBNQo+PiArI2RlZmluZSBUT1BfSU5UUkFfVFlQRV9UT1AJCQkJCQkwWEE2 Cj4+ICsjZGVmaW5lIFJWX0FJX0JVRkZfSU5DCQkJCQkJCTB4QTcKPj4gKyNkZWZpbmUgREVGQVVM VF9NQl9JTkZPX0xPCQkJCQkJMHhBOAo+PiArLyogMCAtLSBubyBuZWVkIHRvIHJlYWQKPj4gKyAq IDEgLS0gbmVlZCB0byB3YWl0IExlZnQKPj4gKyAqIDIgLS0gbmVlZCB0byByZWFkIEludHJhCj4+ ICsgKiAzIC0tIG5lZWQgdG8gcmVhZCBiYWNrIE1WCj4+ICsgKi8KPj4gKyNkZWZpbmUgTkVFRF9S RUFEX1RPUF9JTkZPCQkJCQkJMHhBOQo+PiArLyogMCAtLSBpZGxlCj4+ICsgKiAxIC0tIHdhaXQg TGVmdAo+PiArICogMiAtLSByZWFkaW5nIHRvcCBJbnRyYQo+PiArICogMyAtLSByZWFkaW5nIGJh Y2sgTVYKPj4gKyAqLwo+PiArI2RlZmluZSBSRUFEX1RPUF9JTkZPX1NUQVRFCQkJCQkJMHhBQQo+ PiArI2RlZmluZSBEQ0FDX01CWAkJCQkJCQkweEFCCj4+ICsjZGVmaW5lIFRPUF9NQl9JTkZPX09G RlNFVAkJCQkJCTB4QUMKPj4gKyNkZWZpbmUgVE9QX01CX0lORk9fUkRfSURYCQkJCQkJMHhBRAo+ PiArI2RlZmluZSBUT1BfTUJfSU5GT19XUl9JRFgJCQkJCQkweEFFCj4+ICsKPj4gKyNkZWZpbmUg VkxEX05PX1dBSVQJIDAKPj4gKyNkZWZpbmUgVkxEX1dBSVRfQlVGRkVSIDEKPj4gKyNkZWZpbmUg VkxEX1dBSVRfSE9TVMKgwqAgMgo+PiArI2RlZmluZSBWTERfV0FJVF9HQVAJMwo+PiArCj4+ICsj ZGVmaW5lIFZMRF9XQUlUSU5HCQkJCQkJCTB4QUYKPj4gKwo+PiArI2RlZmluZSBNQl9YX05VTQkJ CQkJCQkweEIwCj4+ICsjZGVmaW5lIE1CX0hFSUdIVAkJCQkJCQkweEIyCj4+ICsjZGVmaW5lIE1C WAkJCQkJCQkJMHhCMwo+PiArI2RlZmluZSBUT1RBTF9NQlkJCQkJCQkJMHhCNAo+PiArI2RlZmlu ZSBJTlRSX01TS19TQVZFCQkJCQkJCTB4QjUKPj4gKyNkZWZpbmUgTkVFRF9ESVNBQkxFX1BQRQkJ CQkJCTB4QjYKPj4gKyNkZWZpbmUgSVNfTkVXX1BJQ1RVUkUJCQkJCQkJMFhCNwo+PiArI2RlZmlu ZSBQUkVWX05BTF9SRUZfSURDCQkJCQkJMFhCOAo+PiArI2RlZmluZSBQUkVWX05BTF9VTklUX1RZ UEUJCQkJCQkwWEI5Cj4+ICsjZGVmaW5lIEZSQU1FX01CX0NPVU5UCQkJCQkJCTBYQkEKPj4gKyNk ZWZpbmUgU0xJQ0VfR1JPVVBfVUNPREUJCQkJCQkwWEJCCj4+ICsjZGVmaW5lIFNMSUNFX0dST1VQ X0NIQU5HRV9SQVRFCQkJCQkJMFhCQwo+PiArI2RlZmluZSBTTElDRV9HUk9VUF9DSEFOR0VfQ1lD TEVfTEVOCQkJCQkwWEJECj4+ICsjZGVmaW5lIERFTEFZX0xFTkdUSAkJCQkJCQkwWEJFCj4+ICsj ZGVmaW5lIFBJQ1RVUkVfU1RSVUNUCQkJCQkJCTBYQkYKPj4gKyNkZWZpbmUgRENBQ19QUkVWSU9V U19NQl9UWVBFCQkJCQkJMHhDMQo+PiArCj4+ICsjZGVmaW5lIFRJTUVfU1RBTVAJCQkJCQkJMFhD Mgo+PiArI2RlZmluZSBIX1RJTUVfU1RBTVAJCQkJCQkJMFhDMwo+PiArI2RlZmluZSBWUFRTX01B UF9BRERSCQkJCQkJCTBYQzQKPj4gKyNkZWZpbmUgSF9WUFRTX01BUF9BRERSCQkJCQkJCTBYQzUK Pj4gKyNkZWZpbmUgUElDX0lOU0VSVF9GTEFHCQkJCQkJCTBYQzcKPj4gKyNkZWZpbmUgVElNRV9T VEFNUF9TVEFSVAkJCQkJCTBYQzgKPj4gKyNkZWZpbmUgVElNRV9TVEFNUF9FTkQJCQkJCQkJMFhE Rgo+PiArI2RlZmluZSBPRkZTRVRfRk9SX05PTl9SRUZfUElDCQkJCQkJMFhFMAo+PiArI2RlZmlu ZSBPRkZTRVRfRk9SX1RPUF9UT19CT1RUT01fRklFTEQJCQkJCTBYRTIKPj4gKyNkZWZpbmUgTUFY X1JFRkVSRU5DRV9GUkFNRV9OVU0JCQkJCQkwWEU0Cj4+ICsjZGVmaW5lIEZSQU1FX05VTV9HQVBf QUxMT1dFRAkJCQkJCTBYRTUKPj4gKyNkZWZpbmUgTlVNX1JFRl9GUkFNRVNfSU5fUElDX09SREVS X0NOVF9DWUNMRQkJCQkwWEU2Cj4+ICsjZGVmaW5lIFBST0ZJTEVfSURDX01NQ08JCQkJCQkwWEU3 Cj4+ICsjZGVmaW5lIExFVkVMX0lEQ19NTUNPCQkJCQkJCTBYRTgKPj4gKyNkZWZpbmUgRlJBTUVf U0laRV9JTl9NQgkJCQkJCTBYRTkKPj4gKyNkZWZpbmUgREVMVEFfUElDX09SREVSX0FMV0FZU19a RVJPX0ZMQUcJCQkJMFhFQQo+PiArI2RlZmluZSBQUFNfTlVNX1JFRl9JRFhfTDBfQUNUSVZFX01J TlVTMQkJCQkwWEVCCj4+ICsjZGVmaW5lIFBQU19OVU1fUkVGX0lEWF9MMV9BQ1RJVkVfTUlOVVMx CQkJCTBYRUMKPj4gKyNkZWZpbmUgQ1VSUkVOVF9TUFNfSUQJCQkJCQkJMFhFRAo+PiArI2RlZmlu ZSBDVVJSRU5UX1BQU19JRAkJCQkJCQkwWEVFCj4+ICsvKiBiaXQgMCAtIHNlcXVlbmNlIHBhcmFt ZXRlciBzZXQgbWF5IGNoYW5nZQo+PiArICogYml0IDEgLSBwaWN0dXJlIHBhcmFtZXRlciBzZXQg bWF5IGNoYW5nZQo+PiArICogYml0IDIgLSBuZXcgZHBiIGp1c3QgaW5pdGVkCj4+ICsgKiBiaXQg MyAtIElEUiBwaWN0dXJlIG5vdCBkZWNvZGVkIHlldAo+PiArICogYml0IDU6NCAtIDA6IG1iIGxl dmVsIGNvZGUgbG9hZGVkIDE6IHBpY3R1cmUKPj4gKyAqIGxldmVsIGNvZGUgbG9hZGVkIDI6IHNs aWNlIGxldmVsIGNvZGUgbG9hZGVkCj4+ICsgKi8KPj4gKyNkZWZpbmUgREVDT0RFX1NUQVRVUwkJ CQkJCQkwWEVGCj4+ICsjZGVmaW5lIEZJUlNUX01CX0lOX1NMSUNFCQkJCQkJMFhGMAo+PiArI2Rl ZmluZSBQUkVWX01CX1dJRFRICQkJCQkJCTBYRjEKPj4gKyNkZWZpbmUgUFJFVl9GUkFNRV9TSVpF X0lOX01CCQkJCQkJMFhGMgo+PiArLyogYml0IDAgLSBhc3BlY3RfcmF0aW9faW5mb19wcmVzZW50 X2ZsYWcKPj4gKyAqIGJpdCAxIC0gdGltaW5nX2luZm9fcHJlc2VudF9mbGFnCj4+ICsgKiBiaXQg MiAtIG5hbF9ocmRfcGFyYW1ldGVyc19wcmVzZW50X2ZsYWcKPj4gKyAqIGJpdCAzIC0gdmNsX2hy ZF9wYXJhbWV0ZXJzX3ByZXNlbnRfZmxhZwo+PiArICogYml0IDQgLSBwaWNfc3RydWN0X3ByZXNl bnRfZmxhZwo+PiArICogYml0IDUgLSBiaXRzdHJlYW1fcmVzdHJpY3Rpb25fZmxhZwo+PiArICov Cj4+ICsjZGVmaW5lIFZVSV9TVEFUVVMJCQkJCQkJMFhGNAo+PiArI2RlZmluZSBBU1BFQ1RfUkFU SU9fSURDCQkJCQkJMFhGNQo+PiArI2RlZmluZSBBU1BFQ1RfUkFUSU9fU0FSX1dJRFRICQkJCQkJ MFhGNgo+PiArI2RlZmluZSBBU1BFQ1RfUkFUSU9fU0FSX0hFSUdIVAkJCQkJCTBYRjcKPj4gKyNk ZWZpbmUgTlVNX1VOSVRTX0lOX1RJQ0sJCQkJCQkwWEY4Cj4+ICsjZGVmaW5lIFRJTUVfU0NBTEUJ CQkJCQkJMFhGQQo+PiArI2RlZmluZSBDVVJSRU5UX1BJQ19JTkZPCQkJCQkJMFhGQwo+PiArI2Rl ZmluZSBEUEJfQlVGRkVSX0lORk8JCQkJCQkJMFhGRAo+PiArI2RlZmluZSBSRUZFUkVOQ0VfUE9P TF9JTkZPCQkJCQkJMFhGRQo+PiArI2RlZmluZSBSRUZFUkVOQ0VfTElTVF9JTkZPCQkJCQkJMFhG Rgo+PiArCj4+ICsjZGVmaW5lIFJFT1JERVJfQ01EX01BWMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDC oCA2Ngo+PiArCj4+ICsvKiBjb25maWcgcGFyYW1ldGVycyB0byBERFIgbG1lbSAqLwo+PiArI2Rl ZmluZSBHRVRfU1BTX1BST0ZJTEVfSURDKHgpwqDCoMKgwqDCoMKgICgoKHgpICYgMHhmZikgPDwg OCkKPj4gKyNkZWZpbmUgR0VUX1NQU19MRVZFTF9JREMoeCnCoMKgwqDCoMKgwqDCoMKgICgoeCkg JiAweGZmKQo+PiArI2RlZmluZSBHRVRfU1BTX1NFUV9QQVJBTV9TRVRfSUQoeCnCoMKgwqDCoMKg wqAgKCgoeCkgJiAweDFmKSA8PCA4KQo+PiArI2RlZmluZSBHRVRfU1BTX0NIUk9NQV9GT1JNQVRf SURDKHgpwqDCoMKgwqDCoCAoKHgpIDw8IDgpCj4+ICsjZGVmaW5lIEdFVF9TUFNfTlVNX1JFRl9G UkFNRVMoeCnCoMKgwqDCoMKgwqDCoMKgICgoeCkgJiAweGZmKQo+PiArI2RlZmluZSBHRVRfU1BT X0dBUFNfQUxMT1dFRF9GTEFHKHgpwqDCoMKgwqDCoCAoKHgpIDw8IDgpCj4+ICsjZGVmaW5lIEdF VF9TUFNfTE9HMl9NQVhfRlJBTUVfTlVNKHgpwqDCoMKgwqAgKCh4KSArIDQpCj4+ICsjZGVmaW5l IEdFVF9TUFNfUElDX09SREVSX0NOVF9MU0IoeCnCoMKgwqDCoMKgICgoeCkgKyA0KQo+PiArI2Rl ZmluZSBHRVRfU1BTX1BJQ19PUkRFUl9UWVBFKHgpwqDCoMKgwqDCoMKgwqDCoCAoeCkKPj4gKyNk ZWZpbmUgR0VUX1NQU19PRkZTRVRfRk9SX05PTlJFRl9QSUNfSElHSCh4KcKgwqDCoMKgwqAgKCgo eCkgJiAweGZmZmYwMDAwKSA+PiAxNikKPj4gKyNkZWZpbmUgR0VUX1NQU19PRkZTRVRfRk9SX05P TlJFRl9QSUNfTE9XKHgpwqDCoMKgwqDCoMKgwqDCoCAoKHgpICYgMHhmZmZmKQo+PiArI2RlZmlu ZSBHRVRfU1BTX09GRlNFVF9GT1JfVE9QX0JPVF9GSUVMRF9ISUdIKHgpwqDCoMKgwqDCoCAoKCh4 KSAmIDB4ZmZmZjAwMDApID4+IDE2KQo+PiArI2RlZmluZSBHRVRfU1BTX09GRlNFVF9GT1JfVE9Q X0JPVF9GSUVMRF9MT1coeCnCoMKgwqDCoMKgwqDCoMKgICgoeCkgJiAweGZmZmYpCj4+ICsjZGVm aW5lIEdFVF9TUFNfUElDX1dJRFRIX0lOX01CUyh4KcKgwqDCoMKgwqDCoCAoKHgpICsgMSkKPj4g KyNkZWZpbmUgR0VUX1NQU19QSUNfSEVJR0hUX0lOX01CUyh4KcKgwqDCoMKgwqAgKCh4KSArIDEp Cj4+ICsjZGVmaW5lIEdFVF9TUFNfRElSRUNUXzhYOF9GTEFHUyh4KcKgwqDCoMKgwqDCoCAoKCh4 KSAmIDB4MSkgPDwgMikKPj4gKyNkZWZpbmUgR0VUX1NQU19NQl9BREFQVElWRV9GUkFNRV9GSUVM RF9GTEFHUyh4KcKgwqDCoMKgwqDCoCAoKCh4KSAmIDB4MSkgPDwgMSkKPj4gKyNkZWZpbmUgR0VU X1NQU19GUkFNRV9NQlNfT05MWV9GTEFHUyh4KcKgwqAgKCh4KSAmIDB4MSkKPj4gKwo+PiArI2Rl ZmluZSBHRVRfUFBTX1BJQ19QQVJBTV9TRVRfSUQoeCnCoMKgwqDCoMKgwqAgKCh4KSAmIDB4ZmYp Cj4+ICsjZGVmaW5lIEdFVF9QUFNfU0VRX1BBUkFNX1NFVF9JRCh4KcKgwqDCoMKgwqDCoCAoKCh4 KSAmIDB4MWYpIDw8IDgpCj4+ICsjZGVmaW5lIEdFVF9QUFNfRU5UUk9QWV9DT0RJTkdfTU9ERV9G TEFHKHgpwqAgKCgoeCkgJiAweDEpIDw8IDEzKQo+PiArI2RlZmluZSBHRVRfUFBTX1BJQ19PUkRF Ul9QUkVTRU5UX0ZMQUcoeCnCoMKgwqAgKCgoeCkgJiAweDEpIDw8IDE0KQo+PiArI2RlZmluZSBH RVRfUFBTX05VTV9JRFhfUkVGX0wwX01JTlVTMSh4KcKgwqDCoMKgwqDCoCAoKHgpICYgMHgxZikK Pj4gKyNkZWZpbmUgR0VUX1BQU19OVU1fSURYX1JFRl9MMV9NSU5VUzEoeCnCoMKgwqDCoMKgwqAg KCgoeCkgJiAweDFmKSA8PCA1KQo+PiArI2RlZmluZSBHRVRfUFBTX1dFSUdIVEVEX1BSRURfRkxB Ryh4KcKgwqDCoMKgwqDCoMKgwqAgKCgoeCkgJiAweDEpIDw8IDEwKQo+PiArI2RlZmluZSBHRVRf UFBTX1dFSUdIVEVEX0JJUFJFRF9JREMoeCnCoMKgwqDCoMKgwqDCoCAoKCh4KSAmIDB4MykgPDwg MTEpCj4+ICsjZGVmaW5lIEdFVF9QUFNfSU5JVF9RU19NSU5VUzI2KHgpwqDCoMKgwqDCoMKgwqDC oMKgwqAgKCgoeCkgJiAweGZmKSA8PCA4KQo+PiArI2RlZmluZSBHRVRfUFBTX0lOSVRfUVBfTUlO VVMyNih4KcKgwqDCoMKgwqDCoMKgwqDCoMKgICgoeCkgJiAweGZmKQo+PiArI2RlZmluZSBHRVRf UFBTX0NIUk9NQV9RUF9JTkRFWF9PRkZTRVQoeCnCoMKgICgoeCkgJiAweGZmKQo+PiArI2RlZmlu ZSBHRVRfUFBTX0RFQkxPQ0tfRklMVEVSX0NUUkxfUFJFU0VOVF9GTEFHKHgpwqDCoCAoKCh4KSAm IDB4MSkgPDwgOCkKPj4gKyNkZWZpbmUgR0VUX1BQU19DT05TVFJBSU5fSU5UUkFfUFJFRF9GTEFH KHgpwqDCoMKgwqDCoMKgwqDCoMKgICgoKHgpICYgMHgxKSA8PCA5KQo+PiArI2RlZmluZSBHRVRf UFBTX1JFRFVOREFOVF9QSUNfQ05UX1BSRVNFTlRfRkxBRyh4KcKgwqDCoMKgICgoKHgpICYgMHgx KSA8PCAxMCkKPj4gKyNkZWZpbmUgR0VUX1BQU19TQ0FMSU5HX01BVFJJWF9QUkVTRU5UX0ZMQUco eCnCoMKgwqDCoMKgwqDCoCAoKCh4KSAmIDB4MSkgPDwgMSkKPj4gKyNkZWZpbmUgR0VUX1BQU19U UkFOU0ZPUk1fOFg4X0ZMQUcoeCnCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoCAoKHgp ICYgMHgxKQo+PiArI2RlZmluZSBHRVRfUFBTX0dFVF9TRUNPTkRfQ0hST01BX1FQX09GRlNFVCh4 KcKgwqDCoMKgwqDCoMKgICh4KQo+PiArCj4+ICtpbnQgYW1sX2gyNjRfaW5pdCh2b2lkICpwcml2 KTsKPj4gK3ZvaWQgYW1sX2gyNjRfZXhpdCh2b2lkICpwcml2KTsKPj4gK2ludCBhbWxfaDI2NF9k ZWNfcnVuKHZvaWQgKnByaXYpOwo+PiArCj4+ICsjZW5kaWYKPj4gZGlmZiAtLWdpdCBhL2RyaXZl cnMvbWVkaWEvcGxhdGZvcm0vYW1sb2dpYy92ZGVjL3JlZ19kZWZpbmVzLmggYi9kcml2ZXJzL21l ZGlhL3BsYXRmb3JtL2FtbG9naWMvdmRlYy9yZWdfZGVmaW5lcy5oCj4+IG5ldyBmaWxlIG1vZGUg MTAwNjQ0Cj4+IGluZGV4IDAwMDAwMDAwMDAwMC4uZWE1MDAxOGEwNzhkCj4+IC0tLSAvZGV2L251 bGwKPj4gKysrIGIvZHJpdmVycy9tZWRpYS9wbGF0Zm9ybS9hbWxvZ2ljL3ZkZWMvcmVnX2RlZmlu ZXMuaAo+PiBAQCAtMCwwICsxLDE3NyBAQAo+PiArLyogU1BEWC1MaWNlbnNlLUlkZW50aWZpZXI6 IChHUEwtMi4wLW9ubHkgT1IgTUlUKSAqLwo+PiArLyoKPj4gKyAqIENvcHlyaWdodCAoQykgMjAy NSBBbWxvZ2ljLCBJbmMuIEFsbCByaWdodHMgcmVzZXJ2ZWQKPj4gKyAqLwo+PiArCj4+ICsjaWZu ZGVmIF9SRUdfREVGSU5FU19IXwo+PiArI2RlZmluZSBfUkVHX0RFRklORVNfSF8KPj4gKwo+PiAr I2RlZmluZSBSRUdfQUxJR04oeCkgKCh4KSA8PCAyKQo+PiArCj4+ICsjZGVmaW5lIFZERUNfQVNT SVNUX01NQ19DVFJMMMKgwqDCoMKgwqDCoMKgIFJFR19BTElHTigweDAwMDEpCj4+ICsjZGVmaW5l IFZERUNfQVNTSVNUX01NQ19DVFJMMcKgwqDCoMKgwqDCoMKgIFJFR19BTElHTigweDAwMDIpCj4+ ICsKPj4gKyNkZWZpbmUgVkRFQ19BU1NJU1RfQ0FOVkFTX0JMSzMywqDCoMKgwqAgUkVHX0FMSUdO KDB4MDAwNSkKPj4gKwo+PiArI2RlZmluZSBWREVDX0FTU0lTVF9NQk9YMV9DTFJfUkVHwqDCoMKg IFJFR19BTElHTigweDAwNzUpCj4+ICsjZGVmaW5lIFZERUNfQVNTSVNUX01CT1gxX01BU0vCoMKg wqDCoMKgwqAgUkVHX0FMSUdOKDB4MDA3NikKPj4gKwo+PiArI2RlZmluZSBNUFNSwqDCoMKgwqDC oMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgIFJFR19BTElHTigweDAzMDEp Cj4+ICsjZGVmaW5lIE1QQ19QwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDC oMKgwqDCoCBSRUdfQUxJR04oMHgwMzA2KQo+PiArI2RlZmluZSBNUENfRMKgwqDCoMKgwqDCoMKg wqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqAgUkVHX0FMSUdOKDB4MDMwNykKPj4gKyNk ZWZpbmUgTVBDX0XCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKg IFJFR19BTElHTigweDAzMDgpCj4+ICsjZGVmaW5lIE1QQ19XwqDCoMKgwqDCoMKgwqDCoMKgwqDC oMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoCBSRUdfQUxJR04oMHgwMzA5KQo+PiArI2RlZmluZSBD UFNSwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgIFJFR19B TElHTigweDAzMjEpCj4+ICsjZGVmaW5lIElNRU1fRE1BX0NUUkzCoMKgwqDCoMKgwqDCoMKgwqDC oMKgwqDCoMKgwqAgUkVHX0FMSUdOKDB4MDM0MCkKPj4gKyNkZWZpbmUgSU1FTV9ETUFfQURSwqDC oMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqAgUkVHX0FMSUdOKDB4MDM0MSkKPj4gKyNkZWZp bmUgSU1FTV9ETUFfQ09VTlTCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgIFJFR19BTElHTigw eDAzNDIpCj4+ICsjZGVmaW5lIFdSUlNQX0lNRU3CoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKg wqDCoMKgwqAgUkVHX0FMSUdOKDB4MDM0MykKPj4gKyNkZWZpbmUgTE1FTV9ETUFfQ1RSTMKgwqDC oMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoCBSRUdfQUxJR04oMHgwMzUwKQo+PiArI2RlZmluZSBX UlJTUF9MTUVNwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgIFJFR19BTElHTigw eDAzNTMpCj4+ICsKPj4gKyNkZWZpbmUgUFNDQUxFX0NUUkzCoMKgwqDCoMKgwqDCoMKgwqDCoMKg wqDCoMKgwqDCoMKgIFJFR19BTElHTigweDA5MTEpCj4+ICsjZGVmaW5lIEdDTEtfRU7CoMKgwqDC oMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqAgUkVHX0FMSUdOKDB4MDk4MykKPj4g KyNkZWZpbmUgTURFQ19QSUNfRENfQ1RSTMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoCBSRUdfQUxJ R04oMHgwOThlKQo+PiArI2RlZmluZSBNREVDX1BJQ19EQ19NVVhfQ1RSTMKgwqDCoMKgwqDCoMKg wqAgUkVHX0FMSUdOKDB4MDk4ZCkKPj4gKyNkZWZpbmUgQU5DMF9DQU5WQVNfQUREUsKgwqDCoMKg wqDCoMKgwqDCoMKgwqDCoCBSRUdfQUxJR04oMHgwOTkwKQo+PiArI2RlZmluZSBBTkMxX0NBTlZB U19BRERSwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgIFJFR19BTElHTigweDA5OTEpCj4+ICsjZGVm aW5lIEFOQzJfQ0FOVkFTX0FERFLCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqAgUkVHX0FMSUdOKDB4 MDk5MikKPj4gKyNkZWZpbmUgQU5DM19DQU5WQVNfQUREUsKgwqDCoMKgwqDCoMKgwqDCoMKgwqDC oCBSRUdfQUxJR04oMHgwOTkzKQo+PiArI2RlZmluZSBBTkM0X0NBTlZBU19BRERSwqDCoMKgwqDC oMKgwqDCoMKgwqDCoMKgIFJFR19BTElHTigweDA5OTQpCj4+ICsjZGVmaW5lIEFOQzVfQ0FOVkFT X0FERFLCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqAgUkVHX0FMSUdOKDB4MDk5NSkKPj4gKyNkZWZp bmUgQU5DNl9DQU5WQVNfQUREUsKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoCBSRUdfQUxJR04oMHgw OTk2KQo+PiArI2RlZmluZSBBTkM3X0NBTlZBU19BRERSwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKg IFJFR19BTElHTigweDA5OTcpCj4+ICsjZGVmaW5lIEFOQzhfQ0FOVkFTX0FERFLCoMKgwqDCoMKg wqDCoMKgwqDCoMKgwqAgUkVHX0FMSUdOKDB4MDk5OCkKPj4gKyNkZWZpbmUgQU5DOV9DQU5WQVNf QUREUsKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoCBSRUdfQUxJR04oMHgwOTk5KQo+PiArI2RlZmlu ZSBBTkMxMF9DQU5WQVNfQUREUsKgwqDCoMKgwqDCoMKgwqDCoMKgwqAgUkVHX0FMSUdOKDB4MDk5 YSkKPj4gKyNkZWZpbmUgQU5DMTFfQ0FOVkFTX0FERFLCoMKgwqDCoMKgwqDCoMKgwqDCoMKgIFJF R19BTElHTigweDA5OWIpCj4+ICsjZGVmaW5lIEFOQzEyX0NBTlZBU19BRERSwqDCoMKgwqDCoMKg wqDCoMKgwqDCoCBSRUdfQUxJR04oMHgwOTljKQo+PiArI2RlZmluZSBBTkMxM19DQU5WQVNfQURE UsKgwqDCoMKgwqDCoMKgwqDCoMKgwqAgUkVHX0FMSUdOKDB4MDk5ZCkKPj4gKyNkZWZpbmUgQU5D MTRfQ0FOVkFTX0FERFLCoMKgwqDCoMKgwqDCoMKgwqDCoMKgIFJFR19BTElHTigweDA5OWUpCj4+ ICsjZGVmaW5lIEFOQzE1X0NBTlZBU19BRERSwqDCoMKgwqDCoMKgwqDCoMKgwqDCoCBSRUdfQUxJ R04oMHgwOTlmKQo+PiArI2RlZmluZSBBTkMxNl9DQU5WQVNfQUREUsKgwqDCoMKgwqDCoMKgwqDC oMKgwqAgUkVHX0FMSUdOKDB4MDlhMCkKPj4gKyNkZWZpbmUgQU5DMTdfQ0FOVkFTX0FERFLCoMKg wqDCoMKgwqDCoMKgwqDCoMKgIFJFR19BTElHTigweDA5YTEpCj4+ICsjZGVmaW5lIEFOQzE4X0NB TlZBU19BRERSwqDCoMKgwqDCoMKgwqDCoMKgwqDCoCBSRUdfQUxJR04oMHgwOWEyKQo+PiArI2Rl ZmluZSBBTkMxOV9DQU5WQVNfQUREUsKgwqDCoMKgwqDCoMKgwqDCoMKgwqAgUkVHX0FMSUdOKDB4 MDlhMykKPj4gKyNkZWZpbmUgQU5DMjBfQ0FOVkFTX0FERFLCoMKgwqDCoMKgwqDCoMKgwqDCoMKg IFJFR19BTElHTigweDA5YTQpCj4+ICsjZGVmaW5lIEFOQzIxX0NBTlZBU19BRERSwqDCoMKgwqDC oMKgwqDCoMKgwqDCoCBSRUdfQUxJR04oMHgwOWE1KQo+PiArI2RlZmluZSBBTkMyMl9DQU5WQVNf QUREUsKgwqDCoMKgwqDCoMKgwqDCoMKgwqAgUkVHX0FMSUdOKDB4MDlhNikKPj4gKyNkZWZpbmUg QU5DMjNfQ0FOVkFTX0FERFLCoMKgwqDCoMKgwqDCoMKgwqDCoMKgIFJFR19BTElHTigweDA5YTcp Cj4+ICsjZGVmaW5lIEFOQzI0X0NBTlZBU19BRERSwqDCoMKgwqDCoMKgwqDCoMKgwqDCoCBSRUdf QUxJR04oMHgwOWE4KQo+PiArI2RlZmluZSBBTkMyNV9DQU5WQVNfQUREUsKgwqDCoMKgwqDCoMKg wqDCoMKgwqAgUkVHX0FMSUdOKDB4MDlhOSkKPj4gKyNkZWZpbmUgQU5DMjZfQ0FOVkFTX0FERFLC oMKgwqDCoMKgwqDCoMKgwqDCoMKgIFJFR19BTElHTigweDA5YWEpCj4+ICsjZGVmaW5lIEFOQzI3 X0NBTlZBU19BRERSwqDCoMKgwqDCoMKgwqDCoMKgwqDCoCBSRUdfQUxJR04oMHgwOWFiKQo+PiAr I2RlZmluZSBBTkMyOF9DQU5WQVNfQUREUsKgwqDCoMKgwqDCoMKgwqDCoMKgwqAgUkVHX0FMSUdO KDB4MDlhYykKPj4gKyNkZWZpbmUgQU5DMjlfQ0FOVkFTX0FERFLCoMKgwqDCoMKgwqDCoMKgwqDC oMKgIFJFR19BTElHTigweDA5YWQpCj4+ICsjZGVmaW5lIEFOQzMwX0NBTlZBU19BRERSwqDCoMKg wqDCoMKgwqDCoMKgwqDCoCBSRUdfQUxJR04oMHgwOWFlKQo+PiArI2RlZmluZSBBTkMzMV9DQU5W QVNfQUREUsKgwqDCoMKgwqDCoMKgwqDCoMKgwqAgUkVHX0FMSUdOKDB4MDlhZikKPj4gKyNkZWZp bmUgREJLUl9DQU5WQVNfQUREUsKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoCBSRUdfQUxJR04oMHgw OWIwKQo+PiArI2RlZmluZSBEQktXX0NBTlZBU19BRERSwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKg IFJFR19BTElHTigweDA5YjEpCj4+ICsjZGVmaW5lIFJFQ19DQU5WQVNfQUREUsKgwqDCoMKgwqDC oMKgwqDCoMKgwqDCoMKgIFJFR19BTElHTigweDA5YjIpCj4+ICsjZGVmaW5lIENVUlJfQ0FOVkFT X0NUUkzCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqAgUkVHX0FMSUdOKDB4MDliMykKPj4gKyNkZWZp bmUgTURFQ19QSUNfRENfVEhSRVNIwqDCoMKgwqDCoMKgwqDCoMKgwqAgUkVHX0FMSUdOKDB4MDli OCkKPj4gKyNkZWZpbmUgQVZfU0NSQVRDSF8wwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKg wqAgUkVHX0FMSUdOKDB4MDljMCkKPj4gKyNkZWZpbmUgQVZfU0NSQVRDSF8xwqDCoMKgwqDCoMKg wqDCoMKgwqDCoMKgwqDCoMKgwqAgUkVHX0FMSUdOKDB4MDljMSkKPj4gKyNkZWZpbmUgQVZfU0NS QVRDSF8ywqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqAgUkVHX0FMSUdOKDB4MDljMikK Pj4gKyNkZWZpbmUgQVZfU0NSQVRDSF8zwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqAg UkVHX0FMSUdOKDB4MDljMykKPj4gKyNkZWZpbmUgQVZfU0NSQVRDSF80wqDCoMKgwqDCoMKgwqDC oMKgwqDCoMKgwqDCoMKgwqAgUkVHX0FMSUdOKDB4MDljNCkKPj4gKyNkZWZpbmUgQVZfU0NSQVRD SF81wqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqAgUkVHX0FMSUdOKDB4MDljNSkKPj4g KyNkZWZpbmUgQVZfU0NSQVRDSF82wqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqAgUkVH X0FMSUdOKDB4MDljNikKPj4gKyNkZWZpbmUgQVZfU0NSQVRDSF83wqDCoMKgwqDCoMKgwqDCoMKg wqDCoMKgwqDCoMKgwqAgUkVHX0FMSUdOKDB4MDljNykKPj4gKyNkZWZpbmUgQVZfU0NSQVRDSF84 wqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqAgUkVHX0FMSUdOKDB4MDljOCkKPj4gKyNk ZWZpbmUgQVZfU0NSQVRDSF85wqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqAgUkVHX0FM SUdOKDB4MDljOSkKPj4gKyNkZWZpbmUgQVZfU0NSQVRDSF9BwqDCoMKgwqDCoMKgwqDCoMKgwqDC oMKgwqDCoMKgwqAgUkVHX0FMSUdOKDB4MDljYSkKPj4gKyNkZWZpbmUgQVZfU0NSQVRDSF9CwqDC oMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqAgUkVHX0FMSUdOKDB4MDljYikKPj4gKyNkZWZp bmUgQVZfU0NSQVRDSF9DwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqAgUkVHX0FMSUdO KDB4MDljYykKPj4gKyNkZWZpbmUgQVZfU0NSQVRDSF9EwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKg wqDCoMKgwqAgUkVHX0FMSUdOKDB4MDljZCkKPj4gKyNkZWZpbmUgQVZfU0NSQVRDSF9FwqDCoMKg wqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqAgUkVHX0FMSUdOKDB4MDljZSkKPj4gKyNkZWZpbmUg QVZfU0NSQVRDSF9GwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqAgUkVHX0FMSUdOKDB4 MDljZikKPj4gKyNkZWZpbmUgQVZfU0NSQVRDSF9HwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDC oMKgwqAgUkVHX0FMSUdOKDB4MDlkMCkKPj4gKyNkZWZpbmUgQVZfU0NSQVRDSF9IwqDCoMKgwqDC oMKgwqDCoMKgwqDCoMKgwqDCoMKgwqAgUkVHX0FMSUdOKDB4MDlkMSkKPj4gKyNkZWZpbmUgQVZf U0NSQVRDSF9JwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqAgUkVHX0FMSUdOKDB4MDlk MikKPj4gKyNkZWZpbmUgQVZfU0NSQVRDSF9KwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKg wqAgUkVHX0FMSUdOKDB4MDlkMykKPj4gKyNkZWZpbmUgQVZfU0NSQVRDSF9LwqDCoMKgwqDCoMKg wqDCoMKgwqDCoMKgwqDCoMKgwqAgUkVHX0FMSUdOKDB4MDlkNCkKPj4gKyNkZWZpbmUgQVZfU0NS QVRDSF9MwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqAgUkVHX0FMSUdOKDB4MDlkNSkK Pj4gKyNkZWZpbmUgQVZfU0NSQVRDSF9NwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqAg UkVHX0FMSUdOKDB4MDlkNikKPj4gKyNkZWZpbmUgQVZfU0NSQVRDSF9OwqDCoMKgwqDCoMKgwqDC oMKgwqDCoMKgwqDCoMKgwqAgUkVHX0FMSUdOKDB4MDlkNykKPj4gKyNkZWZpbmUgV1JSU1BfVkxE wqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqAgUkVHX0FMSUdOKDB4MDlkYSkK Pj4gKyNkZWZpbmUgTURFQ19ET1VCTEVXX0NGRzDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgIFJFR19B TElHTigweDA5ZGIpCj4+ICsjZGVmaW5lIE1ERUNfRE9VQkxFV19DRkcxwqDCoMKgwqDCoMKgwqDC oMKgwqDCoCBSRUdfQUxJR04oMHgwOWRjKQo+PiArI2RlZmluZSBNREVDX0RPVUJMRVdfQ0ZHMsKg wqDCoMKgwqDCoMKgwqDCoMKgwqAgUkVHX0FMSUdOKDB4MDlkZCkKPj4gKyNkZWZpbmUgTURFQ19E T1VCTEVXX0NGRzPCoMKgwqDCoMKgwqDCoMKgwqDCoMKgIFJFR19BTElHTigweDA5ZGUpCj4+ICsj ZGVmaW5lIE1ERUNfRE9VQkxFV19DRkc0wqDCoMKgwqDCoMKgwqDCoMKgwqDCoCBSRUdfQUxJR04o MHgwOWRmKQo+PiArI2RlZmluZSBNREVDX0RPVUJMRVdfQ0ZHNcKgwqDCoMKgwqDCoMKgwqDCoMKg wqAgUkVHX0FMSUdOKDB4MDllMCkKPj4gKyNkZWZpbmUgTURFQ19ET1VCTEVXX0NGRzbCoMKgwqDC oMKgwqDCoMKgwqDCoMKgIFJFR19BTElHTigweDA5ZTEpCj4+ICsjZGVmaW5lIE1ERUNfRE9VQkxF V19DRkc3wqDCoMKgwqDCoMKgwqDCoMKgwqDCoCBSRUdfQUxJR04oMHgwOWUyKQo+PiArI2RlZmlu ZSBNREVDX0RPVUJMRVdfU1RBVFVTwqDCoMKgwqDCoMKgwqDCoMKgIFJFR19BTElHTigweDA5ZTMp Cj4+ICsjZGVmaW5lIE1ERUNfRVhUSUZfQ0ZHMMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgIFJF R19BTElHTigweDA5ZTQpCj4+ICsKPj4gKyNkZWZpbmUgTURFQ19FWFRJRl9DRkcxwqDCoMKgwqDC oMKgwqDCoMKgwqDCoMKgwqAgUkVHX0FMSUdOKDB4MDllNSkKPj4gKyNkZWZpbmUgTURFQ19FWFRJ Rl9DRkcywqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqAgUkVHX0FMSUdOKDB4MDllNikKPj4gKwo+ PiArI2RlZmluZSBQT1dFUl9DVExfVkxEwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgIFJF R19BTElHTigweDBjMDgpCj4+ICsjZGVmaW5lIFZMRF9ERUNPREVfQ09OVFJPTMKgwqDCoMKgwqDC oMKgwqDCoMKgIFJFR19BTElHTigweDBjMTgpCj4+ICsKPj4gKyNkZWZpbmUgUE1WMV9YwqDCoMKg wqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqAgUkVHX0FMSUdOKDB4MGMyMCkK Pj4gKyNkZWZpbmUgUE1WMV9ZwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDC oMKgwqAgUkVHX0FMSUdOKDB4MGMyMSkKPj4gKyNkZWZpbmUgUE1WMl9YwqDCoMKgwqDCoMKgwqDC oMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqAgUkVHX0FMSUdOKDB4MGMyMikKPj4gKyNkZWZp bmUgUE1WMl9ZwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqAgUkVH X0FMSUdOKDB4MGMyMykKPj4gKyNkZWZpbmUgUE1WM19YwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKg wqDCoMKgwqDCoMKgwqDCoMKgwqAgUkVHX0FMSUdOKDB4MGMyNCkKPj4gKyNkZWZpbmUgUE1WM19Z wqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqAgUkVHX0FMSUdOKDB4 MGMyNSkKPj4gKyNkZWZpbmUgUE1WNF9YwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDC oMKgwqDCoMKgwqAgUkVHX0FMSUdOKDB4MGMyNikKPj4gKyNkZWZpbmUgUE1WNF9ZwqDCoMKgwqDC oMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqAgUkVHX0FMSUdOKDB4MGMyNykKPj4g KyNkZWZpbmUgTTRfVEFCTEVfU0VMRUNUwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqAgUkVHX0FM SUdOKDB4MGMyOCkKPj4gKyNkZWZpbmUgTTRfQ09OVFJPTF9SRUfCoMKgwqDCoMKgwqDCoMKgwqDC oMKgwqDCoMKgIFJFR19BTElHTigweDBjMjkpCj4+ICsjZGVmaW5lIEJMT0NLX05VTcKgwqDCoMKg wqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgIFJFR19BTElHTigweDBjMmEpCj4+ICsjZGVm aW5lIFBBVFRFUk5fQ09ERcKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgIFJFR19BTElH TigweDBjMmIpCj4+ICsjZGVmaW5lIE1CX0lORk/CoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKg wqDCoMKgwqDCoMKgwqAgUkVHX0FMSUdOKDB4MGMyYykKPj4gKyNkZWZpbmUgVkxEX0RDX1BSRUTC oMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgIFJFR19BTElHTigweDBjMmQpCj4+ICsj ZGVmaW5lIFZMRF9FUlJPUl9NQVNLwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoCBSRUdfQUxJ R04oMHgwYzJlKQo+PiArI2RlZmluZSBWTERfRENfUFJFRF9DwqDCoMKgwqDCoMKgwqDCoMKgwqDC oMKgwqDCoMKgIFJFR19BTElHTigweDBjMmYpCj4+ICsjZGVmaW5lIExBU1RfU0xJQ0VfTVZfQURE UsKgwqDCoMKgwqDCoMKgwqDCoMKgIFJFR19BTElHTigweDBjMzApCj4+ICsjZGVmaW5lIExBU1Rf TVZYwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoCBSRUdfQUxJR04oMHgw YzMxKQo+PiArI2RlZmluZSBMQVNUX01WWcKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKg wqDCoMKgwqAgUkVHX0FMSUdOKDB4MGMzMikKPj4gKwo+PiArI2RlZmluZSBNQl9NT1RJT05fTU9E RcKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqAgUkVHX0FMSUdOKDB4MGMwNykKPj4gKyNkZWZp bmUgVklGRl9CSVRfQ05UwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqAgUkVHX0FMSUdO KDB4MGMxYSkKPj4gKyNkZWZpbmUgTTRfQ09OVFJPTF9SRUfCoMKgwqDCoMKgwqDCoMKgwqDCoMKg wqDCoMKgIFJFR19BTElHTigweDBjMjkpCj4+ICsjZGVmaW5lIFZMRF9DMzjCoMKgwqDCoMKgwqDC oMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqAgUkVHX0FMSUdOKDB4MGMzOCkKPj4gKyNkZWZp bmUgVkxEX0MzOcKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoCBSRUdf QUxJR04oMHgwYzM5KQo+PiArI2RlZmluZSBWTERfU0hJRlRfU1RBVFVTwqDCoMKgwqDCoMKgwqDC oMKgwqDCoMKgIFJFR19BTElHTigweDBjM2IpCj4+ICsjZGVmaW5lIFZMRF9DM0TCoMKgwqDCoMKg wqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqAgUkVHX0FMSUdOKDB4MGMzZCkKPj4gKyNk ZWZpbmUgVkxEX01FTV9WSUZJRk9fU1RBUlRfUFRSwqDCoMKgwqAgUkVHX0FMSUdOKDB4MGM0MCkK Pj4gKyNkZWZpbmUgVkxEX01FTV9WSUZJRk9fQ1VSUl9QVFLCoMKgwqDCoMKgIFJFR19BTElHTigw eDBjNDEpCj4+ICsjZGVmaW5lIFZMRF9NRU1fVklGSUZPX0VORF9QVFLCoMKgwqDCoMKgwqAgUkVH X0FMSUdOKDB4MGM0MikKPj4gKyNkZWZpbmUgVkxEX01FTV9WSUZJRk9fQllURVNfQVZBSUzCoMKg IFJFR19BTElHTigweDBjNDMpCj4+ICsjZGVmaW5lIFZMRF9NRU1fVklGSUZPX0NPTlRST0zCoMKg wqDCoMKgwqAgUkVHX0FMSUdOKDB4MGM0NCkKPj4gKyNkZWZpbmUgVkxEX01FTV9WSUZJRk9fV1DC oMKgwqDCoMKgwqDCoMKgwqDCoMKgIFJFR19BTElHTigweDBjNDUpCj4+ICsjZGVmaW5lIFZMRF9N RU1fVklGSUZPX1JQwqDCoMKgwqDCoMKgwqDCoMKgwqDCoCBSRUdfQUxJR04oMHgwYzQ2KQo+PiAr I2RlZmluZSBWTERfTUVNX1ZJRklGT19MRVZFTMKgwqDCoMKgwqDCoMKgwqAgUkVHX0FMSUdOKDB4 MGM0NykKPj4gKyNkZWZpbmUgVkxEX01FTV9WSUZJRk9fQlVGX0NOVEzCoMKgwqDCoMKgIFJFR19B TElHTigweDBjNDgpCj4+ICsKPj4gKyNkZWZpbmUgVkNPUF9DVFJMX1JFR8KgwqDCoMKgwqDCoMKg wqDCoMKgwqDCoMKgwqDCoCBSRUdfQUxJR04oMHgwZTAwKQo+PiArI2RlZmluZSBSVl9BSV9NQl9D T1VOVMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqAgUkVHX0FMSUdOKDB4MGUwYykKPj4gKyNk ZWZpbmUgSVFJRENUX0NPTlRST0zCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgIFJFR19BTElH TigweDBlMGUpCj4+ICsjZGVmaW5lIERDQUNfRERSX0JZVEU2NF9DVEzCoMKgwqDCoMKgwqDCoMKg wqAgUkVHX0FMSUdOKDB4MGUxZCkKPj4gKwo+PiArI2RlZmluZSBWREVDMl9JTUVNX0RNQV9DVFJM wqDCoMKgwqDCoMKgwqDCoMKgIFJFR19BTElHTigweDIzNDApCj4+ICsjZGVmaW5lIFZERUMyX0lN RU1fRE1BX0FEUsKgwqDCoMKgwqDCoMKgwqDCoMKgIFJFR19BTElHTigweDIzNDEpCj4+ICsjZGVm aW5lIFZERUMyX0lNRU1fRE1BX0NPVU5UwqDCoMKgwqDCoMKgwqDCoCBSRUdfQUxJR04oMHgyMzQy KQo+PiArCj4+ICsjZGVmaW5lIERPU19TV19SRVNFVDDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDC oMKgwqAgUkVHX0FMSUdOKDB4M2YwMCkKPj4gKyNkZWZpbmUgRE9TX0dDTEtfRU4wwqDCoMKgwqDC oMKgwqDCoMKgwqDCoMKgwqDCoMKgwqAgUkVHX0FMSUdOKDB4M2YwMSkKPj4gKyNkZWZpbmUgRE9T X0dDTEtfRU4xwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqAgUkVHX0FMSUdOKDB4M2Yw OSkKPj4gKyNkZWZpbmUgRE9TX0dDTEtfRU4zwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKg wqAgUkVHX0FMSUdOKDB4M2YzNSkKPj4gKwo+PiArI2RlZmluZSBET1NfTUVNX1BEX1ZERUPCoMKg wqDCoMKgwqDCoMKgwqDCoMKgwqDCoCBSRUdfQUxJR04oMHgzZjMwKQo+PiArI2RlZmluZSBET1Nf TUVNX1BEX1ZERUMywqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgIFJFR19BTElHTigweDNmMzEpCj4+ ICsjZGVmaW5lIERPU19NRU1fUERfSENPREVDwqDCoMKgwqDCoMKgwqDCoMKgwqDCoCBSRUdfQUxJ R04oMHgzZjMyKQo+PiArLyphZGQgZnJvbSBNOE0yKi8KPj4gKyNkZWZpbmUgRE9TX01FTV9QRF9I RVZDwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqAgUkVHX0FMSUdOKDB4M2YzMykKPj4gKwo+PiAr I2RlZmluZSBET1NfU1dfUkVTRVQzwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgIFJFR19B TElHTigweDNmMzQpCj4+ICsjZGVmaW5lIERPU19HQ0xLX0VOM8KgwqDCoMKgwqDCoMKgwqDCoMKg wqDCoMKgwqDCoMKgIFJFR19BTElHTigweDNmMzUpCj4+ICsjZGVmaW5lIERPU19IRVZDX0lOVF9F TsKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgIFJFR19BTElHTigweDNmMzYpCj4+ICsKPj4gKyNl bmRpZgo+PiArCgpfX19fX19fX19fX19fX19fX19fX19fX19fX19fX19fX19fX19fX19fX19fX19f XwpsaW51eC1hbWxvZ2ljIG1haWxpbmcgbGlzdApsaW51eC1hbWxvZ2ljQGxpc3RzLmluZnJhZGVh ZC5vcmcKaHR0cDovL2xpc3RzLmluZnJhZGVhZC5vcmcvbWFpbG1hbi9saXN0aW5mby9saW51eC1h bWxvZ2ljCg== From mboxrd@z Thu Jan 1 00:00:00 1970 Received: from TYPPR03CU001.outbound.protection.outlook.com (mail-japaneastazon11022090.outbound.protection.outlook.com [52.101.126.90]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 6AA5F1D5147; Fri, 12 Dec 2025 04:11:52 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=fail smtp.client-ip=52.101.126.90 ARC-Seal:i=2; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1765512720; cv=fail; b=JzfEnz1oh+WFajXhD9B6CWfAJU8cHw53cwbgCv1WdD9CHDPKDGXOi5QUjml8DDVn8S7fuBPyzluvlgYKoYwAR3BEtS7/ioUIDHe00nz2raDxo7G97AiPnZAOq+PZ+meh1mugaq/r60HPKmDVEi03OBUG+Bpgl1v1bXM+Dr089qA= ARC-Message-Signature:i=2; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1765512720; c=relaxed/simple; bh=pb5Giq/aavYSkx39eK11L1eKO+PmbbCPY5uQYP0mijk=; h=Message-ID:Date:Subject:To:Cc:References:From:In-Reply-To: Content-Type:MIME-Version; b=VccNRuaDr078S8PfKvMg3+GwlnLvl+2LpRw/ICZttctIWIeHcggdqHmMWUgfP/fUHLpEjzOzXkll/M6Q1xFeKVymcis2WW+GiNJW4Awq/cY10YmaoKnAvH/8Cf46JW5riJII00idAip5uuj5cAptT8yzy+Ee0O3Ly8rksEOa6sE= ARC-Authentication-Results:i=2; smtp.subspace.kernel.org; dmarc=pass (p=quarantine dis=none) header.from=amlogic.com; spf=pass smtp.mailfrom=amlogic.com; dkim=pass (2048-bit key) header.d=amlogic.com header.i=@amlogic.com header.b=IKUubrJw; arc=fail smtp.client-ip=52.101.126.90 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=quarantine dis=none) header.from=amlogic.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=amlogic.com Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=amlogic.com header.i=@amlogic.com header.b="IKUubrJw" ARC-Seal: i=1; a=rsa-sha256; s=arcselector10001; d=microsoft.com; cv=none; b=FTKVQyQNwDvmN4WMxx8vxcwo1cDCdzZzjfPvNKG/KdmaelGkfPGKz0wjwRKSqS7/R3AHHswcbyNgK3bs63+vxVwAGk5WNLwLRZ6ZyVNaOM0FNbwVPBQXoMgCBsMK1kcKhUzKbCde5z1bG2QhAT9GxunziNLNV4LwdfEa1l8LaqfYznho5pDc9GWXIQbxJe1E9EYQMWl00lg3OMmmPmMcN6tJxdQbQ+LoQHN4yVPMJklpNNkQz12U6kOxGGxjml+LEAkfoTnlricU40H5lBqozX5dI3cpXRbXDpvAMSZf+MVvFFyZnVsEoYUSlhHycQGSxWKyW501CecbAbNgaaxPOA== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=microsoft.com; s=arcselector10001; h=From:Date:Subject:Message-ID:Content-Type:MIME-Version:X-MS-Exchange-AntiSpam-MessageData-ChunkCount:X-MS-Exchange-AntiSpam-MessageData-0:X-MS-Exchange-AntiSpam-MessageData-1; bh=6IJROTgeS+gdBrVdnKeZpbkhDjF77yTC9ofatEtxDvg=; b=XUjybddFBX2aBnb04BSI871MHP+XOvQ69BqdRLRfqAv6tAsBvClGX7wCAObzaMQpC/iDbPfdmZZpbBmk/SaWzgs8iI1GLyLIdOosVRClUXgsGwg/sFwaTonxrrBLt3hp5oknGoE7jY44yPjGxy9DgPKk1+SW8Yb/Enq4N0qv5JVR3IECMcc51b2GROuATGW2segAFxZK0QsafT/n5pxsw3ITyL1ZJjjSlxU2hHNptb9ysxTBUbQKxZanpuXVeHdVgKqU0lBnMlbbr6rLiHT0e0nHbrSXFuMlwUOpC93D0cBuzmeloJZSyy+XAoRTv0pfqVERiBDVGIoSf/mlycKBDg== ARC-Authentication-Results: i=1; mx.microsoft.com 1; spf=pass smtp.mailfrom=amlogic.com; dmarc=pass action=none header.from=amlogic.com; dkim=pass header.d=amlogic.com; arc=none DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=amlogic.com; s=selector1; h=From:Date:Subject:Message-ID:Content-Type:MIME-Version:X-MS-Exchange-SenderADCheck; bh=6IJROTgeS+gdBrVdnKeZpbkhDjF77yTC9ofatEtxDvg=; b=IKUubrJw5nok7vP3nxBlLQMxxewnj2KQ1PuSixlXuz68CTPvHyEEB6ZTACHE2LSr8oF34zrIig0da2rspXWQSIrWYEV0qsSWVfUMcyKJ8MMC0M6K99vAPNfJKFc/yHPLJ0Ef6HbVBoflSvogH7OyPBBVxpmL9QAd3mcAkoBuhpsMtsKA8Cm3HlU3bwhzG3IqineMv7E6pnFADhMTMp0eZE5WE2hiNPPOX8vMPM8CJU+Ar2qTgHkV608cZY14KdnFM2dTBAddcDIpAEv3oYLHD/heVM56Y6ak4a7N0n/LZHLYHA1pLrmLvi34jocF1D0IK2fSxphBhg43ybOU6/C6bg== Authentication-Results: dkim=none (message not signed) header.d=none;dmarc=none action=none header.from=amlogic.com; Received: from KL1PR03MB5521.apcprd03.prod.outlook.com (2603:1096:820:51::12) by SEYPR03MB6628.apcprd03.prod.outlook.com (2603:1096:101:81::9) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384) id 15.20.9412.10; Fri, 12 Dec 2025 04:11:46 +0000 Received: from KL1PR03MB5521.apcprd03.prod.outlook.com ([fe80::f12b:85e:f95c:191e]) by KL1PR03MB5521.apcprd03.prod.outlook.com ([fe80::f12b:85e:f95c:191e%4]) with mapi id 15.20.9412.005; Fri, 12 Dec 2025 04:11:45 +0000 Message-ID: <12f26bf8-409b-4206-a39b-4bb2a14edec0@amlogic.com> Date: Fri, 12 Dec 2025 12:11:42 +0800 User-Agent: Mozilla Thunderbird Subject: Re: [PATCH RFC v2 2/3] decoder: Add V4L2 stateless H.264 decoder driver To: Nicolas Dufresne , Mauro Carvalho Chehab , Rob Herring , Krzysztof Kozlowski , Conor Dooley , Neil Armstrong , Kevin Hilman , Jerome Brunet , Martin Blumenstingl Cc: linux-media@vger.kernel.org, devicetree@vger.kernel.org, linux-kernel@vger.kernel.org, linux-arm-kernel@lists.infradead.org, linux-amlogic@lists.infradead.org References: <20251124-b4-s4-vdec-upstream-v2-0-bdbbce3f11a6@amlogic.com> <20251124-b4-s4-vdec-upstream-v2-2-bdbbce3f11a6@amlogic.com> <9b74086ac938475328904960add2c284b81efd4a.camel@ndufresne.ca> From: Zhentao Guo In-Reply-To: <9b74086ac938475328904960add2c284b81efd4a.camel@ndufresne.ca> Content-Type: text/plain; charset=UTF-8; format=flowed Content-Transfer-Encoding: 8bit X-ClientProxiedBy: SI2P153CA0016.APCP153.PROD.OUTLOOK.COM (2603:1096:4:140::17) To KL1PR03MB5521.apcprd03.prod.outlook.com (2603:1096:820:51::12) Precedence: bulk X-Mailing-List: devicetree@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 X-MS-PublicTrafficType: Email X-MS-TrafficTypeDiagnostic: KL1PR03MB5521:EE_|SEYPR03MB6628:EE_ X-MS-Office365-Filtering-Correlation-Id: ef578a28-a278-4c3e-b7fe-08de39348f9b X-MS-Exchange-SenderADCheck: 1 X-MS-Exchange-AntiSpam-Relay: 0 X-Microsoft-Antispam: BCL:0;ARA:13230040|7416014|366016|376014|4022899009|1800799024; X-Microsoft-Antispam-Message-Info: =?utf-8?B?bEw5TWFlZmFKYVc0M1gvSnBWYVJHTDhTdExZWnRPejFUbTY3b1ZPTUpyQSt6?= =?utf-8?B?UTZnMkR0aEtQTVlSS05YL09WUkNaUTExOFc2eFBURHVvcStoUTZoVVBxUUEx?= =?utf-8?B?a3lXc2NPOFlWd0RZeG9lajRLWDA1TzEwbXBTMFMxSXBxeDRrcXFIbW1lWjhv?= =?utf-8?B?ZHZ0WS9wblYwSmhvN0trTmVIWEkvMysyWUVJQ0p3Sm5tSHhRQVBZKzhUS3ZK?= =?utf-8?B?R1FpNTNsRUFkUHQvMVNsbmxJb0ZZU3FIblFHZ1lBUEFnWUZkblBEN29mQ0tH?= =?utf-8?B?Z01pS0hlQ1Z1VDYya0NNaVI1YldUMGFlWVhYb25NV0l3bzQramRxWmNSeXFv?= =?utf-8?B?STZZbU1RdEpxTE5OOTQ2cnUxbVpYdGtwZ3BHUnZkdGdpVmp3SDlFREpSV3k0?= =?utf-8?B?Y2x0aTVOR0FmajM5YStsdXcwV08zWEhBbXFiZmNnTDk0Nk1TK1d2eXE0RGov?= =?utf-8?B?OGFYYVJkbTZxTUcrRWJTYlJ4OU5CY3FlVFdvTjNRNC9Hb1lBZ1dBdGd5N2t1?= =?utf-8?B?UDdzOTZnVXgrcGVaWDU1dWpBUkluME9IUnduZC9ZWENWR01xRCtTVHNYR2hs?= =?utf-8?B?dG14ZTYydU43cVRpSmszZXBoT1VGZ1JmWGw4eDh2RmppQ0VVdzI1TFUxbEE2?= =?utf-8?B?N2l5U3BMdEFqeWZ2Z2tseUdyTWJqOW80bzFFTjk0Q043Y1FwNjFONHA5d1dX?= =?utf-8?B?WUNMZUNiZ1gxZm84cEVETWJlVUdnZlE1dDI2bS9oZ09rMkU0Z1dGNlR5ZVYv?= =?utf-8?B?QWE4cEZ2Q2owYkJyRHBCSVUyRUFqWGV4aktPelpDZi92RGJWTWJWQUVEUllx?= =?utf-8?B?cHQ5NW5UWkh6Q3ExcDJJYUdLUXdZUGRuUHhWTmVNMlB0WGFGV3hOdi96VjBK?= =?utf-8?B?RVF5eTlPclYyVXNhclY1SGkyTC9Id1ByWHRhZS8xTGFySS94c3ZNVi84Q1hE?= =?utf-8?B?ZGNIaU93VThHVlluVHpFZE1HWkxpMWdnWmt6ZjdyYm42ZWxRZnVBM05zRFpN?= =?utf-8?B?TTQ1Q3czbUgvRzc5blRJa2ZSVEZpcFg0Y3lSWFQ0aTlDTW9DeURUV0RnUEho?= =?utf-8?B?dFdnbEorQWViditWdUdyYlN0bnkrWFRWdWFjbDVlYS9IbzlKOUsza3ZlRGxL?= =?utf-8?B?eGo2SHFUaTdhV21wa2k0UGU5Zm9Dd3FzRG9Kb0M4bHJHZGIzdTJObmIxRFZN?= =?utf-8?B?b0ZGUHZtdUdKZ0loMFJrVW9GUHJPZkVxRDZaN2ptVEs5WkYxeE9JdTlTWWs0?= =?utf-8?B?bmJyRjlOZHBoaW9IUXpRajFwU1hwWjJ3dGtlUS9Uemh1U0VuQ0xNakh5dmg2?= =?utf-8?B?UFhkcCsremRFSFFCOEZJVEVOMWdFeFAyYjVwNjVkemZCSldSVzFZREJRWlNr?= =?utf-8?B?bVpUQUMwdEdlcDVJZ0ZZQzRpc2o1VnNuRmdqRmNhKzhyTVZOQlVSN3dUakdX?= =?utf-8?B?aGpUWGFCbkFmZE5TdC91YzF1dmphU00wMHE5TURMOE5nc05WY2E0dkJiTFU4?= =?utf-8?B?SDlOYzcyRVNSam9iR1hDNnNPcTMwQnpUbk95emRkQmNSenN5a1VmczZDNk1l?= =?utf-8?B?ZnJKS0FnSmN5UjJIL0tGWDMycFdldHlKSnpJQTgvS1pKbnBUZkJldTRqd1lE?= =?utf-8?B?VlZBVUxYL2o2Y0xmTHlqOHFEUUtzSXNyV1NiTTlXbUlPVlJGYXhpbEhCanlO?= =?utf-8?B?S2l4c2xRTnJQYjNKZjhOdzB5bWVRUHc5MUUxeU1RWVlxd01ZWkNOUzRtaGk0?= =?utf-8?B?cXhPT2FIc0lhUU5jOW9Lc2tmcDRrUy9Wd052N20yQnZOWnlJL2MxOGIxUUlK?= =?utf-8?B?UWJuT0FGNHFTcnVLWUtZUjFPRm9mVUFGVGpHaDEyRjd2by9ISnZBWEpIVWly?= =?utf-8?B?dWFUU1AvbkxUTmpHdWlFVHNDR25HK2VvUThlRExiRHYrZGxlalZNbWsvWFFw?= =?utf-8?Q?GgmWNhf/6m7eF12O0Z6wIlF/s6lO0axR?= X-Forefront-Antispam-Report: CIP:255.255.255.255;CTRY:;LANG:en;SCL:1;SRV:;IPV:NLI;SFV:NSPM;H:KL1PR03MB5521.apcprd03.prod.outlook.com;PTR:;CAT:NONE;SFS:(13230040)(7416014)(366016)(376014)(4022899009)(1800799024);DIR:OUT;SFP:1102; X-MS-Exchange-AntiSpam-MessageData-ChunkCount: 1 X-MS-Exchange-AntiSpam-MessageData-0: =?utf-8?B?N09jcFkvanZFK1dOQldsL3I2WmNyZFFJQlpKeTFiVENiTFRCc25zaHlHaXZP?= =?utf-8?B?VktPQTVqclVSLzg2cHRJdVFzMEwrWGZkaXVLMkhqREF1QVpORGEzWjduYzYv?= =?utf-8?B?SE00SjhzR2JMVndKa1ovLzIyZWZPUWJMTVNHSHhaMStWR2RRQnJKMXFmZ1pZ?= =?utf-8?B?SnBkbEIra0FRcU1xV2YvcVE2dUdzckpNZ3ZFaTJsdlpIYm1RT3V4Nm84RU5G?= =?utf-8?B?eFpoQkgyT04zdDl4UGhaNmxYeEozQnhUd1VCSkxZc0lraWZEdDc4MGt4Q3l1?= =?utf-8?B?R001c0trRkw1R1loN2VzL3lBeisxMk5tK1gzMm9qMFFHUmhLWlNnYmpmS1B6?= =?utf-8?B?UW9xcklGWmo2S3VMUWd3YUNKWWdZQXN2SFRsbnl5WXVIUm9ZbG1ZaEFHT1JK?= =?utf-8?B?RnZNZmpYZGFCdmdiQVYyTVlZTU5yL2ZacWdYYUdaZC9EVnhhSEJVWEdCM2RB?= =?utf-8?B?LzdBeG1sWmJOV3JscnBmazdPYXZlcWRuZFJ6dWVFUmthNFJEaUdFbUdOSHYw?= =?utf-8?B?T1dYc1VuM0MrbkQ0MWtudGNYU0NzZlliWmhtdXNTMEQwU1JidEx0K1FCUHNJ?= =?utf-8?B?M0hWdUFnNWZLY2Vqc0xWT2JIeGdWZWNiZ1gvbG00K2NLWVo3Uy93eWFaOEVG?= =?utf-8?B?bU80UHJmSmdpNzZuZmNTVTRWYll2Rk9kbk5HeVg5T1B6QXJ4TjBuKzkvVzBB?= =?utf-8?B?NnN4VWwrQk0wUm16M2RkaUp4c0FzWXZibXNTK2JEck5yNkdZRXZwaVRIS1F4?= =?utf-8?B?eFZMMnpIbzZGMUh6QW1TOWJCem9mNXZwNm9mT2t6SHo0UDBHRzl1QTY1QUt1?= =?utf-8?B?SE5oUXk4aXdhbEZObE1BMHZadlI4cE1zU1ZIK1hTUnU4dWdsbWlJWldZYWM1?= =?utf-8?B?aGZIM2lnRHBCRlo0OStrc1RxRWZSMW9rYi81WDFVUDkzc0hrcjBFM0V3TUFu?= =?utf-8?B?YjllZE45cldKVXlRNGNnSEt4ZTZEL0tKRXJOaFFQVnBiYjVIaGR0MmFIRVV0?= =?utf-8?B?ZWx4aklxMzVHM1A1Mldka3RCekRDMWFhSkRDR0tYN1VWczhHUDNtbHA0eS9H?= =?utf-8?B?SFBNTTA0Y3lOM2g0Y1U5S0dYVkZ3WWZJdmloVmVnNGo2bE9xTXJGbnFyU2x2?= =?utf-8?B?am5mcW5DS21yKzFWckJXelVpWjloZUdFRGZoajN3ZGd5T3h1Um8zY2lranJ2?= =?utf-8?B?QUM1bjVKYndBQmRQWWxWeGR1d1R0WFNpMVBTZ1p1NWlhSEdFNmJEdllPTHpa?= =?utf-8?B?UWwxdTVIdE9kM1dKSmxYRU14eEVtSEp1ZmhFb29lU3dua0FIUzk4VnhBWGxB?= =?utf-8?B?R2h1WFh6MU54SGVBbWdFeUo3ekZzeU9Fb21oRnkwYmxsWDkvdW5sRVYreDVP?= =?utf-8?B?dWFpeGQ3cmpFL2Q2d05VWlhjZWxNd0V6M3VjN3NFQmNXWkI0RlpUeGRDaW1w?= =?utf-8?B?MTNBZDhQOG1kSkp5Z3g2YkNUMDF0QVJZVWVOVjAzR0RZVlBOYUlVNEdJc0dK?= =?utf-8?B?eXEzQm9seVh5Z3loOXlnL3hGRXVZTWtmUnY2YUNEU1pvTVpvYmhSelBaU3JC?= =?utf-8?B?UHlKS2NCSVhTWmZoZ0w2QVk1VXhZNlN3cHByRHl0ZnlGUkk1dWhYZVZhQmRZ?= =?utf-8?B?Mldja0YxMUt1QVRYNm4zR1Z3eFVpdG9Nbm5CbDl2QVVBNjhEaW1OTEhvS1ZM?= =?utf-8?B?aEQ3WGU1K3hBKy81emdCK2E5bHVoNlpGdk13Szh1cVZ1Z25xN1lIem1nRjVR?= =?utf-8?B?TkNJRlJ6Ynh0ek0vQUlyTmdaM29tcGJOaGdxSWQ0dlJ1WU9wQi84Y25pQTRv?= =?utf-8?B?eUtiU0FmMktZbFZ0VWpZeE9RcXdwdW1KS01iZUE1Ymd1aVh5Nis1VEV5QlJz?= =?utf-8?B?cDJJa2VUYnFCNUNtYU1kRzEvdC9MRTZjU25JRnBpQms3aWVNTlplbkZKZjdx?= =?utf-8?B?SGM0blJmYXhBeUE2ekVqRHVmbDFkMUxjYmRlMzJZSTI4UFNlZ0N3andvQzhU?= =?utf-8?B?eGdJczI2UUNsKzZvVmdoTS9OVytEMWx4QS9QeHRwcWJGOHNZTUVYSmJIdWJL?= =?utf-8?B?Z2c0Q3ljSVRzRkU2OENWaCtVdUh6SmIvRUZCcW1Bei9iYnErQTJpOXhuUStZ?= =?utf-8?Q?jc4nKxLJFG/RzJy40K/jdEL25?= X-OriginatorOrg: amlogic.com X-MS-Exchange-CrossTenant-Network-Message-Id: ef578a28-a278-4c3e-b7fe-08de39348f9b X-MS-Exchange-CrossTenant-AuthSource: KL1PR03MB5521.apcprd03.prod.outlook.com X-MS-Exchange-CrossTenant-AuthAs: Internal X-MS-Exchange-CrossTenant-OriginalArrivalTime: 12 Dec 2025 04:11:45.1665 (UTC) X-MS-Exchange-CrossTenant-FromEntityHeader: Hosted X-MS-Exchange-CrossTenant-Id: 0df2add9-25ca-4b3a-acb4-c99ddf0b1114 X-MS-Exchange-CrossTenant-MailboxType: HOSTED X-MS-Exchange-CrossTenant-UserPrincipalName: xNntlKaeRHbv+NgzNYZw1LoAnILD16y9wizW7HmK/GKzRpCu4qHSMv6plJrVcSkgwF6qtJH8oNqIiRVNJlZsfg== X-MS-Exchange-Transport-CrossTenantHeadersStamped: SEYPR03MB6628 在 2025/12/12 3:53, Nicolas Dufresne 写道: Hi Nicolas > Le lundi 24 novembre 2025 à 11:32 +0800, Zhentao Guo via B4 Relay a écrit : >> From: Zhentao Guo >> >> Add initial support for V4L2 stateless video decoder >> driver on Amlogic S4(S805X2) platform. In phase 1, >> it supports H.264 bitstreams decoding. > Please reflow in next version, you can use something like 72 char. Since this is > subset of what the HW can do, some extra information is appreciate, perhaps > which profiles, pixel depth etc. Thanks, I got it. I will optimize it in the next version according to your suggestions. >> Signed-off-by: Zhentao Guo >> --- >>  MAINTAINERS                                        |    7 + >>  drivers/media/platform/amlogic/Kconfig             |    1 + >>  drivers/media/platform/amlogic/Makefile            |    1 + >>  drivers/media/platform/amlogic/vdec/Kconfig        |   16 + >>  drivers/media/platform/amlogic/vdec/Makefile       |    4 + >>  drivers/media/platform/amlogic/vdec/TODO           |    7 + >>  drivers/media/platform/amlogic/vdec/aml_vdec.c     |  756 ++++++++ >>  drivers/media/platform/amlogic/vdec/aml_vdec.h     |   31 + >>  drivers/media/platform/amlogic/vdec/aml_vdec_drv.c |  239 +++ >>  drivers/media/platform/amlogic/vdec/aml_vdec_drv.h |  196 ++ >>  drivers/media/platform/amlogic/vdec/aml_vdec_hw.c  |  596 ++++++ >>  drivers/media/platform/amlogic/vdec/aml_vdec_hw.h  |  158 ++ >>  .../platform/amlogic/vdec/aml_vdec_platform.c      |   37 + >>  .../platform/amlogic/vdec/aml_vdec_platform.h      |   62 + >>  drivers/media/platform/amlogic/vdec/h264.c         | 1933 ++++++++++++++++++++ >>  drivers/media/platform/amlogic/vdec/h264.h         |  300 +++ >>  drivers/media/platform/amlogic/vdec/reg_defines.h  |  177 ++ >>  17 files changed, 4521 insertions(+) >> >> diff --git a/MAINTAINERS b/MAINTAINERS >> index ec635515c0c4..371c8b828394 100644 >> --- a/MAINTAINERS >> +++ b/MAINTAINERS >> @@ -1365,6 +1365,13 @@ S: Maintained >>  F: Documentation/devicetree/bindings/spi/amlogic,a4-spisg.yaml >>  F: drivers/spi/spi-amlogic-spisg.c >> >> +AMLOGIC VCODEC DRIVER >> +M: Zhentao Guo >> +L: linux-media@vger.kernel.org >> +S: Maintained >> +F: Documentation/devicetree/bindings/media/amlogic,s4-vcodec-dec.yaml >> +F: drivers/media/platform/amlogic/vdec/ >> + >>  AMPHENOL CHIPCAP 2 DRIVER >>  M: Javier Carrasco >>  L: linux-hwmon@vger.kernel.org >> diff --git a/drivers/media/platform/amlogic/Kconfig b/drivers/media/platform/amlogic/Kconfig >> index 458acf3d5fa8..7c541ac0d0c3 100644 >> --- a/drivers/media/platform/amlogic/Kconfig >> +++ b/drivers/media/platform/amlogic/Kconfig >> @@ -4,3 +4,4 @@ comment "Amlogic media platform drivers" >> >>  source "drivers/media/platform/amlogic/c3/Kconfig" >>  source "drivers/media/platform/amlogic/meson-ge2d/Kconfig" >> +source "drivers/media/platform/amlogic/vdec/Kconfig" >> diff --git a/drivers/media/platform/amlogic/Makefile b/drivers/media/platform/amlogic/Makefile >> index c744afcd1b9e..7409de674c0b 100644 >> --- a/drivers/media/platform/amlogic/Makefile >> +++ b/drivers/media/platform/amlogic/Makefile >> @@ -2,3 +2,4 @@ >> >>  obj-y += c3/ >>  obj-y += meson-ge2d/ >> +obj-y += vdec/ >> diff --git a/drivers/media/platform/amlogic/vdec/Kconfig b/drivers/media/platform/amlogic/vdec/Kconfig >> new file mode 100644 >> index 000000000000..95424d64cc1f >> --- /dev/null >> +++ b/drivers/media/platform/amlogic/vdec/Kconfig >> @@ -0,0 +1,16 @@ >> +# SPDX-License-Identifier: (GPL-2.0-only OR MIT) >> + >> +config VIDEO_AMLOGIC_VCODEC >> +    tristate "Amlogic Video Codec Driver" >> +    depends on ARCH_MESON || COMPILE_TEST >> +    depends on VIDEO_DEV >> +    depends on V4L_MEM2MEM_DRIVERS >> +    select VIDEOBUF2_DMA_CONTIG >> +    select V4L2_H264 >> +    select V4L2_MEM2MEM_DEV >> +    select MESON_CANVAS >> +    help >> +      This is a v4l2 driver for Amlogic video codec driver. >> +   This driver is designed to support V4L2 M2M STATELESS >> +   interface. >> +      To compile this driver as a module choose m here. >> diff --git a/drivers/media/platform/amlogic/vdec/Makefile b/drivers/media/platform/amlogic/vdec/Makefile >> new file mode 100644 >> index 000000000000..1a7dcf1d7562 >> --- /dev/null >> +++ b/drivers/media/platform/amlogic/vdec/Makefile >> @@ -0,0 +1,4 @@ >> +# SPDX-License-Identifier: GPL-2.0-only >> +aml-vdec-drv-objs := aml_vdec.o aml_vdec_drv.o aml_vdec_hw.o aml_vdec_platform.o h264.o\ >> + >> +obj-$(CONFIG_VIDEO_AMLOGIC_VCODEC) += aml-vdec-drv.o >> diff --git a/drivers/media/platform/amlogic/vdec/TODO b/drivers/media/platform/amlogic/vdec/TODO >> new file mode 100644 >> index 000000000000..54c60145770e >> --- /dev/null >> +++ b/drivers/media/platform/amlogic/vdec/TODO >> @@ -0,0 +1,7 @@ >> +TODO list for Amlogic V4L2 stateless decoder driver: >> + >> +1. Support decoding for HEVC, VP9, AV1, and MPEG-2. >> +2. Support more SoCs, including the new T7/S7 series and legacy SoCs (e.g., GXL, SM1, G12B). >> +3. Support 10-bit decoding and P010 output. >> +   Note: P010 output requires hardware support. >> +4. Support interlaced stream decoding for H.264, HEVC, and MPEG-2. >> diff --git a/drivers/media/platform/amlogic/vdec/aml_vdec.c b/drivers/media/platform/amlogic/vdec/aml_vdec.c >> new file mode 100644 >> index 000000000000..3ef2d32a7a73 >> --- /dev/null >> +++ b/drivers/media/platform/amlogic/vdec/aml_vdec.c >> @@ -0,0 +1,756 @@ >> +// SPDX-License-Identifier: (GPL-2.0-only OR MIT) >> +/* >> + * Copyright (C) 2025 Amlogic, Inc. All rights reserved >> + */ >> + >> +#include >> +#include >> +#include >> +#include >> +#include >> + >> +#include "aml_vdec.h" >> +#include "aml_vdec_hw.h" >> +#include "aml_vdec_platform.h" >> + >> +#define VCODEC_DRV_NAME "aml-vdec-drv" >> + >> +static const struct aml_vdec_v4l2_ctrl controls[] = { >> + { >> + .codec_type = CODEC_TYPE_H264, >> + .cfg = { >> + .id = V4L2_CID_STATELESS_H264_DECODE_PARAMS, >> + }, >> + }, { >> + .codec_type = CODEC_TYPE_H264, >> + .cfg = { >> + .id = V4L2_CID_STATELESS_H264_SPS, >> + }, >> + }, { >> + .codec_type = CODEC_TYPE_H264, >> + .cfg = { >> + .id = V4L2_CID_STATELESS_H264_PPS, >> + }, >> + }, { >> + .codec_type = CODEC_TYPE_H264, >> + .cfg = { >> + .id = V4L2_CID_STATELESS_H264_SCALING_MATRIX, >> + }, >> + }, { >> + .codec_type = CODEC_TYPE_H264, >> + .cfg = { >> + .id = V4L2_CID_STATELESS_H264_DECODE_MODE, >> + .min = V4L2_STATELESS_H264_DECODE_MODE_FRAME_BASED, >> + .def = V4L2_STATELESS_H264_DECODE_MODE_FRAME_BASED, >> + .max = V4L2_STATELESS_H264_DECODE_MODE_FRAME_BASED, >> + }, >> + }, { >> + .codec_type = CODEC_TYPE_H264, >> + .cfg = { >> + .id = V4L2_CID_MPEG_VIDEO_H264_LEVEL, >> + }, >> + }, { >> + .codec_type = CODEC_TYPE_H264, >> + .cfg = { >> + .id = V4L2_CID_STATELESS_H264_START_CODE, >> + .min = V4L2_STATELESS_H264_START_CODE_ANNEX_B, >> + .def = V4L2_STATELESS_H264_START_CODE_ANNEX_B, >> + .max = V4L2_STATELESS_H264_START_CODE_ANNEX_B, >> + }, >> + }, { >> + .codec_type = CODEC_TYPE_H264, >> + .cfg = { >> + .id = V4L2_CID_MPEG_VIDEO_H264_PROFILE, >> + .min = V4L2_MPEG_VIDEO_H264_PROFILE_BASELINE, >> + .max = V4L2_MPEG_VIDEO_H264_PROFILE_HIGH, >> + .def = V4L2_MPEG_VIDEO_H264_PROFILE_MAIN, >> + }, >> + } >> +}; >> + >> +static struct aml_video_fmt aml_video_formats[] = { >> + { >> + .name = "H.264", >> + .fourcc = V4L2_PIX_FMT_H264_SLICE, >> + .type = AML_FMT_DEC, >> + .codec_type = CODEC_TYPE_H264, >> + .num_planes = 1, >> + .stepwise = {AML_VDEC_MIN_W, AML_VDEC_1080P_MAX_W, 2, >> + AML_VDEC_MIN_H, AML_VDEC_1080P_MAX_H, 2}, >> + }, >> + { >> + .name = "NV21M", >> + .fourcc = V4L2_PIX_FMT_NV21M, >> + .type = AML_FMT_FRAME, >> + .codec_type = CODEC_TYPE_FRAME, >> + .num_planes = 2, >> + .stepwise = {AML_VDEC_MIN_W, AML_VDEC_1080P_MAX_W, 2, >> + AML_VDEC_MIN_H, AML_VDEC_1080P_MAX_H, 2}, > You can make a define to initialize this, so you don't repeat it over and over. > Also, try to use readable style, similar to the cfg above. OK, I'll refer to some other upstreamed drivers and imporve this. > >> + }, >> + { >> + .name = "NV21", >> + .fourcc = V4L2_PIX_FMT_NV21, >> + .type = AML_FMT_FRAME, >> + .codec_type = CODEC_TYPE_FRAME, >> + .num_planes = 1, >> + .stepwise = {AML_VDEC_MIN_W, AML_VDEC_1080P_MAX_W, 2, >> + AML_VDEC_MIN_H, AML_VDEC_1080P_MAX_H, 2}, >> + }, >> + { >> + .name = "NV12M", >> + .fourcc = V4L2_PIX_FMT_NV12M, >> + .type = AML_FMT_FRAME, >> + .codec_type = CODEC_TYPE_FRAME, >> + .num_planes = 2, >> + .stepwise = {AML_VDEC_MIN_W, AML_VDEC_1080P_MAX_W, 2, >> + AML_VDEC_MIN_H, AML_VDEC_1080P_MAX_H, 2}, >> + >> + }, >> + { >> + .name = "NV12", >> + .fourcc = V4L2_PIX_FMT_NV12, >> + .type = AML_FMT_FRAME, >> + .codec_type = CODEC_TYPE_FRAME, >> + .num_planes = 1, >> + .stepwise = {AML_VDEC_MIN_W, AML_VDEC_1080P_MAX_W, 2, >> + AML_VDEC_MIN_H, AML_VDEC_1080P_MAX_H, 2}, >> + }, >> +}; >> + >> +void aml_vdec_set_default_params(struct aml_vdec_ctx *ctx) >> +{ >> + struct aml_q_data *q_data = NULL; >> + >> + ctx->m2m_ctx->q_lock = &ctx->v4l2_intf_lock; >> + >> + ctx->pic_info.colorspace = V4L2_COLORSPACE_DEFAULT; >> + ctx->pic_info.ycbcr_enc = V4L2_YCBCR_ENC_DEFAULT; >> + ctx->pic_info.quantization = V4L2_QUANTIZATION_DEFAULT; >> + ctx->pic_info.xfer_func = V4L2_XFER_FUNC_DEFAULT; >> + >> + q_data = &ctx->q_data[AML_Q_DATA_SRC]; >> + memset(q_data, 0, sizeof(struct aml_q_data)); >> + q_data->visible_width = AML_VDEC_MIN_W; >> + q_data->visible_height = AML_VDEC_MIN_H; >> + q_data->coded_width = AML_VDEC_MIN_W; >> + q_data->coded_height = AML_VDEC_MIN_H; >> + q_data->filed_flag = V4L2_FIELD_NONE; >> + q_data->bytesperline[0] = 0; >> + q_data->sizeimage[0] = (1024 * 1024); >> + q_data->fmt = &aml_video_formats[DEFAULT_OUT_IDX]; >> + >> + q_data = &ctx->q_data[AML_Q_DATA_DST]; >> + memset(q_data, 0, sizeof(struct aml_q_data)); >> + q_data->visible_width = AML_VDEC_MIN_W; >> + q_data->visible_height = AML_VDEC_MIN_H; >> + q_data->coded_width = AML_VDEC_MIN_W; >> + q_data->coded_height = AML_VDEC_MIN_H; >> + q_data->filed_flag = V4L2_FIELD_NONE; >> + q_data->bytesperline[0] = q_data->coded_width; >> + q_data->sizeimage[0] = q_data->coded_width * q_data->coded_height; >> + q_data->bytesperline[1] = q_data->coded_width; >> + q_data->sizeimage[1] = q_data->sizeimage[0] / 2; >> + q_data->fmt = &aml_video_formats[DEFAULT_CAP_IDX]; > Why do you duplicated visible and coded width ? how can you hold two of these ? Indeed the decoder hardware will only use coded width/height. They are used to calculate the offset of the chroma data from the capture buffer. I'll refer to some upstreamed drivers and see how they handle these two values. > Also, to avoid possible deviate in sizeimage/bytesperline calculation, introduce > some reset function, and perhaps make use of your internal implementation of > try_fmt. OK, I'll replace this with a proper reset function. >> +} >> + >> +int aml_vdec_ctrls_setup(struct aml_vdec_ctx *ctx) >> +{ >> + int i; >> + int ctrls_size = sizeof(controls) / sizeof(struct aml_vdec_v4l2_ctrl); >> + >> + v4l2_ctrl_handler_init(&ctx->ctrl_handler, ctrls_size); >> + for (i = 0; i < ctrls_size; i++) { >> + v4l2_ctrl_new_custom(&ctx->ctrl_handler, &controls[i].cfg, NULL); >> + if (ctx->ctrl_handler.error) { >> + dev_info(&ctx->dev->plat_dev->dev, "add ctrl for (%d) failed%d\n", >> + controls[i].cfg.id, ctx->ctrl_handler.error); >> + v4l2_ctrl_handler_free(&ctx->ctrl_handler); >> + return ctx->ctrl_handler.error; >> + } >> + } >> + ctx->fh.ctrl_handler = &ctx->ctrl_handler; >> + return v4l2_ctrl_handler_setup(&ctx->ctrl_handler); >> +} >> + >> +static void m2mops_vdec_device_run(void *m2m_priv) >> +{ >> + struct aml_vdec_ctx *ctx = (struct aml_vdec_ctx *)m2m_priv; > No need to cast void* Got it! > >> + struct aml_vdec_dev *dev = ctx->dev; >> + struct vb2_v4l2_buffer *src, *dst; > nit: src_buf, dst_buf OK, I'll rename them. > >> + struct media_request *src_req; >> + const char *fw_path = dev->pvdec_data->fw_path[ctx->curr_dec_type]; >> + >> + src = v4l2_m2m_next_src_buf(ctx->fh.m2m_ctx); >> + dst = v4l2_m2m_next_dst_buf(ctx->fh.m2m_ctx); >> + dev_dbg(&dev->plat_dev->dev, "device run : src buf : %d dst buf %d\n", >> + src->vb2_buf.index, dst->vb2_buf.index); >> + >> + src_req = src->vb2_buf.req_obj.req; >> + if (src_req) >> + v4l2_ctrl_request_setup(src_req, &ctx->ctrl_handler); > I'll need to check, not all drivers do these check, yet I haven't found in the > core where we prevent this from happening. I want the core to prevent this so we > can remove all these checks, but I'm a bit unsure now. Got it. If you think this can be removed, please feel free to inform me, thanks! >> + >> + dos_enable(dev->dec_hw); >> + /* incase of bus hang in stop_streaming */ >> + ctx->dos_clk_en = 1; >> + aml_vdec_reset_core(dev->dec_hw); >> + load_firmware(dev->dec_hw, fw_path); >> + >> + if (ctx->codec_ops->run) >> + ctx->codec_ops->run(ctx); > use if (!BUG_ON(ctx->codec_ops->run == NULL)), it would be driver programming > error to not have a fun function. Yes, I'll add the BUG_ON here. > >> + >> + v4l2_m2m_buf_copy_metadata(src, dst); >> + if (src_req) >> + v4l2_ctrl_request_complete(src_req, &ctx->ctrl_handler); >> + >> + v4l2_m2m_buf_done_and_job_finish(dev->m2m_dev_dec, ctx->m2m_ctx, VB2_BUF_STATE_DONE); > This is atypical, normally we call this when we receive the IRQ, that avoid > having to poll, and remove a useless context switch. OK, I'll move it to the IRQ function. In fact, I haven't looked into the implementation details of this function yet. I'll go and study it. >> +} >> + >> +const struct v4l2_m2m_ops aml_vdec_m2m_ops = { >> + .device_run = m2mops_vdec_device_run, >> +}; >> + >> +static int vidioc_vdec_querycap(struct file *file, void *priv, >> + struct v4l2_capability *cap) >> +{ >> + strscpy(cap->driver, VCODEC_DRV_NAME, sizeof(cap->driver)); >> + strscpy(cap->card, "platform:" VCODEC_DRV_NAME, sizeof(cap->card)); >> + >> + return 0; >> +} >> + >> +static int vidioc_vdec_enum_fmt(struct v4l2_fmtdesc *f, bool is_output) >> +{ >> + struct aml_video_fmt *fmt; >> + int fmt_size = sizeof(aml_video_formats) / sizeof(struct aml_video_fmt); >> + int i = 0, j = 0; >> + >> + for (; i < fmt_size; i++) { >> + fmt = &aml_video_formats[i]; >> + if (is_output && fmt->type != AML_FMT_DEC) >> + continue; >> + if (!is_output && fmt->type != AML_FMT_FRAME) >> + continue; >> + >> + if (j == f->index) { >> + f->pixelformat = fmt->fourcc; >> + strscpy(f->description, fmt->name, >> + sizeof(f->description)); > There is a memory bounded version of this, and these are fixed size char array, > please use these. Got it. >> + if (strlen(fmt->name) >= sizeof(f->description)) >> + f->description[sizeof(f->description) - 1] = '\0'; > strcpy() would be the preferred helper for this, no need to fill the leading > zero liek this, see include/linux/string.h Ok, it should be more suitable to use strcpy. > >> + return 0; >> + } >> + ++j; >> + } >> + return -EINVAL; >> +} >> + >> +static struct aml_q_data *aml_vdec_get_qdata_by_type(struct aml_vdec_ctx *ctx, >> +      enum v4l2_buf_type type) >> +{ >> + if (V4L2_TYPE_IS_OUTPUT(type)) >> + return &ctx->q_data[AML_Q_DATA_SRC]; >> + >> + return &ctx->q_data[AML_Q_DATA_DST]; >> +} >> + >> +static struct aml_video_fmt *aml_vdec_get_video_fmt(u32 format) >> +{ >> + struct aml_video_fmt *fmt; >> + unsigned int k; >> + >> + for (k = 0; k < (sizeof(aml_video_formats) / sizeof(struct aml_video_fmt)); k++) { > ARRAY_SIZE gain, please apply through the entire patch. OK, this should be replaced with ARRAR_SIZE. >> + fmt = &aml_video_formats[k]; >> + if (fmt->fourcc == format) >> + return fmt; >> + } >> + >> + return NULL; >> +} >> + >> +static int aml_vdec_init_dec_inst(struct aml_vdec_ctx *ctx, >> +   struct aml_video_fmt *fmt_out) >> +{ >> + struct aml_vdec_dev *dev = ctx->dev; >> + int ret = -1; >> + >> + if (!fmt_out) >> + return ret; >> + >> + if (fmt_out->codec_type == CODEC_TYPE_FRAME) { >> + dev_dbg(&dev->plat_dev->dev, "capture type no need to set\n"); >> + return 0; >> + } >> + >> + ctx->codec_ops = &dev->pvdec_data->codec_ops[fmt_out->codec_type]; >> + if (ctx->codec_ops->init) { >> + ret = ctx->codec_ops->init(ctx); >> + if (ret < 0) >> + return ret; >> + } >> + ctx->curr_dec_type = fmt_out->codec_type; >> + dev_info(&dev->plat_dev->dev, "%s set curr_dec_type = %d\n", __func__, ctx->curr_dec_type); > I not sure I want to see a numerical value of an random enum from the code from > a dev_info(), please use dev_info() with the mindset that if you need to check > the code to see what it means, its not a dev_info(). Yes, I'll add format strings to this message. It can help others to understand what is happening. > >> + >> + return ret; >> +} >> + >> +static void set_pic_info(struct aml_vdec_ctx *ctx, >> + struct v4l2_pix_format_mplane *pix_mp, >> + enum v4l2_buf_type type) >> +{ >> + struct aml_q_data *q_data; >> + >> + q_data = aml_vdec_get_qdata_by_type(ctx, type); >> + >> + ctx->pic_info.colorspace = pix_mp->colorspace; >> + ctx->pic_info.ycbcr_enc = pix_mp->ycbcr_enc; >> + ctx->pic_info.quantization = pix_mp->quantization; >> + ctx->pic_info.xfer_func = pix_mp->xfer_func; >> + >> + if (V4L2_TYPE_IS_OUTPUT(type)) { >> + q_data->sizeimage[0] = pix_mp->plane_fmt[0].sizeimage; >> + ctx->pic_info.output_pix_fmt = pix_mp->pixelformat; >> + ctx->pic_info.coded_width = ALIGN(pix_mp->width, 64); >> + ctx->pic_info.coded_height = ALIGN(pix_mp->height, 64); >> + ctx->pic_info.fb_size[0] = >> +     ctx->pic_info.coded_width * ctx->pic_info.coded_height; >> + ctx->pic_info.fb_size[1] = ctx->pic_info.fb_size[0] / 2; >> + ctx->pic_info.plane_num = 1; >> + } else { >> + ctx->pic_info.plane_num = q_data->fmt->num_planes; >> + ctx->pic_info.cap_pix_fmt = pix_mp->pixelformat; >> + q_data->coded_width = ctx->pic_info.coded_width; >> + q_data->coded_height = ctx->pic_info.coded_height; >> + q_data->sizeimage[0] = ctx->pic_info.fb_size[0]; >> + q_data->bytesperline[0] = ctx->pic_info.coded_width; >> + if (q_data->fmt->num_planes > 1) { >> + q_data->sizeimage[1] = ctx->pic_info.fb_size[1]; >> + q_data->bytesperline[1] = ctx->pic_info.coded_width; >> + } else { >> + q_data->sizeimage[0] += ctx->pic_info.fb_size[1]; >> + } >> + } > > Why don't you simply store the format structure ? width/height alignment is well > covered in v4l2-common, use the helpers. Re-use your try_fmt implementation for > this too, and makes sure the changes are reflected to users. Yes, this seems too complicate and superfluous. I'll simplify this. > Finally, don't duplicate the data, its all very error prone. You have pic_info > stored in 3 places now. OK, I'll fix this problem. > >> +} >> + >> +static int vidioc_vdec_enum_framesizes(struct file *file, void *priv, >> +        struct v4l2_frmsizeenum *fsize) >> +{ >> + struct aml_video_fmt *fmt; >> + struct aml_vdec_dev *dev = video_drvdata(file); >> + u32 max_h, max_w; >> + >> + if (fsize->index != 0) >> + return -EINVAL; >> + >> + max_h = dev->pvdec_data->dec_fmt->max_height; >> + max_w = dev->pvdec_data->dec_fmt->max_width; >> + >> + fmt = aml_vdec_get_video_fmt(fsize->pixel_format); >> + if (!fmt) >> + return -EINVAL; >> + >> + fsize->type = V4L2_FRMSIZE_TYPE_STEPWISE; >> + fsize->stepwise = fmt->stepwise; >> + fsize->stepwise.max_height = max_h; >> + fsize->stepwise.max_width = max_w; > no min ? Normally under 1x1 is not allowed. The min width x height should be 64 x 64 for S805X2 platform. This should be added. >> + >> + return 0; >> +} >> + >> +static int vdec_try_fmt_mp(struct aml_vdec_ctx *ctx, struct v4l2_format *f, >> +    const struct aml_video_fmt *fmt_mp) >> +{ >> + struct v4l2_pix_format_mplane *pix_mp = &f->fmt.pix_mp; >> + struct aml_q_data *q_data; >> + struct aml_vdec_dev *dev = ctx->dev; >> + u32 max_h, max_w; >> + int i; >> + >> + max_h = dev->pvdec_data->dec_fmt->max_height; >> + max_w = dev->pvdec_data->dec_fmt->max_width; >> + >> + pix_mp->field = V4L2_FIELD_NONE; >> + q_data = aml_vdec_get_qdata_by_type(ctx, f->type); > I'm not sure it helps anything to use qdata. It was inherited from the legacy code actually, used for the default data storage. I'll try to use some other methods to improve this. >> + >> + pix_mp->height = clamp(pix_mp->height, AML_VDEC_MIN_H, max_h); >> + pix_mp->width = clamp(pix_mp->width, AML_VDEC_MIN_H, max_w); >> + >> + if (V4L2_TYPE_IS_OUTPUT(f->type)) { >> + pix_mp->num_planes = q_data->fmt->num_planes; >> + pix_mp->pixelformat = q_data->fmt->fourcc; >> + pix_mp->plane_fmt[0].bytesperline = q_data->bytesperline[0]; > What would you use bytesperline (stride) for on a bitstrream buffer ? Reset this > to zero at best. Yes, this can be reset to 0. > >> + pix_mp->plane_fmt[0].sizeimage = q_data->sizeimage[0]; > Application should be able to chose a size here. Also it make no sense to used > any cached value. Basically: > > 1. If its zero, compute a size, check what other drivers do > 2. Otherwise keep application provided size, but align it for your HW Got it! I should not be given a cacahed value. It should be given value by the user. I'll fix this. > In S_FMT, if that call succeed, and the queue isn't busy, you will reset the > CAPTURE format to keep it matching. Got it. > >> + } else { >> + v4l2_fill_pixfmt_mp(pix_mp, fmt_mp->fourcc, pix_mp->width, >> +     pix_mp->height); > With a proper reset, you will simply copy the fmt you have stored already. OK, I'll check my code carefully and see if this can be improved. > >> + } >> + >> + for (i = 0; i < pix_mp->num_planes; i++) >> + memset(&pix_mp->plane_fmt[i].reserved[0], 0x0, >> +        sizeof(pix_mp->plane_fmt[0].reserved)); >> + >> + memset(pix_mp->reserved, 0x0, sizeof(pix_mp->reserved)); >> + pix_mp->flags = 0; > The core is suppose to take care. You mean the V4L2 core? Then I will remove this. > >> + >> + return 0; >> +} >> + >> +static int vdec_s_fmt(struct aml_vdec_ctx *ctx, struct v4l2_format *f) >> +{ >> + struct aml_q_data *q_data; >> + struct v4l2_pix_format_mplane *pix_mp = &f->fmt.pix_mp; >> + struct aml_video_fmt *fmt = >> +     aml_vdec_get_video_fmt(f->fmt.pix_mp.pixelformat); >> + >> + q_data = aml_vdec_get_qdata_by_type(ctx, f->type); >> + >> + if (fmt) /* default fmt was set in fopen */ >> + q_data->fmt = fmt; > You should not write into the state before try_fmt, and without checking if the > queues are busy or not. Als, S_FMT(OUTPUT) will reset the capture format to > match, so it requires both queues to not be active. Check other drivers please. OK, I wansn't very clear about the behaviour before. I 'll refer to other upstreamed drivers and improve this. > > I'll stop here, I think you should rework your src/dst format storage. Make use > of v4l2-common. Since you plan to make this multi-variant, add structure to > store th#e alignment per-soc/per-codec etc. Thank you so much for pointing out all these issues ! I'll improve all the points you mentioned in the next patch version. > > regards, > Nicolas Best regards Zhentao >> + >> + vdec_try_fmt_mp(ctx, f, q_data->fmt); >> + set_pic_info(ctx, pix_mp, f->type); >> + >> + return 0; >> +} >> + >> +static int vdec_g_fmt(struct aml_vdec_ctx *ctx, struct v4l2_format *f) >> +{ >> + struct v4l2_pix_format_mplane *pix_mp = &f->fmt.pix_mp; >> + struct aml_q_data *q_data; >> + >> + q_data = aml_vdec_get_qdata_by_type(ctx, f->type); >> + >> + pix_mp->field = V4L2_FIELD_NONE; >> + pix_mp->colorspace = ctx->pic_info.colorspace; >> + pix_mp->ycbcr_enc = ctx->pic_info.ycbcr_enc; >> + pix_mp->quantization = ctx->pic_info.quantization; >> + pix_mp->xfer_func = ctx->pic_info.xfer_func; >> + >> + if (V4L2_TYPE_IS_OUTPUT(f->type)) { >> + pix_mp->height = q_data->coded_height; >> + pix_mp->width = q_data->coded_width; >> + pix_mp->pixelformat = q_data->fmt->fourcc; >> + pix_mp->num_planes = q_data->fmt->num_planes; >> + pix_mp->plane_fmt[0].bytesperline = q_data->bytesperline[0]; >> + pix_mp->plane_fmt[0].sizeimage = q_data->sizeimage[0]; >> + } else { >> + if (ctx->pic_info.coded_width != 0 && ctx->pic_info.coded_height != 0) { >> + pix_mp->width = ctx->pic_info.coded_width; >> + pix_mp->height = ctx->pic_info.coded_height; >> + } else { >> + pix_mp->height = q_data->coded_height; >> + pix_mp->width = q_data->coded_height; >> + } >> + v4l2_fill_pixfmt_mp(pix_mp, q_data->fmt->fourcc, pix_mp->width, >> +     pix_mp->height); >> + } >> + >> + return 0; >> +} >> + >> +static int vidioc_try_fmt_cap_mplane(struct file *file, void *priv, >> +      struct v4l2_format *f) >> +{ >> + struct aml_vdec_ctx *ctx = fh_to_dec_ctx(file); >> + const struct aml_video_fmt *fmt_mp; >> + struct aml_q_data *q_data; >> + >> + q_data = aml_vdec_get_qdata_by_type(ctx, V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE); >> + >> + fmt_mp = aml_vdec_get_video_fmt(f->fmt.pix_mp.pixelformat); >> + if (!fmt_mp) >> + fmt_mp = q_data->fmt; >> + >> + return vdec_try_fmt_mp(ctx, f, fmt_mp); >> +} >> + >> +static int vidioc_try_fmt_out_mplane(struct file *file, void *priv, >> +      struct v4l2_format *f) >> +{ >> + struct aml_vdec_ctx *ctx = fh_to_dec_ctx(file); >> + const struct aml_video_fmt *fmt_mp; >> + struct aml_q_data *q_data = aml_vdec_get_qdata_by_type(ctx, >> +        V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE); >> + >> + fmt_mp = aml_vdec_get_video_fmt(f->fmt.pix_mp.pixelformat); >> + if (!fmt_mp) >> + fmt_mp = q_data->fmt; >> + >> + return vdec_try_fmt_mp(ctx, f, fmt_mp); >> +} >> + >> +static int vidioc_vdec_s_fmt_out_mplane(struct file *file, void *priv, >> + struct v4l2_format *f) >> +{ >> + struct aml_vdec_ctx *ctx = fh_to_dec_ctx(file); >> + >> + return vdec_s_fmt(ctx, f); >> +} >> + >> +static int vidioc_vdec_s_fmt_cap_mplane(struct file *file, void *priv, >> + struct v4l2_format *f) >> +{ >> + struct aml_vdec_ctx *ctx = fh_to_dec_ctx(file); >> + >> + return vdec_s_fmt(ctx, f); >> +} >> + >> +static int vidioc_vdec_g_fmt_out_mplane(struct file *file, void *priv, >> + struct v4l2_format *f) >> +{ >> + struct aml_vdec_ctx *ctx = fh_to_dec_ctx(file); >> + >> + return vdec_g_fmt(ctx, f); >> +} >> + >> +static int vidioc_vdec_g_fmt_cap_mplane(struct file *file, void *priv, >> + struct v4l2_format *f) >> +{ >> + struct aml_vdec_ctx *ctx = fh_to_dec_ctx(file); >> + >> + return vdec_g_fmt(ctx, f); >> +} >> + >> +static int vidioc_vdec_enum_fmt_out_mplane(struct file *file, >> +    void *priv, struct v4l2_fmtdesc *f) >> +{ >> + return vidioc_vdec_enum_fmt(f, 1); >> +} >> + >> +static int vidioc_vdec_enum_fmt_cap_mplane(struct file *file, >> +    void *priv, struct v4l2_fmtdesc *f) >> +{ >> + return vidioc_vdec_enum_fmt(f, 0); >> +} >> + >> +const struct v4l2_ioctl_ops aml_vdec_ioctl_ops = { >> + .vidioc_querycap = vidioc_vdec_querycap, >> + .vidioc_enum_framesizes = vidioc_vdec_enum_framesizes, >> + >> + .vidioc_enum_fmt_vid_cap = vidioc_vdec_enum_fmt_cap_mplane, >> + .vidioc_try_fmt_vid_cap_mplane = vidioc_try_fmt_cap_mplane, >> + .vidioc_s_fmt_vid_cap_mplane = vidioc_vdec_s_fmt_cap_mplane, >> + .vidioc_g_fmt_vid_cap_mplane = vidioc_vdec_g_fmt_cap_mplane, >> + >> + .vidioc_enum_fmt_vid_out = vidioc_vdec_enum_fmt_out_mplane, >> + .vidioc_try_fmt_vid_out_mplane = vidioc_try_fmt_out_mplane, >> + .vidioc_s_fmt_vid_out_mplane = vidioc_vdec_s_fmt_out_mplane, >> + .vidioc_g_fmt_vid_out_mplane = vidioc_vdec_g_fmt_out_mplane, >> + >> + .vidioc_reqbufs = v4l2_m2m_ioctl_reqbufs, >> + .vidioc_querybuf = v4l2_m2m_ioctl_querybuf, >> + .vidioc_qbuf = v4l2_m2m_ioctl_qbuf, >> + .vidioc_dqbuf = v4l2_m2m_ioctl_dqbuf, >> + .vidioc_prepare_buf = v4l2_m2m_ioctl_prepare_buf, >> + .vidioc_create_bufs = v4l2_m2m_ioctl_create_bufs, >> + >> + .vidioc_expbuf = v4l2_m2m_ioctl_expbuf, >> + >> + .vidioc_decoder_cmd = v4l2_m2m_ioctl_stateless_decoder_cmd, >> + .vidioc_try_decoder_cmd = v4l2_m2m_ioctl_stateless_try_decoder_cmd, >> + >> + .vidioc_subscribe_event = v4l2_ctrl_subscribe_event, >> + .vidioc_unsubscribe_event = v4l2_event_unsubscribe, >> + >> + .vidioc_streamon = v4l2_m2m_ioctl_streamon, >> + .vidioc_streamoff = v4l2_m2m_ioctl_streamoff, >> +}; >> + >> +static void aml_vdec_release_instance(struct aml_vdec_ctx *ctx) >> +{ >> + if (ctx->codec_ops && ctx->codec_ops->exit) >> + ctx->codec_ops->exit(ctx); >> +} >> + >> +static int vb2ops_vdec_queue_setup(struct vb2_queue *vq, >> +    unsigned int *nbuffers, >> +    unsigned int *nplanes, >> +    unsigned int sizes[], >> +    struct device *alloc_devs[]) >> +{ >> + struct aml_vdec_ctx *ctx = vb2_get_drv_priv(vq); >> + struct aml_q_data *q_data; >> + unsigned int i; >> + >> + q_data = aml_vdec_get_qdata_by_type(ctx, vq->type); >> + if (!q_data) { >> + dev_err(&ctx->dev->plat_dev->dev, "not supported vq type\n"); >> + return -EINVAL; >> + } >> + >> + if (*nplanes) { >> + if (*nplanes != q_data->fmt->num_planes) >> + return -EINVAL; >> + >> + for (i = 0; i < *nplanes; i++) { >> + if (sizes[i] < q_data->sizeimage[i]) { >> + dev_err(&ctx->dev->plat_dev->dev, "not supported sizeimage\n"); >> + return -EINVAL; >> + } >> + alloc_devs[i] = &ctx->dev->plat_dev->dev; >> + } >> + } else { >> + if (vq->type == V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE) >> + *nplanes = q_data->fmt->num_planes; >> + else if (vq->type == V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE) >> + *nplanes = 1; >> + >> + for (i = 0; i < *nplanes; i++) { >> + alloc_devs[i] = &ctx->dev->plat_dev->dev; >> + sizes[i] = q_data->sizeimage[i]; >> + } >> + } >> + >> + if (*nplanes) { >> + dev_dbg(&ctx->dev->plat_dev->dev, "type: %d, plane: %d, buf cnt: %d, size: [Y: %u, C: %u]\n", >> + vq->type, *nplanes, *nbuffers, sizes[0], sizes[1]); >> + return 0; >> + } >> + >> + return -EINVAL; >> +} >> + >> +static int vb2ops_vdec_buf_prepare(struct vb2_buffer *vb) >> +{ >> + struct aml_vdec_ctx *ctx = vb2_get_drv_priv(vb->vb2_queue); >> + struct aml_q_data *q_data; >> + unsigned int sizeimage = 0; >> + int i; >> + >> + q_data = aml_vdec_get_qdata_by_type(ctx, vb->type); >> + if (!q_data) >> + return -EINVAL; >> + >> + for (i = 0; i < q_data->fmt->num_planes; i++) { >> + sizeimage = q_data->sizeimage[i]; >> + if (vb2_plane_size(vb, i) < sizeimage) >> + return -EINVAL; >> + >> + if (V4L2_TYPE_IS_CAPTURE(vb->type)) >> + vb2_set_plane_payload(vb, i, q_data->sizeimage[i]); >> + } >> + >> + return 0; >> +} >> + >> +static int vb2_ops_vdec_buf_init(struct vb2_buffer *vb) >> +{ >> + return 0; >> +} >> + >> +static void vb2_ops_vdec_buf_queue(struct vb2_buffer *vb) >> +{ >> + struct aml_vdec_ctx *ctx = vb2_get_drv_priv(vb->vb2_queue); >> + struct vb2_v4l2_buffer *vb2_v4l2 = to_vb2_v4l2_buffer(vb); >> + >> + v4l2_m2m_buf_queue(ctx->fh.m2m_ctx, vb2_v4l2); >> +} >> + >> +static void vb2_ops_vdec_buf_finish(struct vb2_buffer *vb) >> +{ >> +} >> + >> +static int vb2ops_vdec_start_streaming(struct vb2_queue *q, unsigned int count) >> +{ >> + struct aml_vdec_ctx *ctx = vb2_get_drv_priv(q); >> + struct aml_q_data *q_data; >> + >> + if (V4L2_TYPE_IS_OUTPUT(q->type)) { >> + ctx->is_output_streamon = 1; >> + q_data = aml_vdec_get_qdata_by_type(ctx, q->type); >> + if (aml_vdec_init_dec_inst(ctx, q_data->fmt) < 0) >> + return -EINVAL; >> + } else { >> + ctx->is_cap_streamon = 1; >> + } >> + >> + return 0; >> +} >> + >> +static void vb2ops_vdec_stop_streaming(struct vb2_queue *q) >> +{ >> + struct aml_vdec_ctx *ctx = vb2_get_drv_priv(q); >> + struct vb2_v4l2_buffer *src_buf = NULL, *dst_buf = NULL; >> + >> + aml_vdec_release_instance(ctx); >> + >> + if (V4L2_TYPE_IS_OUTPUT(q->type)) { >> + while ((src_buf = v4l2_m2m_src_buf_remove(ctx->m2m_ctx))) >> + v4l2_m2m_buf_done(src_buf, VB2_BUF_STATE_ERROR); >> + ctx->is_output_streamon = 0; >> + } else { >> + while ((dst_buf = v4l2_m2m_dst_buf_remove(ctx->m2m_ctx))) >> + v4l2_m2m_buf_done(dst_buf, VB2_BUF_STATE_ERROR); >> + ctx->is_cap_streamon = 0; >> + } >> +} >> + >> +static int vb2ops_vdec_out_buf_validate(struct vb2_buffer *vb) >> +{ >> + struct vb2_v4l2_buffer *vbuf = to_vb2_v4l2_buffer(vb); >> + >> + vbuf->field = V4L2_FIELD_NONE; >> + return 0; >> +} >> + >> +static void vb2ops_vdec_buf_request_complete(struct vb2_buffer *vb) >> +{ >> + struct aml_vdec_ctx *ctx = vb2_get_drv_priv(vb->vb2_queue); >> + >> + v4l2_ctrl_request_complete(vb->req_obj.req, &ctx->ctrl_handler); >> +} >> + >> +static const struct vb2_ops aml_vdec_vb2_ops = { >> + .queue_setup = vb2ops_vdec_queue_setup, >> + .wait_prepare = vb2_ops_wait_prepare, >> + .wait_finish = vb2_ops_wait_finish, >> + .start_streaming = vb2ops_vdec_start_streaming, >> + .stop_streaming = vb2ops_vdec_stop_streaming, >> + >> + .buf_init = vb2_ops_vdec_buf_init, >> + .buf_prepare = vb2ops_vdec_buf_prepare, >> + .buf_out_validate = vb2ops_vdec_out_buf_validate, >> + .buf_queue = vb2_ops_vdec_buf_queue, >> + .buf_finish = vb2_ops_vdec_buf_finish, >> + .buf_request_complete = vb2ops_vdec_buf_request_complete, >> +}; >> + >> +int aml_vdec_queue_init(void *priv, struct vb2_queue *src_vq, >> + struct vb2_queue *dst_vq) >> +{ >> + struct aml_vdec_ctx *ctx = (struct aml_vdec_ctx *)priv; >> + struct aml_vdec_dev *dev = ctx->dev; >> + int ret = 0; >> + >> + src_vq->type = V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE; >> + src_vq->io_modes = VB2_MMAP | VB2_DMABUF; >> + src_vq->mem_ops = &vb2_dma_contig_memops; >> + src_vq->drv_priv = ctx; >> + src_vq->ops = &aml_vdec_vb2_ops; >> + src_vq->lock = &ctx->v4l2_intf_lock; >> + src_vq->buf_struct_size = sizeof(struct v4l2_m2m_buffer); >> + src_vq->supports_requests = true; >> + src_vq->timestamp_flags = V4L2_BUF_FLAG_TIMESTAMP_COPY; >> + ret = vb2_queue_init(src_vq); >> + if (ret) { >> + v4l2_info(&dev->v4l2_dev, >> +   "Failed to initialize videobuf2 queue(output)"); >> + return ret; >> + } >> + >> + dst_vq->type = V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE; >> + dst_vq->io_modes = VB2_MMAP | VB2_DMABUF; >> + dst_vq->drv_priv = ctx; >> + dst_vq->mem_ops = &vb2_dma_contig_memops; >> + dst_vq->ops = &aml_vdec_vb2_ops; >> + dst_vq->lock = &ctx->v4l2_intf_lock; >> + dst_vq->buf_struct_size = sizeof(struct v4l2_m2m_buffer); >> + dst_vq->timestamp_flags = V4L2_BUF_FLAG_TIMESTAMP_COPY; >> + ret = vb2_queue_init(dst_vq); >> + if (ret) { >> + v4l2_info(&dev->v4l2_dev, >> +   "Failed to initialize videobuf2 queue(capture)"); >> + vb2_queue_release(src_vq); >> + } >> + >> + return ret; >> +} >> diff --git a/drivers/media/platform/amlogic/vdec/aml_vdec.h b/drivers/media/platform/amlogic/vdec/aml_vdec.h >> new file mode 100644 >> index 000000000000..a9ff93f25043 >> --- /dev/null >> +++ b/drivers/media/platform/amlogic/vdec/aml_vdec.h >> @@ -0,0 +1,31 @@ >> +/* SPDX-License-Identifier: (GPL-2.0-only OR MIT) */ >> +/* >> + * Copyright (C) 2025 Amlogic, Inc. All rights reserved >> + */ >> + >> +#ifndef _AML_VDEC_H_ >> +#define _AML_VDEC_H_ >> + >> +#include "aml_vdec_drv.h" >> + >> +#define DEFAULT_OUT_IDX  0 /* set default output format to h264 type */ >> +#define DEFAULT_CAP_IDX  2 /* set default capture format to NV21 */ >> + >> +/** >> + * struct aml_vdec_v4l2_ctrl - helper type to declare supported ctrls >> + * @codec_type: codec id this control belong to (CODEC_TYPE_H264, etc.) >> + * @cfg: control configuration >> + */ >> +struct aml_vdec_v4l2_ctrl { >> + unsigned int codec_type; >> + struct v4l2_ctrl_config cfg; >> +}; >> + >> +extern const struct v4l2_m2m_ops aml_vdec_m2m_ops; >> +extern const struct v4l2_ioctl_ops aml_vdec_ioctl_ops; >> + >> +int aml_vdec_ctrls_setup(struct aml_vdec_ctx *ctx); >> +int aml_vdec_queue_init(void *priv, struct vb2_queue *src_vq, >> + struct vb2_queue *dst_vq); >> +void aml_vdec_set_default_params(struct aml_vdec_ctx *ctx); >> +#endif >> diff --git a/drivers/media/platform/amlogic/vdec/aml_vdec_drv.c b/drivers/media/platform/amlogic/vdec/aml_vdec_drv.c >> new file mode 100644 >> index 000000000000..7591e2958f42 >> --- /dev/null >> +++ b/drivers/media/platform/amlogic/vdec/aml_vdec_drv.c >> @@ -0,0 +1,239 @@ >> +// SPDX-License-Identifier: (GPL-2.0-only OR MIT) >> +/* >> + * Copyright (C) 2025 Amlogic, Inc. All rights reserved >> + */ >> + >> +#include >> +#include >> +#include >> +#include >> + >> +#include "aml_vdec.h" >> +#include "aml_vdec_hw.h" >> +#include "aml_vdec_platform.h" >> + >> +#define AML_VDEC_DRV_NAME "aml-vdec-drv" >> + >> +static int fops_vcodec_open(struct file *file) >> +{ >> + struct aml_vdec_dev *dec_dev = video_drvdata(file); >> + struct aml_vdec_ctx *ctx = NULL; >> + int ret = 0; >> + >> + ctx = kzalloc(sizeof(*ctx), GFP_KERNEL); >> + if (!ctx) >> + return -ENOMEM; >> + >> + mutex_lock(&dec_dev->dev_mutex); >> + dec_dev->dec_ctx = ctx; >> + ctx->dev = dec_dev; >> + v4l2_fh_init(&ctx->fh, video_devdata(file)); >> + file->private_data = &ctx->fh; >> + v4l2_fh_add(&ctx->fh, file); >> + dec_dev->filp = file; >> + mutex_init(&ctx->v4l2_intf_lock); >> + init_waitqueue_head(&ctx->queue); >> + ctx->int_cond = 0; >> + >> + ctx->m2m_ctx = v4l2_m2m_ctx_init(dec_dev->m2m_dev_dec, ctx, >> + &aml_vdec_queue_init); >> + if (IS_ERR(ctx->m2m_ctx)) { >> + ret = PTR_ERR((__force void *)ctx->m2m_ctx); >> + v4l2_err(&dec_dev->v4l2_dev, "Failed to v4l2_m2m_ctx_init() (%d)", ret); >> + goto err_m2m_ctx_init; >> + } >> + >> + ctx->fh.m2m_ctx = ctx->m2m_ctx; >> + ret = aml_vdec_ctrls_setup(ctx); >> + if (ret) { >> + v4l2_err(&dec_dev->v4l2_dev, "Failed to init all ctrls (%d)", ret); >> + goto err_ctrls_setup; >> + } >> + >> + aml_vdec_set_default_params(ctx); >> + mutex_unlock(&dec_dev->dev_mutex); >> + >> + return ret; >> + >> +err_ctrls_setup: >> + v4l2_m2m_ctx_release(ctx->m2m_ctx); >> +err_m2m_ctx_init: >> + v4l2_fh_del(&ctx->fh, file); >> + v4l2_fh_exit(&ctx->fh); >> + kfree(ctx); >> + mutex_unlock(&dec_dev->dev_mutex); >> + >> + return ret; >> +} >> + >> +static int fops_vcodec_release(struct file *file) >> +{ >> + struct aml_vdec_dev *dec_dev = video_drvdata(file); >> + struct aml_vdec_ctx *ctx = fh_to_dec_ctx(file); >> + >> + mutex_lock(&dec_dev->dev_mutex); >> + v4l2_ctrl_handler_free(&ctx->ctrl_handler); >> + v4l2_m2m_ctx_release(ctx->m2m_ctx); >> + v4l2_fh_del(&ctx->fh, file); >> + v4l2_fh_exit(&ctx->fh); >> + kfree(ctx); >> + mutex_unlock(&dec_dev->dev_mutex); >> + >> + return 0; >> +} >> + >> +static const struct v4l2_file_operations aml_vdec_fops = { >> + .owner        = THIS_MODULE, >> + .open        = fops_vcodec_open, >> + .release    = fops_vcodec_release, >> + .poll        = v4l2_m2m_fop_poll, >> + .unlocked_ioctl    = video_ioctl2, >> + .mmap        = v4l2_m2m_fop_mmap, >> +}; >> + >> +static const struct video_device dec_dev = { >> + .name = "aml_dev_drv", >> + .fops = &aml_vdec_fops, >> + .ioctl_ops = &aml_vdec_ioctl_ops, >> + .release = video_device_release, >> + .vfl_dir = VFL_DIR_M2M, >> + .device_caps = V4L2_CAP_VIDEO_M2M_MPLANE | V4L2_CAP_STREAMING, >> +}; >> + >> +static const struct media_device_ops aml_m2m_media_ops = { >> + .req_validate = vb2_request_validate, >> + .req_queue = v4l2_m2m_request_queue, >> +}; >> + >> +static int aml_vdec_drv_probe(struct platform_device *pdev) >> +{ >> + struct aml_vdec_dev *dev; >> + struct video_device *vfd_dec; >> + struct aml_vdec_hw *hw; >> + int ret = 0; >> + >> + dev = devm_kzalloc(&pdev->dev, sizeof(*dev), GFP_KERNEL); >> + if (!dev) >> + return -ENOMEM; >> + >> + dev->plat_dev = pdev; >> + mutex_init(&dev->dev_mutex); >> + >> + ret = v4l2_device_register(&pdev->dev, &dev->v4l2_dev); >> + if (ret) >> + return dev_err_probe(&pdev->dev, ret, "v4l2_device_register err\n"); >> + >> + vfd_dec = video_device_alloc(); >> + if (!vfd_dec) { >> + v4l2_err(&dev->v4l2_dev, "Failed to allocate video device\n"); >> + ret = -ENOMEM; >> + goto err_device_alloc; >> + } >> + *vfd_dec = dec_dev; >> + vfd_dec->v4l2_dev = &dev->v4l2_dev; >> + vfd_dec->lock = &dev->dev_mutex; >> + video_set_drvdata(vfd_dec, dev); >> + dev->vfd = vfd_dec; >> + platform_set_drvdata(pdev, dev); >> + >> + hw = devm_kzalloc(&pdev->dev, sizeof(*hw), GFP_KERNEL); >> + if (!hw) { >> + ret = -ENOMEM; >> + goto err_dec_mem_init; >> + } >> + dev->dec_hw = hw; >> + >> + dev->pvdec_data = of_device_get_match_data(&pdev->dev); >> + ret = dev->pvdec_data->req_hw_resource(dev); >> + if (ret < 0) >> + goto err_hw_init; >> + >> + dev->m2m_dev_dec = v4l2_m2m_init(&aml_vdec_m2m_ops); >> + if (IS_ERR(dev->m2m_dev_dec)) { >> + v4l2_err(&dev->v4l2_dev, "Failed to init mem2mem dec device\n"); >> + ret = PTR_ERR((__force void *)dev->m2m_dev_dec); >> + goto err_hw_init; >> + } >> + >> + ret = video_register_device(vfd_dec, VFL_TYPE_VIDEO, -1); >> + if (ret) { >> + v4l2_err(&dev->v4l2_dev, "Failed to register video device"); >> + goto err_vid_dev_register; >> + } >> + >> + dev->mdev.dev = &pdev->dev; >> + strscpy(dev->mdev.model, AML_VDEC_DRV_NAME, sizeof(dev->mdev.model)); >> + media_device_init(&dev->mdev); >> + dev->mdev.ops = &aml_m2m_media_ops; >> + dev->v4l2_dev.mdev = &dev->mdev; >> + >> + ret = v4l2_m2m_register_media_controller(dev->m2m_dev_dec, vfd_dec, >> + MEDIA_ENT_F_PROC_VIDEO_DECODER); >> + if (ret) { >> + v4l2_err(&dev->v4l2_dev, "Failed to init mem2mem media controller\n"); >> + goto error_m2m_mc_register; >> + } >> + >> + ret = media_device_register(&dev->mdev); >> + if (ret) { >> + v4l2_err(&dev->v4l2_dev, "Failed to register media device"); >> + goto err_media_dev_register; >> + } >> + vdec_enable(dev->dec_hw); >> + return 0; >> + >> +err_media_dev_register: >> + v4l2_m2m_unregister_media_controller(dev->m2m_dev_dec); >> +error_m2m_mc_register: >> + media_device_cleanup(&dev->mdev); >> +err_vid_dev_register: >> + v4l2_m2m_release(dev->m2m_dev_dec); >> +err_hw_init: >> + dev->dec_hw = NULL; >> +err_dec_mem_init: >> + video_device_release(vfd_dec); >> +err_device_alloc: >> + v4l2_device_unregister(&dev->v4l2_dev); >> + return ret; >> +} >> + >> +static void aml_vdec_drv_remove(struct platform_device *pdev) >> +{ >> + struct aml_vdec_dev *dev = platform_get_drvdata(pdev); >> + >> + vdec_disable(dev->dec_hw); >> + >> + if (media_devnode_is_registered(dev->mdev.devnode)) { >> + media_device_unregister(&dev->mdev); >> + media_device_cleanup(&dev->mdev); >> + } >> + >> + if (dev->m2m_dev_dec) >> + v4l2_m2m_release(dev->m2m_dev_dec); >> + if (dev->vfd) >> + video_unregister_device(dev->vfd); >> + if (dev->dec_hw) { >> + dev->pvdec_data->destroy_hw_resource(dev); >> + dev->dec_hw = NULL; >> + } >> + v4l2_device_unregister(&dev->v4l2_dev); >> +} >> + >> +static const struct of_device_id aml_vdec_match[] = { >> + {.compatible = "amlogic,s4-vcodec-dec", .data = &aml_vdec_s4_pdata}, >> + {}, >> +}; >> + >> +static struct platform_driver aml_vcodec_dec_driver = { >> + .probe    = aml_vdec_drv_probe, >> + .remove    = aml_vdec_drv_remove, >> + .driver    = { >> + .name    = AML_VDEC_DRV_NAME, >> + .of_match_table = aml_vdec_match, >> + }, >> +}; >> + >> +module_platform_driver(aml_vcodec_dec_driver); >> + >> +MODULE_DESCRIPTION("Amlogic V4L2 decoder driver"); >> +MODULE_LICENSE("GPL"); >> diff --git a/drivers/media/platform/amlogic/vdec/aml_vdec_drv.h b/drivers/media/platform/amlogic/vdec/aml_vdec_drv.h >> new file mode 100644 >> index 000000000000..18659eef87eb >> --- /dev/null >> +++ b/drivers/media/platform/amlogic/vdec/aml_vdec_drv.h >> @@ -0,0 +1,196 @@ >> +/* SPDX-License-Identifier: (GPL-2.0-only OR MIT) */ >> +/* >> + * Copyright (C) 2025 Amlogic, Inc. All rights reserved >> + */ >> + >> +#ifndef _AML_VDEC_DRV_H_ >> +#define _AML_VDEC_DRV_H_ >> + >> +#include >> +#include >> +#include >> + >> +#include >> +#include >> +#include >> +#include >> +#include >> +#include >> + >> +#define AML_VCODEC_MAX_PLANES 3 >> +#define AML_VDEC_MIN_W    64U >> +#define AML_VDEC_MIN_H    64U >> +#define AML_VDEC_1080P_MAX_H  1088U >> +#define AML_VDEC_1080P_MAX_W  1920U >> + >> +struct aml_vdec_ctx; >> +/** >> + * enum aml_fmt_type - Type of format type >> + */ >> +enum aml_fmt_type { >> + AML_FMT_DEC = 0, >> + AML_FMT_FRAME = 1, >> +}; >> + >> +/** >> + * enum aml_codec_type - Type of codec format >> + */ >> +enum aml_codec_type { >> + CODEC_TYPE_H264 = 0, >> + CODEC_TYPE_FRAME, >> +}; >> + >> +/** >> + * enum aml_q_type - Type of queue : cap or output >> + */ >> +enum aml_q_type { >> + AML_Q_DATA_SRC = 0, >> + AML_Q_DATA_DST = 1, >> +}; >> + >> +/** >> + * struct aml_video_fmt - aml video decoder fmt information >> + * @fourcc: FourCC code of the format. See V4L2_PIX_FMT_*. >> + * @type: Curr queue type: capture or output. >> + * @codec_type: Codec mode related. See aml_codec_type. >> + * @num_planes: Num planes of the format. >> + * @name: Name of the format. >> + * @stepwise: Supported range of frame sizes (only for bitstream formats). >> + */ >> +struct aml_video_fmt { >> + u32 fourcc; >> + enum aml_fmt_type type; >> + enum aml_codec_type codec_type; >> + u32 num_planes; >> + const u8 *name; >> + struct v4l2_frmsize_stepwise stepwise; >> +}; >> + >> +/** >> + * struct aml_q_data - aml video queue information >> + * @visible_width: Width for display. >> + * @visible_height: Height for display. >> + * @coded_width: Width for decode, which is 64/32 aligned. >> + * @coded_height: Height for decode, which is 64/32 aligned. >> + * @filed_flag: Field pic flag. >> + * @bytesperline: Byte num of each pixel line. >> + * @sizeimage: Size of frame in bytes. >> + * @fmt: Format for curr queue. See struct aml_video_fmt. >> + */ >> +struct aml_q_data { >> + u32 visible_width; >> + u32 visible_height; >> + u32 coded_width; >> + u32 coded_height; >> + u32 filed_flag; >> + u32 bytesperline[AML_VCODEC_MAX_PLANES]; >> + u32 sizeimage[AML_VCODEC_MAX_PLANES]; >> + struct aml_video_fmt *fmt; >> +}; >> + >> +/** >> + * struct aml_vdec_dev - driver data >> + * @plat_dev: Platform device for the current driver. >> + * @v4l2_dev: V4L2 device to register video devices for. >> + * @m2m_dev_dec: Mem2mem device associated to this device. >> + * @vfd: Video_device associated to this device. >> + * @mdev: Media_device associated to this device. >> + * @dec_ctx: Decoder context. See struct aml_vdec_ctx. >> + * @dec_hw: Decoder hardware resources. See struct aml_vdec_hw. >> + * @pvdec_data: Decoder platform data. See struct aml_dev_platform_data. >> + * @dev_mutex: video_device lock. >> + * @filp: v4l2 file handle pointer. >> + */ >> +struct aml_vdec_dev { >> + struct platform_device *plat_dev; >> + struct v4l2_device v4l2_dev; >> + struct v4l2_m2m_dev *m2m_dev_dec; >> + struct video_device *vfd; >> + struct media_device mdev; >> + >> + struct aml_vdec_ctx *dec_ctx; >> + struct aml_vdec_hw *dec_hw; >> + const struct aml_dev_platform_data *pvdec_data; >> + >> + struct mutex dev_mutex; >> + struct file *filp; >> +}; >> + >> +/** >> + * struct dec_pic_info - pic information description >> + * @colorspace: enum v4l2_colorspace; supplemental to pixelformat >> + * @ycbcr_enc: enum v4l2_ycbcr_encoding, Y'CbCr encoding >> + * @xfer_func: enum v4l2_xfer_func, colorspace transfer function >> + * @quantization: enum v4l2_quantization, colorspace quantization >> + * @cap_pix_fmt: Pixel format for capture queue. >> + * @output_pix_fmt: Pixel format for output queue. >> + * @coded_width: Width for decode. >> + * @coded_height: Height for decode. >> + * @fb_size: Frame buffer size for Y or UV. >> + * @plane_num: Num for planes for curr format. >> + */ >> +struct dec_pic_info { >> + enum v4l2_colorspace colorspace; >> + enum v4l2_ycbcr_encoding ycbcr_enc; >> + enum v4l2_xfer_func xfer_func; >> + enum v4l2_quantization quantization; >> + u32 cap_pix_fmt; >> + u32 output_pix_fmt; >> + u32 coded_width; >> + u32 coded_height; >> + u32 fb_size[2]; >> + u32 plane_num; >> +}; >> + >> +/** >> + * struct aml_vdec_ctx - driver instance context >> + * @dev: pointer to the aml_vdec_dev of the device. >> + * @fh: struct v4l2 fh. >> + * @m2m_ctx: pointer to v4l2_m2m_ctx context. >> + * @ctrl_handler: V4L2 ctrl handler. >> + * @v4l2_intf_lock: Mutex lock for v4l2 interface. >> + * @codec_ops: Codec operation functions. See struct aml_codec_ops. >> + * @int_cond: Variable used by the waitqueue. >> + * @queue: Waitqueue to wait for the current decode context finish. >> + * @q_data: feature supported by the current decoder instance. >> + * @is_cap_streamon: indicates if the current capture stream is on. >> + * @is_output_streamon: indicates if the current output stream is on. >> + * @dos_clk_en: indicates if dos clk is enabled. >> + * @pic_info: Pic information for curr decoder context. See struct dec_pic_info. >> + * @curr_dec_type: Current decoder type. (CODEC_TYPE_H264, etc.) >> + * @codec_priv: Pointer to current decoder instance. >> + */ >> +struct aml_vdec_ctx { >> + struct aml_vdec_dev *dev; >> + struct v4l2_fh fh; >> + struct v4l2_m2m_ctx *m2m_ctx; >> + struct v4l2_ctrl_handler ctrl_handler; >> + struct mutex v4l2_intf_lock; >> + >> + const struct aml_codec_ops *codec_ops; >> + int int_cond; >> + wait_queue_head_t queue; >> + struct aml_q_data q_data[2]; >> + >> + bool is_cap_streamon; >> + bool is_output_streamon; >> + bool dos_clk_en; >> + >> + struct dec_pic_info pic_info; >> + u32 curr_dec_type; >> + void *codec_priv; >> +}; >> + >> +static inline struct aml_vdec_ctx *fh_to_dec_ctx(struct file *file) >> +{ >> + struct v4l2_fh *file_fh = file_to_v4l2_fh(file); >> + >> + return container_of(file_fh, struct aml_vdec_ctx, fh); >> +} >> + >> +static inline struct aml_vdec_ctx *ctrl_to_dec_ctx(struct v4l2_ctrl_handler *ctrl) >> +{ >> + return container_of(ctrl, struct aml_vdec_ctx, ctrl_handler); >> +} >> + >> +#endif >> diff --git a/drivers/media/platform/amlogic/vdec/aml_vdec_hw.c b/drivers/media/platform/amlogic/vdec/aml_vdec_hw.c >> new file mode 100644 >> index 000000000000..1729076de76c >> --- /dev/null >> +++ b/drivers/media/platform/amlogic/vdec/aml_vdec_hw.c >> @@ -0,0 +1,596 @@ >> +// SPDX-License-Identifier: (GPL-2.0-only OR MIT) >> +/* >> + * Copyright (C) 2025 Amlogic, Inc. All rights reserved >> + */ >> + >> +#include >> +#include >> +#include >> +#include >> +#include >> +#include >> +#include >> +#include >> +#include >> + >> +#include "aml_vdec_drv.h" >> +#include "aml_vdec_hw.h" >> +#include "aml_vdec_platform.h" >> + >> +#define MHz     (1000000) >> +#define MC_SIZE (4096 * 16) >> + >> +static struct pm_pd_s vdec_domain_data[] = { >> + [VDEC_1] = {.name = "vdec", }, >> + [VDEC_HEVC] = {.name = "hevc", }, >> +}; >> + >> +u32 read_dos_reg(struct aml_vdec_hw *hw, u32 addr) >> +{ >> + u32 ret_val; >> + >> + regmap_read(hw->map[DOS_BUS], addr, &ret_val); >> + >> + return ret_val; >> +} >> + >> +static void dos_reg_write_bits(struct aml_vdec_hw *hw, u32 reg, u32 val, int start, int len) >> +{ >> + u32 mask = (((1L << (len)) - 1) << (start)); >> + >> + regmap_update_bits(hw->map[DOS_BUS], reg, mask, val); >> +} >> + >> +void dos_enable(struct aml_vdec_hw *hw) >> +{ >> + dos_reg_write_bits(hw, DOS_GCLK_EN0, 0x3ff, 0, 10); >> + >> + regmap_write(hw->map[DOS_BUS], GCLK_EN, 0x3ff); >> + >> + regmap_update_bits(hw->map[DOS_BUS], MDEC_PIC_DC_CTRL, (1 << 31), 0); >> +} >> + >> +void aml_vdec_reset_core(struct aml_vdec_hw *hw) >> +{ >> + unsigned int mask = 0; >> + >> + mask = (1 << 21); >> + >> + regmap_update_bits(hw->map[DMC_BUS], 0x0, mask, 0); >> + usleep_range(60, 70); >> + regmap_write(hw->map[DOS_BUS], DOS_SW_RESET0, >> +      (1 << 3) | (1 << 4) | (1 << 5) | (1 << 7) | >> +      (1 << 8) | (1 << 9)); >> + regmap_write(hw->map[DOS_BUS], DOS_SW_RESET0, 0); >> + regmap_update_bits(hw->map[DOS_BUS], VDEC_ASSIST_MMC_CTRL1, 1 << 3, 0); >> + regmap_update_bits(hw->map[DOS_BUS], MDEC_PIC_DC_MUX_CTRL, 1 << 31, 0); >> + regmap_write(hw->map[DOS_BUS], MDEC_EXTIF_CFG1, 0); >> + >> + regmap_update_bits(hw->map[DMC_BUS], 0x0, mask, mask); >> +} >> + >> +void aml_start_vdec_hw(struct aml_vdec_hw *hw) >> +{ >> + u32 reg_read_val; >> + >> + regmap_read(hw->map[DOS_BUS], DOS_SW_RESET0, ®_read_val); >> + regmap_read(hw->map[DOS_BUS], DOS_SW_RESET0, ®_read_val); >> + regmap_read(hw->map[DOS_BUS], DOS_SW_RESET0, ®_read_val); >> + >> + regmap_write(hw->map[DOS_BUS], DOS_SW_RESET0, (1 << 12) | (1 << 11)); >> + regmap_write(hw->map[DOS_BUS], DOS_SW_RESET0, 0); >> + >> + regmap_read(hw->map[DOS_BUS], DOS_SW_RESET0, ®_read_val); >> + regmap_read(hw->map[DOS_BUS], DOS_SW_RESET0, ®_read_val); >> + regmap_read(hw->map[DOS_BUS], DOS_SW_RESET0, ®_read_val); >> + >> + regmap_write(hw->map[DOS_BUS], MPSR, 0x0001); >> +} >> + >> +void aml_stop_vdec_hw(struct aml_vdec_hw *hw) >> +{ >> + u32 reg_val = 0; >> + int ret; >> + >> + regmap_write(hw->map[DOS_BUS], MPSR, 0); >> + regmap_write(hw->map[DOS_BUS], CPSR, 0); >> + >> + ret = read_poll_timeout_atomic(read_dos_reg, reg_val, >> +        !(reg_val & 0x8000), >> +        10, 100000, true, >> +        hw, IMEM_DMA_CTRL); >> + >> + ret = read_poll_timeout_atomic(read_dos_reg, reg_val, >> +        !(reg_val & 0x8000), >> +        10, 100000, true, >> +        hw, LMEM_DMA_CTRL); >> + >> + ret = read_poll_timeout_atomic(read_dos_reg, reg_val, >> +        !(reg_val & 0xfff), >> +        10, 800000, true, >> +        hw, WRRSP_LMEM); >> + if (ret) >> + dev_err(hw->dev, "%s, ctrl %x, rsp %x, pc %x status %x,%x\n", >> + __func__, read_dos_reg(hw, LMEM_DMA_CTRL), >> + read_dos_reg(hw, WRRSP_LMEM), read_dos_reg(hw, MPC_E), >> + read_dos_reg(hw, AV_SCRATCH_J), read_dos_reg(hw, AV_SCRATCH_9)); >> + >> + regmap_read(hw->map[DOS_BUS], DOS_SW_RESET0, ®_val); >> + regmap_read(hw->map[DOS_BUS], DOS_SW_RESET0, ®_val); >> + regmap_read(hw->map[DOS_BUS], DOS_SW_RESET0, ®_val); >> + >> + regmap_write(hw->map[DOS_BUS], DOS_SW_RESET0, (1 << 12) | (1 << 11)); >> + regmap_write(hw->map[DOS_BUS], DOS_SW_RESET0, 0); >> + >> + regmap_read(hw->map[DOS_BUS], DOS_SW_RESET0, ®_val); >> + regmap_read(hw->map[DOS_BUS], DOS_SW_RESET0, ®_val); >> + regmap_read(hw->map[DOS_BUS], DOS_SW_RESET0, ®_val); >> +} >> + >> +int load_firmware(struct aml_vdec_hw *hw, const char *path) >> +{ >> + const struct firmware *fw; >> + struct device *dev = hw->dev; >> + static u8 *mc_addr; >> + static dma_addr_t mc_addr_map; >> + int fw_head_len; >> + ulong timeout; >> + int ret; >> + >> + ret = request_firmware(&fw, path, dev); >> + if (ret < 0) { >> + dev_info(dev, "request_firmware %s failed ret %d\n", path, ret); >> + return -EINVAL; >> + } >> + >> + if (fw->size > MC_SIZE) { >> + dev_info(dev, "fw %s oversize\n", path); >> + ret = -EINVAL; >> + goto release_firmware; >> + } >> + >> + fw_head_len = 512; >> + mc_addr = dma_alloc_coherent(dev, MC_SIZE, &mc_addr_map, GFP_KERNEL); >> + if (!mc_addr) { >> + dev_info(dev, "no mem for fw %s\n", path); >> + ret = -ENOMEM; >> + goto release_firmware; >> + } >> + memset(mc_addr, 0, MC_SIZE); >> + memcpy(mc_addr, ((u8 *)fw->data + fw_head_len), >> +        (fw->size - fw_head_len)); >> + >> + regmap_write(hw->map[DOS_BUS], MPSR, 0); >> + regmap_write(hw->map[DOS_BUS], CPSR, 0); >> + >> + timeout = read_dos_reg(hw, MPSR); >> + timeout = read_dos_reg(hw, MPSR); >> + >> + timeout = jiffies + HZ; >> + >> + regmap_write(hw->map[DOS_BUS], IMEM_DMA_ADR, mc_addr_map); >> + regmap_write(hw->map[DOS_BUS], IMEM_DMA_COUNT, 0x1000); >> + regmap_write(hw->map[DOS_BUS], IMEM_DMA_CTRL, (0x8000 | (7 << 16))); >> + >> + while (read_dos_reg(hw, IMEM_DMA_CTRL) & 0x8000) { >> + if (time_before(jiffies, timeout)) { >> + schedule(); >> + } else { >> + dev_info(dev, "vdec load mc error\n"); >> + ret = -EBUSY; >> + break; >> + } >> + } >> + >> + /* Only h264 needs this step */ >> + if (hw->hw_ops.load_firmware_ex) { >> + ret = hw->hw_ops.load_firmware_ex(hw->curr_ctx, >> +   mc_addr, >> +   (fw->size - fw_head_len)); >> + if (ret < 0) { >> + ret = -EINVAL; >> + goto free_dma_mem; >> + } >> + } >> + >> +free_dma_mem: >> + dma_free_coherent(dev, MC_SIZE, mc_addr, mc_addr_map); >> +release_firmware: >> + release_firmware(fw); >> + return ret; >> +} >> + >> +static int vdec_clock_gate_init(struct aml_vdec_hw *hw) >> +{ >> + hw->gates[VDEC].id = "vdec"; >> + hw->gates[VDEC_MUX].id = "clk_vdec_mux"; >> + hw->gates[HEVCF_MUX].id = "clk_hevcf_mux"; >> + >> + return devm_clk_bulk_get(hw->dev, DOS_CLK_MAX, hw->gates); >> +} >> + >> +static struct clk_bulk_data *vdec_get_clk_by_name(struct aml_vdec_hw *hw, >> +   const char *name) >> +{ >> + int i; >> + >> + for (i = 0; i < DOS_CLK_MAX; i++) { >> + if (!strcmp(name, hw->gates[i].id)) { >> + if (hw->gates[i].clk) >> + return &hw->gates[i]; >> + } >> + } >> + return NULL; >> +} >> + >> +static int pm_vdec_power_domain_init(struct aml_vdec_hw *hw) >> +{ >> + int i, err; >> + const struct power_manager_s *pm = hw->pm; >> + struct pm_pd_s *pd = pm->pd_data; >> + >> + mutex_init(&hw->pm_mutex); >> + >> + for (i = 0; i < VDEC_MAX; i++) { >> + pd[i].dev = dev_pm_domain_attach_by_name(hw->dev, pd[i].name); >> + if (IS_ERR_OR_NULL(pd[i].dev)) { >> + err = PTR_ERR(pd[i].dev); >> + dev_dbg(hw->dev, "Get %s failed, pm-domain: %d\n", >> + pd[i].name, err); >> + continue; >> + } >> + >> + pd[i].link = device_link_add(hw->dev, pd[i].dev, >> +      DL_FLAG_PM_RUNTIME | >> +      DL_FLAG_STATELESS); >> + if (IS_ERR_OR_NULL(pd[i].link)) { >> + dev_err(hw->dev, "Adding %s device link failed!\n", pd[i].name); >> + return -ENODEV; >> + } >> + >> + dev_dbg(hw->dev, "power domain: name: %s, dev: %p, link: %p\n", >> + pd[i].name, pd[i].dev, pd[i].link); >> + } >> + >> + return 0; >> +} >> + >> +static void pm_vdec_power_domain_release(struct aml_vdec_hw *hw) >> +{ >> + int i; >> + const struct power_manager_s *pm = hw->pm; >> + struct pm_pd_s *pd = pm->pd_data; >> + >> + for (i = 0; i < VDEC_MAX; i++) { >> + if (!IS_ERR_OR_NULL(pd[i].link)) >> + device_link_del(pd[i].link); >> + >> + if (!IS_ERR_OR_NULL(pd[i].dev)) >> + dev_pm_domain_detach(pd[i].dev, true); >> + } >> +} >> + >> +static void dos_local_config(struct aml_vdec_hw *hw, bool is_on, int id) >> +{ >> + if (is_on) { >> + usleep_range(20, 100); >> + >> + switch (id) { >> + case VDEC_1: >> + regmap_write(hw->map[DOS_BUS], DOS_MEM_PD_VDEC, 0); >> + regmap_write(hw->map[DOS_BUS], DOS_SW_RESET0, 0xfffffffc); >> + usleep_range(20, 100); >> + regmap_write(hw->map[DOS_BUS], DOS_SW_RESET0, 0); >> + usleep_range(20, 100); >> + regmap_write(hw->map[DOS_BUS], DOS_MEM_PD_VDEC, 0); >> + break; >> + case VDEC_HEVC: >> + regmap_write(hw->map[DOS_BUS], DOS_MEM_PD_HEVC, 0); >> + regmap_write(hw->map[DOS_BUS], DOS_SW_RESET3, 0xffffffff); >> + usleep_range(20, 100); >> + regmap_write(hw->map[DOS_BUS], DOS_SW_RESET3, 0); >> + usleep_range(20, 100); >> + regmap_write(hw->map[DOS_BUS], DOS_MEM_PD_HEVC, 0); >> + break; >> + default: >> + dev_info(hw->dev, "%s on, not found id %d\n", __func__, id); >> + break; >> + } >> + } else { >> + switch (id) { >> + case VDEC_1: >> + regmap_write(hw->map[DOS_BUS], DOS_SW_RESET0, 0xfffffffc); >> + usleep_range(20, 100); >> + regmap_write(hw->map[DOS_BUS], DOS_SW_RESET0, 0); >> + usleep_range(20, 100); >> + regmap_write(hw->map[DOS_BUS], DOS_MEM_PD_VDEC, 0xffffffffUL); >> + break; >> + case VDEC_HEVC: >> + regmap_write(hw->map[DOS_BUS], DOS_SW_RESET3, 0xffffffff); >> + usleep_range(20, 100); >> + regmap_write(hw->map[DOS_BUS], DOS_SW_RESET3, 0); >> + usleep_range(20, 100); >> + regmap_write(hw->map[DOS_BUS], DOS_MEM_PD_HEVC, 0xffffffffUL); >> + break; >> + default: >> + dev_info(hw->dev, "%s off, not found id %d\n", __func__, id); >> + break; >> + } >> + } >> + >> + dev_dbg(hw->dev, "%s end, id %d, is_on %d\n", __func__, id, is_on); >> +} >> + >> +static void pm_vdec_power_domain_power_on(struct aml_vdec_hw *hw, int id) >> +{ >> + const struct power_manager_s *pm = hw->pm; >> + struct device *dev = pm->pd_data[id].dev; >> + struct clk_bulk_data *gate_node; >> + >> + if (id == VDEC_1) >> + gate_node = vdec_get_clk_by_name(hw, "clk_vdec_mux"); >> + else if (id == VDEC_HEVC) >> + gate_node = vdec_get_clk_by_name(hw, "clk_hevcf_mux"); >> + >> + if (gate_node) { >> + clk_prepare_enable(gate_node->clk); >> + if (id == VDEC_1) { >> + clk_set_rate(gate_node->clk, 499999992); >> + dev_dbg(hw->dev, "after set, vdec mux clock is %lu Hz\n", >> + clk_get_rate(gate_node->clk)); >> + } >> + dev_dbg(hw->dev, "the %-15s clock on\n", gate_node->id); >> + } else { >> + dev_info(hw->dev, "clk %d, unreachable\n", id); >> + } >> + >> + if (dev) { >> + pm_runtime_get_sync(dev); >> + dev_dbg(dev, "dev: %p link %p the %-15s power on\n", >> + dev, pm->pd_data[id].link, pm->pd_data[id].name); >> + } >> + >> + dos_local_config(hw, 1, id); >> +} >> + >> +static void pm_vdec_power_domain_power_off(struct aml_vdec_hw *hw, int id) >> +{ >> + const struct power_manager_s *pm = hw->pm; >> + struct device *dev = pm->pd_data[id].dev; >> + struct clk_bulk_data *gate_node; >> + >> + dos_local_config(hw, 0, id); >> + >> + if (dev) { >> + pm_runtime_put_sync(dev); >> + dev_dbg(dev, "dev: %p link %p the %-15s power off\n", >> + dev, pm->pd_data[id].link, pm->pd_data[id].name); >> + } >> + >> + if (id == VDEC_1) >> + gate_node = vdec_get_clk_by_name(hw, "clk_vdec_mux"); >> + else if (id == VDEC_HEVC) >> + gate_node = vdec_get_clk_by_name(hw, "clk_hevcf_mux"); >> + >> + if (gate_node) { >> + clk_disable_unprepare(gate_node->clk); >> + dev_dbg(hw->dev, "the %-15s clock off\n", gate_node->id); >> + } else { >> + dev_info(hw->dev, "clk %d, unreachable\n", id); >> + } >> +} >> + >> +static bool pm_vdec_power_domain_power_state(struct aml_vdec_hw *hw, int id) >> +{ >> + if (hw->pm->pd_data[id].dev) >> + return pm_runtime_active(hw->pm->pd_data[id].dev); >> + else >> + return false; >> +} >> + >> +static void vdec_poweron(struct aml_vdec_hw *hw, enum vdec_type_e core) >> +{ >> + if (core >= VDEC_MAX) >> + return; >> + >> + mutex_lock(&hw->pm_mutex); >> + if (!hw->pm->pd_data[core].dev) >> + goto out; >> + >> + hw->pm->pd_data[core].ref_count++; >> + if (hw->pm->pd_data[core].ref_count > 1) >> + goto out; >> + >> + if (hw->pm->power_state(hw, core)) >> + goto out; >> + >> + hw->pm->power_on(hw, core); >> + >> +out: >> + mutex_unlock(&hw->pm_mutex); >> +} >> + >> +static void vdec_poweroff(struct aml_vdec_hw *hw, enum vdec_type_e core) >> +{ >> + if (core >= VDEC_MAX) >> + return; >> + >> + mutex_lock(&hw->pm_mutex); >> + if (hw->pm->pd_data[core].ref_count == 0) >> + goto out; >> + >> + hw->pm->pd_data[core].ref_count--; >> + if (hw->pm->pd_data[core].ref_count > 0) >> + goto out; >> + >> + hw->pm->power_off(hw, core); >> + >> +out: >> + mutex_unlock(&hw->pm_mutex); >> +} >> + >> +int vdec_enable(struct aml_vdec_hw *hw) >> +{ >> + vdec_poweron(hw, VDEC_1); >> + >> + return 0; >> +} >> + >> +int vdec_disable(struct aml_vdec_hw *hw) >> +{ >> + vdec_poweroff(hw, VDEC_1); >> + >> + return 0; >> +} >> + >> +static const struct power_manager_s pm[] = { >> + [AML_PM_PD] = { >> + .pd_data    = vdec_domain_data, >> + .init        = pm_vdec_power_domain_init, >> + .release    = pm_vdec_power_domain_release, >> + .power_on    = pm_vdec_power_domain_power_on, >> + .power_off    = pm_vdec_power_domain_power_off, >> + .power_state = pm_vdec_power_domain_power_state, >> + }, >> +}; >> + >> +static irqreturn_t vdec_irq_handler(int irq, void *priv) >> +{ >> + struct aml_vdec_dev *dev = (struct aml_vdec_dev *)priv; >> + struct aml_vdec_hw *hw = dev->dec_hw; >> + irqreturn_t ret; >> + >> + if (hw->hw_ops.irq_handler) >> + ret = hw->hw_ops.irq_handler(irq, priv); >> + >> + return ret; >> +} >> + >> +static irqreturn_t vdec_threaded_isr_handler(int irq, void *priv) >> +{ >> + struct aml_vdec_dev *dev = (struct aml_vdec_dev *)priv; >> + struct aml_vdec_hw *hw = dev->dec_hw; >> + irqreturn_t ret = IRQ_HANDLED; >> + >> + if (hw->hw_ops.irq_threaded_func) >> + ret = hw->hw_ops.irq_threaded_func(irq, priv); >> + >> + return ret; >> +} >> + >> +struct aml_vdec_hw *vdec_get_hw(void *priv) >> +{ >> + struct aml_vdec_dev *dev = (struct aml_vdec_dev *)priv; >> + >> + return dev->dec_hw; >> +} >> + >> +static const struct regmap_config dos_regmap_conf = { >> + .reg_bits = 32, >> + .val_bits = 32, >> + .reg_stride = 4, >> + .max_register = 0x10000, >> +}; >> + >> +static const struct regmap_config dmc_regmap_conf = { >> + .reg_bits = 32, >> + .val_bits = 32, >> + .reg_stride = 4, >> + .max_register = 0x20, >> +}; >> + >> +int dev_request_hw_resources(void *priv) >> +{ >> + struct aml_vdec_dev *dev = (struct aml_vdec_dev *)priv; >> + struct aml_vdec_hw *hw; >> + struct platform_device *pdev; >> + void __iomem *reg_base[MAX_REG_BUS]; >> + struct resource res; >> + int i; >> + int ret = -1; >> + >> + if (!dev || !dev->dec_hw) >> + return -1; >> + >> + pdev = dev->plat_dev; >> + hw = dev->dec_hw; >> + hw->dev = &pdev->dev; >> + >> + hw->dec_irq = platform_get_irq(pdev, VDEC_IRQ_1); >> + if (hw->dec_irq < 0) { >> + dev_err(&pdev->dev, "get irq failed\n"); >> + return hw->dec_irq; >> + } >> + ret = devm_request_threaded_irq(&pdev->dev, hw->dec_irq, vdec_irq_handler, >> + vdec_threaded_isr_handler, IRQF_ONESHOT, >> + "vdec-1", dev); >> + if (ret) { >> + dev_err(&pdev->dev, "failed to install irq %d (%d)", >> + hw->dec_irq, ret); >> + return -1; >> + } >> + >> + for (i = 0; i < MAX_REG_BUS; i++) { >> + if (of_address_to_resource(pdev->dev.of_node, i, &res)) { >> + dev_err(&pdev->dev, "of_address_to_resource %d failed\n", i); >> + return -EINVAL; >> + } >> + reg_base[i] = devm_ioremap_resource(&pdev->dev, &res); >> + >> + if (IS_ERR(reg_base[i])) >> + return PTR_ERR(reg_base[i]); >> + >> + if (i == DOS_BUS) { >> + hw->map[i] = devm_regmap_init_mmio(&pdev->dev, reg_base[i], >> +    &dos_regmap_conf); >> + } else if (i == DMC_BUS) { >> + hw->map[i] = devm_regmap_init_mmio(&pdev->dev, reg_base[i], >> +    &dmc_regmap_conf); >> + } >> + >> + if (IS_ERR(hw->map[i])) >> + return PTR_ERR(hw->map[i]); >> + >> + dev_dbg(&pdev->dev, "%s, res start %llx, end %llx, iomap: %p\n", >> + __func__, (unsigned long long)res.start, >> + (unsigned long long)res.end, reg_base[i]); >> + } >> + hw->canvas = meson_canvas_get(&pdev->dev); >> + if (IS_ERR(&pdev->dev)) >> + return PTR_ERR(&pdev->dev); >> + >> + hw->pm = &pm[dev->pvdec_data->power_type]; >> + if (hw->pm->init) { >> + ret = hw->pm->init(hw); >> + if (ret < 0) { >> + dev_err(&pdev->dev, "power mgr init failed!\n"); >> + return ret; >> + } >> + } >> + >> + ret = vdec_clock_gate_init(hw); >> + if (ret) { >> + dev_err(&pdev->dev, "clk bulk init failed!\n"); >> + return ret; >> + } >> + >> + dev_dbg(&pdev->dev, "##Amlogic hw resource init OK##\n"); >> + >> + return 0; >> +} >> + >> +void dev_destroy_hw_resources(void *priv) >> +{ >> + struct aml_vdec_dev *dev = (struct aml_vdec_dev *)priv; >> + struct aml_vdec_hw *hw; >> + >> + if (!dev || !dev->dec_hw) >> + return; >> + >> + hw = dev->dec_hw; >> + >> + if (hw->pm->release) >> + hw->pm->release(hw); >> + >> + dev_dbg(hw->dev, "##Amlogic hw resource release OK##\n"); >> +} >> diff --git a/drivers/media/platform/amlogic/vdec/aml_vdec_hw.h b/drivers/media/platform/amlogic/vdec/aml_vdec_hw.h >> new file mode 100644 >> index 000000000000..6aac89a6356c >> --- /dev/null >> +++ b/drivers/media/platform/amlogic/vdec/aml_vdec_hw.h >> @@ -0,0 +1,158 @@ >> +/* SPDX-License-Identifier: (GPL-2.0-only OR MIT) */ >> +/* >> + * Copyright (C) 2025 Amlogic, Inc. All rights reserved >> + */ >> + >> +#ifndef _AML_VDEC_HW_H_ >> +#define _AML_VDEC_HW_H_ >> + >> +#include >> +#include >> +#include >> +#include >> +#include >> +#include >> +#include >> +#include >> +#include >> +#include >> +#include "reg_defines.h" >> + >> +#define VDEC_FIFO_ALIGN     8 >> +#define VLD_PADDING_SIZE    1024 >> + >> +/** >> + * struct aml_vdec_hw_ops - codec mode specific operations for hw >> + * @load_firmware_ex: Load firmware for current dec specific. >> + * @irq_handler: mandatory call when the ISR triggers >> + * @irq_threaded_func: mandatory call for the threaded ISR >> + * @canvas_alloc: Alloc canvas for curr frame >> + * @canvas_free: Release canvas. >> + * @config_canvas: Config for curr frame, such as w/h, Y/UV start addr etc. >> + */ >> +struct aml_vdec_hw_ops { >> + int (*load_firmware_ex)(void *priv, const u8 *data, u32 len); >> + irqreturn_t (*irq_handler)(int irq, void *priv); >> + irqreturn_t (*irq_threaded_func)(int irq, void *priv); >> + int (*canvas_alloc)(u8 *canvas_index); >> + void (*canvas_free)(u8 canvas_index); >> + void (*config_canvas)(u8 canvas_index, >> +       ulong addr, u32 width, u32 height, >> +       u32 wrap, u32 blkmode, u32 endian); >> +}; >> + >> +/** >> + * enum vdec_type_e - Type of decoder hardware. >> + */ >> +enum vdec_type_e { >> + VDEC_1 = 0, >> + VDEC_HEVC, >> + VDEC_MAX, >> +}; >> + >> +/** >> + * enum vdec_irq_num - Definition of the irq. >> + */ >> +enum vdec_irq_num { >> + VDEC_IRQ_0 = 0, >> + VDEC_IRQ_1, >> + VDEC_IRQ_2, >> + VDEC_IRQ_MAX, >> +}; >> + >> +/** >> + * enum vdec_type_e - Type of decoder clock. >> + */ >> +enum clk_type_e { >> + VDEC = 0, >> + VDEC_MUX, >> + HEVCF_MUX, >> + DOS_CLK_MAX, >> +}; >> + >> +/** >> + * enum aml_power_type_e - Type of decoder power. >> + */ >> +enum aml_power_type_e { >> + AML_PM_PD = 0, >> +}; >> + >> +/** >> + * enum mm_bus_e - Type of decoder hardware bus. >> + */ >> +enum mm_bus_e { >> + DOS_BUS = 0, >> + DMC_BUS, >> + MAX_REG_BUS >> +}; >> + >> +/** >> + * struct pm_pd_s - power domain definition >> + * @name: Power domain name. >> + * @dev: Pointer to device structure. >> + * @mutex: Pointer to device_link structure. >> + * @ref_count: Curr power domain instance ref count. >> + */ >> +struct pm_pd_s { >> + u8 *name; >> + struct device *dev; >> + struct device_link *link; >> + int ref_count; >> +}; >> + >> +/** >> + * struct aml_vdec_hw - decoder hardware resources definition >> + * @pdev: Pointer to struct platform_device. >> + * @dev: Pointer to struct device. >> + * @regs: Reg base for dos/dmc hardware. >> + * @pm_mutex: Mutex for pm->pd_data. >> + * @pm: Pointer to struct power_manager_s. >> + * @hw_ops: Hardware resource operation functions. See struct aml_vdec_hw_ops. >> + * @gates: Clk instance used by curr decoder context. >> + * @dec_irq: Irq registered. >> + * @curr_ctx: Pointer to curr decoder context. >> + */ >> +struct aml_vdec_hw { >> + struct platform_device *pdev; >> + struct device *dev; >> + struct regmap *map[MAX_REG_BUS]; >> + struct mutex pm_mutex; >> + struct meson_canvas *canvas; >> + const struct power_manager_s *pm; >> + struct aml_vdec_hw_ops hw_ops; >> + struct clk_bulk_data gates[DOS_CLK_MAX]; >> + int dec_irq; >> + void *curr_ctx; >> +}; >> + >> +/** >> + * struct power_manager_s - Power manager & opertion function >> + * @pd_data: Pointer to struct pm_pd_s >> + * @init: Power manager init. >> + * @release: Power manager release. >> + * @power_on: Power on for decoder hw. >> + * @power_off: Power off for decoder hw. >> + * @power_state: Query the power state. >> + */ >> +struct power_manager_s { >> + struct pm_pd_s *pd_data; >> + int (*init)(struct aml_vdec_hw *hw); >> + void (*release)(struct aml_vdec_hw *hw); >> + void (*power_on)(struct aml_vdec_hw *hw, int id); >> + void (*power_off)(struct aml_vdec_hw *hw, int id); >> + bool (*power_state)(struct aml_vdec_hw *hw, int id); >> +}; >> + >> +int dev_request_hw_resources(void *priv); >> +void dev_destroy_hw_resources(void *priv); >> +struct aml_vdec_hw *vdec_get_hw(void *priv); >> +u32 read_dos_reg(struct aml_vdec_hw *hw, u32 reg_addr); >> +int vdec_enable(struct aml_vdec_hw *hw); >> +int vdec_disable(struct aml_vdec_hw *hw); >> +void dos_enable(struct aml_vdec_hw *hw); >> +void aml_start_vdec_hw(struct aml_vdec_hw *hw); >> +void aml_stop_vdec_hw(struct aml_vdec_hw *hw); >> +int load_firmware(struct aml_vdec_hw *hw, const char *path); >> +void aml_vdec_reset_core(struct aml_vdec_hw *hw); >> + >> +#endif >> diff --git a/drivers/media/platform/amlogic/vdec/aml_vdec_platform.c b/drivers/media/platform/amlogic/vdec/aml_vdec_platform.c >> new file mode 100644 >> index 000000000000..f1f8ba1f4ff6 >> --- /dev/null >> +++ b/drivers/media/platform/amlogic/vdec/aml_vdec_platform.c >> @@ -0,0 +1,37 @@ >> +// SPDX-License-Identifier: (GPL-2.0-only OR MIT) >> +/* >> + * Copyright (C) 2025 Amlogic, Inc. All rights reserved >> + */ >> + >> +#include "aml_vdec_platform.h" >> +#include "aml_vdec_drv.h" >> +#include "aml_vdec_hw.h" >> +#include "h264.h" >> + >> +#define VIDEO_DEC_H264  "s4_h264_multi.bin" >> + >> +const struct aml_codec_ops aml_S4_dec_ops[] = { >> + [CODEC_TYPE_H264] = { >> + .init = aml_h264_init, >> + .exit = aml_h264_exit, >> + .run = aml_h264_dec_run, >> + }, >> +}; >> + >> +static const struct aml_video_dec_fmt aml_S4_dec_fmts = { >> + .max_height = AML_VDEC_1080P_MAX_H, >> + .max_width = AML_VDEC_1080P_MAX_W, >> + .align = 32, >> + .is_10_bit_support = 0, >> +}; >> + >> +const struct aml_dev_platform_data aml_vdec_s4_pdata = { >> + .dec_fmt = &aml_S4_dec_fmts, >> + .codec_ops = aml_S4_dec_ops, >> + .power_type = AML_PM_PD, >> + .req_hw_resource = dev_request_hw_resources, >> + .destroy_hw_resource = dev_destroy_hw_resources, >> + .fw_path = { >> + VIDEO_DEC_H264, >> + }, >> +}; >> diff --git a/drivers/media/platform/amlogic/vdec/aml_vdec_platform.h b/drivers/media/platform/amlogic/vdec/aml_vdec_platform.h >> new file mode 100644 >> index 000000000000..ff0933f6f074 >> --- /dev/null >> +++ b/drivers/media/platform/amlogic/vdec/aml_vdec_platform.h >> @@ -0,0 +1,62 @@ >> +/* SPDX-License-Identifier: (GPL-2.0-only OR MIT) */ >> +/* >> + * Copyright (C) 2025 Amlogic, Inc. All rights reserved >> + */ >> + >> +#ifndef AML_VDEC_PLATFORM_H_ >> +#define AML_VDEC_PLATFORM_H_ >> + >> +#include >> + >> +#define MAX_DEC_FORMAT 3 >> + >> +/** >> + * struct aml_codec_ops - codec mode specific operations >> + * @init: Used for decoder initialization. >> + * @exit: If needed, can be used to undo the .init phase. >> + * @run: Start a single decoding job. Called from atomic context. >> + * Caller should ensure that a pair of buffers is ready and the >> + * hardware is powered on and clk is enabled. Returns zero if OK, >> + * a negative value in error cases. >> + */ >> +struct aml_codec_ops { >> + int (*init)(void *priv); >> + void (*exit)(void *priv); >> + int (*run)(void *priv); >> +}; >> + >> +/** >> + * struct aml_video_dec_fmt - codec format required by platform >> + * @max_height: Max decode frame height of current platform. >> + * @max_width: Max decode frame width of current platform. >> + * @align: Align requirement of the current platform. >> + * @is_10_bit_support: Whether the platform supports 10 bit. >> + */ >> +struct aml_video_dec_fmt { >> + u32 max_height; >> + u32 max_width; >> + int align; >> + int is_10_bit_support; >> +}; >> + >> +/** >> + * struct aml_dev_platform_data - compatible data for each chip. >> + * @dec_fmt: Support dec format. >> + * @codec_ops: Codec operation function. >> + * @req_hw_resource: Operation function to request the hardware resource. >> + * @destroy_hw_resource: Operation function to release the hardware resource. >> + * @power_type: Type of power that the current chip need. See aml_power_type_e. >> + * @fw_path: Path of the firmware.bin. >> + */ >> +struct aml_dev_platform_data { >> + const struct aml_video_dec_fmt *dec_fmt; >> + const struct aml_codec_ops *codec_ops; >> + int (*req_hw_resource)(void *priv); >> + void (*destroy_hw_resource)(void *priv); >> + int power_type; >> + const char *fw_path[MAX_DEC_FORMAT]; >> +}; >> + >> +extern const struct aml_dev_platform_data aml_vdec_s4_pdata; >> + >> +#endif >> diff --git a/drivers/media/platform/amlogic/vdec/h264.c b/drivers/media/platform/amlogic/vdec/h264.c >> new file mode 100644 >> index 000000000000..d8619e160a6b >> --- /dev/null >> +++ b/drivers/media/platform/amlogic/vdec/h264.c >> @@ -0,0 +1,1933 @@ >> +// SPDX-License-Identifier: (GPL-2.0-only OR MIT) >> +/* >> + * Copyright (C) 2025 Amlogic, Inc. All rights reserved >> + */ >> + >> +#include >> +#include >> +#include "aml_vdec.h" >> +#include "aml_vdec_hw.h" >> +#include "h264.h" >> + >> +#define INVALID_POC 0xffffffff >> + >> +#define H264_SLICE_HEADER_DONE 0x1 >> +#define H264_SLICE_DATA_DONE 0x2 >> + >> +#define H264_MAX_COL_BUF 32 >> +#define H264_MAX_CANVAS_POS 26 >> + >> +#define DECODER_TIMEOUT_MS 500 >> + >> +#define COL_BUFFER_MARGIN 2 >> +#define COL_SIZE_FOR_ONE_MB 96 >> + >> +struct vdec_h264_stateless_ctrl_ref { >> + const struct v4l2_ctrl_h264_decode_params *decode; >> + const struct v4l2_ctrl_h264_scaling_matrix *scaling; >> + const struct v4l2_ctrl_h264_sps *sps; >> + const struct v4l2_ctrl_h264_pps *pps; >> +}; >> + >> +enum SliceType { >> + P_SLICE = 0, >> + B_SLICE = 1, >> + I_SLICE = 2, >> + SP_SLICE = 3, >> + SI_SLICE = 4, >> + MAX_SLICE_TYPES = 5 >> +}; >> + >> +/* Used by firmware */ >> +union param { >> + struct { >> + unsigned short data[RPM_END - RPM_BEGIN]; >> + } l; >> + struct { >> + unsigned short dump[DPB_OFFSET]; >> + unsigned short dpb_base[FRAME_IN_DPB << 3]; >> + >> + unsigned short dpb_max_buffer_frame; >> + unsigned short actual_dpb_size; >> + >> + unsigned short colocated_buf_status; >> + >> + unsigned short num_forward_short_term_reference_pic; >> + unsigned short num_short_term_reference_pic; >> + unsigned short num_reference_pic; >> + >> + unsigned short current_dpb_index; >> + unsigned short current_decoded_frame_num; >> + unsigned short current_reference_frame_num; >> + >> + unsigned short l0_size; >> + unsigned short l1_size; >> + /** >> + * [6:5] : nal_ref_idc >> + * [4:0] : nal_unit_type >> + */ >> + unsigned short NAL_info_mmco; >> + /** >> + * [1:0] : 00 - top field, 01 - bottom field, >> + *         10 - frame, 11 - mbaff frame >> + */ >> + unsigned short picture_structure_mmco; >> + unsigned short frame_num; >> + unsigned short pic_order_cnt_lsb; >> + >> + unsigned short num_ref_idx_l0_active_minus1; >> + unsigned short num_ref_idx_l1_active_minus1; >> + >> + unsigned short PrevPicOrderCntLsb; >> + unsigned short PreviousFrameNum; >> + >> + /* 32 bits variables */ >> + unsigned short delta_pic_order_cnt_bottom[2]; >> + unsigned short delta_pic_order_cnt_0[2]; >> + unsigned short delta_pic_order_cnt_1[2]; >> + >> + unsigned short PrevPicOrderCntMsb[2]; >> + unsigned short PrevFrameNumOffset[2]; >> + >> + unsigned short frame_pic_order_cnt[2]; >> + unsigned short top_field_pic_order_cnt[2]; >> + unsigned short bottom_field_pic_order_cnt[2]; >> + >> + unsigned short colocated_mv_addr_start[2]; >> + unsigned short colocated_mv_addr_end[2]; >> + unsigned short colocated_mv_wr_addr[2]; >> + } dpb; >> + struct { >> + unsigned short dump[MMCO_OFFSET]; >> + >> + /* array base address for offset_for_ref_frame */ >> + unsigned short offset_for_ref_frame_base[128]; >> + >> + /** >> + * 0 - Index in DPB >> + * 1 - Picture Flag >> + *  [2] : 0 - short term reference, >> + * 1 - long term reference >> + *  [1] : bottom field >> + *  [0] : top field >> + * 2 - Picture Number (short term or long term) low 16 bits >> + * 3 - Picture Number (short term or long term) high 16 bits >> + */ >> + unsigned short reference_base[128]; >> + >> + /* command and parameter, until command is 3 */ >> + unsigned short l0_reorder_cmd[REORDER_CMD_MAX]; >> + unsigned short l1_reorder_cmd[REORDER_CMD_MAX]; >> + >> + /* command and parameter, until command is 0 */ >> + unsigned short mmco_cmd[44]; >> + >> + unsigned short l0_base[40]; >> + unsigned short l1_base[40]; >> + } mmco; >> + struct { >> + /* from ucode lmem, do not change this struct */ >> + } p; >> +}; >> + >> +struct h264_decode_buf_spec { >> + struct v4l2_h264_dpb_entry *dpb; >> + u32 canvas_pos; >> + u32 dpb_index; >> + u32 poc; >> + int col_buf_index; >> + u8 y_canvas_index; >> + u8 u_canvas_index; >> + u8 v_canvas_index; >> + u8 used; >> + u8 long_term_flag; >> + dma_addr_t y_dma_addr; >> + dma_addr_t c_dma_addr; >> +}; >> + >> +#define REORDERING_COMMAND_MAX_SIZE 33 >> +struct slice { >> + int frame_num; >> + /*modification */ >> + int slice_type; >> + int num_ref_idx_l0; >> + int num_ref_idx_l1; >> + int first_mb_in_slice; >> + int ref_pic_list_reordering_flag[2]; >> + int modification_of_pic_nums_idc[2][REORDERING_COMMAND_MAX_SIZE]; >> + int abs_diff_pic_num_minus1[2][REORDERING_COMMAND_MAX_SIZE]; >> + int long_term_pic_idx[2][REORDERING_COMMAND_MAX_SIZE]; >> + unsigned char dec_ref_pic_marking_buffer_valid; >> +}; >> + >> +struct aml_h264_ctx { >> + struct aml_vdec_ctx *v4l2_ctx; >> + u8 init_flag; >> + u8 new_pic_flag; >> + u8 mc_cpu_loaded; >> + u8 param_set; >> + u8 colocated_buf_num; >> + u8 reg_iqidct_control_init_flag; >> + u32 reg_iqidct_control; >> + u32 reg_vcop_ctrl_reg; >> + u32 reg_rv_ai_mb_count; >> + u32 vld_dec_control; >> + u32 save_avscratch_f; >> + u32 seq_info; >> + u32 decode_pic_count; >> + union param dpb_param; >> + u32 dec_status; >> + struct slice mslice; >> + struct h264_decode_buf_spec curr_spec; >> + struct h264_decode_buf_spec ref_list0[V4L2_H264_NUM_DPB_ENTRIES + 1]; >> + struct h264_decode_buf_spec ref_list1[V4L2_H264_NUM_DPB_ENTRIES + 1]; >> + struct h264_decode_buf_spec ref_list0_unreordered[V4L2_H264_NUM_DPB_ENTRIES + 1]; >> + struct h264_decode_buf_spec ref_list1_unreordered[V4L2_H264_NUM_DPB_ENTRIES + 1]; >> + u8 list_size[2]; >> + dma_addr_t lmem_phy_addr; >> + void *lmem_addr; >> + dma_addr_t mc_cpu_paddr; >> + void *mc_cpu_vaddr; >> + dma_addr_t cma_alloc_addr; >> + void *cma_alloc_vaddr; >> + dma_addr_t collated_cma_addr; >> + dma_addr_t collated_cma_addr_end; >> + void *collated_cma_vaddr; >> + dma_addr_t workspace_offset; >> + void *workspace_vaddr; >> + u32 col_buf_alloc_size; >> + u32 one_col_buf_size; >> + u32 colocated_buf_map; >> + int colocated_buf_poc[H264_MAX_COL_BUF]; >> + int canvas_pos_poc[H264_MAX_CANVAS_POS]; >> + >> + u32 frame_width; >> + u32 frame_height; >> + u32 mb_width; >> + u32 mb_height; >> + u32 mb_total; >> + u32 max_num_ref_frames; >> + >> + struct vdec_h264_stateless_ctrl_ref ctrl_ref; >> +}; >> + >> +static inline int get_flag(u32 flag, u32 mask) >> +{ >> + return (flag & mask) ? 1 : 0; >> +} >> + >> +static inline void write_lmem(unsigned short *base, u32 offset, u32 value) >> +{ >> + base[offset] = value; >> +} >> + >> +static inline uint32_t spec2canvas(struct h264_decode_buf_spec *buf_spec) >> +{ >> + return (buf_spec->v_canvas_index << 16) | >> + (buf_spec->u_canvas_index << 8) | >> + (buf_spec->y_canvas_index << 0); >> +} >> + >> +static struct h264_decode_buf_spec *find_spec_by_dpb_index(struct aml_h264_ctx *h264_ctx, int index, >> +    int list) >> +{ >> + int i; >> + int size; >> + struct h264_decode_buf_spec *ref_list; >> + >> + size = h264_ctx->list_size[list]; >> + if (list == 0) >> + ref_list = &h264_ctx->ref_list0[0]; >> + else >> + ref_list = &h264_ctx->ref_list1[0]; >> + >> + for (i = 0; i < size; i++) { >> + if (index == ref_list[i].dpb_index) >> + return &ref_list[i]; >> + } >> + >> + return NULL; >> +} >> + >> +static int h264_prepare_input(struct aml_vdec_ctx *ctx) >> +{ >> + struct aml_vdec_hw *hw = vdec_get_hw(ctx->dev); >> + struct vb2_v4l2_buffer *src; >> + struct vb2_buffer *vb; >> + dma_addr_t src_dma; >> + u32 payload_size; >> + int dummy; >> + >> + src = v4l2_m2m_next_src_buf(ctx->fh.m2m_ctx); >> + if (!src) { >> + dev_info(hw->dev, "no input buffer available!\n"); >> + return -1; >> + } >> + vb = &src->vb2_buf; >> + payload_size = vb2_get_plane_payload(vb, 0); >> + src_dma = vb2_dma_contig_plane_dma_addr(vb, 0); >> + >> + regmap_write(hw->map[DOS_BUS], VLD_MEM_VIFIFO_CONTROL, 0); >> + /* reset VLD fifo for all vdec */ >> + regmap_write(hw->map[DOS_BUS], DOS_SW_RESET0, (1 << 5) | (1 << 4) | (1 << 3)); >> + regmap_write(hw->map[DOS_BUS], DOS_SW_RESET0, 0); >> + regmap_write(hw->map[DOS_BUS], POWER_CTL_VLD, 1 << 4); >> + >> + regmap_write(hw->map[DOS_BUS], VLD_MEM_VIFIFO_START_PTR, src_dma); >> + regmap_write(hw->map[DOS_BUS], VLD_MEM_VIFIFO_END_PTR, (src_dma + payload_size)); >> + regmap_write(hw->map[DOS_BUS], VLD_MEM_VIFIFO_CURR_PTR, >> +      round_down(src_dma, VDEC_FIFO_ALIGN)); >> + >> + regmap_write(hw->map[DOS_BUS], VLD_MEM_VIFIFO_CONTROL, 1); >> + regmap_write(hw->map[DOS_BUS], VLD_MEM_VIFIFO_CONTROL, 0); >> + regmap_write(hw->map[DOS_BUS], VLD_MEM_VIFIFO_BUF_CNTL, 2); >> + >> + regmap_write(hw->map[DOS_BUS], VLD_MEM_VIFIFO_RP, >> +      round_down(src_dma, VDEC_FIFO_ALIGN)); >> + dummy = payload_size + VLD_PADDING_SIZE; >> + regmap_write(hw->map[DOS_BUS], VLD_MEM_VIFIFO_WP, >> +      round_down((src_dma + dummy), VDEC_FIFO_ALIGN)); >> + >> + regmap_write(hw->map[DOS_BUS], VLD_MEM_VIFIFO_BUF_CNTL, 3); >> + regmap_write(hw->map[DOS_BUS], VLD_MEM_VIFIFO_BUF_CNTL, 2); >> + >> + regmap_write(hw->map[DOS_BUS], VLD_MEM_VIFIFO_CONTROL, >> +      (0x11 << 16) | (1 << 10) | (7 << 3)); >> + >> + regmap_write(hw->map[DOS_BUS], AV_SCRATCH_1, 0x0); >> + regmap_write(hw->map[DOS_BUS], H264_DECODE_INFO, (1 << 13)); >> + regmap_write(hw->map[DOS_BUS], H264_DECODE_SIZE, payload_size); >> + regmap_write(hw->map[DOS_BUS], VIFF_BIT_CNT, payload_size * 8); >> + >> + return 0; >> +} >> + >> +static void config_sps_params(struct aml_h264_ctx *h264_ctx, >> +       unsigned short *sps_base, >> +       const struct v4l2_ctrl_h264_sps *sps) >> +{ >> + struct aml_vdec_ctx *ctx = h264_ctx->v4l2_ctx; >> + struct aml_vdec_hw *hw = vdec_get_hw(ctx->dev); >> + u32 cfg_tmp = 0; >> + u32 frame_size; >> + u32 offset = 0; >> + unsigned short data_tmp[0x100]; >> + int i, ii; >> + >> + memset(sps_base, 0, 0x100); >> + >> + h264_ctx->frame_width = (sps->pic_width_in_mbs_minus1 + 1) << 4; >> + h264_ctx->frame_height = (sps->pic_height_in_map_units_minus1 + 1) << 4; >> + >> + data_tmp[offset] = PARAM_BASE_VAL; >> + offset += 2; >> + >> + data_tmp[offset++] = GET_SPS_PROFILE_IDC(sps->profile_idc); >> + >> + data_tmp[offset++] = GET_SPS_SEQ_PARAM_SET_ID(sps->seq_parameter_set_id) | >> +     GET_SPS_LEVEL_IDC(sps->level_idc); >> + >> + if (sps->profile_idc >= 100) { >> + data_tmp[offset++] = GET_SPS_CHROMA_FORMAT_IDC(sps->chroma_format_idc); >> + >> + data_tmp[offset++] = ((sps->chroma_format_idc ^ 1) << 1); >> + } >> + >> + data_tmp[offset++] = GET_SPS_LOG2_MAX_FRAME_NUM(sps->log2_max_frame_num_minus4); >> + data_tmp[offset++] = GET_SPS_PIC_ORDER_TYPE(sps->pic_order_cnt_type); >> + >> + if (sps->pic_order_cnt_type == 0) { >> + data_tmp[offset++] = >> + GET_SPS_PIC_ORDER_CNT_LSB(sps->log2_max_pic_order_cnt_lsb_minus4); >> + } else if (sps->pic_order_cnt_type == 1) { >> + data_tmp[offset++] = >> + get_flag(sps->flags, >> + V4L2_H264_SPS_FLAG_DELTA_PIC_ORDER_ALWAYS_ZERO); >> + data_tmp[offset++] = >> + GET_SPS_OFFSET_FOR_NONREF_PIC_LOW(sps->offset_for_non_ref_pic); >> + data_tmp[offset++] = >> + GET_SPS_OFFSET_FOR_NONREF_PIC_HIGH(sps->offset_for_non_ref_pic); >> + data_tmp[offset++] = >> + GET_SPS_OFFSET_FOR_TOP_BOT_FIELD_LOW(sps->offset_for_top_to_bottom_field); >> + data_tmp[offset++] = >> + GET_SPS_OFFSET_FOR_TOP_BOT_FIELD_HIGH(sps->offset_for_top_to_bottom_field); >> + data_tmp[offset++] = sps->num_ref_frames_in_pic_order_cnt_cycle; >> + } >> + >> + data_tmp[offset++] = GET_SPS_NUM_REF_FRAMES(sps->max_num_ref_frames) | >> +     GET_SPS_GAPS_ALLOWED_FLAG(get_flag(sps->flags, >> +        V4L2_H264_SPS_FLAG_GAPS_IN_FRAME_NUM_VALUE_ALLOWED)); >> + >> + data_tmp[offset++] = GET_SPS_PIC_WIDTH_IN_MBS(sps->pic_width_in_mbs_minus1); >> + >> + data_tmp[offset++] = GET_SPS_PIC_HEIGHT_IN_MBS(sps->pic_height_in_map_units_minus1); >> + data_tmp[offset++] = >> + GET_SPS_DIRECT_8X8_FLAGS >> + (get_flag(sps->flags, >> +   V4L2_H264_SPS_FLAG_DIRECT_8X8_INFERENCE)) | >> + GET_SPS_MB_ADAPTIVE_FRAME_FIELD_FLAGS >> + (get_flag(sps->flags, >> +   V4L2_H264_SPS_FLAG_MB_ADAPTIVE_FRAME_FIELD)) | >> + GET_SPS_FRAME_MBS_ONLY_FLAGS >> + (get_flag(sps->flags, >> +   V4L2_H264_SPS_FLAG_FRAME_MBS_ONLY)); >> + >> + for (i = 0; i < 0x100; i += 4) { >> + for (ii = 0; ii < 4; ii++) >> + sps_base[i + 3 - ii] = data_tmp[i + ii]; >> + } >> + >> + frame_size = (sps->pic_width_in_mbs_minus1 + 1) * (sps->pic_height_in_map_units_minus1 + 1); >> + cfg_tmp = (get_flag(sps->flags, V4L2_H264_SPS_FLAG_FRAME_MBS_ONLY) << 31) | >> + (sps->max_num_ref_frames << 24) | (frame_size << 8) | >> + (sps->pic_width_in_mbs_minus1 + 1); >> + regmap_write(hw->map[DOS_BUS], AV_SCRATCH_1, cfg_tmp); >> + h264_ctx->seq_info = cfg_tmp; >> + >> + cfg_tmp = 0; >> + cfg_tmp = (get_flag(sps->flags, V4L2_H264_SPS_FLAG_DIRECT_8X8_INFERENCE) << 15) | >> + (sps->chroma_format_idc); >> + regmap_write(hw->map[DOS_BUS], AV_SCRATCH_2, cfg_tmp); >> + >> + cfg_tmp = 0; >> + cfg_tmp = (sps->max_num_ref_frames << 8) | (sps->level_idc); >> + regmap_write(hw->map[DOS_BUS], AV_SCRATCH_B, cfg_tmp); >> + >> + cfg_tmp = ((sps->level_idc & 0xff) << 7) | >> +     (get_flag(sps->flags, V4L2_H264_SPS_FLAG_FRAME_MBS_ONLY) << 2); >> + regmap_write(hw->map[DOS_BUS], NAL_SEARCH_CTL, >> +      read_dos_reg(hw, NAL_SEARCH_CTL) | cfg_tmp); >> + >> + h264_ctx->mb_width = (sps->pic_width_in_mbs_minus1 + 4) & 0xfffffffc; >> + h264_ctx->mb_height = (sps->pic_height_in_map_units_minus1 + 4) & 0xfffffffc; >> + h264_ctx->mb_total = h264_ctx->mb_width * h264_ctx->mb_height; >> + h264_ctx->max_num_ref_frames = sps->max_num_ref_frames; >> +} >> + >> +static void config_pps_params(struct aml_h264_ctx *h264_ctx, >> +       unsigned short *pps_base, >> +       const struct v4l2_ctrl_h264_pps *pps) >> +{ >> + struct aml_vdec_ctx *ctx = h264_ctx->v4l2_ctx; >> + struct aml_vdec_hw *hw = vdec_get_hw(ctx->dev); >> + u32 offset = 0; >> + unsigned short data_tmp[0x100]; >> + u32 max_reference_size = V4L2_H264_NUM_DPB_ENTRIES; >> + u32 max_list_size; >> + int i, ii; >> + >> + memset(pps_base, 0, 0x100); >> + >> + data_tmp[offset++] = PARAM_BASE_VAL; >> + >> + data_tmp[offset++] = >> + GET_PPS_PIC_PARAM_SET_ID(pps->pic_parameter_set_id) | >> +     GET_PPS_SEQ_PARAM_SET_ID(pps->seq_parameter_set_id) | >> +     GET_PPS_ENTROPY_CODING_MODE_FLAG >> + (get_flag(pps->flags, >> +   V4L2_H264_PPS_FLAG_ENTROPY_CODING_MODE)) | >> +     GET_PPS_PIC_ORDER_PRESENT_FLAG >> + (get_flag(pps->flags, >> +   V4L2_H264_PPS_FLAG_BOTTOM_FIELD_PIC_ORDER_IN_FRAME_PRESENT)); >> + >> + data_tmp[offset++] = >> + GET_PPS_WEIGHTED_BIPRED_IDC(pps->weighted_bipred_idc) | >> + GET_PPS_WEIGHTED_PRED_FLAG(get_flag(pps->flags, >> +     V4L2_H264_PPS_FLAG_WEIGHTED_PRED)) | >> + GET_PPS_NUM_IDX_REF_L1_MINUS1(pps->num_ref_idx_l1_default_active_minus1) | >> + GET_PPS_NUM_IDX_REF_L0_MINUS1(pps->num_ref_idx_l0_default_active_minus1); >> + >> + data_tmp[offset++] = GET_PPS_INIT_QS_MINUS26(pps->pic_init_qs_minus26) | >> +     GET_PPS_INIT_QP_MINUS26(pps->pic_init_qp_minus26); >> + >> + data_tmp[offset] = >> +     GET_PPS_CHROMA_QP_INDEX_OFFSET(pps->chroma_qp_index_offset) | >> +     GET_PPS_DEBLOCK_FILTER_CTRL_PRESENT_FLAG >> + (get_flag(pps->flags, >> +   V4L2_H264_PPS_FLAG_DEBLOCKING_FILTER_CONTROL_PRESENT)) | >> +     GET_PPS_CONSTRAIN_INTRA_PRED_FLAG >> + (get_flag(pps->flags, >> +   V4L2_H264_PPS_FLAG_CONSTRAINED_INTRA_PRED)) | >> +     GET_PPS_REDUNDANT_PIC_CNT_PRESENT_FLAG >> + (get_flag(pps->flags, >> +   V4L2_H264_PPS_FLAG_REDUNDANT_PIC_CNT_PRESENT)); >> + if (get_flag >> +     (pps->flags, >> +      V4L2_H264_PPS_FLAG_TRANSFORM_8X8_MODE | >> +      V4L2_H264_PPS_FLAG_SCALING_MATRIX_PRESENT)) >> + data_tmp[offset] |= (1 << 11); >> + offset++; >> + >> + data_tmp[offset++] = >> +     GET_PPS_SCALING_MATRIX_PRESENT_FLAG(get_flag >> + (pps->flags, >> + V4L2_H264_PPS_FLAG_SCALING_MATRIX_PRESENT)) | >> +     GET_PPS_TRANSFORM_8X8_FLAG(get_flag >> +        (pps->flags, >> + V4L2_H264_PPS_FLAG_TRANSFORM_8X8_MODE)); >> + >> + data_tmp[offset++] = >> + GET_PPS_GET_SECOND_CHROMA_QP_OFFSET(pps->second_chroma_qp_index_offset); >> + >> + max_list_size = (pps->num_ref_idx_l1_default_active_minus1 + 1) + >> +     (pps->num_ref_idx_l0_default_active_minus1 + 1); >> + >> + h264_ctx->max_num_ref_frames = max_list_size > h264_ctx->max_num_ref_frames ? >> + max_list_size : h264_ctx->max_num_ref_frames; >> + >> + regmap_write(hw->map[DOS_BUS], AV_SCRATCH_0, >> +      ((h264_ctx->max_num_ref_frames + 1) << 24) | >> +      (max_reference_size << 16) | (max_reference_size << 8)); >> + >> + for (i = 0; i < 0x100; i += 4) { >> + for (ii = 0; ii < 4; ii++) >> + pps_base[i + 3 - ii] = data_tmp[i + ii]; >> + } >> +} >> + >> +static void h264_config_params(struct aml_vdec_ctx *ctx) >> +{ >> + struct aml_h264_ctx *h264_ctx = (struct aml_h264_ctx *)ctx->codec_priv; >> + unsigned short *p_sps_base, *p_pps_base; >> + struct vdec_h264_stateless_ctrl_ref *ctrls = &h264_ctx->ctrl_ref; >> + const struct v4l2_ctrl_h264_sps *sps = ctrls->sps; >> + const struct v4l2_ctrl_h264_pps *pps = ctrls->pps; >> + >> + p_sps_base = (unsigned short *)(h264_ctx->workspace_vaddr + >> + MEM_SPS_BASE + sps->seq_parameter_set_id * 0x400); >> + p_pps_base = (unsigned short *)(h264_ctx->workspace_vaddr + >> + MEM_PPS_BASE + pps->pic_parameter_set_id * 0x200); >> + >> + config_sps_params(h264_ctx, p_sps_base, sps); >> + config_pps_params(h264_ctx, p_pps_base, pps); >> +} >> + >> +static void config_decode_canvas(struct aml_vdec_hw *hw, >> + struct h264_decode_buf_spec *buf_spec, >> + u32 mb_width, u32 mb_height) >> +{ >> + int canvas_alloc_result = 0; >> + int blkmode = 0x0; >> + >> + canvas_alloc_result = meson_canvas_alloc(hw->canvas, &buf_spec->y_canvas_index); >> + canvas_alloc_result = meson_canvas_alloc(hw->canvas, &buf_spec->u_canvas_index); >> + buf_spec->v_canvas_index = buf_spec->u_canvas_index; >> + >> + if (!canvas_alloc_result) { >> + /* config y canvas */ >> + meson_canvas_config(hw->canvas, >> +     buf_spec->y_canvas_index, buf_spec->y_dma_addr, >> +     mb_width << 4, mb_height << 4, >> +     MESON_CANVAS_WRAP_NONE, MESON_CANVAS_BLKMODE_LINEAR, >> +     MESON_CANVAS_ENDIAN_SWAP64); >> + regmap_write(hw->map[DOS_BUS], VDEC_ASSIST_CANVAS_BLK32, >> +      (1 << 11) | /* canvas_blk32_wr */ >> +      (blkmode << 10) | /* canvas_blk32 */ >> +      (1 << 8) | /* canvas_index_wr */ >> +      (buf_spec->y_canvas_index << 0) /* canvas index */ >> +     ); >> + >> + /* config uv canvas */ >> + meson_canvas_config(hw->canvas, >> +     buf_spec->u_canvas_index, buf_spec->c_dma_addr, >> +     mb_width << 4, mb_height << 3, >> +     MESON_CANVAS_WRAP_NONE, MESON_CANVAS_BLKMODE_LINEAR, >> +     MESON_CANVAS_ENDIAN_SWAP64); >> + regmap_write(hw->map[DOS_BUS], VDEC_ASSIST_CANVAS_BLK32, >> +      (1 << 11) | /* canvas_blk32_wr */ >> +      (blkmode << 10) | /* canvas_blk32 */ >> +      (1 << 8) | /* canvas_index_wr */ >> +      (buf_spec->u_canvas_index << 0) /* canvas index */ >> +     ); >> + >> + regmap_write(hw->map[DOS_BUS], ANC0_CANVAS_ADDR + (buf_spec->canvas_pos << 2), >> +      spec2canvas(buf_spec)); >> + } >> +} >> + >> +static int allocate_colocate_buf(struct aml_h264_ctx *h264_ctx, int poc) >> +{ >> + int i; >> + struct aml_vdec_ctx *ctx = h264_ctx->v4l2_ctx; >> + >> + for (i = 0; i < h264_ctx->colocated_buf_num; i++) { >> + if (((h264_ctx->colocated_buf_map >> i) & 0x1) == 0) { >> + h264_ctx->colocated_buf_map |= (1 << i); >> + break; >> + } >> + } >> + >> + if (i == h264_ctx->colocated_buf_num) >> + return -1; >> + >> + h264_ctx->colocated_buf_poc[i] = poc; >> + dev_dbg(&ctx->dev->plat_dev->dev, "%s colocated_buf_index %d poc %d\n", __func__, i, >> + h264_ctx->colocated_buf_poc[i]); >> + >> + return i; >> +} >> + >> +static void release_colocate_buf(struct aml_h264_ctx *h264_ctx, int index) >> +{ >> + struct aml_vdec_ctx *ctx = h264_ctx->v4l2_ctx; >> + >> + if (index >= 0) { >> + if (index >= h264_ctx->colocated_buf_num) { >> + dev_dbg >> +     (&ctx->dev->plat_dev->dev, >> + "%s error, index %d is bigger than buf count %d\n", >> +      __func__, index, h264_ctx->max_num_ref_frames); >> + } else { >> + if (h264_ctx->colocated_buf_poc[index] != INVALID_POC && >> +     ((h264_ctx->colocated_buf_map >> index) & 0x1) == 0x1) { >> + h264_ctx->colocated_buf_map &= (~(1 << index)); >> + dev_dbg >> +     (&ctx->dev->plat_dev->dev, >> +      "%s colocated_buf_index %d released poc %d\n", >> +      __func__, index, >> +      h264_ctx->colocated_buf_poc[index]); >> + } >> + h264_ctx->colocated_buf_poc[index] = INVALID_POC; >> + } >> + } >> +} >> + >> +static int get_col_buf_index_by_poc(struct aml_h264_ctx *h264_ctx, int poc) >> +{ >> + int idx; >> + >> + for (idx = 0; idx < h264_ctx->colocated_buf_num; idx++) { >> + if (h264_ctx->colocated_buf_poc[idx] == poc) >> + break; >> + } >> + >> + if (idx == h264_ctx->colocated_buf_num) >> + idx = -1; >> + >> + return idx; >> +} >> + >> +static int alloc_colocate_cma(struct aml_h264_ctx *h264_ctx, >> +       struct aml_vdec_ctx *ctx) >> +{ >> + int alloc_size = 0; >> + int i; >> + struct aml_vdec_hw *hw; >> + >> + if (h264_ctx->collated_cma_vaddr) >> + return 0; >> + >> + hw = vdec_get_hw(ctx->dev); >> + if (!hw) >> + return -1; >> + >> + /* 96 :col buf size for each mb */ >> + h264_ctx->one_col_buf_size = h264_ctx->mb_total * 96; >> + alloc_size = PAGE_ALIGN(h264_ctx->one_col_buf_size * >> + (h264_ctx->max_num_ref_frames + COL_BUFFER_MARGIN)); >> + h264_ctx->collated_cma_vaddr = dma_alloc_coherent(hw->dev, alloc_size, >> +   &h264_ctx->collated_cma_addr, GFP_KERNEL); >> + if (!h264_ctx->collated_cma_vaddr) >> + return -ENOMEM; >> + >> + dev_dbg >> +     (&ctx->dev->plat_dev->dev, >> +     "collated_cma_addr = 0x%llx, one_col_buf_size = %x alloc_size = %x\n", >> +      h264_ctx->collated_cma_addr, h264_ctx->one_col_buf_size, >> +      alloc_size); >> + h264_ctx->collated_cma_addr_end = >> +     h264_ctx->collated_cma_addr + alloc_size; >> + memset(h264_ctx->collated_cma_vaddr, 0, alloc_size); >> + h264_ctx->col_buf_alloc_size = alloc_size; >> + h264_ctx->colocated_buf_map = 0; >> + h264_ctx->colocated_buf_num = h264_ctx->max_num_ref_frames + COL_BUFFER_MARGIN; >> + >> + for (i = 0; i < H264_MAX_COL_BUF; i++) >> + h264_ctx->colocated_buf_poc[i] = INVALID_POC; >> + >> + return 0; >> +} >> + >> +static void config_p_reflist(struct aml_h264_ctx *h264_ctx, >> +      struct v4l2_h264_reference *v4l2_p0_reflist, >> +      u32 list_size) >> +{ >> + struct vdec_h264_stateless_ctrl_ref *ctrls = &h264_ctx->ctrl_ref; >> + struct v4l2_ctrl_h264_decode_params *decode = >> +     (struct v4l2_ctrl_h264_decode_params *)ctrls->decode; >> + struct v4l2_h264_dpb_entry *dpb = decode->dpb; >> + u8 index; >> + int i; >> + >> + for (i = 0; i < list_size; i++) { >> + index = v4l2_p0_reflist[i].index; >> + h264_ctx->ref_list0[i].used = 1; >> + h264_ctx->ref_list0[i].dpb = &dpb[index]; >> + h264_ctx->ref_list0[i].poc = dpb[index].top_field_order_cnt; >> + h264_ctx->ref_list0[i].long_term_flag = >> +     dpb[index].flags & V4L2_H264_DPB_ENTRY_FLAG_LONG_TERM ? true : false; >> + h264_ctx->ref_list0[i].dpb_index = index; >> + } >> + h264_ctx->list_size[0] = i; >> +} >> + >> +static void config_b_reflist(struct aml_h264_ctx *h264_ctx, >> +      struct v4l2_h264_reference *v4l2_b0_reflist, >> +      struct v4l2_h264_reference *v4l2_b1_reflist, >> +      u32 list_size) >> +{ >> + struct aml_vdec_ctx *ctx = h264_ctx->v4l2_ctx; >> + struct vdec_h264_stateless_ctrl_ref *ctrls = &h264_ctx->ctrl_ref; >> + struct v4l2_ctrl_h264_decode_params *decode = >> +     (struct v4l2_ctrl_h264_decode_params *)ctrls->decode; >> + struct v4l2_h264_dpb_entry *dpb = decode->dpb; >> + struct slice *curr_slice = &h264_ctx->mslice; >> + u8 index; >> + int i, j; >> + >> + h264_ctx->list_size[0] = curr_slice->num_ref_idx_l0; >> + for (i = 0; i < list_size && i < curr_slice->num_ref_idx_l0; i++) { >> + index = v4l2_b0_reflist[i].index; >> + h264_ctx->ref_list0[i].used = 1; >> + h264_ctx->ref_list0[i].dpb = &dpb[index]; >> + h264_ctx->ref_list0[i].poc = dpb[index].top_field_order_cnt; >> + h264_ctx->ref_list0[i].long_term_flag = >> +     dpb[index].flags & V4L2_H264_DPB_ENTRY_FLAG_LONG_TERM ? true : false; >> + h264_ctx->ref_list0[i].col_buf_index = >> + get_col_buf_index_by_poc(h264_ctx, dpb[index].top_field_order_cnt); >> + h264_ctx->ref_list0[i].dpb_index = index; >> + } >> + >> + h264_ctx->list_size[1] = curr_slice->num_ref_idx_l1; >> + for (j = 0; j < list_size && j < curr_slice->num_ref_idx_l1; j++) { >> + index = v4l2_b1_reflist[j].index; >> + h264_ctx->ref_list1[j].used = 1; >> + h264_ctx->ref_list1[j].dpb = &dpb[index]; >> + h264_ctx->ref_list1[j].poc = dpb[index].top_field_order_cnt; >> + h264_ctx->ref_list1[j].long_term_flag = >> +     dpb[index].flags & V4L2_H264_DPB_ENTRY_FLAG_LONG_TERM ? true : false; >> + h264_ctx->ref_list1[j].col_buf_index = >> + get_col_buf_index_by_poc(h264_ctx, dpb[index].top_field_order_cnt); >> + h264_ctx->ref_list1[j].dpb_index = index; >> + } >> + >> + if ((h264_ctx->list_size[1] + h264_ctx->list_size[0]) < list_size) >> + dev_info(&ctx->dev->plat_dev->dev, "ref list incorrect list0 %d list0 %d list_size%d\n", >> + h264_ctx->list_size[0], h264_ctx->list_size[1], list_size); >> +} >> + >> +static int poc_is_in_dpb(int poc, const struct v4l2_h264_dpb_entry *dpb) >> +{ >> + int i; >> + int ret = 0; >> + >> + for (i = 0; i < V4L2_H264_NUM_DPB_ENTRIES; i++) { >> + if (poc == dpb[i].top_field_order_cnt) { >> + ret = 1; >> + break; >> + } >> + } >> + >> + return ret; >> +} >> + >> +static int get_ref_list_size(struct aml_h264_ctx *h264_ctx, int cur_list) >> +{ >> + struct aml_vdec_ctx *ctx = h264_ctx->v4l2_ctx; >> + unsigned short override_flag = h264_ctx->dpb_param.l.data[REF_IDC_OVERRIDE_FLAG]; >> + int num_ref_idx_lx_active_minus1; >> + >> + if (cur_list == 0) { >> + num_ref_idx_lx_active_minus1 = >> + h264_ctx->ctrl_ref.pps->num_ref_idx_l0_default_active_minus1; >> + if (override_flag) >> + num_ref_idx_lx_active_minus1 = >> + h264_ctx->dpb_param.dpb.num_ref_idx_l0_active_minus1; >> + } else { >> + num_ref_idx_lx_active_minus1 = >> + h264_ctx->ctrl_ref.pps->num_ref_idx_l1_default_active_minus1; >> + } >> + dev_dbg(&ctx->dev->plat_dev->dev, "%s get list %d size %d\n", >> + __func__, cur_list, num_ref_idx_lx_active_minus1 + 1); >> + >> + return num_ref_idx_lx_active_minus1 + 1; >> +} >> + >> +static int get_refidx_by_picnum(struct aml_h264_ctx *h264_ctx, int pic_num, >> + int curr_list) >> +{ >> + int i; >> + struct h264_decode_buf_spec *ref_list; >> + >> + if (curr_list == 0) >> + ref_list = &h264_ctx->ref_list0[0]; >> + else >> + ref_list = &h264_ctx->ref_list1[0]; >> + >> + for (i = 0; ref_list[i].dpb; i++) { >> + if (pic_num == ref_list[i].dpb->pic_num) >> + return i; >> + } >> + >> + return -1; >> +} >> + >> +static struct h264_decode_buf_spec *get_st_refpic_by_num(struct aml_h264_ctx *h264_ctx, >> + int pic_num, int curr_list) >> +{ >> + int i; >> + struct h264_decode_buf_spec *ref_list; >> + >> + if (curr_list == 0) >> + ref_list = &h264_ctx->ref_list0_unreordered[0]; >> + else >> + ref_list = &h264_ctx->ref_list1_unreordered[0]; >> + >> + for (i = 0; ref_list[i].dpb; i++) { >> + if (pic_num == ref_list[i].dpb->pic_num && ref_list[i].long_term_flag == 0) >> + return &ref_list[i]; >> + } >> + >> + return NULL; >> +} >> + >> +static struct h264_decode_buf_spec *get_lt_refpic_by_num(struct aml_h264_ctx *h264_ctx, >> + int pic_num, int curr_list) >> +{ >> + int i; >> + struct h264_decode_buf_spec *ref_list; >> + >> + if (curr_list == 0) >> + ref_list = &h264_ctx->ref_list0_unreordered[0]; >> + else >> + ref_list = &h264_ctx->ref_list1_unreordered[0]; >> + >> + for (i = 0; ref_list[i].dpb; i++) { >> + if (pic_num == ref_list[i].dpb->pic_num && ref_list[i].long_term_flag == 1) >> + return &ref_list[i]; >> + } >> + >> + return NULL; >> +} >> + >> +static void reorder_short_term(struct slice *curr_slice, int cur_list, >> +        int pic_num_lx, int *ref_idx_lx) >> +{ >> + struct aml_h264_ctx *h264_ctx = container_of(curr_slice, struct aml_h264_ctx, mslice); >> + struct aml_vdec_ctx *ctx = h264_ctx->v4l2_ctx; >> + int c_idx, n_idx; >> + int num_ref_idx_lx_active; >> + struct h264_decode_buf_spec *pic_lx = NULL; >> + struct h264_decode_buf_spec *ref_list_reordered; >> + >> + if (cur_list == 0) >> + ref_list_reordered = &h264_ctx->ref_list0[0]; >> + else >> + ref_list_reordered = &h264_ctx->ref_list1[0]; >> + >> + num_ref_idx_lx_active = get_ref_list_size(h264_ctx, cur_list); >> + >> + /* find short-term ref frame with pic_num is pic_num_lx */ >> + pic_lx = get_st_refpic_by_num(h264_ctx, pic_num_lx, cur_list); >> + if (!pic_lx) { >> + dev_dbg(&ctx->dev->plat_dev->dev, "cannot find st pic_lx for %d\n", pic_num_lx); >> + return; >> + } >> + >> + if (*ref_idx_lx == get_refidx_by_picnum(h264_ctx, pic_num_lx, cur_list)) { >> + dev_dbg(&ctx->dev->plat_dev->dev, "no need to move pic lx %d\n", *ref_idx_lx); >> + *ref_idx_lx = *ref_idx_lx + 1; >> + return; >> + } >> + >> + for (c_idx = num_ref_idx_lx_active; c_idx > *ref_idx_lx; c_idx--) >> + memcpy(&ref_list_reordered[c_idx], &ref_list_reordered[c_idx - 1], >> +        sizeof(struct h264_decode_buf_spec)); >> + >> + memcpy(&ref_list_reordered[*ref_idx_lx], pic_lx, sizeof(struct h264_decode_buf_spec)); >> + dev_dbg(&ctx->dev->plat_dev->dev, "%s : RefPicListX[%d ] = pic %p pic_num(%d)\n", __func__, >> + *ref_idx_lx, pic_lx, ref_list_reordered[*ref_idx_lx].dpb->pic_num); >> + *ref_idx_lx = *ref_idx_lx + 1; >> + >> + n_idx = *ref_idx_lx; >> + for (c_idx = *ref_idx_lx; c_idx <= num_ref_idx_lx_active; c_idx++) { >> + if (ref_list_reordered[c_idx].long_term_flag || !ref_list_reordered[c_idx].dpb || >> +     ref_list_reordered[c_idx].dpb->pic_num != pic_num_lx) >> + memcpy(&ref_list_reordered[n_idx++], &ref_list_reordered[c_idx], >> +        sizeof(struct h264_decode_buf_spec)); >> + } >> + >> + h264_ctx->list_size[cur_list] = num_ref_idx_lx_active; >> +} >> + >> +static void reorder_long_term(struct slice *curr_slice, int cur_list, >> +       int lt_pic_num, int *ref_idx_lx) >> +{ >> + struct aml_h264_ctx *h264_ctx = container_of(curr_slice, struct aml_h264_ctx, mslice); >> + struct aml_vdec_ctx *ctx = h264_ctx->v4l2_ctx; >> + int num_ref_idx_lx_active; >> + int c_idx, n_idx; >> + struct h264_decode_buf_spec *ref_list; >> + struct h264_decode_buf_spec *pic_lt = NULL; >> + >> + if (cur_list == 0) >> + ref_list = &h264_ctx->ref_list0[0]; >> + else >> + ref_list = &h264_ctx->ref_list1[0]; >> + >> + num_ref_idx_lx_active = get_ref_list_size(h264_ctx, cur_list); >> + >> + /* find long-term ref frame with pic_num is lt_pic_num */ >> + pic_lt = get_lt_refpic_by_num(h264_ctx, lt_pic_num, cur_list); >> + if (!pic_lt) { >> + dev_dbg(&ctx->dev->plat_dev->dev, "cannot find lt pic_lx for %d\n", lt_pic_num); >> + return; >> + } >> + >> + if (*ref_idx_lx == get_refidx_by_picnum(h264_ctx, lt_pic_num, cur_list)) { >> + dev_dbg(&ctx->dev->plat_dev->dev, "no need to move pic lx %d\n", *ref_idx_lx); >> + *ref_idx_lx = *ref_idx_lx + 1; >> + return; >> + } >> + >> + for (c_idx = num_ref_idx_lx_active; c_idx > *ref_idx_lx; c_idx--) >> + memcpy(&ref_list[c_idx], &ref_list[c_idx - 1], sizeof(struct h264_decode_buf_spec)); >> + >> + memcpy(&ref_list[*ref_idx_lx], pic_lt, sizeof(struct h264_decode_buf_spec)); >> + dev_dbg(&ctx->dev->plat_dev->dev, "%s : RefPicListX[%d ] = pic %p pic_num(%d)\n", __func__, >> + *ref_idx_lx, pic_lt, ref_list[*ref_idx_lx].dpb->pic_num); >> + *ref_idx_lx = *ref_idx_lx + 1; >> + >> + n_idx = *ref_idx_lx; >> + /* Pointer dpb is NULL means this is a dummy frame store */ >> + for (c_idx = *ref_idx_lx; c_idx <= num_ref_idx_lx_active; c_idx++) { >> + if (!ref_list[c_idx].long_term_flag || !ref_list[c_idx].dpb || >> +     ref_list[c_idx].dpb->pic_num != lt_pic_num) >> + memcpy(&ref_list[n_idx++], &ref_list[c_idx], >> +        sizeof(struct h264_decode_buf_spec)); >> + } >> + >> + h264_ctx->list_size[cur_list] = num_ref_idx_lx_active; >> +} >> + >> +static void get_modification_cmd(unsigned short *reorder_cmd, struct slice *curr_slice, int list) >> +{ >> + int i, j, val; >> + >> + val = curr_slice->ref_pic_list_reordering_flag[list]; >> + if (val) { >> + i = 0; >> + j = 0; >> + do { >> + curr_slice->modification_of_pic_nums_idc[list][i] = >> + reorder_cmd[j++]; >> + if (j >= REORDER_CMD_MAX) { >> + curr_slice->modification_of_pic_nums_idc[list][i] = 0; >> + break; >> + } >> + >> + val = curr_slice->modification_of_pic_nums_idc[list][i]; >> + if (val == 0 || val == 1) >> + curr_slice->abs_diff_pic_num_minus1[list][i] = reorder_cmd[j++]; >> + else if (val == 2) >> + curr_slice->long_term_pic_idx[list][i] = reorder_cmd[j++]; >> + >> + i++; >> + >> + if (i >= REORDERING_COMMAND_MAX_SIZE) { >> + curr_slice->ref_pic_list_reordering_flag[list] = 0; >> + break; >> + }; >> + if (j > REORDER_CMD_MAX) { >> + curr_slice->ref_pic_list_reordering_flag[list] = 0; >> + break; >> + }; >> + } while (val != 3); >> + } >> +} >> + >> +static void reorder_pics(struct aml_h264_ctx *h264_ctx, struct slice *curr_slice, int cur_list) >> +{ >> + struct aml_vdec_ctx *ctx = h264_ctx->v4l2_ctx; >> + int *modification_of_pic_nums_idc = >> + curr_slice->modification_of_pic_nums_idc[cur_list]; >> + int *abs_diff_pic_num_minus1 = >> + curr_slice->abs_diff_pic_num_minus1[cur_list]; >> + int *long_term_pic_idx = curr_slice->long_term_pic_idx[cur_list]; >> + int pic_num_lx_nowarp, pic_num_lx_pred, pic_num_lx; >> + int curr_pic_num = curr_slice->frame_num; >> + int max_pic_num = 1 << (4 + h264_ctx->ctrl_ref.sps->log2_max_frame_num_minus4); >> + int ref_idx_lx = 0; >> + int nowarp_tmp = 0; >> + int i; >> + >> + pic_num_lx_pred = curr_pic_num; >> + for (i = 0; i < REORDERING_COMMAND_MAX_SIZE && modification_of_pic_nums_idc[i] != 3; i++) { >> + if (modification_of_pic_nums_idc[i] > 3) { >> + dev_info(&ctx->dev->plat_dev->dev, "error, Invalid modification_of_pic_nums_idc command\n"); >> + break; >> + } >> + >> + if (modification_of_pic_nums_idc[i] < 2) { >> + if (modification_of_pic_nums_idc[i] == 0) { >> + nowarp_tmp = pic_num_lx_pred - (abs_diff_pic_num_minus1[i] + 1); >> + pic_num_lx_nowarp = nowarp_tmp + (nowarp_tmp < 0 ? max_pic_num : 0); >> + } else if (modification_of_pic_nums_idc[i] == 1) { >> + nowarp_tmp = pic_num_lx_pred + (abs_diff_pic_num_minus1[i] + 1); >> + pic_num_lx_nowarp = nowarp_tmp - >> + (nowarp_tmp > max_pic_num ? max_pic_num : 0); >> + } >> + pic_num_lx_pred = pic_num_lx_nowarp; >> + if (pic_num_lx_nowarp > curr_pic_num) >> + pic_num_lx = pic_num_lx_nowarp - max_pic_num; >> + else >> + pic_num_lx = pic_num_lx_nowarp; >> + >> + reorder_short_term(curr_slice, cur_list, pic_num_lx, &ref_idx_lx); >> + } else { >> + reorder_long_term(curr_slice, cur_list, long_term_pic_idx[i], &ref_idx_lx); >> + } >> + } >> +} >> + >> +static void copy_ref_list(struct aml_h264_ctx *h264_ctx, int curr_list) >> +{ >> + if (curr_list == 0) >> + memcpy(h264_ctx->ref_list0_unreordered, h264_ctx->ref_list0, >> +        sizeof(h264_ctx->ref_list0)); >> + else >> + memcpy(h264_ctx->ref_list1_unreordered, h264_ctx->ref_list0, >> +        sizeof(h264_ctx->ref_list1)); >> +} >> + >> +static void h264_reorder_reflists(struct aml_h264_ctx *h264_ctx) >> +{ >> + unsigned short *reorder_cmd; >> + struct slice *curr_slice = &h264_ctx->mslice; >> + >> + if (curr_slice->slice_type != I_SLICE && curr_slice->slice_type != SI_SLICE) { >> + reorder_cmd = &h264_ctx->dpb_param.mmco.l0_reorder_cmd[0]; >> + /* 3:parsed by ucode, means no reorder needed */ >> + if (reorder_cmd[0] != 3) >> + curr_slice->ref_pic_list_reordering_flag[0] = 1; >> + else >> + curr_slice->ref_pic_list_reordering_flag[0] = 0; >> + >> + get_modification_cmd(reorder_cmd, curr_slice, 0); >> + } >> + >> + if (curr_slice->slice_type == B_SLICE) { >> + reorder_cmd = &h264_ctx->dpb_param.mmco.l1_reorder_cmd[0]; >> + /* 3:parsed by ucode, means no reorder needed */ >> + if (reorder_cmd[0] != 3) >> + curr_slice->ref_pic_list_reordering_flag[1] = 1; >> + else >> + curr_slice->ref_pic_list_reordering_flag[1] = 0; >> + >> + get_modification_cmd(reorder_cmd, curr_slice, 1); >> + } >> + >> + if (curr_slice->slice_type != I_SLICE && >> +     curr_slice->slice_type != SI_SLICE && >> +     curr_slice->ref_pic_list_reordering_flag[0] != 0) { >> + copy_ref_list(h264_ctx, 0); >> + reorder_pics(h264_ctx, curr_slice, 0); >> + } >> + >> + if (curr_slice->slice_type == B_SLICE && curr_slice->ref_pic_list_reordering_flag[1] != 0) { >> + copy_ref_list(h264_ctx, 1); >> + reorder_pics(h264_ctx, curr_slice, 1); >> + } >> +} >> + >> +static void h264_config_ref_lists(struct aml_vdec_ctx *ctx) >> +{ >> + struct aml_h264_ctx *h264_ctx = (struct aml_h264_ctx *)ctx->codec_priv; >> + struct vdec_h264_stateless_ctrl_ref *ctrls = &h264_ctx->ctrl_ref; >> + struct v4l2_ctrl_h264_decode_params *decode = >> + (struct v4l2_ctrl_h264_decode_params *)ctrls->decode; >> + struct v4l2_ctrl_h264_sps *sps = (struct v4l2_ctrl_h264_sps *)ctrls->sps; >> + const struct v4l2_h264_dpb_entry *dpb = decode->dpb; >> + struct v4l2_h264_reflist_builder builder; >> + struct v4l2_h264_reference v4l2_p0_reflist[V4L2_H264_REF_LIST_LEN]; >> + struct v4l2_h264_reference v4l2_b0_reflist[V4L2_H264_REF_LIST_LEN]; >> + struct v4l2_h264_reference v4l2_b1_reflist[V4L2_H264_REF_LIST_LEN]; >> + >> + if (decode->flags == V4L2_H264_DECODE_PARAM_FLAG_IDR_PIC) >> + return; >> + >> + v4l2_h264_init_reflist_builder(&builder, decode, sps, dpb); >> + dev_dbg(&ctx->dev->plat_dev->dev, "%s num_valid = %d", __func__, builder.num_valid); >> + >> + if (decode->flags & V4L2_H264_DECODE_PARAM_FLAG_PFRAME) { >> + v4l2_h264_build_p_ref_list(&builder, v4l2_p0_reflist); >> + config_p_reflist(h264_ctx, v4l2_p0_reflist, builder.num_valid); >> + } else if (decode->flags & V4L2_H264_DECODE_PARAM_FLAG_BFRAME) { >> + v4l2_h264_build_b_ref_lists(&builder, v4l2_b0_reflist, v4l2_b1_reflist); >> + config_b_reflist(h264_ctx, v4l2_b0_reflist, v4l2_b1_reflist, builder.num_valid); >> + } >> +} >> + >> +static void clear_unused_col_buf(struct aml_h264_ctx *h264_ctx, >> + struct v4l2_ctrl_h264_decode_params *decode) >> +{ >> + int i, col_poc; >> + >> + /* flush all col buffers when IDR */ >> + if (decode->flags == V4L2_H264_DECODE_PARAM_FLAG_IDR_PIC) { >> + /* 32 : max index of co-locate buffer */ >> + for (i = 0; i < 32; i++) >> + release_colocate_buf(h264_ctx, i); >> + return; >> + } >> + >> + for (i = 0; i < h264_ctx->colocated_buf_num; i++) { >> + col_poc = h264_ctx->colocated_buf_poc[i]; >> + if (col_poc != INVALID_POC && (poc_is_in_dpb(col_poc, decode->dpb) != 1)) >> + release_colocate_buf(h264_ctx, i); >> + } >> +} >> + >> +static void h264_config_decode_spec(struct aml_vdec_hw *hw, struct aml_vdec_ctx *ctx) >> +{ >> + struct aml_h264_ctx *h264_ctx = (struct aml_h264_ctx *)hw->curr_ctx; >> + struct vdec_h264_stateless_ctrl_ref *ctrls = &h264_ctx->ctrl_ref; >> + struct v4l2_ctrl_h264_decode_params *decode = >> + (struct v4l2_ctrl_h264_decode_params *)ctrls->decode; >> + struct h264_decode_buf_spec *buf_spec_l0, *buf_spec_l1; >> + struct vb2_buffer *vb; >> + struct vb2_v4l2_buffer *vb2_v4l2; >> + struct vb2_queue *vq; >> + int i; >> + >> + clear_unused_col_buf(h264_ctx, decode); >> + >> + vb2_v4l2 = v4l2_m2m_next_dst_buf(ctx->m2m_ctx); >> + vb = &vb2_v4l2->vb2_buf; >> + >> + h264_ctx->curr_spec.y_dma_addr = vb2_dma_contig_plane_dma_addr(vb, 0); >> + if (ctx->pic_info.plane_num > 1) >> + h264_ctx->curr_spec.c_dma_addr = vb2_dma_contig_plane_dma_addr(vb, 1); >> + else >> + h264_ctx->curr_spec.c_dma_addr = >> + h264_ctx->curr_spec.y_dma_addr + ctx->pic_info.fb_size[0]; >> + h264_ctx->curr_spec.canvas_pos = 0; >> + if (decode->nal_ref_idc) >> + h264_ctx->curr_spec.col_buf_index = >> + allocate_colocate_buf(h264_ctx, decode->top_field_order_cnt); >> + else >> + h264_ctx->curr_spec.col_buf_index = -1; >> + h264_ctx->curr_spec.poc = decode->top_field_order_cnt; >> + config_decode_canvas(hw, &h264_ctx->curr_spec, h264_ctx->mb_width, h264_ctx->mb_height); >> + h264_ctx->canvas_pos_poc[0] = decode->top_field_order_cnt; >> + >> + h264_config_ref_lists(ctx); >> + >> + vq = v4l2_m2m_get_vq(ctx->m2m_ctx, V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE); >> + >> + for (i = 0; i < V4L2_H264_NUM_DPB_ENTRIES; i++) { >> + struct v4l2_h264_dpb_entry *dpb = &decode->dpb[i]; >> + >> + if (!(dpb->flags & V4L2_H264_DPB_ENTRY_FLAG_ACTIVE)) >> + break; >> + >> + buf_spec_l0 = find_spec_by_dpb_index(h264_ctx, i, 0); >> + if (buf_spec_l0) { >> + buf_spec_l0->canvas_pos = i + 1; >> + vb = vb2_find_buffer(vq, dpb->reference_ts); >> + if (!vb) { >> + dev_err(&ctx->dev->plat_dev->dev, >> + "ref pic for ts %llu lost\n", dpb->reference_ts); >> + continue; >> + } >> + >> + buf_spec_l0->y_dma_addr = >> + vb2_dma_contig_plane_dma_addr(vb, 0); >> + if (ctx->pic_info.plane_num > 1) >> + buf_spec_l0->c_dma_addr = vb2_dma_contig_plane_dma_addr(vb, 1); >> + else >> + buf_spec_l0->c_dma_addr = >> + buf_spec_l0->y_dma_addr + ctx->pic_info.fb_size[0]; >> + config_decode_canvas(hw, buf_spec_l0, >> +      h264_ctx->mb_width, h264_ctx->mb_height); >> + if (h264_ctx->canvas_pos_poc[buf_spec_l0->canvas_pos] == INVALID_POC) >> + h264_ctx->canvas_pos_poc[buf_spec_l0->canvas_pos] = >> + buf_spec_l0->dpb->top_field_order_cnt; >> + dev_dbg >> +     (&ctx->dev->plat_dev->dev, >> +      "config canvas for poc %d canvas %d y_dma_addr 0x%llx\n", >> +      buf_spec_l0->dpb->top_field_order_cnt, >> +      buf_spec_l0->canvas_pos, buf_spec_l0->y_dma_addr); >> + } >> + >> + buf_spec_l1 = find_spec_by_dpb_index(h264_ctx, i, 1); >> + if (!buf_spec_l0 && buf_spec_l1) { >> + buf_spec_l1->canvas_pos = i + 1; >> + vb = vb2_find_buffer(vq, dpb->reference_ts); >> + if (!vb) { >> + dev_err(&ctx->dev->plat_dev->dev, >> + "ref pic for ts %llu lost\n", dpb->reference_ts); >> + continue; >> + } >> + >> + buf_spec_l1->y_dma_addr = >> + vb2_dma_contig_plane_dma_addr(vb, 0); >> + if (ctx->pic_info.plane_num > 1) >> + buf_spec_l1->c_dma_addr = vb2_dma_contig_plane_dma_addr(vb, 1); >> + else >> + buf_spec_l1->c_dma_addr = >> + buf_spec_l1->y_dma_addr + ctx->pic_info.fb_size[0]; >> + config_decode_canvas(hw, buf_spec_l1, h264_ctx->mb_width, >> +      h264_ctx->mb_height); >> + if (h264_ctx->canvas_pos_poc[buf_spec_l1->canvas_pos] == INVALID_POC) >> + h264_ctx->canvas_pos_poc[buf_spec_l1->canvas_pos] = >> + buf_spec_l1->dpb->top_field_order_cnt; >> + dev_dbg >> +     (&ctx->dev->plat_dev->dev, >> +      "config canvas for poc %d canvas %d y_dma_addr 0x%llx\n", >> +      buf_spec_l1->dpb->top_field_order_cnt, >> +      buf_spec_l1->canvas_pos, buf_spec_l1->y_dma_addr); >> + } else if (buf_spec_l0 && buf_spec_l1) { >> + memcpy(buf_spec_l1, buf_spec_l0, sizeof(struct h264_decode_buf_spec)); >> + dev_dbg >> + (&ctx->dev->plat_dev->dev, >> + "config canvas for poc %d canvas %d y_dma_addr 0x%llx\n", >> + buf_spec_l1->dpb->top_field_order_cnt, >> + buf_spec_l1->canvas_pos, buf_spec_l1->y_dma_addr); >> + } >> + } >> + >> + h264_reorder_reflists(h264_ctx); >> +} >> + >> +static int h264_config_decode_buf(struct aml_vdec_hw *hw, struct aml_vdec_ctx *ctx) >> +{ >> + struct aml_h264_ctx *h264_ctx = (struct aml_h264_ctx *)hw->curr_ctx; >> + struct vdec_h264_stateless_ctrl_ref *ctrls = &h264_ctx->ctrl_ref; >> + struct v4l2_ctrl_h264_decode_params *decode = >> + (struct v4l2_ctrl_h264_decode_params *)ctrls->decode; >> + unsigned int canvas_adr; >> + unsigned int ref_cfg; >> + unsigned int ref_cfg_once = 0; >> + struct slice *curr_slice = &h264_ctx->mslice; >> + unsigned int type_cfg = 0x3; /* 0x3: frame type */ >> + unsigned int colocate_adr_offset = 0; >> + unsigned int colocate_wr_adr; >> + unsigned int info0; >> + unsigned int info1; >> + unsigned int info2; >> + int i, j; >> + int h264_buffer_info_data_write_count; >> + u8 canvas_pos; >> + u8 use_mode_8x8_flag; >> + u32 reg_val; >> + >> + regmap_write(hw->map[DOS_BUS], H264_CURRENT_POC_IDX_RESET, 0); >> + regmap_write(hw->map[DOS_BUS], H264_CURRENT_POC, decode->top_field_order_cnt); >> + regmap_write(hw->map[DOS_BUS], H264_CURRENT_POC, decode->top_field_order_cnt); >> + regmap_write(hw->map[DOS_BUS], H264_CURRENT_POC, decode->bottom_field_order_cnt); >> + regmap_write(hw->map[DOS_BUS], CURR_CANVAS_CTRL, h264_ctx->curr_spec.canvas_pos << 24); >> + regmap_read(hw->map[DOS_BUS], CURR_CANVAS_CTRL, &canvas_adr); >> + canvas_adr &= 0xffffff; >> + dev_dbg(hw->dev, "canvas_pos = %d canvas_adr 0x%x\n", >> + h264_ctx->curr_spec.canvas_pos, canvas_adr); >> + >> + regmap_write(hw->map[DOS_BUS], REC_CANVAS_ADDR, canvas_adr); >> + regmap_write(hw->map[DOS_BUS], DBKR_CANVAS_ADDR, canvas_adr); >> + regmap_write(hw->map[DOS_BUS], DBKW_CANVAS_ADDR, canvas_adr); >> + >> + regmap_write(hw->map[DOS_BUS], H264_BUFFER_INFO_INDEX, 16); >> + info0 = 0xf480; >> + info1 = decode->top_field_order_cnt; >> + info2 = decode->bottom_field_order_cnt; >> + if (decode->bottom_field_order_cnt < decode->top_field_order_cnt) >> + info0 |= 0x100; >> + >> + regmap_write(hw->map[DOS_BUS], H264_BUFFER_INFO_DATA, info0 | 0xf); >> + regmap_write(hw->map[DOS_BUS], H264_BUFFER_INFO_DATA, info1); >> + regmap_write(hw->map[DOS_BUS], H264_BUFFER_INFO_DATA, info2); >> + >> + for (j = 0; j < V4L2_H264_NUM_DPB_ENTRIES; j++) { >> + struct v4l2_h264_dpb_entry *dpb = &decode->dpb[j]; >> + >> + info0 = 0; >> + info1 = 0; >> + info2 = 0; >> + if (dpb->flags & V4L2_H264_DPB_ENTRY_FLAG_ACTIVE) { >> + info0 = 0xf480; >> + if (dpb->bottom_field_order_cnt < dpb->top_field_order_cnt) >> + info0 |= 0x100; >> + info1 = dpb->top_field_order_cnt; >> + info2 = dpb->bottom_field_order_cnt; >> + if (dpb->flags & V4L2_H264_DPB_ENTRY_FLAG_LONG_TERM) >> + info0 |= ((1 << 5) | (1 << 4)); >> + } >> + regmap_write(hw->map[DOS_BUS], H264_BUFFER_INFO_DATA, info0); >> + regmap_write(hw->map[DOS_BUS], H264_BUFFER_INFO_DATA, info1); >> + regmap_write(hw->map[DOS_BUS], H264_BUFFER_INFO_DATA, info2); >> + } >> + >> + regmap_write(hw->map[DOS_BUS], H264_BUFFER_INFO_INDEX, 0); >> + /* when frame width <= 256, Disable DDR_BYTE64_CACHE */ >> + if (ctx->pic_info.coded_width <= 256) { >> + regmap_update_bits(hw->map[DOS_BUS], IQIDCT_CONTROL, (1 << 16), (1 << 16)); >> + regmap_write(hw->map[DOS_BUS], DCAC_DDR_BYTE64_CTL, >> +      (read_dos_reg(hw, DCAC_DDR_BYTE64_CTL) & (~0xf)) | 0xa); >> + } else { >> + regmap_update_bits(hw->map[DOS_BUS], IQIDCT_CONTROL, (1 << 16), 0); >> + regmap_write(hw->map[DOS_BUS], DCAC_DDR_BYTE64_CTL, >> +      (read_dos_reg(hw, DCAC_DDR_BYTE64_CTL) & (~0xf))); >> + } >> + >> + ref_cfg = 0; >> + j = 0; >> + >> + if (h264_ctx->list_size[0] > 0) { >> + for (i = 0; i < h264_ctx->list_size[0]; i++) { >> + canvas_pos = h264_ctx->ref_list0[i].canvas_pos; >> + /* bit 0:3 canvas_pos bit 5:6 frame struct cfg */ >> + ref_cfg_once = (canvas_pos & 0x1f) | (type_cfg << 5); >> + ref_cfg <<= 8; >> + ref_cfg |= ref_cfg_once; >> + j++; >> + >> + if (j == 4) { >> + regmap_write(hw->map[DOS_BUS], H264_BUFFER_INFO_DATA, ref_cfg); >> + dev_dbg(hw->dev, "H264_BUFFER_INFO_DATA: %x\n", ref_cfg); >> + h264_buffer_info_data_write_count++; >> + j = 0; >> + } >> + } >> + >> + if (j != 0) { >> + while (j != 4) { >> + ref_cfg <<= 8; >> + ref_cfg |= ref_cfg_once; >> + j++; >> + } >> + regmap_write(hw->map[DOS_BUS], H264_BUFFER_INFO_DATA, ref_cfg); >> + dev_dbg(hw->dev, "H264_BUFFER_INFO_DATA: %x\n", ref_cfg); >> + h264_buffer_info_data_write_count++; >> + } >> + ref_cfg = (ref_cfg_once << 24) | (ref_cfg_once << 16) | >> + (ref_cfg_once << 8) | ref_cfg_once; >> + for (j = h264_buffer_info_data_write_count; j < 8; j++) >> + regmap_write(hw->map[DOS_BUS], H264_BUFFER_INFO_DATA, ref_cfg); >> + } >> + >> + regmap_write(hw->map[DOS_BUS], H264_BUFFER_INFO_INDEX, 8); >> + j = 0; >> + ref_cfg = 0; >> + >> + if (h264_ctx->list_size[1] > 0) { >> + for (i = 0; i < h264_ctx->list_size[1]; i++) { >> + canvas_pos = h264_ctx->ref_list1[i].canvas_pos; >> + ref_cfg_once = (canvas_pos & 0x1f) | (type_cfg << 5); >> + ref_cfg <<= 8; >> + ref_cfg |= ref_cfg_once; >> + j++; >> + >> + if (j == 4) { >> + regmap_write(hw->map[DOS_BUS], H264_BUFFER_INFO_DATA, ref_cfg); >> + dev_dbg(hw->dev, "H264_BUFFER_INFO_DATA: %x\n", ref_cfg); >> + j = 0; >> + } >> + } >> + } >> + >> + if (j != 0) { >> + while (j != 4) { >> + ref_cfg <<= 8; >> + ref_cfg |= ref_cfg_once; >> + j++; >> + } >> + dev_dbg(hw->dev, "H264_BUFFER_INFO_DATA: %x\n", ref_cfg); >> + regmap_write(hw->map[DOS_BUS], H264_BUFFER_INFO_DATA, ref_cfg); >> + } >> + >> + if (get_flag(ctrls->sps->flags, V4L2_H264_SPS_FLAG_FRAME_MBS_ONLY) && >> +     get_flag(ctrls->sps->flags, V4L2_H264_SPS_FLAG_DIRECT_8X8_INFERENCE)) >> + use_mode_8x8_flag = 1; >> + else >> + use_mode_8x8_flag = 0; >> + >> + read_poll_timeout(read_dos_reg, reg_val, >> +   !(reg_val & 0x800), >> +   10, 0, true, >> +   hw, H264_CO_MB_RW_CTL); >> + >> + /* col buf for curr frame */ >> + colocate_adr_offset = COL_SIZE_FOR_ONE_MB; >> + if (use_mode_8x8_flag) >> + colocate_adr_offset >>= 2; >> + colocate_adr_offset *= curr_slice->first_mb_in_slice; >> + >> + if (h264_ctx->curr_spec.col_buf_index >= 0 && >> +     h264_ctx->curr_spec.col_buf_index < h264_ctx->colocated_buf_num) { >> + colocate_wr_adr = h264_ctx->collated_cma_addr + >> + ((h264_ctx->one_col_buf_size * h264_ctx->curr_spec.col_buf_index) >> >> + (use_mode_8x8_flag ? 2 : 0)); >> + if (colocate_adr_offset > h264_ctx->one_col_buf_size || >> +     colocate_wr_adr + h264_ctx->one_col_buf_size > >> +     h264_ctx->collated_cma_addr_end) { >> + dev_err >> +     (hw->dev, "Error, colocate buf is not enough, index is %d\n", >> +      h264_ctx->curr_spec.col_buf_index); >> + return -1; >> + } >> + regmap_write(hw->map[DOS_BUS], H264_CO_MB_WR_ADDR, >> +      (colocate_wr_adr + colocate_adr_offset)); >> + dev_dbg(hw->dev, "col buffer addr = 0x%x col_buf_index %d\n", >> + (colocate_wr_adr + colocate_adr_offset), >> + h264_ctx->curr_spec.col_buf_index); >> + } else { >> + regmap_write(hw->map[DOS_BUS], H264_CO_MB_WR_ADDR, 0xffffffff); >> + dev_dbg(hw->dev, "col buffer addr = 0xffffffff\n"); >> + } >> + >> + if (h264_ctx->list_size[1] > 0) { >> + struct h264_decode_buf_spec *colocate_pic = &h264_ctx->ref_list1[0]; >> + struct h264_decode_buf_spec *curr_pic = &h264_ctx->curr_spec; >> + int l10_structure = 2; /* for pic struct == FRAME, default to 2 */ >> + int cur_colocate_ref_type; >> + unsigned int colocate_rd_adr; >> + unsigned int colocate_rd_adr_offset = 0; >> + unsigned int val; >> + >> + cur_colocate_ref_type = >> + (abs(curr_pic->poc - colocate_pic->dpb->top_field_order_cnt) < >> + abs(curr_pic->poc - colocate_pic->dpb->bottom_field_order_cnt)) ? >> + 0 : 1; >> + colocate_rd_adr_offset = COL_SIZE_FOR_ONE_MB; >> + if (use_mode_8x8_flag) >> + colocate_rd_adr_offset >>= 2; >> + >> + colocate_rd_adr_offset *= curr_slice->first_mb_in_slice; >> + if (colocate_pic->col_buf_index >= 0 && >> +     colocate_pic->col_buf_index < h264_ctx->colocated_buf_num) { >> + colocate_rd_adr = h264_ctx->collated_cma_addr + >> + ((h264_ctx->one_col_buf_size * colocate_pic->col_buf_index) >> >> + (use_mode_8x8_flag ? 2 : 0)); >> + if (colocate_rd_adr + h264_ctx->one_col_buf_size > >> +     h264_ctx->collated_cma_addr_end) { >> + dev_err >> +     (hw->dev, "Error, colocate rd buf is not enough, index is %d\n", >> +      colocate_pic->col_buf_index); >> + return -1; >> + } >> + val  = ((colocate_rd_adr_offset + colocate_rd_adr) >> 3) | >> + (cur_colocate_ref_type << 29) | >> + (l10_structure << 30); >> + regmap_write(hw->map[DOS_BUS], H264_CO_MB_RD_ADDR, val); >> + } else { >> + dev_err >> +     (hw->dev, "Error, reference pic has no colocated buf poc %d\n", >> +      curr_pic->poc); >> + return -1; >> + } >> + } >> + >> + return 0; >> +} >> + >> +static void release_canvas_index(struct aml_vdec_hw *hw, >> + struct h264_decode_buf_spec *buf) >> +{ >> + struct aml_h264_ctx *h264_ctx = (struct aml_h264_ctx *)hw->curr_ctx; >> + >> + if (h264_ctx->canvas_pos_poc[buf->canvas_pos] == INVALID_POC) >> + return; >> + >> + if (buf->y_canvas_index >= 0) { >> + meson_canvas_free(hw->canvas, buf->y_canvas_index); >> + buf->y_canvas_index = -1; >> + } >> + >> + if (buf->u_canvas_index >= 0) { >> + meson_canvas_free(hw->canvas, buf->u_canvas_index); >> + buf->u_canvas_index = -1; >> + buf->v_canvas_index = -1; >> + } >> + h264_ctx->canvas_pos_poc[buf->canvas_pos] = INVALID_POC; >> +} >> + >> +static void h264_release_decode_spec(struct aml_vdec_hw *hw, struct aml_vdec_ctx *ctx) >> +{ >> + struct aml_h264_ctx *h264_ctx = (struct aml_h264_ctx *)hw->curr_ctx; >> + int i; >> + struct h264_decode_buf_spec *buf; >> + >> + release_canvas_index(hw, &h264_ctx->curr_spec); >> + >> + if (h264_ctx->list_size[0] > 0) { >> + for (i = 0; i < h264_ctx->list_size[0]; i++) { >> + buf = &h264_ctx->ref_list0[i]; >> + if (buf->used) { >> + buf->dpb = NULL; >> + release_canvas_index(hw, buf); >> + buf->used = 0; >> + } >> + } >> + h264_ctx->list_size[0] = 0; >> + } >> + >> + if (h264_ctx->list_size[1] > 0) { >> + for (i = 0; i < h264_ctx->list_size[1]; i++) { >> + buf = &h264_ctx->ref_list1[i]; >> + if (buf->used) { >> + buf->dpb = NULL; >> + release_canvas_index(hw, buf); >> + buf->used = 0; >> + } >> + } >> + h264_ctx->list_size[1] = 0; >> + } >> +} >> + >> +static void save_reg_status(struct aml_h264_ctx *h264_ctx) >> +{ >> + struct aml_vdec_ctx *ctx = h264_ctx->v4l2_ctx; >> + struct aml_vdec_hw *hw = vdec_get_hw(ctx->dev); >> + >> + regmap_read(hw->map[DOS_BUS], IQIDCT_CONTROL, &h264_ctx->reg_iqidct_control); >> + h264_ctx->reg_iqidct_control_init_flag = 1; >> + regmap_read(hw->map[DOS_BUS], VCOP_CTRL_REG, &h264_ctx->reg_vcop_ctrl_reg); >> + regmap_read(hw->map[DOS_BUS], RV_AI_MB_COUNT, &h264_ctx->reg_rv_ai_mb_count); >> + regmap_read(hw->map[DOS_BUS], VLD_DECODE_CONTROL, &h264_ctx->vld_dec_control); >> +} >> + >> +static void h264_get_slice_params(struct aml_h264_ctx *h264_ctx) >> +{ >> + struct slice *curr_slice = &h264_ctx->mslice; >> + >> + memset(curr_slice, 0, sizeof(struct slice)); >> + /* parsed by ucode */ >> + curr_slice->slice_type = h264_ctx->dpb_param.l.data[SLICE_TYPE]; >> + curr_slice->first_mb_in_slice = h264_ctx->dpb_param.l.data[FIRST_MB_IN_SLICE]; >> + curr_slice->num_ref_idx_l0 = h264_ctx->dpb_param.dpb.num_ref_idx_l0_active_minus1 + 1; >> + curr_slice->num_ref_idx_l1 = h264_ctx->dpb_param.dpb.num_ref_idx_l1_active_minus1 + 1; >> + curr_slice->frame_num = h264_ctx->ctrl_ref.decode->frame_num; >> +} >> + >> +static irqreturn_t h264_isr(int irq, void *priv) >> +{ >> + struct aml_vdec_dev *dev = (struct aml_vdec_dev *)priv; >> + >> + regmap_write(dev->dec_hw->map[DOS_BUS], VDEC_ASSIST_MBOX1_CLR_REG, 1); >> + >> + return IRQ_WAKE_THREAD; >> +} >> + >> +static irqreturn_t h264_threaded_isr_func(int irq, void *priv) >> +{ >> + u32 dec_status; >> + struct aml_vdec_dev *dev = (struct aml_vdec_dev *)priv; >> + struct aml_h264_ctx *h264_ctx = (struct aml_h264_ctx *)dev->dec_hw->curr_ctx; >> + struct aml_vdec_ctx *ctx = (struct aml_vdec_ctx *)dev->dec_ctx; >> + struct aml_vdec_hw *hw = vdec_get_hw(ctx->dev); >> + unsigned short *p = (unsigned short *)h264_ctx->lmem_addr; >> + int i, ii; >> + >> + regmap_read(hw->map[DOS_BUS], DPB_STATUS_REG, &dec_status); >> + h264_ctx->dec_status = dec_status; >> + dev_dbg >> +     (&dev->plat_dev->dev, >> + "%s, dec_status 0x%x VIFF_BIT_CNT 0x%x MBY_MBX 0x%x VLD_SHIFT_STATUS 0x%x\n", >> +     __func__, dec_status, read_dos_reg(hw, VIFF_BIT_CNT), read_dos_reg(hw, MBY_MBX), >> +     read_dos_reg(hw, VLD_SHIFT_STATUS)); >> + >> + regmap_read(hw->map[DOS_BUS], DPB_STATUS_REG, &h264_ctx->save_avscratch_f); >> + >> + switch (dec_status) { >> + case H264_SLICE_HEADER_DONE: >> + for (i = 0; i < 0x400; i += 4) >> + for (ii = 0; ii < 4; ii++) >> + h264_ctx->dpb_param.l.data[i + ii] = p[i + 3 - ii]; >> + save_reg_status(h264_ctx); >> + h264_get_slice_params(h264_ctx); >> + if (h264_ctx->new_pic_flag == 1) >> + h264_config_decode_spec(hw, ctx); >> + >> + if (h264_config_decode_buf(hw, ctx) < 0) { >> + h264_release_decode_spec(hw, ctx); >> + ctx->int_cond = 1; >> + wake_up_interruptible(&ctx->queue); >> + goto irq_handled; >> + } >> + if (h264_ctx->new_pic_flag == 1) { >> + regmap_write(hw->map[DOS_BUS], DPB_STATUS_REG, H264_ACTION_DECODE_NEWPIC); >> + dev_dbg(&dev->plat_dev->dev, "action decode new pic\n"); >> + h264_ctx->new_pic_flag = 0; >> + } else { >> + regmap_write(hw->map[DOS_BUS], DPB_STATUS_REG, H264_ACTION_DECODE_SLICE); >> + dev_dbg(&dev->plat_dev->dev, "action decode new slice\n"); >> + } >> + break; >> + case H264_SLICE_DATA_DONE: >> + h264_release_decode_spec(hw, ctx); >> + h264_ctx->decode_pic_count++; >> + ctx->int_cond = 1; >> + wake_up_interruptible(&ctx->queue); >> + break; >> + default: >> + h264_release_decode_spec(hw, ctx); >> + ctx->int_cond = 1; >> + wake_up_interruptible(&ctx->queue); >> + break; >> + } >> +irq_handled: >> + return IRQ_HANDLED; >> +} >> + >> +static int h264_restore_hw_ctx(struct aml_vdec_ctx *ctx) >> +{ >> + struct aml_h264_ctx *h264_ctx = >> + (struct aml_h264_ctx *)ctx->codec_priv; >> + struct aml_vdec_hw *hw = vdec_get_hw(ctx->dev); >> + int i; >> + >> + regmap_write(hw->map[DOS_BUS], POWER_CTL_VLD, >> +      (read_dos_reg(hw, POWER_CTL_VLD) >> +      | (0 << 10) | (1 << 9) | (1 << 6))); >> + >> + regmap_write(hw->map[DOS_BUS], PSCALE_CTRL, 0); >> + >> + /* clear mailbox interrupt */ >> + regmap_write(hw->map[DOS_BUS], VDEC_ASSIST_MBOX1_CLR_REG, 1); >> + >> + /* enable mailbox interrupt */ >> + regmap_write(hw->map[DOS_BUS], VDEC_ASSIST_MBOX1_MASK, 1); >> + >> + regmap_update_bits(hw->map[DOS_BUS], MDEC_PIC_DC_CTRL, (1 << 17), (1 << 17)); >> + if (ctx->q_data[AML_Q_DATA_DST].fmt->fourcc == V4L2_PIX_FMT_NV21 || >> +     ctx->q_data[AML_Q_DATA_DST].fmt->fourcc == V4L2_PIX_FMT_NV21M) >> + regmap_update_bits(hw->map[DOS_BUS], MDEC_PIC_DC_CTRL, >> +    (1 << 16), (1 << 16)); >> + else >> + regmap_update_bits(hw->map[DOS_BUS], MDEC_PIC_DC_CTRL, (1 << 16), 0); >> + >> + regmap_update_bits(hw->map[DOS_BUS], MDEC_PIC_DC_CTRL, >> +    (0xbf << 24), (0xbf << 24)); >> + regmap_update_bits(hw->map[DOS_BUS], MDEC_PIC_DC_CTRL, (0xbf << 24), 0); >> + regmap_update_bits(hw->map[DOS_BUS], MDEC_PIC_DC_CTRL, (1 << 31), 0); >> + >> + regmap_update_bits(hw->map[DOS_BUS], MDEC_PIC_DC_MUX_CTRL, (1 << 31), 0); >> + regmap_write(hw->map[DOS_BUS], MDEC_EXTIF_CFG1, 0); >> + regmap_write(hw->map[DOS_BUS], MDEC_PIC_DC_THRESH, 0x404038aa); >> + >> + regmap_write(hw->map[DOS_BUS], DPB_STATUS_REG, 0); >> + >> + regmap_write(hw->map[DOS_BUS], LMEM_DUMP_ADR, h264_ctx->lmem_phy_addr); >> + regmap_write(hw->map[DOS_BUS], FRAME_COUNTER_REG, h264_ctx->decode_pic_count); >> + regmap_write(hw->map[DOS_BUS], AV_SCRATCH_8, h264_ctx->workspace_offset); >> + regmap_write(hw->map[DOS_BUS], AV_SCRATCH_G, h264_ctx->mc_cpu_paddr); >> + >> + regmap_write(hw->map[DOS_BUS], AV_SCRATCH_F, >> +      ((h264_ctx->save_avscratch_f & 0xffffffc3) | (1 << 4))); >> + regmap_update_bits(hw->map[DOS_BUS], AV_SCRATCH_F, (1 << 6), 0); >> + >> + regmap_write(hw->map[DOS_BUS], MDEC_PIC_DC_THRESH, 0x404038aa); >> + >> + if (h264_ctx->reg_iqidct_control_init_flag == 0) >> + regmap_write(hw->map[DOS_BUS], IQIDCT_CONTROL, 0x200); >> + >> + if (h264_ctx->reg_iqidct_control) >> + regmap_write(hw->map[DOS_BUS], IQIDCT_CONTROL, h264_ctx->reg_iqidct_control); >> + >> + if (h264_ctx->reg_vcop_ctrl_reg) >> + regmap_write(hw->map[DOS_BUS], VCOP_CTRL_REG, h264_ctx->reg_vcop_ctrl_reg); >> + >> + if (h264_ctx->vld_dec_control) >> + regmap_write(hw->map[DOS_BUS], VLD_DECODE_CONTROL, h264_ctx->vld_dec_control); >> + >> + dev_dbg >> +     (hw->dev, >> +      "IQIDCT_CONTROL = 0x%x, VCOP_CTRL_REG 0x%x VLD_DECODE_CONTROL 0x%x\n", >> +      read_dos_reg(hw, IQIDCT_CONTROL), read_dos_reg(hw, VCOP_CTRL_REG), >> +      read_dos_reg(hw, VLD_DECODE_CONTROL)); >> + >> + for (i = 0; i < H264_MAX_CANVAS_POS; i++) >> + h264_ctx->canvas_pos_poc[i] = INVALID_POC; >> + >> + return 0; >> +} >> + >> +static void *aml_h264_get_ctrl(struct v4l2_ctrl_handler *hdl, u32 id) >> +{ >> + struct v4l2_ctrl *ctrl; >> + >> + ctrl = v4l2_ctrl_find(hdl, id); >> + return ctrl ? ctrl->p_cur.p : NULL; >> +} >> + >> +static int aml_h264_get_stateless_ctrl_ref(struct aml_h264_ctx *h264_ctx) >> +{ >> + struct aml_vdec_ctx *ctx = h264_ctx->v4l2_ctx; >> + struct vdec_h264_stateless_ctrl_ref *ctrls = &h264_ctx->ctrl_ref; >> + >> + ctrls->sps = >> + (struct v4l2_ctrl_h264_sps *)aml_h264_get_ctrl(&ctx->ctrl_handler, >> + V4L2_CID_STATELESS_H264_SPS); >> + if (WARN_ON(!ctrls->sps)) >> + return -EINVAL; >> + >> + ctrls->pps = >> + (struct v4l2_ctrl_h264_pps *)aml_h264_get_ctrl(&ctx->ctrl_handler, >> + V4L2_CID_STATELESS_H264_PPS); >> + if (WARN_ON(!ctrls->pps)) >> + return -EINVAL; >> + >> + ctrls->decode = >> + (struct v4l2_ctrl_h264_decode_params *)aml_h264_get_ctrl(&ctx->ctrl_handler, >> + V4L2_CID_STATELESS_H264_DECODE_PARAMS); >> + if (WARN_ON(!ctrls->decode)) >> + return -EINVAL; >> + >> + ctrls->scaling = >> + (struct v4l2_ctrl_h264_scaling_matrix *)aml_h264_get_ctrl(&ctx->ctrl_handler, >> + V4L2_CID_STATELESS_H264_SCALING_MATRIX); >> + if (WARN_ON(!ctrls->scaling)) >> + return -EINVAL; >> + >> + return 0; >> +} >> + >> +static void copy_mc_cpu_fw(void *mc_cpu_addr, const u8 *data) >> +{ >> + /*header */ >> + memcpy((u8 *)mc_cpu_addr + MC_OFFSET_HEADER, >> +        data + 0x4000, MC_SWAP_SIZE); >> + /*data */ >> + memcpy((u8 *)mc_cpu_addr + MC_OFFSET_DATA, >> +        data + 0x2000, MC_SWAP_SIZE); >> + /*mmco */ >> + memcpy((u8 *)mc_cpu_addr + MC_OFFSET_MMCO, >> +        data + 0x6000, MC_SWAP_SIZE); >> + /*list */ >> + memcpy((u8 *)mc_cpu_addr + MC_OFFSET_LIST, >> +        data + 0x3000, MC_SWAP_SIZE); >> + /*slice */ >> + memcpy((u8 *)mc_cpu_addr + MC_OFFSET_SLICE, >> +        data + 0x5000, MC_SWAP_SIZE); >> + /*main */ >> + memcpy((u8 *)mc_cpu_addr + MC_OFFSET_MAIN, data, 0x2000); >> + /*data */ >> + memcpy((u8 *)mc_cpu_addr + MC_OFFSET_MAIN + 0x2000, >> +        data + 0x2000, 0x1000); >> + /*slice */ >> + memcpy((u8 *)mc_cpu_addr + MC_OFFSET_MAIN + 0x3000, >> +        data + 0x5000, 0x1000); >> +} >> + >> +static int aml_h264_load_fw_ext(void *priv, const u8 *data, u32 len) >> +{ >> + struct aml_h264_ctx *h264_ctx = (struct aml_h264_ctx *)priv; >> + struct aml_vdec_ctx *ctx = (struct aml_vdec_ctx *)h264_ctx->v4l2_ctx; >> + struct aml_vdec_hw *dec_hw; >> + >> + if (h264_ctx->mc_cpu_loaded) >> + return 0; >> + >> + dec_hw = vdec_get_hw(ctx->dev); >> + if (!dec_hw) >> + return -1; >> + >> + if (len > MC_TOTAL_SIZE) { >> + dev_info(dec_hw->dev, "size of mc_cpu_fw id invalid\n"); >> + return -1; >> + } >> + >> + h264_ctx->mc_cpu_vaddr = dma_alloc_coherent(dec_hw->dev, MC_TOTAL_SIZE, >> +     &h264_ctx->mc_cpu_paddr, >> +     GFP_KERNEL); >> + if (!h264_ctx->mc_cpu_vaddr) >> + return -ENOMEM; >> + >> + copy_mc_cpu_fw(h264_ctx->mc_cpu_vaddr, data); >> + >> + h264_ctx->mc_cpu_loaded = true; >> + >> + dev_dbg(dec_hw->dev, "h264 mccpu fw loaded\n"); >> + >> + return 0; >> +} >> + >> +int aml_h264_init(void *priv) >> +{ >> + struct aml_vdec_ctx *ctx = (struct aml_vdec_ctx *)priv; >> + struct aml_vdec_hw *dec_hw; >> + struct aml_h264_ctx *h264_ctx; >> + int ret = 0; >> + >> + h264_ctx = kzalloc(sizeof(*h264_ctx), GFP_KERNEL); >> + if (!h264_ctx) >> + return -ENOMEM; >> + >> + h264_ctx->v4l2_ctx = ctx; >> + dec_hw = vdec_get_hw(ctx->dev); >> + if (!dec_hw) >> + return -1; >> + >> + h264_ctx->mc_cpu_loaded = false; >> + dec_hw->hw_ops.irq_handler = h264_isr; >> + dec_hw->hw_ops.irq_threaded_func = h264_threaded_isr_func; >> + dec_hw->hw_ops.load_firmware_ex = aml_h264_load_fw_ext; >> + >> + h264_ctx->lmem_addr = dma_alloc_coherent(dec_hw->dev, LMEM_DUMP_SIZE, >> + &h264_ctx->lmem_phy_addr, >> + GFP_KERNEL); >> + if (!h264_ctx->lmem_addr) { >> + ret = -ENOMEM; >> + goto err_alloc_lmem; >> + } >> + >> + h264_ctx->cma_alloc_vaddr = >> +     dma_alloc_coherent(dec_hw->dev, V_BUF_ADDR_OFFSET, >> +        &h264_ctx->cma_alloc_addr, GFP_KERNEL); >> + if (!h264_ctx->cma_alloc_vaddr) { >> + ret = -ENOMEM; >> + goto err_alloc_workspace; >> + } >> + >> + h264_ctx->workspace_offset = h264_ctx->cma_alloc_addr + DCAC_READ_MARGIN; >> + h264_ctx->workspace_vaddr = h264_ctx->cma_alloc_vaddr + DCAC_READ_MARGIN; >> + >> + ctx->codec_priv = h264_ctx; >> + dec_hw->curr_ctx = h264_ctx; >> + h264_ctx->col_buf_alloc_size = 0; >> + h264_ctx->init_flag = 0; >> + h264_ctx->new_pic_flag = 0; >> + h264_ctx->param_set = 0; >> + h264_ctx->reg_iqidct_control_init_flag = 0; >> + h264_ctx->decode_pic_count = 0; >> + >> + return 0; >> + >> +err_alloc_workspace: >> + dma_free_coherent(dec_hw->dev, LMEM_DUMP_SIZE, >> +   h264_ctx->lmem_addr, h264_ctx->lmem_phy_addr); >> +err_alloc_lmem: >> + kfree(h264_ctx); >> + >> + return ret; >> +} >> + >> +void aml_h264_exit(void *priv) >> +{ >> + struct aml_vdec_ctx *ctx = (struct aml_vdec_ctx *)priv; >> + struct aml_h264_ctx *h264_ctx = (struct aml_h264_ctx *)ctx->codec_priv; >> + struct aml_vdec_hw *dec_hw; >> + >> + if (!h264_ctx) { >> + dev_info(&ctx->dev->plat_dev->dev, "h264 decoder is already destroyed or not created!\n"); >> + return; >> + } >> + dec_hw = vdec_get_hw(ctx->dev); >> + h264_ctx->param_set = 0; >> + >> + if (ctx->dos_clk_en) >> + aml_stop_vdec_hw(dec_hw); >> + >> + if (h264_ctx->collated_cma_vaddr) { >> + dma_free_coherent(dec_hw->dev, h264_ctx->col_buf_alloc_size, >> +   h264_ctx->collated_cma_vaddr, >> +   h264_ctx->collated_cma_addr); >> + h264_ctx->col_buf_alloc_size = 0; >> + } >> + >> + if (h264_ctx->mc_cpu_vaddr) { >> + dma_free_coherent(dec_hw->dev, MC_TOTAL_SIZE, >> +   h264_ctx->mc_cpu_vaddr, >> +   h264_ctx->mc_cpu_paddr); >> + h264_ctx->mc_cpu_loaded = false; >> + } >> + >> + if (h264_ctx->lmem_addr) >> + dma_free_coherent(dec_hw->dev, LMEM_DUMP_SIZE, >> +   h264_ctx->lmem_addr, h264_ctx->lmem_phy_addr); >> + >> + if (h264_ctx->cma_alloc_vaddr) >> + dma_free_coherent(dec_hw->dev, V_BUF_ADDR_OFFSET, >> +   h264_ctx->cma_alloc_vaddr, >> +   h264_ctx->cma_alloc_addr); >> + >> + kfree(ctx->codec_priv); >> + dec_hw->curr_ctx = NULL; >> + ctx->codec_priv = NULL; >> +} >> + >> +static void config_decode_mode(struct aml_vdec_ctx *ctx) >> +{ >> + struct aml_h264_ctx *h264_ctx = (struct aml_h264_ctx *)ctx->codec_priv; >> + struct aml_vdec_hw *hw = vdec_get_hw(ctx->dev); >> + >> + regmap_write(hw->map[DOS_BUS], H264_DECODE_MODE, 0x1); /*decode mode framebase*/ >> + regmap_write(hw->map[DOS_BUS], HEAD_PADDING_REG, 0); >> + regmap_write(hw->map[DOS_BUS], H264_DECODE_SEQINFO, h264_ctx->seq_info); >> + regmap_write(hw->map[DOS_BUS], INIT_FLAG_REG, 1); >> +} >> + >> +int aml_h264_dec_run(void *priv) >> +{ >> + struct aml_vdec_ctx *ctx = (struct aml_vdec_ctx *)priv; >> + struct aml_h264_ctx *h264_ctx = (struct aml_h264_ctx *)ctx->codec_priv; >> + struct aml_vdec_hw *dec_hw = vdec_get_hw(ctx->dev); >> + int ret = -1; >> + int i; >> + >> + ret = aml_h264_get_stateless_ctrl_ref(h264_ctx); >> + if (ret < 0) { >> + dev_err(&ctx->dev->plat_dev->dev, "not ctrl ref for h264 decoder\n"); >> + return ret; >> + } >> + >> + h264_config_params(ctx); >> + >> + if (h264_prepare_input(ctx) < 0) >> + return ret; >> + >> + if (alloc_colocate_cma(h264_ctx, ctx) < 0) >> + return ret; >> + >> + h264_restore_hw_ctx(ctx); >> + >> + config_decode_mode(ctx); >> + /* enable stream input hardware */ >> + regmap_update_bits(dec_hw->map[DOS_BUS], VLD_MEM_VIFIFO_CONTROL, 0x6, 0x6); >> + /* enable hardware timer */ >> + regmap_write(dec_hw->map[DOS_BUS], NAL_SEARCH_CTL, >> +      read_dos_reg(dec_hw, NAL_SEARCH_CTL) | (1 << 16)); >> + regmap_write(dec_hw->map[DOS_BUS], MDEC_EXTIF_CFG2, >> +      read_dos_reg(dec_hw, MDEC_EXTIF_CFG2) | 0x20); >> + regmap_write(dec_hw->map[DOS_BUS], NAL_SEARCH_CTL, >> +      read_dos_reg(dec_hw, NAL_SEARCH_CTL) & (~0x2)); >> + regmap_update_bits(dec_hw->map[DOS_BUS], VDEC_ASSIST_MMC_CTRL1, >> +    (1 << 3), 0); >> + >> + aml_start_vdec_hw(dec_hw); >> + h264_ctx->init_flag = 1; >> + h264_ctx->new_pic_flag = 1; >> + >> + regmap_write(dec_hw->map[DOS_BUS], DPB_STATUS_REG, H264_ACTION_SEARCH_HEAD); >> + >> + ret = wait_event_interruptible_timeout(ctx->queue, ctx->int_cond, >> +        msecs_to_jiffies(DECODER_TIMEOUT_MS)); >> + ctx->int_cond = 0; >> + if (!ret) { >> + ret = -1; >> + dev_err(&ctx->dev->plat_dev->dev, "dec timeout=%u\n", DECODER_TIMEOUT_MS); >> + for (i = 0; i < 16; i++) { /* 16 : show ucode PC 16 times when timeout */ >> + dev_info(&ctx->dev->plat_dev->dev, "decoder timeout, pc 0x%x\n", >> + read_dos_reg(dec_hw, MPC_E)); >> + usleep_range(10, 20); >> + } >> + } else if (-ERESTARTSYS == ret) { >> + ret = -1; >> + dev_err(&ctx->dev->plat_dev->dev, "dec inter fail\n"); >> + } >> + >> + aml_stop_vdec_hw(dec_hw); >> + h264_ctx->init_flag = 0; >> + >> + return ret; >> +} >> diff --git a/drivers/media/platform/amlogic/vdec/h264.h b/drivers/media/platform/amlogic/vdec/h264.h >> new file mode 100644 >> index 000000000000..3d3a35a641c9 >> --- /dev/null >> +++ b/drivers/media/platform/amlogic/vdec/h264.h >> @@ -0,0 +1,300 @@ >> +/* SPDX-License-Identifier: (GPL-2.0-only OR MIT) */ >> +/* >> + * Copyright (C) 2025 Amlogic, Inc. All rights reserved >> + */ >> +#ifndef _H264_H_ >> +#define _H264_H_ >> + >> +#define RPM_BEGIN           0x0 >> +#define FRAME_IN_DPB        24 >> +#define RPM_END             0x400 >> +#define DPB_OFFSET          0x100 >> +#define MMCO_OFFSET         0x200 >> +#define SPS_OFFSET          0x100 >> +#define PPS_OFFSET          0x300 >> +#define PARAM_BASE_VAL      0x414d >> +#define MEM_MMCO_BASE       0x01c3000 >> +#define MEM_SPS_BASE        0x01c3c00 >> +#define MEM_PPS_BASE        0x01cbc00 >> +#define MC_TOTAL_SIZE       ((20 + 16) * SZ_1K) >> +#define MC_SWAP_SIZE        (4 * SZ_1K) >> +#define LMEM_DUMP_SIZE      4096 >> +#define V_BUF_ADDR_OFFSET   (0x200000 + 0x8000 + 0x20000 + 0x1000) >> +#define DCAC_READ_MARGIN    (64 * 1024) >> +#define MC_OFFSET_HEADER    0x0000 >> +#define MC_OFFSET_DATA      0x1000 >> +#define MC_OFFSET_MMCO      0x2000 >> +#define MC_OFFSET_LIST      0x3000 >> +#define MC_OFFSET_SLICE     0x4000 >> +#define MC_OFFSET_MAIN      0x5000 >> + >> +/* Rename the dos regs */ >> +#define H264_DECODE_INFO    M4_CONTROL_REG >> +#define INIT_FLAG_REG       AV_SCRATCH_2 >> +#define HEAD_PADDING_REG     AV_SCRATCH_3 >> +#define UCODE_WATCHDOG_REG   AV_SCRATCH_7 >> +#define LMEM_DUMP_ADR       AV_SCRATCH_L >> +#define DEBUG_REG1          AV_SCRATCH_M >> +#define DEBUG_REG2          AV_SCRATCH_N >> +#define FRAME_COUNTER_REG       AV_SCRATCH_I >> +#define RPM_CMD_REG          AV_SCRATCH_A >> +#define H264_DECODE_SIZE    AV_SCRATCH_E >> +#define H264_DECODE_MODE    AV_SCRATCH_4 >> +#define H264_DECODE_SEQINFO    AV_SCRATCH_5 >> +/** >> + * NAL_SEARCH_CTL: bit 0, enable itu_t35 >> + * NAL_SEARCH_CTL: bit 1, enable mmu >> + * NAL_SEARCH_CTL: bit 2, detect frame_mbs_only_flag whether switch resolution >> + * NAL_SEARCH_CTL: bit 3, recover the correct sps pps >> + * NAL_SEARCH_CTL: bit 7-14,level_idc >> + * NAL_SEARCH_CTL: bit 15,bitstream_restriction_flag >> + */ >> +#define NAL_SEARCH_CTL      AV_SCRATCH_9 >> +#define DPB_STATUS_REG      AV_SCRATCH_J >> +#define ERROR_STATUS_REG    AV_SCRATCH_9 >> + >> +#define H264_BUFFER_INFO_INDEX      PMV3_X /* 0xc24 */ >> +#define H264_BUFFER_INFO_DATA       PMV2_X /* 0xc22 */ >> +#define H264_CURRENT_POC_IDX_RESET  LAST_SLICE_MV_ADDR /* 0xc30 */ >> +#define H264_CURRENT_POC            LAST_MVY /* 0xc32 shared with conceal MV */ >> +#define H264_CO_MB_WR_ADDR          VLD_C38 >> +#define H264_CO_MB_RD_ADDR          VLD_C39 >> +#define H264_CO_MB_RW_CTL           VLD_C3D >> +#define MBY_MBX                     MB_MOTION_MODE >> + >> +#define H264_ACTION_SEARCH_HEAD     0xf0 >> +#define H264_ACTION_DECODE_SLICE    0xf1 >> +#define H264_ACTION_CONFIG_DONE     0xf2 >> +#define H264_ACTION_DECODE_NEWPIC   0xf3 >> +#define H264_ACTION_DECODE_START    0xff >> + >> +/* RPM memory definition */ >> +#define FIXED_FRAME_RATE_FLAG 0X21 >> +#define OFFSET_DELIMITER_LO 0x2f >> +#define OFFSET_DELIMITER_HI 0x30 >> +#define REF_IDC_OVERRIDE_FLAG 0x35 >> +#define SLICE_IPONLY_BREAK 0X5C >> +#define PREV_MAX_REFERENCE_FRAME_NUM 0X5D >> +#define EOS 0X5E >> +#define FRAME_PACKING_TYPE 0X5F >> +#define OLD_POC_PAR_1 0X60 >> +#define OLD_POC_PAR_2 0X61 >> +#define PREV_MBX 0X62 >> +#define PREV_MBY 0X63 >> +#define ERROR_SKIP_MB_NUM 0X64 >> +#define ERROR_MB_STATUS 0X65 >> +#define L0_PIC0_STATUS 0X66 >> +#define TIMEOUT_COUNTER 0X67 >> +#define BUFFER_SIZE 0X68 >> +#define BUFFER_SIZE_HI 0X69 >> +#define CROPPING_LEFT_RIGHT 0X6A >> +#define CROPPING_TOP_BOTTOM 0X6B >> +/** >> + * sps_flags2: >> + * bit 3, bitstream_restriction_flag >> + * bit 2, pic_struct_present_flag >> + * bit 1, vcl_hrd_parameters_present_flag >> + * bit 0, nal_hrd_parameters_present_flag >> + */ >> +#define SPS_FLAGS2 0x6C >> +#define NUM_REORDER_FRAMES 0x6D >> +#define MAX_BUFFER_FRAME 0X6E >> + >> +#define NON_CONFORMING_STREAM 0X70 >> +#define RECOVERY_POINT 0X71 >> +#define POST_CANVAS 0X72 >> +#define POST_CANVAS_H 0X73 >> +#define SKIP_PIC_COUNT 0X74 >> +#define TARGET_NUM_SCALING_LIST 0X75 >> +#define FF_POST_ONE_FRAME 0X76 >> +#define PREVIOUS_BIT_CNT 0X77 >> +#define MB_NOT_SHIFT_COUNT 0X78 >> +#define PIC_STATUS 0X79 >> +#define FRAME_COUNTER 0X7A >> +#define NEW_SLICE_TYPE 0X7B >> +#define NEW_PICTURE_STRUCTURE 0X7C >> +#define NEW_FRAME_NUM 0X7D >> +#define NEW_IDR_PIC_ID 0X7E >> +#define IDR_PIC_ID 0X7F >> + >> +/* h264 LOCAL */ >> +#define NAL_UNIT_TYPE 0X80 >> +#define NAL_REF_IDC 0X81 >> +#define SLICE_TYPE 0X82 >> +#define LOG2_MAX_FRAME_NUM 0X83 >> +#define FRAME_MBS_ONLY_FLAG 0X84 >> +#define PIC_ORDER_CNT_TYPE 0X85 >> +#define LOG2_MAX_PIC_ORDER_CNT_LSB 0X86 >> +#define PIC_ORDER_PRESENT_FLAG 0X87 >> +#define REDUNDANT_PIC_CNT_PRESENT_FLAG 0X88 >> +#define PIC_INIT_QP_MINUS26 0X89 >> +#define DEBLOCKING_FILTER_CONTROL_PRESENT_FLAG 0X8A >> +#define NUM_SLICE_GROUPS_MINUS1 0X8B >> +#define MODE_8X8_FLAGS 0X8C >> +#define ENTROPY_CODING_MODE_FLAG 0X8D >> +#define SLICE_QUANT 0X8E >> +#define TOTAL_MB_HEIGHT 0X8F >> +#define PICTURE_STRUCTURE 0X90 >> +#define TOP_INTRA_TYPE 0X91 >> +#define RV_AI_STATUS 0X92 >> +#define AI_READ_START 0X93 >> +#define AI_WRITE_START 0X94 >> +#define AI_CUR_BUFFER 0X95 >> +#define AI_DMA_BUFFER 0X96 >> +#define AI_READ_OFFSET 0X97 >> +#define AI_WRITE_OFFSET 0X98 >> +#define AI_WRITE_OFFSET_SAVE 0X99 >> +#define RV_AI_BUFF_START 0X9A >> +#define I_PIC_MB_COUNT 0X9B >> +#define AI_WR_DCAC_DMA_CTRL 0X9C >> +#define SLICE_MB_COUNT 0X9D >> +#define PICTYPE 0X9E >> +#define SLICE_GROUP_MAP_TYPE 0X9F >> +#define MB_TYPE 0XA0 >> +#define MB_AFF_ADDED_DMA 0XA1 >> +#define PREVIOUS_MB_TYPE 0XA2 >> +#define WEIGHTED_PRED_FLAG 0XA3 >> +#define WEIGHTED_BIPRED_IDC 0XA4 >> +/* bit 3:2 - PICTURE_STRUCTURE >> + * bit 1 - MB_ADAPTIVE_FRAME_FIELD_FLAG >> + * bit 0 - FRAME_MBS_ONLY_FLAG >> + */ >> +#define MBFF_INFO 0XA5 >> +#define TOP_INTRA_TYPE_TOP 0XA6 >> +#define RV_AI_BUFF_INC 0xA7 >> +#define DEFAULT_MB_INFO_LO 0xA8 >> +/* 0 -- no need to read >> + * 1 -- need to wait Left >> + * 2 -- need to read Intra >> + * 3 -- need to read back MV >> + */ >> +#define NEED_READ_TOP_INFO 0xA9 >> +/* 0 -- idle >> + * 1 -- wait Left >> + * 2 -- reading top Intra >> + * 3 -- reading back MV >> + */ >> +#define READ_TOP_INFO_STATE 0xAA >> +#define DCAC_MBX 0xAB >> +#define TOP_MB_INFO_OFFSET 0xAC >> +#define TOP_MB_INFO_RD_IDX 0xAD >> +#define TOP_MB_INFO_WR_IDX 0xAE >> + >> +#define VLD_NO_WAIT 0 >> +#define VLD_WAIT_BUFFER 1 >> +#define VLD_WAIT_HOST   2 >> +#define VLD_WAIT_GAP 3 >> + >> +#define VLD_WAITING 0xAF >> + >> +#define MB_X_NUM 0xB0 >> +#define MB_HEIGHT 0xB2 >> +#define MBX 0xB3 >> +#define TOTAL_MBY 0xB4 >> +#define INTR_MSK_SAVE 0xB5 >> +#define NEED_DISABLE_PPE 0xB6 >> +#define IS_NEW_PICTURE 0XB7 >> +#define PREV_NAL_REF_IDC 0XB8 >> +#define PREV_NAL_UNIT_TYPE 0XB9 >> +#define FRAME_MB_COUNT 0XBA >> +#define SLICE_GROUP_UCODE 0XBB >> +#define SLICE_GROUP_CHANGE_RATE 0XBC >> +#define SLICE_GROUP_CHANGE_CYCLE_LEN 0XBD >> +#define DELAY_LENGTH 0XBE >> +#define PICTURE_STRUCT 0XBF >> +#define DCAC_PREVIOUS_MB_TYPE 0xC1 >> + >> +#define TIME_STAMP 0XC2 >> +#define H_TIME_STAMP 0XC3 >> +#define VPTS_MAP_ADDR 0XC4 >> +#define H_VPTS_MAP_ADDR 0XC5 >> +#define PIC_INSERT_FLAG 0XC7 >> +#define TIME_STAMP_START 0XC8 >> +#define TIME_STAMP_END 0XDF >> +#define OFFSET_FOR_NON_REF_PIC 0XE0 >> +#define OFFSET_FOR_TOP_TO_BOTTOM_FIELD 0XE2 >> +#define MAX_REFERENCE_FRAME_NUM 0XE4 >> +#define FRAME_NUM_GAP_ALLOWED 0XE5 >> +#define NUM_REF_FRAMES_IN_PIC_ORDER_CNT_CYCLE 0XE6 >> +#define PROFILE_IDC_MMCO 0XE7 >> +#define LEVEL_IDC_MMCO 0XE8 >> +#define FRAME_SIZE_IN_MB 0XE9 >> +#define DELTA_PIC_ORDER_ALWAYS_ZERO_FLAG 0XEA >> +#define PPS_NUM_REF_IDX_L0_ACTIVE_MINUS1 0XEB >> +#define PPS_NUM_REF_IDX_L1_ACTIVE_MINUS1 0XEC >> +#define CURRENT_SPS_ID 0XED >> +#define CURRENT_PPS_ID 0XEE >> +/* bit 0 - sequence parameter set may change >> + * bit 1 - picture parameter set may change >> + * bit 2 - new dpb just inited >> + * bit 3 - IDR picture not decoded yet >> + * bit 5:4 - 0: mb level code loaded 1: picture >> + * level code loaded 2: slice level code loaded >> + */ >> +#define DECODE_STATUS 0XEF >> +#define FIRST_MB_IN_SLICE 0XF0 >> +#define PREV_MB_WIDTH 0XF1 >> +#define PREV_FRAME_SIZE_IN_MB 0XF2 >> +/* bit 0 - aspect_ratio_info_present_flag >> + * bit 1 - timing_info_present_flag >> + * bit 2 - nal_hrd_parameters_present_flag >> + * bit 3 - vcl_hrd_parameters_present_flag >> + * bit 4 - pic_struct_present_flag >> + * bit 5 - bitstream_restriction_flag >> + */ >> +#define VUI_STATUS 0XF4 >> +#define ASPECT_RATIO_IDC 0XF5 >> +#define ASPECT_RATIO_SAR_WIDTH 0XF6 >> +#define ASPECT_RATIO_SAR_HEIGHT 0XF7 >> +#define NUM_UNITS_IN_TICK 0XF8 >> +#define TIME_SCALE 0XFA >> +#define CURRENT_PIC_INFO 0XFC >> +#define DPB_BUFFER_INFO 0XFD >> +#define REFERENCE_POOL_INFO 0XFE >> +#define REFERENCE_LIST_INFO 0XFF >> + >> +#define REORDER_CMD_MAX             66 >> + >> +/* config parameters to DDR lmem */ >> +#define GET_SPS_PROFILE_IDC(x)       (((x) & 0xff) << 8) >> +#define GET_SPS_LEVEL_IDC(x)         ((x) & 0xff) >> +#define GET_SPS_SEQ_PARAM_SET_ID(x)       (((x) & 0x1f) << 8) >> +#define GET_SPS_CHROMA_FORMAT_IDC(x)      ((x) << 8) >> +#define GET_SPS_NUM_REF_FRAMES(x)         ((x) & 0xff) >> +#define GET_SPS_GAPS_ALLOWED_FLAG(x)      ((x) << 8) >> +#define GET_SPS_LOG2_MAX_FRAME_NUM(x)     ((x) + 4) >> +#define GET_SPS_PIC_ORDER_CNT_LSB(x)      ((x) + 4) >> +#define GET_SPS_PIC_ORDER_TYPE(x)         (x) >> +#define GET_SPS_OFFSET_FOR_NONREF_PIC_HIGH(x)      (((x) & 0xffff0000) >> 16) >> +#define GET_SPS_OFFSET_FOR_NONREF_PIC_LOW(x)         ((x) & 0xffff) >> +#define GET_SPS_OFFSET_FOR_TOP_BOT_FIELD_HIGH(x)      (((x) & 0xffff0000) >> 16) >> +#define GET_SPS_OFFSET_FOR_TOP_BOT_FIELD_LOW(x)         ((x) & 0xffff) >> +#define GET_SPS_PIC_WIDTH_IN_MBS(x)       ((x) + 1) >> +#define GET_SPS_PIC_HEIGHT_IN_MBS(x)      ((x) + 1) >> +#define GET_SPS_DIRECT_8X8_FLAGS(x)       (((x) & 0x1) << 2) >> +#define GET_SPS_MB_ADAPTIVE_FRAME_FIELD_FLAGS(x)       (((x) & 0x1) << 1) >> +#define GET_SPS_FRAME_MBS_ONLY_FLAGS(x)   ((x) & 0x1) >> + >> +#define GET_PPS_PIC_PARAM_SET_ID(x)       ((x) & 0xff) >> +#define GET_PPS_SEQ_PARAM_SET_ID(x)       (((x) & 0x1f) << 8) >> +#define GET_PPS_ENTROPY_CODING_MODE_FLAG(x)  (((x) & 0x1) << 13) >> +#define GET_PPS_PIC_ORDER_PRESENT_FLAG(x)    (((x) & 0x1) << 14) >> +#define GET_PPS_NUM_IDX_REF_L0_MINUS1(x)       ((x) & 0x1f) >> +#define GET_PPS_NUM_IDX_REF_L1_MINUS1(x)       (((x) & 0x1f) << 5) >> +#define GET_PPS_WEIGHTED_PRED_FLAG(x)         (((x) & 0x1) << 10) >> +#define GET_PPS_WEIGHTED_BIPRED_IDC(x)        (((x) & 0x3) << 11) >> +#define GET_PPS_INIT_QS_MINUS26(x)           (((x) & 0xff) << 8) >> +#define GET_PPS_INIT_QP_MINUS26(x)           ((x) & 0xff) >> +#define GET_PPS_CHROMA_QP_INDEX_OFFSET(x)   ((x) & 0xff) >> +#define GET_PPS_DEBLOCK_FILTER_CTRL_PRESENT_FLAG(x)   (((x) & 0x1) << 8) >> +#define GET_PPS_CONSTRAIN_INTRA_PRED_FLAG(x)          (((x) & 0x1) << 9) >> +#define GET_PPS_REDUNDANT_PIC_CNT_PRESENT_FLAG(x)     (((x) & 0x1) << 10) >> +#define GET_PPS_SCALING_MATRIX_PRESENT_FLAG(x)        (((x) & 0x1) << 1) >> +#define GET_PPS_TRANSFORM_8X8_FLAG(x)                 ((x) & 0x1) >> +#define GET_PPS_GET_SECOND_CHROMA_QP_OFFSET(x)        (x) >> + >> +int aml_h264_init(void *priv); >> +void aml_h264_exit(void *priv); >> +int aml_h264_dec_run(void *priv); >> + >> +#endif >> diff --git a/drivers/media/platform/amlogic/vdec/reg_defines.h b/drivers/media/platform/amlogic/vdec/reg_defines.h >> new file mode 100644 >> index 000000000000..ea50018a078d >> --- /dev/null >> +++ b/drivers/media/platform/amlogic/vdec/reg_defines.h >> @@ -0,0 +1,177 @@ >> +/* SPDX-License-Identifier: (GPL-2.0-only OR MIT) */ >> +/* >> + * Copyright (C) 2025 Amlogic, Inc. All rights reserved >> + */ >> + >> +#ifndef _REG_DEFINES_H_ >> +#define _REG_DEFINES_H_ >> + >> +#define REG_ALIGN(x) ((x) << 2) >> + >> +#define VDEC_ASSIST_MMC_CTRL0        REG_ALIGN(0x0001) >> +#define VDEC_ASSIST_MMC_CTRL1        REG_ALIGN(0x0002) >> + >> +#define VDEC_ASSIST_CANVAS_BLK32     REG_ALIGN(0x0005) >> + >> +#define VDEC_ASSIST_MBOX1_CLR_REG    REG_ALIGN(0x0075) >> +#define VDEC_ASSIST_MBOX1_MASK       REG_ALIGN(0x0076) >> + >> +#define MPSR                         REG_ALIGN(0x0301) >> +#define MPC_P                        REG_ALIGN(0x0306) >> +#define MPC_D                        REG_ALIGN(0x0307) >> +#define MPC_E                        REG_ALIGN(0x0308) >> +#define MPC_W                        REG_ALIGN(0x0309) >> +#define CPSR                         REG_ALIGN(0x0321) >> +#define IMEM_DMA_CTRL                REG_ALIGN(0x0340) >> +#define IMEM_DMA_ADR                 REG_ALIGN(0x0341) >> +#define IMEM_DMA_COUNT               REG_ALIGN(0x0342) >> +#define WRRSP_IMEM                   REG_ALIGN(0x0343) >> +#define LMEM_DMA_CTRL                REG_ALIGN(0x0350) >> +#define WRRSP_LMEM                   REG_ALIGN(0x0353) >> + >> +#define PSCALE_CTRL                  REG_ALIGN(0x0911) >> +#define GCLK_EN                      REG_ALIGN(0x0983) >> +#define MDEC_PIC_DC_CTRL             REG_ALIGN(0x098e) >> +#define MDEC_PIC_DC_MUX_CTRL         REG_ALIGN(0x098d) >> +#define ANC0_CANVAS_ADDR             REG_ALIGN(0x0990) >> +#define ANC1_CANVAS_ADDR             REG_ALIGN(0x0991) >> +#define ANC2_CANVAS_ADDR             REG_ALIGN(0x0992) >> +#define ANC3_CANVAS_ADDR             REG_ALIGN(0x0993) >> +#define ANC4_CANVAS_ADDR             REG_ALIGN(0x0994) >> +#define ANC5_CANVAS_ADDR             REG_ALIGN(0x0995) >> +#define ANC6_CANVAS_ADDR             REG_ALIGN(0x0996) >> +#define ANC7_CANVAS_ADDR             REG_ALIGN(0x0997) >> +#define ANC8_CANVAS_ADDR             REG_ALIGN(0x0998) >> +#define ANC9_CANVAS_ADDR             REG_ALIGN(0x0999) >> +#define ANC10_CANVAS_ADDR            REG_ALIGN(0x099a) >> +#define ANC11_CANVAS_ADDR            REG_ALIGN(0x099b) >> +#define ANC12_CANVAS_ADDR            REG_ALIGN(0x099c) >> +#define ANC13_CANVAS_ADDR            REG_ALIGN(0x099d) >> +#define ANC14_CANVAS_ADDR            REG_ALIGN(0x099e) >> +#define ANC15_CANVAS_ADDR            REG_ALIGN(0x099f) >> +#define ANC16_CANVAS_ADDR            REG_ALIGN(0x09a0) >> +#define ANC17_CANVAS_ADDR            REG_ALIGN(0x09a1) >> +#define ANC18_CANVAS_ADDR            REG_ALIGN(0x09a2) >> +#define ANC19_CANVAS_ADDR            REG_ALIGN(0x09a3) >> +#define ANC20_CANVAS_ADDR            REG_ALIGN(0x09a4) >> +#define ANC21_CANVAS_ADDR            REG_ALIGN(0x09a5) >> +#define ANC22_CANVAS_ADDR            REG_ALIGN(0x09a6) >> +#define ANC23_CANVAS_ADDR            REG_ALIGN(0x09a7) >> +#define ANC24_CANVAS_ADDR            REG_ALIGN(0x09a8) >> +#define ANC25_CANVAS_ADDR            REG_ALIGN(0x09a9) >> +#define ANC26_CANVAS_ADDR            REG_ALIGN(0x09aa) >> +#define ANC27_CANVAS_ADDR            REG_ALIGN(0x09ab) >> +#define ANC28_CANVAS_ADDR            REG_ALIGN(0x09ac) >> +#define ANC29_CANVAS_ADDR            REG_ALIGN(0x09ad) >> +#define ANC30_CANVAS_ADDR            REG_ALIGN(0x09ae) >> +#define ANC31_CANVAS_ADDR            REG_ALIGN(0x09af) >> +#define DBKR_CANVAS_ADDR             REG_ALIGN(0x09b0) >> +#define DBKW_CANVAS_ADDR             REG_ALIGN(0x09b1) >> +#define REC_CANVAS_ADDR              REG_ALIGN(0x09b2) >> +#define CURR_CANVAS_CTRL             REG_ALIGN(0x09b3) >> +#define MDEC_PIC_DC_THRESH           REG_ALIGN(0x09b8) >> +#define AV_SCRATCH_0                 REG_ALIGN(0x09c0) >> +#define AV_SCRATCH_1                 REG_ALIGN(0x09c1) >> +#define AV_SCRATCH_2                 REG_ALIGN(0x09c2) >> +#define AV_SCRATCH_3                 REG_ALIGN(0x09c3) >> +#define AV_SCRATCH_4                 REG_ALIGN(0x09c4) >> +#define AV_SCRATCH_5                 REG_ALIGN(0x09c5) >> +#define AV_SCRATCH_6                 REG_ALIGN(0x09c6) >> +#define AV_SCRATCH_7                 REG_ALIGN(0x09c7) >> +#define AV_SCRATCH_8                 REG_ALIGN(0x09c8) >> +#define AV_SCRATCH_9                 REG_ALIGN(0x09c9) >> +#define AV_SCRATCH_A                 REG_ALIGN(0x09ca) >> +#define AV_SCRATCH_B                 REG_ALIGN(0x09cb) >> +#define AV_SCRATCH_C                 REG_ALIGN(0x09cc) >> +#define AV_SCRATCH_D                 REG_ALIGN(0x09cd) >> +#define AV_SCRATCH_E                 REG_ALIGN(0x09ce) >> +#define AV_SCRATCH_F                 REG_ALIGN(0x09cf) >> +#define AV_SCRATCH_G                 REG_ALIGN(0x09d0) >> +#define AV_SCRATCH_H                 REG_ALIGN(0x09d1) >> +#define AV_SCRATCH_I                 REG_ALIGN(0x09d2) >> +#define AV_SCRATCH_J                 REG_ALIGN(0x09d3) >> +#define AV_SCRATCH_K                 REG_ALIGN(0x09d4) >> +#define AV_SCRATCH_L                 REG_ALIGN(0x09d5) >> +#define AV_SCRATCH_M                 REG_ALIGN(0x09d6) >> +#define AV_SCRATCH_N                 REG_ALIGN(0x09d7) >> +#define WRRSP_VLD                    REG_ALIGN(0x09da) >> +#define MDEC_DOUBLEW_CFG0            REG_ALIGN(0x09db) >> +#define MDEC_DOUBLEW_CFG1            REG_ALIGN(0x09dc) >> +#define MDEC_DOUBLEW_CFG2            REG_ALIGN(0x09dd) >> +#define MDEC_DOUBLEW_CFG3            REG_ALIGN(0x09de) >> +#define MDEC_DOUBLEW_CFG4            REG_ALIGN(0x09df) >> +#define MDEC_DOUBLEW_CFG5            REG_ALIGN(0x09e0) >> +#define MDEC_DOUBLEW_CFG6            REG_ALIGN(0x09e1) >> +#define MDEC_DOUBLEW_CFG7            REG_ALIGN(0x09e2) >> +#define MDEC_DOUBLEW_STATUS          REG_ALIGN(0x09e3) >> +#define MDEC_EXTIF_CFG0              REG_ALIGN(0x09e4) >> + >> +#define MDEC_EXTIF_CFG1              REG_ALIGN(0x09e5) >> +#define MDEC_EXTIF_CFG2              REG_ALIGN(0x09e6) >> + >> +#define POWER_CTL_VLD                REG_ALIGN(0x0c08) >> +#define VLD_DECODE_CONTROL           REG_ALIGN(0x0c18) >> + >> +#define PMV1_X                       REG_ALIGN(0x0c20) >> +#define PMV1_Y                       REG_ALIGN(0x0c21) >> +#define PMV2_X                       REG_ALIGN(0x0c22) >> +#define PMV2_Y                       REG_ALIGN(0x0c23) >> +#define PMV3_X                       REG_ALIGN(0x0c24) >> +#define PMV3_Y                       REG_ALIGN(0x0c25) >> +#define PMV4_X                       REG_ALIGN(0x0c26) >> +#define PMV4_Y                       REG_ALIGN(0x0c27) >> +#define M4_TABLE_SELECT              REG_ALIGN(0x0c28) >> +#define M4_CONTROL_REG               REG_ALIGN(0x0c29) >> +#define BLOCK_NUM                    REG_ALIGN(0x0c2a) >> +#define PATTERN_CODE                 REG_ALIGN(0x0c2b) >> +#define MB_INFO                      REG_ALIGN(0x0c2c) >> +#define VLD_DC_PRED                  REG_ALIGN(0x0c2d) >> +#define VLD_ERROR_MASK               REG_ALIGN(0x0c2e) >> +#define VLD_DC_PRED_C                REG_ALIGN(0x0c2f) >> +#define LAST_SLICE_MV_ADDR           REG_ALIGN(0x0c30) >> +#define LAST_MVX                     REG_ALIGN(0x0c31) >> +#define LAST_MVY                     REG_ALIGN(0x0c32) >> + >> +#define MB_MOTION_MODE               REG_ALIGN(0x0c07) >> +#define VIFF_BIT_CNT                 REG_ALIGN(0x0c1a) >> +#define M4_CONTROL_REG               REG_ALIGN(0x0c29) >> +#define VLD_C38                      REG_ALIGN(0x0c38) >> +#define VLD_C39                      REG_ALIGN(0x0c39) >> +#define VLD_SHIFT_STATUS             REG_ALIGN(0x0c3b) >> +#define VLD_C3D                      REG_ALIGN(0x0c3d) >> +#define VLD_MEM_VIFIFO_START_PTR     REG_ALIGN(0x0c40) >> +#define VLD_MEM_VIFIFO_CURR_PTR      REG_ALIGN(0x0c41) >> +#define VLD_MEM_VIFIFO_END_PTR       REG_ALIGN(0x0c42) >> +#define VLD_MEM_VIFIFO_BYTES_AVAIL   REG_ALIGN(0x0c43) >> +#define VLD_MEM_VIFIFO_CONTROL       REG_ALIGN(0x0c44) >> +#define VLD_MEM_VIFIFO_WP            REG_ALIGN(0x0c45) >> +#define VLD_MEM_VIFIFO_RP            REG_ALIGN(0x0c46) >> +#define VLD_MEM_VIFIFO_LEVEL         REG_ALIGN(0x0c47) >> +#define VLD_MEM_VIFIFO_BUF_CNTL      REG_ALIGN(0x0c48) >> + >> +#define VCOP_CTRL_REG                REG_ALIGN(0x0e00) >> +#define RV_AI_MB_COUNT               REG_ALIGN(0x0e0c) >> +#define IQIDCT_CONTROL               REG_ALIGN(0x0e0e) >> +#define DCAC_DDR_BYTE64_CTL          REG_ALIGN(0x0e1d) >> + >> +#define VDEC2_IMEM_DMA_CTRL          REG_ALIGN(0x2340) >> +#define VDEC2_IMEM_DMA_ADR           REG_ALIGN(0x2341) >> +#define VDEC2_IMEM_DMA_COUNT         REG_ALIGN(0x2342) >> + >> +#define DOS_SW_RESET0                REG_ALIGN(0x3f00) >> +#define DOS_GCLK_EN0                 REG_ALIGN(0x3f01) >> +#define DOS_GCLK_EN1                 REG_ALIGN(0x3f09) >> +#define DOS_GCLK_EN3                 REG_ALIGN(0x3f35) >> + >> +#define DOS_MEM_PD_VDEC              REG_ALIGN(0x3f30) >> +#define DOS_MEM_PD_VDEC2             REG_ALIGN(0x3f31) >> +#define DOS_MEM_PD_HCODEC            REG_ALIGN(0x3f32) >> +/*add from M8M2*/ >> +#define DOS_MEM_PD_HEVC              REG_ALIGN(0x3f33) >> + >> +#define DOS_SW_RESET3                REG_ALIGN(0x3f34) >> +#define DOS_GCLK_EN3                 REG_ALIGN(0x3f35) >> +#define DOS_HEVC_INT_EN              REG_ALIGN(0x3f36) >> + >> +#endif >> +