From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org X-Spam-Level: X-Spam-Status: No, score=-15.3 required=3.0 tests=BAYES_00, HEADER_FROM_DIFFERENT_DOMAINS,INCLUDES_CR_TRAILER,INCLUDES_PATCH, MAILING_LIST_MULTI,NICE_REPLY_A,SPF_HELO_NONE,SPF_PASS,URIBL_BLOCKED, USER_AGENT_SANE_1 autolearn=ham autolearn_force=no version=3.4.0 Received: from mail.kernel.org (mail.kernel.org [198.145.29.99]) by smtp.lore.kernel.org (Postfix) with ESMTP id 096AAC433DB for ; Tue, 30 Mar 2021 20:05:27 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by mail.kernel.org (Postfix) with ESMTP id CF7AE61864 for ; Tue, 30 Mar 2021 20:05:26 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S233312AbhC3UEz (ORCPT ); Tue, 30 Mar 2021 16:04:55 -0400 Received: from relay12.mail.gandi.net ([217.70.178.232]:52005 "EHLO relay12.mail.gandi.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S233337AbhC3UEX (ORCPT ); Tue, 30 Mar 2021 16:04:23 -0400 Received: from [192.168.1.100] (lfbn-lyo-1-457-219.w2-7.abo.wanadoo.fr [2.7.49.219]) (Authenticated sender: alex@ghiti.fr) by relay12.mail.gandi.net (Postfix) with ESMTPSA id 8CAD2200003; Tue, 30 Mar 2021 20:04:18 +0000 (UTC) Subject: Re: [PATCH v6] RISC-V: enable XIP To: Palmer Dabbelt Cc: vitaly.wool@konsulko.com, linux-riscv@lists.infradead.org, linux-kernel@vger.kernel.org, bin.meng@windriver.com, anup@brainfault.org, Alistair Francis , nico@fluxnic.net References: From: Alex Ghiti Message-ID: Date: Tue, 30 Mar 2021 16:04:18 -0400 User-Agent: Mozilla/5.0 (X11; Linux x86_64; rv:78.0) Gecko/20100101 Thunderbird/78.9.0 MIME-Version: 1.0 In-Reply-To: Content-Type: text/plain; charset=utf-8; format=flowed Content-Language: fr Content-Transfer-Encoding: 8bit Precedence: bulk List-ID: X-Mailing-List: linux-kernel@vger.kernel.org Le 3/30/21 à 3:33 PM, Palmer Dabbelt a écrit : > On Tue, 30 Mar 2021 11:39:10 PDT (-0700), alex@ghiti.fr wrote: >> >> >> Le 3/30/21 à 2:26 AM, Vitaly Wool a écrit : >>> On Tue, Mar 30, 2021 at 8:23 AM Palmer Dabbelt >>> wrote: >>>> >>>> On Sun, 21 Mar 2021 17:12:15 PDT (-0700), vitaly.wool@konsulko.com >>>> wrote: >>>>> Introduce XIP (eXecute In Place) support for RISC-V platforms. >>>>> It allows code to be executed directly from non-volatile storage >>>>> directly addressable by the CPU, such as QSPI NOR flash which can >>>>> be found on many RISC-V platforms. This makes way for significant >>>>> optimization of RAM footprint. The XIP kernel is not compressed >>>>> since it has to run directly from flash, so it will occupy more >>>>> space on the non-volatile storage. The physical flash address used >>>>> to link the kernel object files and for storing it has to be known >>>>> at compile time and is represented by a Kconfig option. >>>>> >>>>> XIP on RISC-V will for the time being only work on MMU-enabled >>>>> kernels. >>>>> >>>>> Signed-off-by: Vitaly Wool >>>>> >>>>> --- >>>>> >>>>> Changes in v2: >>>>> - dedicated macro for XIP address fixup when MMU is not enabled yet >>>>>    o both for 32-bit and 64-bit RISC-V >>>>> - SP is explicitly set to a safe place in RAM before __copy_data call >>>>> - removed redundant alignment requirements in vmlinux-xip.lds.S >>>>> - changed long -> uintptr_t typecast in __XIP_FIXUP macro. >>>>> Changes in v3: >>>>> - rebased against latest for-next >>>>> - XIP address fixup macro now takes an argument >>>>> - SMP related fixes >>>>> Changes in v4: >>>>> - rebased against the current for-next >>>>> - less #ifdef's in C/ASM code >>>>> - dedicated XIP_FIXUP_OFFSET assembler macro in head.S >>>>> - C-specific definitions moved into #ifndef __ASSEMBLY__ >>>>> - Fixed multi-core boot >>>>> Changes in v5: >>>>> - fixed build error for non-XIP kernels >>>>> Changes in v6: >>>>> - XIP_PHYS_RAM_BASE config option renamed to PHYS_RAM_BASE >>>>> - added PHYS_RAM_BASE_FIXED config flag to allow usage of >>>>>    PHYS_RAM_BASE in non-XIP configurations if needed >>>>> - XIP_FIXUP macro rewritten with a tempoarary variable to avoid side >>>>>    effects >>>>> - fixed crash for non-XIP kernels that don't use built-in DTB >>>> >>>> So v5 landed on for-next, which generally means it's best to avoid >>>> re-spinning the patch and instead send along fixups.  That said, the v5 >>>> is causing some testing failures for me. >>>> >>>> I'm going to drop the v5 for now as I don't have time to test this >>>> tonight.  I'll try and take a look soon, as it will conflict with >>>> Alex's >>>> patches. >>> >>> I can come up with the incremental patch instead pretty much straight >>> away if that works better. >>> >>> ~Vitaly >>> >>>>>   arch/riscv/Kconfig                  |  49 ++++++++++- >>>>>   arch/riscv/Makefile                 |   8 +- >>>>>   arch/riscv/boot/Makefile            |  13 +++ >>>>>   arch/riscv/include/asm/pgtable.h    |  65 ++++++++++++-- >>>>>   arch/riscv/kernel/cpu_ops_sbi.c     |  11 ++- >>>>>   arch/riscv/kernel/head.S            |  49 ++++++++++- >>>>>   arch/riscv/kernel/head.h            |   3 + >>>>>   arch/riscv/kernel/setup.c           |   8 +- >>>>>   arch/riscv/kernel/vmlinux-xip.lds.S | 132 >>>>> ++++++++++++++++++++++++++++ >>>>>   arch/riscv/kernel/vmlinux.lds.S     |   6 ++ >>>>>   arch/riscv/mm/init.c                | 100 +++++++++++++++++++-- >>>>>   11 files changed, 426 insertions(+), 18 deletions(-) >>>>>   create mode 100644 arch/riscv/kernel/vmlinux-xip.lds.S >>>>> >>>>> diff --git a/arch/riscv/Kconfig b/arch/riscv/Kconfig >>>>> index 8ea60a0a19ae..bd6f82240c34 100644 >>>>> --- a/arch/riscv/Kconfig >>>>> +++ b/arch/riscv/Kconfig >>>>> @@ -441,7 +441,7 @@ config EFI_STUB >>>>> >>>>>   config EFI >>>>>        bool "UEFI runtime support" >>>>> -     depends on OF >>>>> +     depends on OF && !XIP_KERNEL >>>>>        select LIBFDT >>>>>        select UCS2_STRING >>>>>        select EFI_PARAMS_FROM_FDT >>>>> @@ -465,11 +465,56 @@ config STACKPROTECTOR_PER_TASK >>>>>        def_bool y >>>>>        depends on STACKPROTECTOR && CC_HAVE_STACKPROTECTOR_TLS >>>>> >>>>> +config PHYS_RAM_BASE_FIXED >>>>> +     bool "Explicitly specified physical RAM address" >>>>> +     default n >>>>> + >>>>> +config PHYS_RAM_BASE >>>>> +     hex "Platform Physical RAM address" >>>>> +     depends on PHYS_RAM_BASE_FIXED >>>>> +     default "0x80000000" >>>>> +     help >>>>> +       This is the physical address of RAM in the system. It has >>>>> to be >>>>> +       explicitly specified to run early relocations of read-write >>>>> data >>>>> +       from flash to RAM. >>>>> + >>>>> +config XIP_KERNEL >>>>> +     bool "Kernel Execute-In-Place from ROM" >>>>> +     depends on MMU >>>>> +     select PHYS_RAM_BASE_FIXED >>>>> +     help >>>>> +       Execute-In-Place allows the kernel to run from non-volatile >>>>> storage >>>>> +       directly addressable by the CPU, such as NOR flash. This >>>>> saves RAM >>>>> +       space since the text section of the kernel is not loaded >>>>> from flash >>>>> +       to RAM.  Read-write sections, such as the data section and >>>>> stack, >>>>> +       are still copied to RAM.  The XIP kernel is not compressed >>>>> since >>>>> +       it has to run directly from flash, so it will take more >>>>> space to >>>>> +       store it.  The flash address used to link the kernel object >>>>> files, >>>>> +       and for storing it, is configuration dependent. Therefore, >>>>> if you >>>>> +       say Y here, you must know the proper physical address where to >>>>> +       store the kernel image depending on your own flash memory >>>>> usage. >>>>> + >>>>> +       Also note that the make target becomes "make xipImage" >>>>> rather than >>>>> +       "make zImage" or "make Image".  The final kernel binary to >>>>> put in >>>>> +       ROM memory will be arch/riscv/boot/xipImage. >>>>> + >>>>> +       If unsure, say N. >>>>> + >>>>> +config XIP_PHYS_ADDR >>>>> +     hex "XIP Kernel Physical Location" >>>>> +     depends on XIP_KERNEL >>>>> +     default "0x21000000" >>>>> +     help >>>>> +       This is the physical address in your flash memory the >>>>> kernel will >>>>> +       be linked for and stored to.  This address is dependent on >>>>> your >>>>> +       own flash usage. >>>>> + >>>>>   endmenu >>>>> >>>>>   config BUILTIN_DTB >>>>> -     def_bool n >>>>> +     bool >>>>>        depends on OF >>>>> +     default y if XIP_KERNEL >>>>> >>>>>   menu "Power management options" >>>>> >>>>> diff --git a/arch/riscv/Makefile b/arch/riscv/Makefile >>>>> index 1368d943f1f3..8fcbec03974d 100644 >>>>> --- a/arch/riscv/Makefile >>>>> +++ b/arch/riscv/Makefile >>>>> @@ -82,7 +82,11 @@ CHECKFLAGS += -D__riscv -D__riscv_xlen=$(BITS) >>>>> >>>>>   # Default target when executing plain make >>>>>   boot         := arch/riscv/boot >>>>> +ifeq ($(CONFIG_XIP_KERNEL),y) >>>>> +KBUILD_IMAGE := $(boot)/xipImage >>>>> +else >>>>>   KBUILD_IMAGE := $(boot)/Image.gz >>>>> +endif >>>>> >>>>>   head-y := arch/riscv/kernel/head.o >>>>> >>>>> @@ -95,12 +99,14 @@ PHONY += vdso_install >>>>>   vdso_install: >>>>>        $(Q)$(MAKE) $(build)=arch/riscv/kernel/vdso $@ >>>>> >>>>> +ifneq ($(CONFIG_XIP_KERNEL),y) >>>>>   ifeq ($(CONFIG_RISCV_M_MODE)$(CONFIG_SOC_CANAAN),yy) >>>>>   KBUILD_IMAGE := $(boot)/loader.bin >>>>>   else >>>>>   KBUILD_IMAGE := $(boot)/Image.gz >>>>>   endif >>>>> -BOOT_TARGETS := Image Image.gz loader loader.bin >>>>> +endif >>>>> +BOOT_TARGETS := Image Image.gz loader loader.bin xipImage >>>>> >>>>>   all: $(notdir $(KBUILD_IMAGE)) >>>>> >>>>> diff --git a/arch/riscv/boot/Makefile b/arch/riscv/boot/Makefile >>>>> index 03404c84f971..6bf299f70c27 100644 >>>>> --- a/arch/riscv/boot/Makefile >>>>> +++ b/arch/riscv/boot/Makefile >>>>> @@ -17,8 +17,21 @@ >>>>>   KCOV_INSTRUMENT := n >>>>> >>>>>   OBJCOPYFLAGS_Image :=-O binary -R .note -R .note.gnu.build-id -R >>>>> .comment -S >>>>> +OBJCOPYFLAGS_xipImage :=-O binary -R .note -R .note.gnu.build-id >>>>> -R .comment -S >>>>> >>>>>   targets := Image Image.* loader loader.o loader.lds loader.bin >>>>> +targets := Image Image.* loader loader.o loader.lds loader.bin >>>>> xipImage >>>>> + >>>>> +ifeq ($(CONFIG_XIP_KERNEL),y) >>>>> + >>>>> +quiet_cmd_mkxip = $(quiet_cmd_objcopy) >>>>> +cmd_mkxip = $(cmd_objcopy) >>>>> + >>>>> +$(obj)/xipImage: vmlinux FORCE >>>>> +     $(call if_changed,mkxip) >>>>> +     @$(kecho) '  Physical Address of xipImage: >>>>> $(CONFIG_XIP_PHYS_ADDR)' >>>>> + >>>>> +endif >>>>> >>>>>   $(obj)/Image: vmlinux FORCE >>>>>        $(call if_changed,objcopy) >>>>> diff --git a/arch/riscv/include/asm/pgtable.h >>>>> b/arch/riscv/include/asm/pgtable.h >>>>> index ebf817c1bdf4..21a9b2f8d1c7 100644 >>>>> --- a/arch/riscv/include/asm/pgtable.h >>>>> +++ b/arch/riscv/include/asm/pgtable.h >>>>> @@ -11,6 +11,33 @@ >>>>> >>>>>   #include >>>>> >>>>> +#ifdef CONFIG_MMU >>>>> + >>>>> +#define VMALLOC_START    (PAGE_OFFSET - VMALLOC_SIZE) >>>>> + >>>>> +#ifdef CONFIG_XIP_KERNEL >>>>> +#define VMALLOC_SIZE     ((KERN_VIRT_SIZE >> 1) - SZ_16M) >>>>> +#define VMALLOC_END      (PAGE_OFFSET - SZ_16M - 1) >>>>> + >>>>> +#define XIP_OFFSET           SZ_8M >>>>> +#define XIP_MASK             (SZ_8M - 1) >>>>> +#define XIP_VIRT_ADDR(physaddr)      \ >>>>> +     (PAGE_OFFSET - XIP_OFFSET + ((physaddr) & XIP_MASK)) >>>>> + >>>>> +#else >>>>> + >>>>> +#define VMALLOC_SIZE     (KERN_VIRT_SIZE >> 1) >>>>> +#define VMALLOC_END      (PAGE_OFFSET - 1) >>>>> + >>>>> +#endif /* CONFIG_XIP_KERNEL */ >>>>> + >>>>> +#else >>>>> + >>>>> +#ifdef CONFIG_XIP_KERNEL >>>>> +#define XIP_VIRT_ADDR(physaddr) (physaddr) >>>>> +#endif /* CONFIG_XIP_KERNEL */ >>>>> +#endif /* CONFIG_MMU */ >>>>> + >>>>>   #ifndef __ASSEMBLY__ >>>>> >>>>>   /* Page Upper Directory not used in RISC-V */ >>>>> @@ -21,9 +48,25 @@ >>>>> >>>>>   #ifdef CONFIG_MMU >>>>> >>>>> -#define VMALLOC_SIZE     (KERN_VIRT_SIZE >> 1) >>>>> -#define VMALLOC_END      (PAGE_OFFSET - 1) >>>>> -#define VMALLOC_START    (PAGE_OFFSET - VMALLOC_SIZE) >>>>> +#ifdef CONFIG_XIP_KERNEL >>>>> +/* >>>>> + * Since we use sections to map it, this macro replaces the >>>>> physical address >>>>> + * with its virtual address while keeping offset from the base >>>>> section. >>>>> + */ >>>>> +#define XIP_PHYS_ADDR(va)     \ >>>>> +     ((uintptr_t)(va) - PAGE_OFFSET + XIP_OFFSET + >>>>> CONFIG_XIP_PHYS_ADDR) >>>>> + >>>>> +#define XIP_VIRT_ADDR_START  XIP_VIRT_ADDR(CONFIG_XIP_PHYS_ADDR) >>>>> + >>>>> +#define XIP_FIXUP(addr)              ({ \ >>>>> +     uintptr_t __a = (uintptr_t)(addr); \ >>>>> +     (__a >= CONFIG_XIP_PHYS_ADDR && \ >>>>> +      __a < CONFIG_XIP_PHYS_ADDR + SZ_16M) ? \ >>>>> +     __a - CONFIG_XIP_PHYS_ADDR + CONFIG_PHYS_RAM_BASE - >>>>> XIP_OFFSET : __a; \ >>>>> +}) >>>>> +#else >>>>> +#define XIP_FIXUP(addr)              (addr) >>>>> +#endif /* CONFIG_XIP_KERNEL */ >>>>> >>>>>   #define BPF_JIT_REGION_SIZE  (SZ_128M) >>>>>   #define BPF_JIT_REGION_START (PAGE_OFFSET - BPF_JIT_REGION_SIZE) >>>>> @@ -484,8 +527,20 @@ static inline int >>>>> ptep_clear_flush_young(struct vm_area_struct *vma, >>>>> >>>>>   #define kern_addr_valid(addr)   (1) /* FIXME */ >>>>> >>>>> -extern void *dtb_early_va; >>>>> -extern uintptr_t dtb_early_pa; >>>>> +extern void *_dtb_early_va; >>>>> +extern uintptr_t _dtb_early_pa; >>>>> +#if defined(CONFIG_XIP_KERNEL) && defined(CONFIG_MMU) >>>>> + >>>>> +#define dtb_early_va (*(void **)XIP_FIXUP(&_dtb_early_va)) >>>>> +#define dtb_early_pa (*(uintptr_t *)XIP_FIXUP(&_dtb_early_pa)) >>>>> + >>>>> +#else >>>>> + >>>>> +#define dtb_early_va _dtb_early_va >>>>> +#define dtb_early_pa _dtb_early_pa >>>>> + >>>>> +#endif /* CONFIG_XIP_KERNEL */ >>>>> + >>>>>   void setup_bootmem(void); >>>>>   void paging_init(void); >>>>>   void misc_mem_init(void); >>>>> diff --git a/arch/riscv/kernel/cpu_ops_sbi.c >>>>> b/arch/riscv/kernel/cpu_ops_sbi.c >>>>> index 685fae72b7f5..2413c2997350 100644 >>>>> --- a/arch/riscv/kernel/cpu_ops_sbi.c >>>>> +++ b/arch/riscv/kernel/cpu_ops_sbi.c >>>>> @@ -53,10 +53,19 @@ static int sbi_hsm_hart_get_status(unsigned >>>>> long hartid) >>>>>   } >>>>>   #endif >>>>> >>>>> +static inline unsigned long get_secondary_start_phys(void) >>>>> +{ >>>>> +#ifdef CONFIG_XIP_KERNEL >>>>> +     return XIP_PHYS_ADDR(secondary_start_sbi); >>>>> +#else >>>>> +     return __pa_symbol(secondary_start_sbi); >>>>> +#endif >>>>> +} >>>>> + >>>>>   static int sbi_cpu_start(unsigned int cpuid, struct task_struct >>>>> *tidle) >>>>>   { >>>>>        int rc; >>>>> -     unsigned long boot_addr = __pa_symbol(secondary_start_sbi); >>>>> +     unsigned long boot_addr = get_secondary_start_phys(); >>>>>        int hartid = cpuid_to_hartid_map(cpuid); >>>>> >>>>>        cpu_update_secondary_bootdata(cpuid, tidle); >>>>> diff --git a/arch/riscv/kernel/head.S b/arch/riscv/kernel/head.S >>>>> index f5a9bad86e58..bbe74e37914f 100644 >>>>> --- a/arch/riscv/kernel/head.S >>>>> +++ b/arch/riscv/kernel/head.S >>>>> @@ -9,11 +9,23 @@ >>>>>   #include >>>>>   #include >>>>>   #include >>>>> +#include >>>>>   #include >>>>>   #include >>>>>   #include >>>>>   #include "efi-header.S" >>>>> >>>>> +#ifdef CONFIG_XIP_KERNEL >>>>> +.macro XIP_FIXUP_OFFSET reg >>>>> +     REG_L t0, _xip_fixup >>>>> +     add \reg, \reg, t0 >>>>> +.endm >>>>> +_xip_fixup: .dword CONFIG_PHYS_RAM_BASE - CONFIG_XIP_PHYS_ADDR - >>>>> XIP_OFFSET >>>>> +#else >>>>> +.macro XIP_FIXUP_OFFSET reg >>>>> +.endm >>>>> +#endif /* CONFIG_XIP_KERNEL */ >>>>> + >>>>>   __HEAD >>>>>   ENTRY(_start) >>>>>        /* >>>>> @@ -69,7 +81,11 @@ pe_head_start: >>>>>   #ifdef CONFIG_MMU >>>>>   relocate: >>>>>        /* Relocate return address */ >>>>> +#ifdef CONFIG_XIP_KERNEL >>>>> +     li a1, XIP_VIRT_ADDR(CONFIG_XIP_PHYS_ADDR) >>>>> +#else >>>>>        li a1, PAGE_OFFSET >>>>> +#endif >>>>>        la a2, _start >>>>>        sub a1, a1, a2 >>>>>        add ra, ra, a1 >>>>> @@ -91,6 +107,7 @@ relocate: >>>>>         * to ensure the new translations are in use. >>>>>         */ >>>>>        la a0, trampoline_pg_dir >>>>> +     XIP_FIXUP_OFFSET a0 >>>>>        srl a0, a0, PAGE_SHIFT >>>>>        or a0, a0, a1 >>>>>        sfence.vma >>>>> @@ -144,7 +161,9 @@ secondary_start_sbi: >>>>> >>>>>        slli a3, a0, LGREG >>>>>        la a4, __cpu_up_stack_pointer >>>>> +     XIP_FIXUP_OFFSET a4 >>>>>        la a5, __cpu_up_task_pointer >>>>> +     XIP_FIXUP_OFFSET a5 >>>>>        add a4, a3, a4 >>>>>        add a5, a3, a5 >>>>>        REG_L sp, (a4) >>>>> @@ -156,6 +175,7 @@ secondary_start_common: >>>>>   #ifdef CONFIG_MMU >>>>>        /* Enable virtual memory and relocate to virtual address */ >>>>>        la a0, swapper_pg_dir >>>>> +     XIP_FIXUP_OFFSET a0 >>>>>        call relocate >>>>>   #endif >>>>>        call setup_trap_vector >>>>> @@ -236,12 +256,33 @@ pmp_done: >>>>>   .Lgood_cores: >>>>>   #endif >>>>> >>>>> +#ifndef CONFIG_XIP_KERNEL >>>>>        /* Pick one hart to run the main boot sequence */ >>>>>        la a3, hart_lottery >>>>>        li a2, 1 >>>>>        amoadd.w a3, a2, (a3) >>>>>        bnez a3, .Lsecondary_start >>>>> >>>>> +#else >>>>> +     /* hart_lottery in flash contains a magic number */ >>>>> +     la a3, hart_lottery >>>>> +     mv a2, a3 >>>>> +     XIP_FIXUP_OFFSET a2 >>>>> +     lw t1, (a3) >>>>> +     amoswap.w t0, t1, (a2) >>>>> +     /* first time here if hart_lottery in RAM is not set */ >>>>> +     beq t0, t1, .Lsecondary_start >>>>> + >>>>> +     la sp, _end + THREAD_SIZE >>>>> +     XIP_FIXUP_OFFSET sp >>>>> +     mv s0, a0 >>>>> +     call __copy_data >>>>> + >>>>> +     /* Restore a0 copy */ >>>>> +     mv a0, s0 >>>>> +#endif >>>>> + >>>>> +#ifndef CONFIG_XIP_KERNEL >>>>>        /* Clear BSS for flat non-ELF images */ >>>>>        la a3, __bss_start >>>>>        la a4, __bss_stop >>>>> @@ -251,15 +292,18 @@ clear_bss: >>>>>        add a3, a3, RISCV_SZPTR >>>>>        blt a3, a4, clear_bss >>>>>   clear_bss_done: >>>>> - >>>>> +#endif >>>>>        /* Save hart ID and DTB physical address */ >>>>>        mv s0, a0 >>>>>        mv s1, a1 >>>>> + >>>>>        la a2, boot_cpu_hartid >>>>> +     XIP_FIXUP_OFFSET a2 >>>>>        REG_S a0, (a2) >>>>> >>>>>        /* Initialize page tables and relocate to virtual addresses */ >>>>>        la sp, init_thread_union + THREAD_SIZE >>>>> +     XIP_FIXUP_OFFSET sp >>>>>   #ifdef CONFIG_BUILTIN_DTB >>>>>        la a0, __dtb_start >>>>>   #else >>>>> @@ -268,6 +312,7 @@ clear_bss_done: >>>>>        call setup_vm >>>>>   #ifdef CONFIG_MMU >>>>>        la a0, early_pg_dir >>>>> +     XIP_FIXUP_OFFSET a0 >>>>>        call relocate >>>>>   #endif /* CONFIG_MMU */ >>>>> >>>>> @@ -292,7 +337,9 @@ clear_bss_done: >>>>> >>>>>        slli a3, a0, LGREG >>>>>        la a1, __cpu_up_stack_pointer >>>>> +     XIP_FIXUP_OFFSET a1 >>>>>        la a2, __cpu_up_task_pointer >>>>> +     XIP_FIXUP_OFFSET a2 >>>>>        add a1, a3, a1 >>>>>        add a2, a3, a2 >>>>> >>>>> diff --git a/arch/riscv/kernel/head.h b/arch/riscv/kernel/head.h >>>>> index b48dda3d04f6..aabbc3ac3e48 100644 >>>>> --- a/arch/riscv/kernel/head.h >>>>> +++ b/arch/riscv/kernel/head.h >>>>> @@ -12,6 +12,9 @@ extern atomic_t hart_lottery; >>>>> >>>>>   asmlinkage void do_page_fault(struct pt_regs *regs); >>>>>   asmlinkage void __init setup_vm(uintptr_t dtb_pa); >>>>> +#ifdef CONFIG_XIP_KERNEL >>>>> +asmlinkage void __init __copy_data(void); >>>>> +#endif >>>>> >>>>>   extern void *__cpu_up_stack_pointer[]; >>>>>   extern void *__cpu_up_task_pointer[]; >>>>> diff --git a/arch/riscv/kernel/setup.c b/arch/riscv/kernel/setup.c >>>>> index e85bacff1b50..a0384c72c272 100644 >>>>> --- a/arch/riscv/kernel/setup.c >>>>> +++ b/arch/riscv/kernel/setup.c >>>>> @@ -50,7 +50,11 @@ struct screen_info screen_info >>>>> __section(".data") = { >>>>>    * This is used before the kernel initializes the BSS so it can't >>>>> be in the >>>>>    * BSS. >>>>>    */ >>>>> -atomic_t hart_lottery __section(".sdata"); >>>>> +atomic_t hart_lottery __section(".sdata") >>>>> +#ifdef CONFIG_XIP_KERNEL >>>>> += ATOMIC_INIT(0xC001BEEF) >>>>> +#endif >>>>> +; >>>>>   unsigned long boot_cpu_hartid; >>>>>   static DEFINE_PER_CPU(struct cpu, cpu_devices); >>>>> >>>>> @@ -254,7 +258,7 @@ void __init setup_arch(char **cmdline_p) >>>>>   #if IS_ENABLED(CONFIG_BUILTIN_DTB) >>>>>        unflatten_and_copy_device_tree(); >>>>>   #else >>>>> -     if (early_init_dt_verify(__va(dtb_early_pa))) >>>>> +     if (early_init_dt_verify(__va(XIP_FIXUP(dtb_early_pa)))) >>>>>                unflatten_device_tree(); >>>>>        else >>>>>                pr_err("No DTB found in kernel mappings\n"); >>>>> diff --git a/arch/riscv/kernel/vmlinux-xip.lds.S >>>>> b/arch/riscv/kernel/vmlinux-xip.lds.S >>>>> new file mode 100644 >>>>> index 000000000000..9f0f08c34cd3 >>>>> --- /dev/null >>>>> +++ b/arch/riscv/kernel/vmlinux-xip.lds.S >>>>> @@ -0,0 +1,132 @@ >>>>> +/* SPDX-License-Identifier: GPL-2.0-only */ >>>>> +/* >>>>> + * Copyright (C) 2012 Regents of the University of California >>>>> + * Copyright (C) 2017 SiFive >>>>> + * Copyright (C) 2020 Vitaly Wool, Konsulko AB >>>>> + */ >>>>> + >>>>> +#define LOAD_OFFSET XIP_VIRT_ADDR(CONFIG_XIP_PHYS_ADDR) >>>>> +/* No __ro_after_init data in the .rodata section - which will >>>>> always be ro */ >>>>> +#define RO_AFTER_INIT_DATA >>>>> + >>>>> +#include >>>>> +#include >>>>> +#include >>>>> +#include >>>>> +#include >>>>> + >>>>> +OUTPUT_ARCH(riscv) >>>>> +ENTRY(_start) >>>>> + >>>>> +jiffies = jiffies_64; >>>>> + >>>>> +SECTIONS >>>>> +{ >>>>> +     /* Beginning of code and text segment */ >>>>> +     . = XIP_VIRT_ADDR(CONFIG_XIP_PHYS_ADDR); >>>>> +     _xiprom = .; >>>>> +     _start = .; >>>>> +     HEAD_TEXT_SECTION >>>>> +     INIT_TEXT_SECTION(PAGE_SIZE) >>>>> +     /* we have to discard exit text and such at runtime, not link >>>>> time */ >>>>> +     .exit.text : >>>>> +     { >>>>> +             EXIT_TEXT >>>>> +     } >>>>> + >>>>> +     .text : { >>>>> +             _text = .; >>>>> +             _stext = .; >>>>> +             TEXT_TEXT >>>>> +             SCHED_TEXT >>>>> +             CPUIDLE_TEXT >>>>> +             LOCK_TEXT >>>>> +             KPROBES_TEXT >>>>> +             ENTRY_TEXT >>>>> +             IRQENTRY_TEXT >>>>> +             SOFTIRQENTRY_TEXT >>>>> +             *(.fixup) >>>>> +             _etext = .; >>>>> +     } >>>>> +     RO_DATA(L1_CACHE_BYTES) >>>>> +     .srodata : { >>>>> +             *(.srodata*) >>>>> +     } >>>>> +     .init.rodata : { >>>>> +             INIT_SETUP(16) >>>>> +             INIT_CALLS >>>>> +             CON_INITCALL >>>>> +             INIT_RAM_FS >>>>> +     } >>>>> +     _exiprom = .;                   /* End of XIP ROM area */ >>>>> + >>>>> + >>>>> +/* >>>>> + * From this point, stuff is considered writable and will be >>>>> copied to RAM >>>>> + */ >>>>> +     __data_loc = ALIGN(16);         /* location in file */ >>>>> +     . = PAGE_OFFSET;                /* location in memory */ >>>>> + >>>>> +     _sdata = .;                     /* Start of data section */ >>>>> +     _data = .; >>>>> +     RW_DATA(L1_CACHE_BYTES, PAGE_SIZE, THREAD_SIZE) >>>>> +     _edata = .; >>>>> +     __start_ro_after_init = .; >>>>> +     .data.ro_after_init : AT(ADDR(.data.ro_after_init) - >>>>> LOAD_OFFSET) { >>>>> +             *(.data..ro_after_init) >>>>> +     } >>>>> +     __end_ro_after_init = .; >>>>> + >>>>> +     . = ALIGN(PAGE_SIZE); >>>>> +     __init_begin = .; >>>>> +     .init.data : { >>>>> +             INIT_DATA >>>>> +     } >>>>> +     .exit.data : { >>>>> +             EXIT_DATA >>>>> +     } >>>>> +     . = ALIGN(8); >>>>> +     __soc_early_init_table : { >>>>> +             __soc_early_init_table_start = .; >>>>> +             KEEP(*(__soc_early_init_table)) >>>>> +             __soc_early_init_table_end = .; >>>>> +     } >>>>> +     __soc_builtin_dtb_table : { >>>>> +             __soc_builtin_dtb_table_start = .; >>>>> +             KEEP(*(__soc_builtin_dtb_table)) >>>>> +             __soc_builtin_dtb_table_end = .; >>>>> +     } >>>>> +     PERCPU_SECTION(L1_CACHE_BYTES) >>>>> + >>>>> +     . = ALIGN(PAGE_SIZE); >>>>> +     __init_end = .; >>>>> + >>>>> +     .sdata : { >>>>> +             __global_pointer$ = . + 0x800; >>>>> +             *(.sdata*) >>>>> +             *(.sbss*) >>>>> +     } >>>>> + >>>>> +     BSS_SECTION(PAGE_SIZE, PAGE_SIZE, 0) >>>>> +     EXCEPTION_TABLE(0x10) >>>>> + >>>>> +     .rel.dyn : AT(ADDR(.rel.dyn) - LOAD_OFFSET) { >>>>> +             *(.rel.dyn*) >>>>> +     } >>>>> + >>>>> +     /* >>>>> +      * End of copied data. We need a dummy section to get its LMA. >>>>> +      * Also located before final ALIGN() as trailing padding is >>>>> not stored >>>>> +      * in the resulting binary file and useless to copy. >>>>> +      */ >>>>> +     .data.endmark : AT(ADDR(.data.endmark) - LOAD_OFFSET) { } >>>>> +     _edata_loc = LOADADDR(.data.endmark); >>>>> + >>>>> +     . = ALIGN(PAGE_SIZE); >>>>> +     _end = .; >>>>> + >>>>> +     STABS_DEBUG >>>>> +     DWARF_DEBUG >>>>> + >>>>> +     DISCARDS >>>>> +} >>>>> diff --git a/arch/riscv/kernel/vmlinux.lds.S >>>>> b/arch/riscv/kernel/vmlinux.lds.S >>>>> index de03cb22d0e9..6745ec325930 100644 >>>>> --- a/arch/riscv/kernel/vmlinux.lds.S >>>>> +++ b/arch/riscv/kernel/vmlinux.lds.S >>>>> @@ -4,7 +4,12 @@ >>>>>    * Copyright (C) 2017 SiFive >>>>>    */ >>>>> >>>>> +#ifdef CONFIG_XIP_KERNEL >>>>> +#include "vmlinux-xip.lds.S" >>>>> +#else >>>>> + >>>>>   #define LOAD_OFFSET PAGE_OFFSET >>>>> + >>>>>   #include >>>>>   #include >>>>>   #include >>>>> @@ -132,3 +137,4 @@ SECTIONS >>>>> >>>>>        DISCARDS >>>>>   } >>>>> +#endif /* CONFIG_XIP_KERNEL */ >>>>> diff --git a/arch/riscv/mm/init.c b/arch/riscv/mm/init.c >>>>> index 7f5036fbee8c..efe649d41f95 100644 >>>>> --- a/arch/riscv/mm/init.c >>>>> +++ b/arch/riscv/mm/init.c >>>>> @@ -31,8 +31,8 @@ EXPORT_SYMBOL(empty_zero_page); >>>>> >>>>>   extern char _start[]; >>>>>   #define DTB_EARLY_BASE_VA      PGDIR_SIZE >>>>> -void *dtb_early_va __initdata; >>>>> -uintptr_t dtb_early_pa __initdata; >>>>> +void *_dtb_early_va __initdata; >>>>> +uintptr_t _dtb_early_pa __initdata; >>>>> >>>>>   struct pt_alloc_ops { >>>>>        pte_t *(*get_pte_virt)(phys_addr_t pa); >>>>> @@ -88,6 +88,10 @@ static void print_vm_layout(void) >>>>>                  (unsigned long)VMALLOC_END); >>>>>        print_mlm("lowmem", (unsigned long)PAGE_OFFSET, >>>>>                  (unsigned long)high_memory); >>>>> +#ifdef CONFIG_XIP_KERNEL >>>>> +     print_mlm("xip", (unsigned long)XIP_VIRT_ADDR_START, >>>>> +               (unsigned long)XIP_VIRT_ADDR_START + SZ_16M); >>>>> +#endif /* CONFIG_XIP_KERNEL */ >>>>>   } >>>>>   #else >>>>>   static void print_vm_layout(void) { } >>>>> @@ -113,6 +117,10 @@ void __init setup_bootmem(void) >>>>>        phys_addr_t dram_end = memblock_end_of_DRAM(); >>>>>        phys_addr_t max_mapped_addr = __pa(~(ulong)0); >>>>> >>>>> +#ifdef CONFIG_XIP_KERNEL >>>>> +     vmlinux_start = __pa_symbol(&_sdata); >>>>> +#endif >>>>> + >>>>>        /* The maximal physical memory size is -PAGE_OFFSET. */ >>>>>        memblock_enforce_memory_limit(-PAGE_OFFSET); >>>>> >>>>> @@ -149,11 +157,27 @@ void __init setup_bootmem(void) >>>>>        memblock_allow_resize(); >>>>>   } >>>>> >>>>> +#ifdef CONFIG_XIP_KERNEL >>>>> + >>>>> +extern char _xiprom[], _exiprom[]; >>>>> +extern char _sdata[], _edata[]; >>>>> + >>>>> +#endif /* CONFIG_XIP_KERNEL */ >>>>> + >>>>>   #ifdef CONFIG_MMU >>>>> -static struct pt_alloc_ops pt_ops; >>>>> +static struct pt_alloc_ops _pt_ops; >>>>> + >>>>> +#ifdef CONFIG_XIP_KERNEL >>>>> +#define pt_ops (*(struct pt_alloc_ops *)XIP_FIXUP(&_pt_ops)) >>>>> +#else >>>>> +#define pt_ops       _pt_ops >>>>> +#endif >>>>> >>>>>   unsigned long va_pa_offset; >>>>>   EXPORT_SYMBOL(va_pa_offset); >>>>> +#ifdef CONFIG_XIP_KERNEL >>>>> +#define va_pa_offset (*((unsigned long *)XIP_FIXUP(&va_pa_offset))) >>>>> +#endif >>>>>   unsigned long pfn_base; >>>>>   EXPORT_SYMBOL(pfn_base); >>>>> >>>>> @@ -163,6 +187,12 @@ pte_t fixmap_pte[PTRS_PER_PTE] >>>>> __page_aligned_bss; >>>>> >>>>>   pgd_t early_pg_dir[PTRS_PER_PGD] __initdata __aligned(PAGE_SIZE); >>>>> >>>>> +#ifdef CONFIG_XIP_KERNEL >>>>> +#define trampoline_pg_dir    ((pgd_t *)XIP_FIXUP(trampoline_pg_dir)) >>>>> +#define fixmap_pte           ((pte_t *)XIP_FIXUP(fixmap_pte)) >>>>> +#define early_pg_dir         ((pgd_t *)XIP_FIXUP(early_pg_dir)) >>>>> +#endif /* CONFIG_XIP_KERNEL */ >>>>> + >>>>>   void __set_fixmap(enum fixed_addresses idx, phys_addr_t phys, >>>>> pgprot_t prot) >>>>>   { >>>>>        unsigned long addr = __fix_to_virt(idx); >>>>> @@ -238,6 +268,15 @@ pmd_t fixmap_pmd[PTRS_PER_PMD] >>>>> __page_aligned_bss; >>>>>   pmd_t early_pmd[PTRS_PER_PMD] __initdata __aligned(PAGE_SIZE); >>>>>   pmd_t early_dtb_pmd[PTRS_PER_PMD] __initdata __aligned(PAGE_SIZE); >>>>> >>>>> +#ifdef CONFIG_XIP_KERNEL >>>>> +pmd_t xip_pmd[PTRS_PER_PMD] __page_aligned_bss; >>>>> + >>>>> +#define trampoline_pmd       ((pmd_t *)XIP_FIXUP(trampoline_pmd)) >>>>> +#define fixmap_pmd   ((pmd_t *)XIP_FIXUP(fixmap_pmd)) >>>>> +#define xip_pmd              ((pmd_t *)XIP_FIXUP(xip_pmd)) >>>>> +#define early_pmd    ((pmd_t *)XIP_FIXUP(early_pmd)) >>>>> +#endif /* CONFIG_XIP_KERNEL */ >>>>> + >>>>>   static pmd_t *__init get_pmd_virt_early(phys_addr_t pa) >>>>>   { >>>>>        /* Before MMU is enabled */ >>>>> @@ -354,6 +393,19 @@ static uintptr_t __init >>>>> best_map_size(phys_addr_t base, phys_addr_t size) >>>>>        return PMD_SIZE; >>>>>   } >>>>> >>>>> +#ifdef CONFIG_XIP_KERNEL >>>>> +/* called from head.S with MMU off */ >>>>> +asmlinkage void __init __copy_data(void) >>>>> +{ >>>>> +     void *from = (void *)(&_sdata); >>>>> +     void *end = (void *)(&_end); >>>>> +     void *to = (void *)CONFIG_PHYS_RAM_BASE; >>>>> +     size_t sz = (size_t)(end - from); >>>>> + >>>>> +     memcpy(to, from, sz); >>>>> +} >>>>> +#endif >>>>> + >>>>>   /* >>>>>    * setup_vm() is called from head.S with MMU-off. >>>>>    * >>>>> @@ -374,7 +426,8 @@ static uintptr_t __init >>>>> best_map_size(phys_addr_t base, phys_addr_t size) >>>>> >>>>>   asmlinkage void __init setup_vm(uintptr_t dtb_pa) >>>>>   { >>>>> -     uintptr_t va, pa, end_va; >>>>> +     uintptr_t va, end_va; >>>>> +     uintptr_t __maybe_unused pa; >>>>>        uintptr_t load_pa = (uintptr_t)(&_start); >>>>>        uintptr_t load_sz = (uintptr_t)(&_end) - load_pa; >>>>>        uintptr_t map_size; >>>>> @@ -382,6 +435,13 @@ asmlinkage void __init setup_vm(uintptr_t dtb_pa) >>>>>        pmd_t fix_bmap_spmd, fix_bmap_epmd; >>>>>   #endif >>>>> >>>>> +#ifdef CONFIG_XIP_KERNEL >>>>> +     uintptr_t xiprom = (uintptr_t)CONFIG_XIP_PHYS_ADDR; >>>>> +     uintptr_t xiprom_sz = (uintptr_t)(&_exiprom) - >>>>> (uintptr_t)(&_xiprom); >>>>> + >>>>> +     load_pa = (uintptr_t)CONFIG_PHYS_RAM_BASE; >>>>> +     load_sz = (uintptr_t)(&_end) - (uintptr_t)(&_sdata); >>>>> +#endif >>>>>        va_pa_offset = PAGE_OFFSET - load_pa; >> >> I should have seen this before, I was too focused on having a XIP kernel >> boot. I already moved the kernel mapping in the vmalloc zone: the >> virtual to physical translations need to be handled differently now that >> the kernel mapping does not lie into linear mapping anymore, we can't >> use va_pa_offset defined above for both mappings. >> >> I was rebasing my patchset on the XIP patch but I believe that doing the >> other way around would greatly simplify the XIP patch as the kernel >> mapping would already be moved outside the linear mapping, there would >> be no need to reserve a zone in vmalloc anymore (that simplifies >> pgtable.h quite a lot). And the XIP kernel mapping could be implemented >> in a new create_kernel_page_table (that would also simplify mm/init.c). >> >> I can help to do that but I don't think we should merge this patch as is >> now. > > I think that's the right way to go for now: it's a lot harder to test > the XIP stuff, as it requires a bunch of harness changes.  So let's take > the page table refactoring in now and rebase this stuff on top of it. > There's really no way to do both without making more work for someone, > it's just a headache on timing. > > Alex: if you want to sign up to spend some time there that'd be great, > otherwise I will. I can take care of that, no problem. > Either way, can you point me (either just indicate > the old version is OK or send a new one) to what you want me to look at > WRT the page table code?  IIRC it looked pretty much fine, but I'll take > another look ASAP so we can avoid serializing everything. The v3 is fine for me: https://patchwork.kernel.org/project/linux-riscv/list/?series=447699 > >> >> Alex >> >>>>>        pfn_base = PFN_DOWN(load_pa); >>>>> >>>>> @@ -420,6 +480,21 @@ asmlinkage void __init setup_vm(uintptr_t dtb_pa) >>>>>                           load_pa, PGDIR_SIZE, PAGE_KERNEL_EXEC); >>>>>   #endif >>>>> >>>>> +#ifdef CONFIG_XIP_KERNEL >>>>> +     create_pgd_mapping(trampoline_pg_dir, XIP_VIRT_ADDR_START, >>>>> +                        (uintptr_t)xip_pmd, PGDIR_SIZE, PAGE_TABLE); >>>>> +     for (va = XIP_VIRT_ADDR_START; >>>>> +          va < XIP_VIRT_ADDR_START + xiprom_sz; >>>>> +          va += PMD_SIZE) { >>>>> +             create_pmd_mapping(xip_pmd, va, >>>>> +                                xiprom + (va - XIP_VIRT_ADDR_START), >>>>> +                                PMD_SIZE, PAGE_KERNEL_EXEC); >>>>> +     } >>>>> + >>>>> +     create_pgd_mapping(early_pg_dir, XIP_VIRT_ADDR_START, >>>>> +                        (uintptr_t)xip_pmd, PGDIR_SIZE, PAGE_TABLE); >>>>> +#endif >>>>> + >>>>>        /* >>>>>         * Setup early PGD covering entire kernel which will allows >>>>>         * us to reach paging_init(). We map all memory banks later >>>>> @@ -444,7 +519,7 @@ asmlinkage void __init setup_vm(uintptr_t dtb_pa) >>>>>                           pa + PMD_SIZE, PMD_SIZE, PAGE_KERNEL); >>>>>        dtb_early_va = (void *)DTB_EARLY_BASE_VA + (dtb_pa & >>>>> (PMD_SIZE - 1)); >>>>>   #else /* CONFIG_BUILTIN_DTB */ >>>>> -     dtb_early_va = __va(dtb_pa); >>>>> +     dtb_early_va = __va(XIP_FIXUP(dtb_pa)); >>>>>   #endif /* CONFIG_BUILTIN_DTB */ >>>>>   #else >>>>>   #ifndef CONFIG_BUILTIN_DTB >>>>> @@ -456,7 +531,7 @@ asmlinkage void __init setup_vm(uintptr_t dtb_pa) >>>>>                           pa + PGDIR_SIZE, PGDIR_SIZE, PAGE_KERNEL); >>>>>        dtb_early_va = (void *)DTB_EARLY_BASE_VA + (dtb_pa & >>>>> (PGDIR_SIZE - 1)); >>>>>   #else /* CONFIG_BUILTIN_DTB */ >>>>> -     dtb_early_va = __va(dtb_pa); >>>>> +     dtb_early_va = __va(XIP_FIXUP(dtb_pa)); >>>>>   #endif /* CONFIG_BUILTIN_DTB */ >>>>>   #endif >>>>>        dtb_early_pa = dtb_pa; >>>>> @@ -497,6 +572,9 @@ static void __init setup_vm_final(void) >>>>>        uintptr_t va, map_size; >>>>>        phys_addr_t pa, start, end; >>>>>        u64 i; >>>>> +#ifdef CONFIG_XIP_KERNEL >>>>> +     uintptr_t xiprom_sz = (uintptr_t)(&_exiprom) - >>>>> (uintptr_t)(&_xiprom); >>>>> +#endif >>>>> >>>>>        /** >>>>>         * MMU is enabled at this point. But page table setup is not >>>>> complete yet. >>>>> @@ -528,6 +606,16 @@ static void __init setup_vm_final(void) >>>>>                                           map_size, PAGE_KERNEL_EXEC); >>>>>                } >>>>>        } >>>>> +#ifdef CONFIG_XIP_KERNEL >>>>> +     map_size = best_map_size(CONFIG_XIP_PHYS_ADDR, xiprom_sz); >>>>> +     for (va = XIP_VIRT_ADDR_START; >>>>> +          va < XIP_VIRT_ADDR_START + xiprom_sz; >>>>> +          va += map_size) >>>>> +             create_pgd_mapping(swapper_pg_dir, va, >>>>> +                                CONFIG_XIP_PHYS_ADDR + (va - >>>>> XIP_VIRT_ADDR_START), >>>>> +                                map_size, PAGE_KERNEL_EXEC); >>>>> + >>>>> +#endif >>>>> >>>>>        /* Clear fixmap PTE and PMD mappings */ >>>>>        clear_fixmap(FIX_PTE); >>> >>> _______________________________________________ >>> linux-riscv mailing list >>> linux-riscv@lists.infradead.org >>> http://lists.infradead.org/mailman/listinfo/linux-riscv >>> > > _______________________________________________ > linux-riscv mailing list > linux-riscv@lists.infradead.org > http://lists.infradead.org/mailman/listinfo/linux-riscv From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org X-Spam-Level: X-Spam-Status: No, score=-15.3 required=3.0 tests=BAYES_00,DKIMWL_WL_HIGH, DKIM_SIGNED,DKIM_VALID,HEADER_FROM_DIFFERENT_DOMAINS,INCLUDES_CR_TRAILER, INCLUDES_PATCH,MAILING_LIST_MULTI,NICE_REPLY_A,SPF_HELO_NONE,SPF_PASS, URIBL_BLOCKED,USER_AGENT_SANE_1 autolearn=ham autolearn_force=no version=3.4.0 Received: from mail.kernel.org (mail.kernel.org [198.145.29.99]) by smtp.lore.kernel.org (Postfix) with ESMTP id 2DA68C433DB for ; Tue, 30 Mar 2021 20:04:59 +0000 (UTC) Received: from desiato.infradead.org (desiato.infradead.org [90.155.92.199]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by mail.kernel.org (Postfix) with ESMTPS id B66F3619CA for ; Tue, 30 Mar 2021 20:04:57 +0000 (UTC) DMARC-Filter: OpenDMARC Filter v1.3.2 mail.kernel.org B66F3619CA Authentication-Results: mail.kernel.org; dmarc=none (p=none dis=none) header.from=ghiti.fr Authentication-Results: mail.kernel.org; spf=none smtp.mailfrom=linux-riscv-bounces+linux-riscv=archiver.kernel.org@lists.infradead.org DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; d=lists.infradead.org; s=desiato.20200630; h=Sender:Content-Type: Content-Transfer-Encoding:List-Subscribe:List-Help:List-Post:List-Archive: List-Unsubscribe:List-Id:In-Reply-To:MIME-Version:Date:Message-ID:From: References:Cc:To:Subject:Reply-To:Content-ID:Content-Description:Resent-Date: Resent-From:Resent-Sender:Resent-To:Resent-Cc:Resent-Message-ID:List-Owner; bh=T8LL6xZN3zmrVAbNW4I+vNTlf4ltmtuJLyMBG/s3l1Q=; b=fOdvLWfO834dtsR2KZHMm2kAH JGLJBRBf0rLrHQMw7f5xfxkx4iKgKRPndqaX1WRhDx/ww59LUe7F+U2hJW1mjowyR8M/zFgm3/eea AXhScDxZgKcnzB808JntD5xB/zxL4QKv4TuBdAIhR1dlaeZAQLSV2/eMDxH8bVALJlhXqOEopTIEE 3l0/2DOoHblgqoJYA+7ISliHbtbG3efy95KuJF8ga1VqU/jmdWB22ux7uEQgqP5ouhF9egIneEHK5 H2J+B3wc5jrvueUbnv979nh1R7aN6Cpw90orEeifoCo3DaCPkYzUtnW9XkI4is0m97nyUDZT/oOFT T+Sjo6C0g==; Received: from localhost ([::1] helo=desiato.infradead.org) by desiato.infradead.org with esmtp (Exim 4.94 #2 (Red Hat Linux)) id 1lRKbJ-004lZX-Oj; Tue, 30 Mar 2021 20:04:34 +0000 Received: from relay12.mail.gandi.net ([217.70.178.232]) by desiato.infradead.org with esmtps (Exim 4.94 #2 (Red Hat Linux)) id 1lRKb8-004lYk-9H for linux-riscv@lists.infradead.org; Tue, 30 Mar 2021 20:04:26 +0000 Received: from [192.168.1.100] (lfbn-lyo-1-457-219.w2-7.abo.wanadoo.fr [2.7.49.219]) (Authenticated sender: alex@ghiti.fr) by relay12.mail.gandi.net (Postfix) with ESMTPSA id 8CAD2200003; Tue, 30 Mar 2021 20:04:18 +0000 (UTC) Subject: Re: [PATCH v6] RISC-V: enable XIP To: Palmer Dabbelt Cc: vitaly.wool@konsulko.com, linux-riscv@lists.infradead.org, linux-kernel@vger.kernel.org, bin.meng@windriver.com, anup@brainfault.org, Alistair Francis , nico@fluxnic.net References: From: Alex Ghiti Message-ID: Date: Tue, 30 Mar 2021 16:04:18 -0400 User-Agent: Mozilla/5.0 (X11; Linux x86_64; rv:78.0) Gecko/20100101 Thunderbird/78.9.0 MIME-Version: 1.0 In-Reply-To: Content-Language: fr X-CRM114-Version: 20100106-BlameMichelson ( TRE 0.8.0 (BSD) ) MR-646709E3 X-CRM114-CacheID: sfid-20210330_210423_076681_F574AC38 X-CRM114-Status: GOOD ( 27.49 ) X-BeenThere: linux-riscv@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-riscv" Errors-To: linux-riscv-bounces+linux-riscv=archiver.kernel.org@lists.infradead.org TGUgMy8zMC8yMSDDoCAzOjMzIFBNLCBQYWxtZXIgRGFiYmVsdCBhIMOpY3JpdMKgOgo+IE9uIFR1 ZSwgMzAgTWFyIDIwMjEgMTE6Mzk6MTAgUERUICgtMDcwMCksIGFsZXhAZ2hpdGkuZnIgd3JvdGU6 Cj4+Cj4+Cj4+IExlIDMvMzAvMjEgw6AgMjoyNiBBTSwgVml0YWx5IFdvb2wgYSDDqWNyaXTCoDoK Pj4+IE9uIFR1ZSwgTWFyIDMwLCAyMDIxIGF0IDg6MjMgQU0gUGFsbWVyIERhYmJlbHQgCj4+PiA8 cGFsbWVyZGFiYmVsdEBnb29nbGUuY29tPiB3cm90ZToKPj4+Pgo+Pj4+IE9uIFN1biwgMjEgTWFy IDIwMjEgMTc6MTI6MTUgUERUICgtMDcwMCksIHZpdGFseS53b29sQGtvbnN1bGtvLmNvbSAKPj4+ PiB3cm90ZToKPj4+Pj4gSW50cm9kdWNlIFhJUCAoZVhlY3V0ZSBJbiBQbGFjZSkgc3VwcG9ydCBm b3IgUklTQy1WIHBsYXRmb3Jtcy4KPj4+Pj4gSXQgYWxsb3dzIGNvZGUgdG8gYmUgZXhlY3V0ZWQg ZGlyZWN0bHkgZnJvbSBub24tdm9sYXRpbGUgc3RvcmFnZQo+Pj4+PiBkaXJlY3RseSBhZGRyZXNz YWJsZSBieSB0aGUgQ1BVLCBzdWNoIGFzIFFTUEkgTk9SIGZsYXNoIHdoaWNoIGNhbgo+Pj4+PiBi ZSBmb3VuZCBvbiBtYW55IFJJU0MtViBwbGF0Zm9ybXMuIFRoaXMgbWFrZXMgd2F5IGZvciBzaWdu aWZpY2FudAo+Pj4+PiBvcHRpbWl6YXRpb24gb2YgUkFNIGZvb3RwcmludC4gVGhlIFhJUCBrZXJu ZWwgaXMgbm90IGNvbXByZXNzZWQKPj4+Pj4gc2luY2UgaXQgaGFzIHRvIHJ1biBkaXJlY3RseSBm cm9tIGZsYXNoLCBzbyBpdCB3aWxsIG9jY3VweSBtb3JlCj4+Pj4+IHNwYWNlIG9uIHRoZSBub24t dm9sYXRpbGUgc3RvcmFnZS4gVGhlIHBoeXNpY2FsIGZsYXNoIGFkZHJlc3MgdXNlZAo+Pj4+PiB0 byBsaW5rIHRoZSBrZXJuZWwgb2JqZWN0IGZpbGVzIGFuZCBmb3Igc3RvcmluZyBpdCBoYXMgdG8g YmUga25vd24KPj4+Pj4gYXQgY29tcGlsZSB0aW1lIGFuZCBpcyByZXByZXNlbnRlZCBieSBhIEtj b25maWcgb3B0aW9uLgo+Pj4+Pgo+Pj4+PiBYSVAgb24gUklTQy1WIHdpbGwgZm9yIHRoZSB0aW1l IGJlaW5nIG9ubHkgd29yayBvbiBNTVUtZW5hYmxlZAo+Pj4+PiBrZXJuZWxzLgo+Pj4+Pgo+Pj4+ PiBTaWduZWQtb2ZmLWJ5OiBWaXRhbHkgV29vbCA8dml0YWx5Lndvb2xAa29uc3Vsa28uY29tPgo+ Pj4+Pgo+Pj4+PiAtLS0KPj4+Pj4KPj4+Pj4gQ2hhbmdlcyBpbiB2MjoKPj4+Pj4gLSBkZWRpY2F0 ZWQgbWFjcm8gZm9yIFhJUCBhZGRyZXNzIGZpeHVwIHdoZW4gTU1VIGlzIG5vdCBlbmFibGVkIHll dAo+Pj4+PiDCoMKgIG8gYm90aCBmb3IgMzItYml0IGFuZCA2NC1iaXQgUklTQy1WCj4+Pj4+IC0g U1AgaXMgZXhwbGljaXRseSBzZXQgdG8gYSBzYWZlIHBsYWNlIGluIFJBTSBiZWZvcmUgX19jb3B5 X2RhdGEgY2FsbAo+Pj4+PiAtIHJlbW92ZWQgcmVkdW5kYW50IGFsaWdubWVudCByZXF1aXJlbWVu dHMgaW4gdm1saW51eC14aXAubGRzLlMKPj4+Pj4gLSBjaGFuZ2VkIGxvbmcgLT4gdWludHB0cl90 IHR5cGVjYXN0IGluIF9fWElQX0ZJWFVQIG1hY3JvLgo+Pj4+PiBDaGFuZ2VzIGluIHYzOgo+Pj4+ PiAtIHJlYmFzZWQgYWdhaW5zdCBsYXRlc3QgZm9yLW5leHQKPj4+Pj4gLSBYSVAgYWRkcmVzcyBm aXh1cCBtYWNybyBub3cgdGFrZXMgYW4gYXJndW1lbnQKPj4+Pj4gLSBTTVAgcmVsYXRlZCBmaXhl cwo+Pj4+PiBDaGFuZ2VzIGluIHY0Ogo+Pj4+PiAtIHJlYmFzZWQgYWdhaW5zdCB0aGUgY3VycmVu dCBmb3ItbmV4dAo+Pj4+PiAtIGxlc3MgI2lmZGVmJ3MgaW4gQy9BU00gY29kZQo+Pj4+PiAtIGRl ZGljYXRlZCBYSVBfRklYVVBfT0ZGU0VUIGFzc2VtYmxlciBtYWNybyBpbiBoZWFkLlMKPj4+Pj4g LSBDLXNwZWNpZmljIGRlZmluaXRpb25zIG1vdmVkIGludG8gI2lmbmRlZiBfX0FTU0VNQkxZX18K Pj4+Pj4gLSBGaXhlZCBtdWx0aS1jb3JlIGJvb3QKPj4+Pj4gQ2hhbmdlcyBpbiB2NToKPj4+Pj4g LSBmaXhlZCBidWlsZCBlcnJvciBmb3Igbm9uLVhJUCBrZXJuZWxzCj4+Pj4+IENoYW5nZXMgaW4g djY6Cj4+Pj4+IC0gWElQX1BIWVNfUkFNX0JBU0UgY29uZmlnIG9wdGlvbiByZW5hbWVkIHRvIFBI WVNfUkFNX0JBU0UKPj4+Pj4gLSBhZGRlZCBQSFlTX1JBTV9CQVNFX0ZJWEVEIGNvbmZpZyBmbGFn IHRvIGFsbG93IHVzYWdlIG9mCj4+Pj4+IMKgwqAgUEhZU19SQU1fQkFTRSBpbiBub24tWElQIGNv bmZpZ3VyYXRpb25zIGlmIG5lZWRlZAo+Pj4+PiAtIFhJUF9GSVhVUCBtYWNybyByZXdyaXR0ZW4g d2l0aCBhIHRlbXBvYXJhcnkgdmFyaWFibGUgdG8gYXZvaWQgc2lkZQo+Pj4+PiDCoMKgIGVmZmVj dHMKPj4+Pj4gLSBmaXhlZCBjcmFzaCBmb3Igbm9uLVhJUCBrZXJuZWxzIHRoYXQgZG9uJ3QgdXNl IGJ1aWx0LWluIERUQgo+Pj4+Cj4+Pj4gU28gdjUgbGFuZGVkIG9uIGZvci1uZXh0LCB3aGljaCBn ZW5lcmFsbHkgbWVhbnMgaXQncyBiZXN0IHRvIGF2b2lkCj4+Pj4gcmUtc3Bpbm5pbmcgdGhlIHBh dGNoIGFuZCBpbnN0ZWFkIHNlbmQgYWxvbmcgZml4dXBzLsKgIFRoYXQgc2FpZCwgdGhlIHY1Cj4+ Pj4gaXMgY2F1c2luZyBzb21lIHRlc3RpbmcgZmFpbHVyZXMgZm9yIG1lLgo+Pj4+Cj4+Pj4gSSdt IGdvaW5nIHRvIGRyb3AgdGhlIHY1IGZvciBub3cgYXMgSSBkb24ndCBoYXZlIHRpbWUgdG8gdGVz dCB0aGlzCj4+Pj4gdG9uaWdodC7CoCBJJ2xsIHRyeSBhbmQgdGFrZSBhIGxvb2sgc29vbiwgYXMg aXQgd2lsbCBjb25mbGljdCB3aXRoIAo+Pj4+IEFsZXgncwo+Pj4+IHBhdGNoZXMuCj4+Pgo+Pj4g SSBjYW4gY29tZSB1cCB3aXRoIHRoZSBpbmNyZW1lbnRhbCBwYXRjaCBpbnN0ZWFkIHByZXR0eSBt dWNoIHN0cmFpZ2h0Cj4+PiBhd2F5IGlmIHRoYXQgd29ya3MgYmV0dGVyLgo+Pj4KPj4+IH5WaXRh bHkKPj4+Cj4+Pj4+IMKgIGFyY2gvcmlzY3YvS2NvbmZpZ8KgwqDCoMKgwqDCoMKgwqDCoMKgwqDC oMKgwqDCoMKgwqAgfMKgIDQ5ICsrKysrKysrKystCj4+Pj4+IMKgIGFyY2gvcmlzY3YvTWFrZWZp bGXCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoCB8wqDCoCA4ICstCj4+Pj4+IMKgIGFy Y2gvcmlzY3YvYm9vdC9NYWtlZmlsZcKgwqDCoMKgwqDCoMKgwqDCoMKgwqAgfMKgIDEzICsrKwo+ Pj4+PiDCoCBhcmNoL3Jpc2N2L2luY2x1ZGUvYXNtL3BndGFibGUuaMKgwqDCoCB8wqAgNjUgKysr KysrKysrKysrLS0KPj4+Pj4gwqAgYXJjaC9yaXNjdi9rZXJuZWwvY3B1X29wc19zYmkuY8KgwqDC oMKgIHzCoCAxMSArKy0KPj4+Pj4gwqAgYXJjaC9yaXNjdi9rZXJuZWwvaGVhZC5TwqDCoMKgwqDC oMKgwqDCoMKgwqDCoCB8wqAgNDkgKysrKysrKysrKy0KPj4+Pj4gwqAgYXJjaC9yaXNjdi9rZXJu ZWwvaGVhZC5owqDCoMKgwqDCoMKgwqDCoMKgwqDCoCB8wqDCoCAzICsKPj4+Pj4gwqAgYXJjaC9y aXNjdi9rZXJuZWwvc2V0dXAuY8KgwqDCoMKgwqDCoMKgwqDCoMKgIHzCoMKgIDggKy0KPj4+Pj4g wqAgYXJjaC9yaXNjdi9rZXJuZWwvdm1saW51eC14aXAubGRzLlMgfCAxMzIgCj4+Pj4+ICsrKysr KysrKysrKysrKysrKysrKysrKysrKysKPj4+Pj4gwqAgYXJjaC9yaXNjdi9rZXJuZWwvdm1saW51 eC5sZHMuU8KgwqDCoMKgIHzCoMKgIDYgKysKPj4+Pj4gwqAgYXJjaC9yaXNjdi9tbS9pbml0LmPC oMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqAgfCAxMDAgKysrKysrKysrKysrKysrKysrKy0t Cj4+Pj4+IMKgIDExIGZpbGVzIGNoYW5nZWQsIDQyNiBpbnNlcnRpb25zKCspLCAxOCBkZWxldGlv bnMoLSkKPj4+Pj4gwqAgY3JlYXRlIG1vZGUgMTAwNjQ0IGFyY2gvcmlzY3Yva2VybmVsL3ZtbGlu dXgteGlwLmxkcy5TCj4+Pj4+Cj4+Pj4+IGRpZmYgLS1naXQgYS9hcmNoL3Jpc2N2L0tjb25maWcg Yi9hcmNoL3Jpc2N2L0tjb25maWcKPj4+Pj4gaW5kZXggOGVhNjBhMGExOWFlLi5iZDZmODIyNDBj MzQgMTAwNjQ0Cj4+Pj4+IC0tLSBhL2FyY2gvcmlzY3YvS2NvbmZpZwo+Pj4+PiArKysgYi9hcmNo L3Jpc2N2L0tjb25maWcKPj4+Pj4gQEAgLTQ0MSw3ICs0NDEsNyBAQCBjb25maWcgRUZJX1NUVUIK Pj4+Pj4KPj4+Pj4gwqAgY29uZmlnIEVGSQo+Pj4+PiDCoMKgwqDCoMKgwqAgYm9vbCAiVUVGSSBy dW50aW1lIHN1cHBvcnQiCj4+Pj4+IC3CoMKgwqDCoCBkZXBlbmRzIG9uIE9GCj4+Pj4+ICvCoMKg wqDCoCBkZXBlbmRzIG9uIE9GICYmICFYSVBfS0VSTkVMCj4+Pj4+IMKgwqDCoMKgwqDCoCBzZWxl Y3QgTElCRkRUCj4+Pj4+IMKgwqDCoMKgwqDCoCBzZWxlY3QgVUNTMl9TVFJJTkcKPj4+Pj4gwqDC oMKgwqDCoMKgIHNlbGVjdCBFRklfUEFSQU1TX0ZST01fRkRUCj4+Pj4+IEBAIC00NjUsMTEgKzQ2 NSw1NiBAQCBjb25maWcgU1RBQ0tQUk9URUNUT1JfUEVSX1RBU0sKPj4+Pj4gwqDCoMKgwqDCoMKg IGRlZl9ib29sIHkKPj4+Pj4gwqDCoMKgwqDCoMKgIGRlcGVuZHMgb24gU1RBQ0tQUk9URUNUT1Ig JiYgQ0NfSEFWRV9TVEFDS1BST1RFQ1RPUl9UTFMKPj4+Pj4KPj4+Pj4gK2NvbmZpZyBQSFlTX1JB TV9CQVNFX0ZJWEVECj4+Pj4+ICvCoMKgwqDCoCBib29sICJFeHBsaWNpdGx5IHNwZWNpZmllZCBw aHlzaWNhbCBSQU0gYWRkcmVzcyIKPj4+Pj4gK8KgwqDCoMKgIGRlZmF1bHQgbgo+Pj4+PiArCj4+ Pj4+ICtjb25maWcgUEhZU19SQU1fQkFTRQo+Pj4+PiArwqDCoMKgwqAgaGV4ICJQbGF0Zm9ybSBQ aHlzaWNhbCBSQU0gYWRkcmVzcyIKPj4+Pj4gK8KgwqDCoMKgIGRlcGVuZHMgb24gUEhZU19SQU1f QkFTRV9GSVhFRAo+Pj4+PiArwqDCoMKgwqAgZGVmYXVsdCAiMHg4MDAwMDAwMCIKPj4+Pj4gK8Kg wqDCoMKgIGhlbHAKPj4+Pj4gK8KgwqDCoMKgwqDCoCBUaGlzIGlzIHRoZSBwaHlzaWNhbCBhZGRy ZXNzIG9mIFJBTSBpbiB0aGUgc3lzdGVtLiBJdCBoYXMgCj4+Pj4+IHRvIGJlCj4+Pj4+ICvCoMKg wqDCoMKgwqAgZXhwbGljaXRseSBzcGVjaWZpZWQgdG8gcnVuIGVhcmx5IHJlbG9jYXRpb25zIG9m IHJlYWQtd3JpdGUgCj4+Pj4+IGRhdGEKPj4+Pj4gK8KgwqDCoMKgwqDCoCBmcm9tIGZsYXNoIHRv IFJBTS4KPj4+Pj4gKwo+Pj4+PiArY29uZmlnIFhJUF9LRVJORUwKPj4+Pj4gK8KgwqDCoMKgIGJv b2wgIktlcm5lbCBFeGVjdXRlLUluLVBsYWNlIGZyb20gUk9NIgo+Pj4+PiArwqDCoMKgwqAgZGVw ZW5kcyBvbiBNTVUKPj4+Pj4gK8KgwqDCoMKgIHNlbGVjdCBQSFlTX1JBTV9CQVNFX0ZJWEVECj4+ Pj4+ICvCoMKgwqDCoCBoZWxwCj4+Pj4+ICvCoMKgwqDCoMKgwqAgRXhlY3V0ZS1Jbi1QbGFjZSBh bGxvd3MgdGhlIGtlcm5lbCB0byBydW4gZnJvbSBub24tdm9sYXRpbGUgCj4+Pj4+IHN0b3JhZ2UK Pj4+Pj4gK8KgwqDCoMKgwqDCoCBkaXJlY3RseSBhZGRyZXNzYWJsZSBieSB0aGUgQ1BVLCBzdWNo IGFzIE5PUiBmbGFzaC4gVGhpcyAKPj4+Pj4gc2F2ZXMgUkFNCj4+Pj4+ICvCoMKgwqDCoMKgwqAg c3BhY2Ugc2luY2UgdGhlIHRleHQgc2VjdGlvbiBvZiB0aGUga2VybmVsIGlzIG5vdCBsb2FkZWQg Cj4+Pj4+IGZyb20gZmxhc2gKPj4+Pj4gK8KgwqDCoMKgwqDCoCB0byBSQU0uwqAgUmVhZC13cml0 ZSBzZWN0aW9ucywgc3VjaCBhcyB0aGUgZGF0YSBzZWN0aW9uIGFuZCAKPj4+Pj4gc3RhY2ssCj4+ Pj4+ICvCoMKgwqDCoMKgwqAgYXJlIHN0aWxsIGNvcGllZCB0byBSQU0uwqAgVGhlIFhJUCBrZXJu ZWwgaXMgbm90IGNvbXByZXNzZWQgCj4+Pj4+IHNpbmNlCj4+Pj4+ICvCoMKgwqDCoMKgwqAgaXQg aGFzIHRvIHJ1biBkaXJlY3RseSBmcm9tIGZsYXNoLCBzbyBpdCB3aWxsIHRha2UgbW9yZSAKPj4+ Pj4gc3BhY2UgdG8KPj4+Pj4gK8KgwqDCoMKgwqDCoCBzdG9yZSBpdC7CoCBUaGUgZmxhc2ggYWRk cmVzcyB1c2VkIHRvIGxpbmsgdGhlIGtlcm5lbCBvYmplY3QgCj4+Pj4+IGZpbGVzLAo+Pj4+PiAr wqDCoMKgwqDCoMKgIGFuZCBmb3Igc3RvcmluZyBpdCwgaXMgY29uZmlndXJhdGlvbiBkZXBlbmRl bnQuIFRoZXJlZm9yZSwgCj4+Pj4+IGlmIHlvdQo+Pj4+PiArwqDCoMKgwqDCoMKgIHNheSBZIGhl cmUsIHlvdSBtdXN0IGtub3cgdGhlIHByb3BlciBwaHlzaWNhbCBhZGRyZXNzIHdoZXJlIHRvCj4+ Pj4+ICvCoMKgwqDCoMKgwqAgc3RvcmUgdGhlIGtlcm5lbCBpbWFnZSBkZXBlbmRpbmcgb24geW91 ciBvd24gZmxhc2ggbWVtb3J5IAo+Pj4+PiB1c2FnZS4KPj4+Pj4gKwo+Pj4+PiArwqDCoMKgwqDC oMKgIEFsc28gbm90ZSB0aGF0IHRoZSBtYWtlIHRhcmdldCBiZWNvbWVzICJtYWtlIHhpcEltYWdl IiAKPj4+Pj4gcmF0aGVyIHRoYW4KPj4+Pj4gK8KgwqDCoMKgwqDCoCAibWFrZSB6SW1hZ2UiIG9y ICJtYWtlIEltYWdlIi7CoCBUaGUgZmluYWwga2VybmVsIGJpbmFyeSB0byAKPj4+Pj4gcHV0IGlu Cj4+Pj4+ICvCoMKgwqDCoMKgwqAgUk9NIG1lbW9yeSB3aWxsIGJlIGFyY2gvcmlzY3YvYm9vdC94 aXBJbWFnZS4KPj4+Pj4gKwo+Pj4+PiArwqDCoMKgwqDCoMKgIElmIHVuc3VyZSwgc2F5IE4uCj4+ Pj4+ICsKPj4+Pj4gK2NvbmZpZyBYSVBfUEhZU19BRERSCj4+Pj4+ICvCoMKgwqDCoCBoZXggIlhJ UCBLZXJuZWwgUGh5c2ljYWwgTG9jYXRpb24iCj4+Pj4+ICvCoMKgwqDCoCBkZXBlbmRzIG9uIFhJ UF9LRVJORUwKPj4+Pj4gK8KgwqDCoMKgIGRlZmF1bHQgIjB4MjEwMDAwMDAiCj4+Pj4+ICvCoMKg wqDCoCBoZWxwCj4+Pj4+ICvCoMKgwqDCoMKgwqAgVGhpcyBpcyB0aGUgcGh5c2ljYWwgYWRkcmVz cyBpbiB5b3VyIGZsYXNoIG1lbW9yeSB0aGUgCj4+Pj4+IGtlcm5lbCB3aWxsCj4+Pj4+ICvCoMKg wqDCoMKgwqAgYmUgbGlua2VkIGZvciBhbmQgc3RvcmVkIHRvLsKgIFRoaXMgYWRkcmVzcyBpcyBk ZXBlbmRlbnQgb24gCj4+Pj4+IHlvdXIKPj4+Pj4gK8KgwqDCoMKgwqDCoCBvd24gZmxhc2ggdXNh Z2UuCj4+Pj4+ICsKPj4+Pj4gwqAgZW5kbWVudQo+Pj4+Pgo+Pj4+PiDCoCBjb25maWcgQlVJTFRJ Tl9EVEIKPj4+Pj4gLcKgwqDCoMKgIGRlZl9ib29sIG4KPj4+Pj4gK8KgwqDCoMKgIGJvb2wKPj4+ Pj4gwqDCoMKgwqDCoMKgIGRlcGVuZHMgb24gT0YKPj4+Pj4gK8KgwqDCoMKgIGRlZmF1bHQgeSBp ZiBYSVBfS0VSTkVMCj4+Pj4+Cj4+Pj4+IMKgIG1lbnUgIlBvd2VyIG1hbmFnZW1lbnQgb3B0aW9u cyIKPj4+Pj4KPj4+Pj4gZGlmZiAtLWdpdCBhL2FyY2gvcmlzY3YvTWFrZWZpbGUgYi9hcmNoL3Jp c2N2L01ha2VmaWxlCj4+Pj4+IGluZGV4IDEzNjhkOTQzZjFmMy4uOGZjYmVjMDM5NzRkIDEwMDY0 NAo+Pj4+PiAtLS0gYS9hcmNoL3Jpc2N2L01ha2VmaWxlCj4+Pj4+ICsrKyBiL2FyY2gvcmlzY3Yv TWFrZWZpbGUKPj4+Pj4gQEAgLTgyLDcgKzgyLDExIEBAIENIRUNLRkxBR1MgKz0gLURfX3Jpc2N2 IC1EX19yaXNjdl94bGVuPSQoQklUUykKPj4+Pj4KPj4+Pj4gwqAgIyBEZWZhdWx0IHRhcmdldCB3 aGVuIGV4ZWN1dGluZyBwbGFpbiBtYWtlCj4+Pj4+IMKgIGJvb3TCoMKgwqDCoMKgwqDCoMKgIDo9 IGFyY2gvcmlzY3YvYm9vdAo+Pj4+PiAraWZlcSAoJChDT05GSUdfWElQX0tFUk5FTCkseSkKPj4+ Pj4gK0tCVUlMRF9JTUFHRSA6PSAkKGJvb3QpL3hpcEltYWdlCj4+Pj4+ICtlbHNlCj4+Pj4+IMKg IEtCVUlMRF9JTUFHRSA6PSAkKGJvb3QpL0ltYWdlLmd6Cj4+Pj4+ICtlbmRpZgo+Pj4+Pgo+Pj4+ PiDCoCBoZWFkLXkgOj0gYXJjaC9yaXNjdi9rZXJuZWwvaGVhZC5vCj4+Pj4+Cj4+Pj4+IEBAIC05 NSwxMiArOTksMTQgQEAgUEhPTlkgKz0gdmRzb19pbnN0YWxsCj4+Pj4+IMKgIHZkc29faW5zdGFs bDoKPj4+Pj4gwqDCoMKgwqDCoMKgICQoUSkkKE1BS0UpICQoYnVpbGQpPWFyY2gvcmlzY3Yva2Vy bmVsL3Zkc28gJEAKPj4+Pj4KPj4+Pj4gK2lmbmVxICgkKENPTkZJR19YSVBfS0VSTkVMKSx5KQo+ Pj4+PiDCoCBpZmVxICgkKENPTkZJR19SSVNDVl9NX01PREUpJChDT05GSUdfU09DX0NBTkFBTiks eXkpCj4+Pj4+IMKgIEtCVUlMRF9JTUFHRSA6PSAkKGJvb3QpL2xvYWRlci5iaW4KPj4+Pj4gwqAg ZWxzZQo+Pj4+PiDCoCBLQlVJTERfSU1BR0UgOj0gJChib290KS9JbWFnZS5nego+Pj4+PiDCoCBl bmRpZgo+Pj4+PiAtQk9PVF9UQVJHRVRTIDo9IEltYWdlIEltYWdlLmd6IGxvYWRlciBsb2FkZXIu YmluCj4+Pj4+ICtlbmRpZgo+Pj4+PiArQk9PVF9UQVJHRVRTIDo9IEltYWdlIEltYWdlLmd6IGxv YWRlciBsb2FkZXIuYmluIHhpcEltYWdlCj4+Pj4+Cj4+Pj4+IMKgIGFsbDogJChub3RkaXIgJChL QlVJTERfSU1BR0UpKQo+Pj4+Pgo+Pj4+PiBkaWZmIC0tZ2l0IGEvYXJjaC9yaXNjdi9ib290L01h a2VmaWxlIGIvYXJjaC9yaXNjdi9ib290L01ha2VmaWxlCj4+Pj4+IGluZGV4IDAzNDA0Yzg0Zjk3 MS4uNmJmMjk5ZjcwYzI3IDEwMDY0NAo+Pj4+PiAtLS0gYS9hcmNoL3Jpc2N2L2Jvb3QvTWFrZWZp bGUKPj4+Pj4gKysrIGIvYXJjaC9yaXNjdi9ib290L01ha2VmaWxlCj4+Pj4+IEBAIC0xNyw4ICsx NywyMSBAQAo+Pj4+PiDCoCBLQ09WX0lOU1RSVU1FTlQgOj0gbgo+Pj4+Pgo+Pj4+PiDCoCBPQkpD T1BZRkxBR1NfSW1hZ2UgOj0tTyBiaW5hcnkgLVIgLm5vdGUgLVIgLm5vdGUuZ251LmJ1aWxkLWlk IC1SIAo+Pj4+PiAuY29tbWVudCAtUwo+Pj4+PiArT0JKQ09QWUZMQUdTX3hpcEltYWdlIDo9LU8g YmluYXJ5IC1SIC5ub3RlIC1SIC5ub3RlLmdudS5idWlsZC1pZCAKPj4+Pj4gLVIgLmNvbW1lbnQg LVMKPj4+Pj4KPj4+Pj4gwqAgdGFyZ2V0cyA6PSBJbWFnZSBJbWFnZS4qIGxvYWRlciBsb2FkZXIu byBsb2FkZXIubGRzIGxvYWRlci5iaW4KPj4+Pj4gK3RhcmdldHMgOj0gSW1hZ2UgSW1hZ2UuKiBs b2FkZXIgbG9hZGVyLm8gbG9hZGVyLmxkcyBsb2FkZXIuYmluIAo+Pj4+PiB4aXBJbWFnZQo+Pj4+ PiArCj4+Pj4+ICtpZmVxICgkKENPTkZJR19YSVBfS0VSTkVMKSx5KQo+Pj4+PiArCj4+Pj4+ICtx dWlldF9jbWRfbWt4aXAgPSAkKHF1aWV0X2NtZF9vYmpjb3B5KQo+Pj4+PiArY21kX21reGlwID0g JChjbWRfb2JqY29weSkKPj4+Pj4gKwo+Pj4+PiArJChvYmopL3hpcEltYWdlOiB2bWxpbnV4IEZP UkNFCj4+Pj4+ICvCoMKgwqDCoCAkKGNhbGwgaWZfY2hhbmdlZCxta3hpcCkKPj4+Pj4gK8KgwqDC oMKgIEAkKGtlY2hvKSAnwqAgUGh5c2ljYWwgQWRkcmVzcyBvZiB4aXBJbWFnZTogCj4+Pj4+ICQo Q09ORklHX1hJUF9QSFlTX0FERFIpJwo+Pj4+PiArCj4+Pj4+ICtlbmRpZgo+Pj4+Pgo+Pj4+PiDC oCAkKG9iaikvSW1hZ2U6IHZtbGludXggRk9SQ0UKPj4+Pj4gwqDCoMKgwqDCoMKgICQoY2FsbCBp Zl9jaGFuZ2VkLG9iamNvcHkpCj4+Pj4+IGRpZmYgLS1naXQgYS9hcmNoL3Jpc2N2L2luY2x1ZGUv YXNtL3BndGFibGUuaCAKPj4+Pj4gYi9hcmNoL3Jpc2N2L2luY2x1ZGUvYXNtL3BndGFibGUuaAo+ Pj4+PiBpbmRleCBlYmY4MTdjMWJkZjQuLjIxYTliMmY4ZDFjNyAxMDA2NDQKPj4+Pj4gLS0tIGEv YXJjaC9yaXNjdi9pbmNsdWRlL2FzbS9wZ3RhYmxlLmgKPj4+Pj4gKysrIGIvYXJjaC9yaXNjdi9p bmNsdWRlL2FzbS9wZ3RhYmxlLmgKPj4+Pj4gQEAgLTExLDYgKzExLDMzIEBACj4+Pj4+Cj4+Pj4+ IMKgICNpbmNsdWRlIDxhc20vcGd0YWJsZS1iaXRzLmg+Cj4+Pj4+Cj4+Pj4+ICsjaWZkZWYgQ09O RklHX01NVQo+Pj4+PiArCj4+Pj4+ICsjZGVmaW5lIFZNQUxMT0NfU1RBUlTCoMKgwqAgKFBBR0Vf T0ZGU0VUIC0gVk1BTExPQ19TSVpFKQo+Pj4+PiArCj4+Pj4+ICsjaWZkZWYgQ09ORklHX1hJUF9L RVJORUwKPj4+Pj4gKyNkZWZpbmUgVk1BTExPQ19TSVpFwqDCoMKgwqAgKChLRVJOX1ZJUlRfU0la RSA+PiAxKSAtIFNaXzE2TSkKPj4+Pj4gKyNkZWZpbmUgVk1BTExPQ19FTkTCoMKgwqDCoMKgIChQ QUdFX09GRlNFVCAtIFNaXzE2TSAtIDEpCj4+Pj4+ICsKPj4+Pj4gKyNkZWZpbmUgWElQX09GRlNF VMKgwqDCoMKgwqDCoMKgwqDCoMKgIFNaXzhNCj4+Pj4+ICsjZGVmaW5lIFhJUF9NQVNLwqDCoMKg wqDCoMKgwqDCoMKgwqDCoMKgIChTWl84TSAtIDEpCj4+Pj4+ICsjZGVmaW5lIFhJUF9WSVJUX0FE RFIocGh5c2FkZHIpwqDCoMKgwqDCoCBcCj4+Pj4+ICvCoMKgwqDCoCAoUEFHRV9PRkZTRVQgLSBY SVBfT0ZGU0VUICsgKChwaHlzYWRkcikgJiBYSVBfTUFTSykpCj4+Pj4+ICsKPj4+Pj4gKyNlbHNl Cj4+Pj4+ICsKPj4+Pj4gKyNkZWZpbmUgVk1BTExPQ19TSVpFwqDCoMKgwqAgKEtFUk5fVklSVF9T SVpFID4+IDEpCj4+Pj4+ICsjZGVmaW5lIFZNQUxMT0NfRU5EwqDCoMKgwqDCoCAoUEFHRV9PRkZT RVQgLSAxKQo+Pj4+PiArCj4+Pj4+ICsjZW5kaWYgLyogQ09ORklHX1hJUF9LRVJORUwgKi8KPj4+ Pj4gKwo+Pj4+PiArI2Vsc2UKPj4+Pj4gKwo+Pj4+PiArI2lmZGVmIENPTkZJR19YSVBfS0VSTkVM Cj4+Pj4+ICsjZGVmaW5lIFhJUF9WSVJUX0FERFIocGh5c2FkZHIpIChwaHlzYWRkcikKPj4+Pj4g KyNlbmRpZiAvKiBDT05GSUdfWElQX0tFUk5FTCAqLwo+Pj4+PiArI2VuZGlmIC8qIENPTkZJR19N TVUgKi8KPj4+Pj4gKwo+Pj4+PiDCoCAjaWZuZGVmIF9fQVNTRU1CTFlfXwo+Pj4+Pgo+Pj4+PiDC oCAvKiBQYWdlIFVwcGVyIERpcmVjdG9yeSBub3QgdXNlZCBpbiBSSVNDLVYgKi8KPj4+Pj4gQEAg LTIxLDkgKzQ4LDI1IEBACj4+Pj4+Cj4+Pj4+IMKgICNpZmRlZiBDT05GSUdfTU1VCj4+Pj4+Cj4+ Pj4+IC0jZGVmaW5lIFZNQUxMT0NfU0laRcKgwqDCoMKgIChLRVJOX1ZJUlRfU0laRSA+PiAxKQo+ Pj4+PiAtI2RlZmluZSBWTUFMTE9DX0VORMKgwqDCoMKgwqAgKFBBR0VfT0ZGU0VUIC0gMSkKPj4+ Pj4gLSNkZWZpbmUgVk1BTExPQ19TVEFSVMKgwqDCoCAoUEFHRV9PRkZTRVQgLSBWTUFMTE9DX1NJ WkUpCj4+Pj4+ICsjaWZkZWYgQ09ORklHX1hJUF9LRVJORUwKPj4+Pj4gKy8qCj4+Pj4+ICsgKiBT aW5jZSB3ZSB1c2Ugc2VjdGlvbnMgdG8gbWFwIGl0LCB0aGlzIG1hY3JvIHJlcGxhY2VzIHRoZSAK Pj4+Pj4gcGh5c2ljYWwgYWRkcmVzcwo+Pj4+PiArICogd2l0aCBpdHMgdmlydHVhbCBhZGRyZXNz IHdoaWxlIGtlZXBpbmcgb2Zmc2V0IGZyb20gdGhlIGJhc2UgCj4+Pj4+IHNlY3Rpb24uCj4+Pj4+ ICsgKi8KPj4+Pj4gKyNkZWZpbmUgWElQX1BIWVNfQUREUih2YSnCoMKgwqDCoCBcCj4+Pj4+ICvC oMKgwqDCoCAoKHVpbnRwdHJfdCkodmEpIC0gUEFHRV9PRkZTRVQgKyBYSVBfT0ZGU0VUICsgCj4+ Pj4+IENPTkZJR19YSVBfUEhZU19BRERSKQo+Pj4+PiArCj4+Pj4+ICsjZGVmaW5lIFhJUF9WSVJU X0FERFJfU1RBUlTCoCBYSVBfVklSVF9BRERSKENPTkZJR19YSVBfUEhZU19BRERSKQo+Pj4+PiAr Cj4+Pj4+ICsjZGVmaW5lIFhJUF9GSVhVUChhZGRyKcKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKg ICh7IFwKPj4+Pj4gK8KgwqDCoMKgIHVpbnRwdHJfdCBfX2EgPSAodWludHB0cl90KShhZGRyKTsg XAo+Pj4+PiArwqDCoMKgwqAgKF9fYSA+PSBDT05GSUdfWElQX1BIWVNfQUREUiAmJiBcCj4+Pj4+ ICvCoMKgwqDCoMKgIF9fYSA8IENPTkZJR19YSVBfUEhZU19BRERSICsgU1pfMTZNKSA/IFwKPj4+ Pj4gK8KgwqDCoMKgIF9fYSAtIENPTkZJR19YSVBfUEhZU19BRERSICsgQ09ORklHX1BIWVNfUkFN X0JBU0UgLSAKPj4+Pj4gWElQX09GRlNFVCA6IF9fYTsgXAo+Pj4+PiArfSkKPj4+Pj4gKyNlbHNl Cj4+Pj4+ICsjZGVmaW5lIFhJUF9GSVhVUChhZGRyKcKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKg IChhZGRyKQo+Pj4+PiArI2VuZGlmIC8qIENPTkZJR19YSVBfS0VSTkVMICovCj4+Pj4+Cj4+Pj4+ IMKgICNkZWZpbmUgQlBGX0pJVF9SRUdJT05fU0laRcKgIChTWl8xMjhNKQo+Pj4+PiDCoCAjZGVm aW5lIEJQRl9KSVRfUkVHSU9OX1NUQVJUIChQQUdFX09GRlNFVCAtIEJQRl9KSVRfUkVHSU9OX1NJ WkUpCj4+Pj4+IEBAIC00ODQsOCArNTI3LDIwIEBAIHN0YXRpYyBpbmxpbmUgaW50IAo+Pj4+PiBw dGVwX2NsZWFyX2ZsdXNoX3lvdW5nKHN0cnVjdCB2bV9hcmVhX3N0cnVjdCAqdm1hLAo+Pj4+Pgo+ Pj4+PiDCoCAjZGVmaW5lIGtlcm5fYWRkcl92YWxpZChhZGRyKcKgwqAgKDEpIC8qIEZJWE1FICov Cj4+Pj4+Cj4+Pj4+IC1leHRlcm4gdm9pZCAqZHRiX2Vhcmx5X3ZhOwo+Pj4+PiAtZXh0ZXJuIHVp bnRwdHJfdCBkdGJfZWFybHlfcGE7Cj4+Pj4+ICtleHRlcm4gdm9pZCAqX2R0Yl9lYXJseV92YTsK Pj4+Pj4gK2V4dGVybiB1aW50cHRyX3QgX2R0Yl9lYXJseV9wYTsKPj4+Pj4gKyNpZiBkZWZpbmVk KENPTkZJR19YSVBfS0VSTkVMKSAmJiBkZWZpbmVkKENPTkZJR19NTVUpCj4+Pj4+ICsKPj4+Pj4g KyNkZWZpbmUgZHRiX2Vhcmx5X3ZhICgqKHZvaWQgKiopWElQX0ZJWFVQKCZfZHRiX2Vhcmx5X3Zh KSkKPj4+Pj4gKyNkZWZpbmUgZHRiX2Vhcmx5X3BhICgqKHVpbnRwdHJfdCAqKVhJUF9GSVhVUCgm X2R0Yl9lYXJseV9wYSkpCj4+Pj4+ICsKPj4+Pj4gKyNlbHNlCj4+Pj4+ICsKPj4+Pj4gKyNkZWZp bmUgZHRiX2Vhcmx5X3ZhIF9kdGJfZWFybHlfdmEKPj4+Pj4gKyNkZWZpbmUgZHRiX2Vhcmx5X3Bh IF9kdGJfZWFybHlfcGEKPj4+Pj4gKwo+Pj4+PiArI2VuZGlmIC8qIENPTkZJR19YSVBfS0VSTkVM ICovCj4+Pj4+ICsKPj4+Pj4gwqAgdm9pZCBzZXR1cF9ib290bWVtKHZvaWQpOwo+Pj4+PiDCoCB2 b2lkIHBhZ2luZ19pbml0KHZvaWQpOwo+Pj4+PiDCoCB2b2lkIG1pc2NfbWVtX2luaXQodm9pZCk7 Cj4+Pj4+IGRpZmYgLS1naXQgYS9hcmNoL3Jpc2N2L2tlcm5lbC9jcHVfb3BzX3NiaS5jIAo+Pj4+ PiBiL2FyY2gvcmlzY3Yva2VybmVsL2NwdV9vcHNfc2JpLmMKPj4+Pj4gaW5kZXggNjg1ZmFlNzJi N2Y1Li4yNDEzYzI5OTczNTAgMTAwNjQ0Cj4+Pj4+IC0tLSBhL2FyY2gvcmlzY3Yva2VybmVsL2Nw dV9vcHNfc2JpLmMKPj4+Pj4gKysrIGIvYXJjaC9yaXNjdi9rZXJuZWwvY3B1X29wc19zYmkuYwo+ Pj4+PiBAQCAtNTMsMTAgKzUzLDE5IEBAIHN0YXRpYyBpbnQgc2JpX2hzbV9oYXJ0X2dldF9zdGF0 dXModW5zaWduZWQgCj4+Pj4+IGxvbmcgaGFydGlkKQo+Pj4+PiDCoCB9Cj4+Pj4+IMKgICNlbmRp Zgo+Pj4+Pgo+Pj4+PiArc3RhdGljIGlubGluZSB1bnNpZ25lZCBsb25nIGdldF9zZWNvbmRhcnlf c3RhcnRfcGh5cyh2b2lkKQo+Pj4+PiArewo+Pj4+PiArI2lmZGVmIENPTkZJR19YSVBfS0VSTkVM Cj4+Pj4+ICvCoMKgwqDCoCByZXR1cm4gWElQX1BIWVNfQUREUihzZWNvbmRhcnlfc3RhcnRfc2Jp KTsKPj4+Pj4gKyNlbHNlCj4+Pj4+ICvCoMKgwqDCoCByZXR1cm4gX19wYV9zeW1ib2woc2Vjb25k YXJ5X3N0YXJ0X3NiaSk7Cj4+Pj4+ICsjZW5kaWYKPj4+Pj4gK30KPj4+Pj4gKwo+Pj4+PiDCoCBz dGF0aWMgaW50IHNiaV9jcHVfc3RhcnQodW5zaWduZWQgaW50IGNwdWlkLCBzdHJ1Y3QgdGFza19z dHJ1Y3QgCj4+Pj4+ICp0aWRsZSkKPj4+Pj4gwqAgewo+Pj4+PiDCoMKgwqDCoMKgwqAgaW50IHJj Owo+Pj4+PiAtwqDCoMKgwqAgdW5zaWduZWQgbG9uZyBib290X2FkZHIgPSBfX3BhX3N5bWJvbChz ZWNvbmRhcnlfc3RhcnRfc2JpKTsKPj4+Pj4gK8KgwqDCoMKgIHVuc2lnbmVkIGxvbmcgYm9vdF9h ZGRyID0gZ2V0X3NlY29uZGFyeV9zdGFydF9waHlzKCk7Cj4+Pj4+IMKgwqDCoMKgwqDCoCBpbnQg aGFydGlkID0gY3B1aWRfdG9faGFydGlkX21hcChjcHVpZCk7Cj4+Pj4+Cj4+Pj4+IMKgwqDCoMKg wqDCoCBjcHVfdXBkYXRlX3NlY29uZGFyeV9ib290ZGF0YShjcHVpZCwgdGlkbGUpOwo+Pj4+PiBk aWZmIC0tZ2l0IGEvYXJjaC9yaXNjdi9rZXJuZWwvaGVhZC5TIGIvYXJjaC9yaXNjdi9rZXJuZWwv aGVhZC5TCj4+Pj4+IGluZGV4IGY1YTliYWQ4NmU1OC4uYmJlNzRlMzc5MTRmIDEwMDY0NAo+Pj4+ PiAtLS0gYS9hcmNoL3Jpc2N2L2tlcm5lbC9oZWFkLlMKPj4+Pj4gKysrIGIvYXJjaC9yaXNjdi9r ZXJuZWwvaGVhZC5TCj4+Pj4+IEBAIC05LDExICs5LDIzIEBACj4+Pj4+IMKgICNpbmNsdWRlIDxs aW51eC9saW5rYWdlLmg+Cj4+Pj4+IMKgICNpbmNsdWRlIDxhc20vdGhyZWFkX2luZm8uaD4KPj4+ Pj4gwqAgI2luY2x1ZGUgPGFzbS9wYWdlLmg+Cj4+Pj4+ICsjaW5jbHVkZSA8YXNtL3BndGFibGUu aD4KPj4+Pj4gwqAgI2luY2x1ZGUgPGFzbS9jc3IuaD4KPj4+Pj4gwqAgI2luY2x1ZGUgPGFzbS9o d2NhcC5oPgo+Pj4+PiDCoCAjaW5jbHVkZSA8YXNtL2ltYWdlLmg+Cj4+Pj4+IMKgICNpbmNsdWRl ICJlZmktaGVhZGVyLlMiCj4+Pj4+Cj4+Pj4+ICsjaWZkZWYgQ09ORklHX1hJUF9LRVJORUwKPj4+ Pj4gKy5tYWNybyBYSVBfRklYVVBfT0ZGU0VUIHJlZwo+Pj4+PiArwqDCoMKgwqAgUkVHX0wgdDAs IF94aXBfZml4dXAKPj4+Pj4gK8KgwqDCoMKgIGFkZCBccmVnLCBccmVnLCB0MAo+Pj4+PiArLmVu ZG0KPj4+Pj4gK194aXBfZml4dXA6IC5kd29yZCBDT05GSUdfUEhZU19SQU1fQkFTRSAtIENPTkZJ R19YSVBfUEhZU19BRERSIC0gCj4+Pj4+IFhJUF9PRkZTRVQKPj4+Pj4gKyNlbHNlCj4+Pj4+ICsu bWFjcm8gWElQX0ZJWFVQX09GRlNFVCByZWcKPj4+Pj4gKy5lbmRtCj4+Pj4+ICsjZW5kaWYgLyog Q09ORklHX1hJUF9LRVJORUwgKi8KPj4+Pj4gKwo+Pj4+PiDCoCBfX0hFQUQKPj4+Pj4gwqAgRU5U UlkoX3N0YXJ0KQo+Pj4+PiDCoMKgwqDCoMKgwqAgLyoKPj4+Pj4gQEAgLTY5LDcgKzgxLDExIEBA IHBlX2hlYWRfc3RhcnQ6Cj4+Pj4+IMKgICNpZmRlZiBDT05GSUdfTU1VCj4+Pj4+IMKgIHJlbG9j YXRlOgo+Pj4+PiDCoMKgwqDCoMKgwqAgLyogUmVsb2NhdGUgcmV0dXJuIGFkZHJlc3MgKi8KPj4+ Pj4gKyNpZmRlZiBDT05GSUdfWElQX0tFUk5FTAo+Pj4+PiArwqDCoMKgwqAgbGkgYTEsIFhJUF9W SVJUX0FERFIoQ09ORklHX1hJUF9QSFlTX0FERFIpCj4+Pj4+ICsjZWxzZQo+Pj4+PiDCoMKgwqDC oMKgwqAgbGkgYTEsIFBBR0VfT0ZGU0VUCj4+Pj4+ICsjZW5kaWYKPj4+Pj4gwqDCoMKgwqDCoMKg IGxhIGEyLCBfc3RhcnQKPj4+Pj4gwqDCoMKgwqDCoMKgIHN1YiBhMSwgYTEsIGEyCj4+Pj4+IMKg wqDCoMKgwqDCoCBhZGQgcmEsIHJhLCBhMQo+Pj4+PiBAQCAtOTEsNiArMTA3LDcgQEAgcmVsb2Nh dGU6Cj4+Pj4+IMKgwqDCoMKgwqDCoMKgICogdG8gZW5zdXJlIHRoZSBuZXcgdHJhbnNsYXRpb25z IGFyZSBpbiB1c2UuCj4+Pj4+IMKgwqDCoMKgwqDCoMKgICovCj4+Pj4+IMKgwqDCoMKgwqDCoCBs YSBhMCwgdHJhbXBvbGluZV9wZ19kaXIKPj4+Pj4gK8KgwqDCoMKgIFhJUF9GSVhVUF9PRkZTRVQg YTAKPj4+Pj4gwqDCoMKgwqDCoMKgIHNybCBhMCwgYTAsIFBBR0VfU0hJRlQKPj4+Pj4gwqDCoMKg wqDCoMKgIG9yIGEwLCBhMCwgYTEKPj4+Pj4gwqDCoMKgwqDCoMKgIHNmZW5jZS52bWEKPj4+Pj4g QEAgLTE0NCw3ICsxNjEsOSBAQCBzZWNvbmRhcnlfc3RhcnRfc2JpOgo+Pj4+Pgo+Pj4+PiDCoMKg wqDCoMKgwqAgc2xsaSBhMywgYTAsIExHUkVHCj4+Pj4+IMKgwqDCoMKgwqDCoCBsYSBhNCwgX19j cHVfdXBfc3RhY2tfcG9pbnRlcgo+Pj4+PiArwqDCoMKgwqAgWElQX0ZJWFVQX09GRlNFVCBhNAo+ Pj4+PiDCoMKgwqDCoMKgwqAgbGEgYTUsIF9fY3B1X3VwX3Rhc2tfcG9pbnRlcgo+Pj4+PiArwqDC oMKgwqAgWElQX0ZJWFVQX09GRlNFVCBhNQo+Pj4+PiDCoMKgwqDCoMKgwqAgYWRkIGE0LCBhMywg YTQKPj4+Pj4gwqDCoMKgwqDCoMKgIGFkZCBhNSwgYTMsIGE1Cj4+Pj4+IMKgwqDCoMKgwqDCoCBS RUdfTCBzcCwgKGE0KQo+Pj4+PiBAQCAtMTU2LDYgKzE3NSw3IEBAIHNlY29uZGFyeV9zdGFydF9j b21tb246Cj4+Pj4+IMKgICNpZmRlZiBDT05GSUdfTU1VCj4+Pj4+IMKgwqDCoMKgwqDCoCAvKiBF bmFibGUgdmlydHVhbCBtZW1vcnkgYW5kIHJlbG9jYXRlIHRvIHZpcnR1YWwgYWRkcmVzcyAqLwo+ Pj4+PiDCoMKgwqDCoMKgwqAgbGEgYTAsIHN3YXBwZXJfcGdfZGlyCj4+Pj4+ICvCoMKgwqDCoCBY SVBfRklYVVBfT0ZGU0VUIGEwCj4+Pj4+IMKgwqDCoMKgwqDCoCBjYWxsIHJlbG9jYXRlCj4+Pj4+ IMKgICNlbmRpZgo+Pj4+PiDCoMKgwqDCoMKgwqAgY2FsbCBzZXR1cF90cmFwX3ZlY3Rvcgo+Pj4+ PiBAQCAtMjM2LDEyICsyNTYsMzMgQEAgcG1wX2RvbmU6Cj4+Pj4+IMKgIC5MZ29vZF9jb3JlczoK Pj4+Pj4gwqAgI2VuZGlmCj4+Pj4+Cj4+Pj4+ICsjaWZuZGVmIENPTkZJR19YSVBfS0VSTkVMCj4+ Pj4+IMKgwqDCoMKgwqDCoCAvKiBQaWNrIG9uZSBoYXJ0IHRvIHJ1biB0aGUgbWFpbiBib290IHNl cXVlbmNlICovCj4+Pj4+IMKgwqDCoMKgwqDCoCBsYSBhMywgaGFydF9sb3R0ZXJ5Cj4+Pj4+IMKg wqDCoMKgwqDCoCBsaSBhMiwgMQo+Pj4+PiDCoMKgwqDCoMKgwqAgYW1vYWRkLncgYTMsIGEyLCAo YTMpCj4+Pj4+IMKgwqDCoMKgwqDCoCBibmV6IGEzLCAuTHNlY29uZGFyeV9zdGFydAo+Pj4+Pgo+ Pj4+PiArI2Vsc2UKPj4+Pj4gK8KgwqDCoMKgIC8qIGhhcnRfbG90dGVyeSBpbiBmbGFzaCBjb250 YWlucyBhIG1hZ2ljIG51bWJlciAqLwo+Pj4+PiArwqDCoMKgwqAgbGEgYTMsIGhhcnRfbG90dGVy eQo+Pj4+PiArwqDCoMKgwqAgbXYgYTIsIGEzCj4+Pj4+ICvCoMKgwqDCoCBYSVBfRklYVVBfT0ZG U0VUIGEyCj4+Pj4+ICvCoMKgwqDCoCBsdyB0MSwgKGEzKQo+Pj4+PiArwqDCoMKgwqAgYW1vc3dh cC53IHQwLCB0MSwgKGEyKQo+Pj4+PiArwqDCoMKgwqAgLyogZmlyc3QgdGltZSBoZXJlIGlmIGhh cnRfbG90dGVyeSBpbiBSQU0gaXMgbm90IHNldCAqLwo+Pj4+PiArwqDCoMKgwqAgYmVxIHQwLCB0 MSwgLkxzZWNvbmRhcnlfc3RhcnQKPj4+Pj4gKwo+Pj4+PiArwqDCoMKgwqAgbGEgc3AsIF9lbmQg KyBUSFJFQURfU0laRQo+Pj4+PiArwqDCoMKgwqAgWElQX0ZJWFVQX09GRlNFVCBzcAo+Pj4+PiAr wqDCoMKgwqAgbXYgczAsIGEwCj4+Pj4+ICvCoMKgwqDCoCBjYWxsIF9fY29weV9kYXRhCj4+Pj4+ ICsKPj4+Pj4gK8KgwqDCoMKgIC8qIFJlc3RvcmUgYTAgY29weSAqLwo+Pj4+PiArwqDCoMKgwqAg bXYgYTAsIHMwCj4+Pj4+ICsjZW5kaWYKPj4+Pj4gKwo+Pj4+PiArI2lmbmRlZiBDT05GSUdfWElQ X0tFUk5FTAo+Pj4+PiDCoMKgwqDCoMKgwqAgLyogQ2xlYXIgQlNTIGZvciBmbGF0IG5vbi1FTEYg aW1hZ2VzICovCj4+Pj4+IMKgwqDCoMKgwqDCoCBsYSBhMywgX19ic3Nfc3RhcnQKPj4+Pj4gwqDC oMKgwqDCoMKgIGxhIGE0LCBfX2Jzc19zdG9wCj4+Pj4+IEBAIC0yNTEsMTUgKzI5MiwxOCBAQCBj bGVhcl9ic3M6Cj4+Pj4+IMKgwqDCoMKgwqDCoCBhZGQgYTMsIGEzLCBSSVNDVl9TWlBUUgo+Pj4+ PiDCoMKgwqDCoMKgwqAgYmx0IGEzLCBhNCwgY2xlYXJfYnNzCj4+Pj4+IMKgIGNsZWFyX2Jzc19k b25lOgo+Pj4+PiAtCj4+Pj4+ICsjZW5kaWYKPj4+Pj4gwqDCoMKgwqDCoMKgIC8qIFNhdmUgaGFy dCBJRCBhbmQgRFRCIHBoeXNpY2FsIGFkZHJlc3MgKi8KPj4+Pj4gwqDCoMKgwqDCoMKgIG12IHMw LCBhMAo+Pj4+PiDCoMKgwqDCoMKgwqAgbXYgczEsIGExCj4+Pj4+ICsKPj4+Pj4gwqDCoMKgwqDC oMKgIGxhIGEyLCBib290X2NwdV9oYXJ0aWQKPj4+Pj4gK8KgwqDCoMKgIFhJUF9GSVhVUF9PRkZT RVQgYTIKPj4+Pj4gwqDCoMKgwqDCoMKgIFJFR19TIGEwLCAoYTIpCj4+Pj4+Cj4+Pj4+IMKgwqDC oMKgwqDCoCAvKiBJbml0aWFsaXplIHBhZ2UgdGFibGVzIGFuZCByZWxvY2F0ZSB0byB2aXJ0dWFs IGFkZHJlc3NlcyAqLwo+Pj4+PiDCoMKgwqDCoMKgwqAgbGEgc3AsIGluaXRfdGhyZWFkX3VuaW9u ICsgVEhSRUFEX1NJWkUKPj4+Pj4gK8KgwqDCoMKgIFhJUF9GSVhVUF9PRkZTRVQgc3AKPj4+Pj4g wqAgI2lmZGVmIENPTkZJR19CVUlMVElOX0RUQgo+Pj4+PiDCoMKgwqDCoMKgwqAgbGEgYTAsIF9f ZHRiX3N0YXJ0Cj4+Pj4+IMKgICNlbHNlCj4+Pj4+IEBAIC0yNjgsNiArMzEyLDcgQEAgY2xlYXJf YnNzX2RvbmU6Cj4+Pj4+IMKgwqDCoMKgwqDCoCBjYWxsIHNldHVwX3ZtCj4+Pj4+IMKgICNpZmRl ZiBDT05GSUdfTU1VCj4+Pj4+IMKgwqDCoMKgwqDCoCBsYSBhMCwgZWFybHlfcGdfZGlyCj4+Pj4+ ICvCoMKgwqDCoCBYSVBfRklYVVBfT0ZGU0VUIGEwCj4+Pj4+IMKgwqDCoMKgwqDCoCBjYWxsIHJl bG9jYXRlCj4+Pj4+IMKgICNlbmRpZiAvKiBDT05GSUdfTU1VICovCj4+Pj4+Cj4+Pj4+IEBAIC0y OTIsNyArMzM3LDkgQEAgY2xlYXJfYnNzX2RvbmU6Cj4+Pj4+Cj4+Pj4+IMKgwqDCoMKgwqDCoCBz bGxpIGEzLCBhMCwgTEdSRUcKPj4+Pj4gwqDCoMKgwqDCoMKgIGxhIGExLCBfX2NwdV91cF9zdGFj a19wb2ludGVyCj4+Pj4+ICvCoMKgwqDCoCBYSVBfRklYVVBfT0ZGU0VUIGExCj4+Pj4+IMKgwqDC oMKgwqDCoCBsYSBhMiwgX19jcHVfdXBfdGFza19wb2ludGVyCj4+Pj4+ICvCoMKgwqDCoCBYSVBf RklYVVBfT0ZGU0VUIGEyCj4+Pj4+IMKgwqDCoMKgwqDCoCBhZGQgYTEsIGEzLCBhMQo+Pj4+PiDC oMKgwqDCoMKgwqAgYWRkIGEyLCBhMywgYTIKPj4+Pj4KPj4+Pj4gZGlmZiAtLWdpdCBhL2FyY2gv cmlzY3Yva2VybmVsL2hlYWQuaCBiL2FyY2gvcmlzY3Yva2VybmVsL2hlYWQuaAo+Pj4+PiBpbmRl eCBiNDhkZGEzZDA0ZjYuLmFhYmJjM2FjM2U0OCAxMDA2NDQKPj4+Pj4gLS0tIGEvYXJjaC9yaXNj di9rZXJuZWwvaGVhZC5oCj4+Pj4+ICsrKyBiL2FyY2gvcmlzY3Yva2VybmVsL2hlYWQuaAo+Pj4+ PiBAQCAtMTIsNiArMTIsOSBAQCBleHRlcm4gYXRvbWljX3QgaGFydF9sb3R0ZXJ5Owo+Pj4+Pgo+ Pj4+PiDCoCBhc21saW5rYWdlIHZvaWQgZG9fcGFnZV9mYXVsdChzdHJ1Y3QgcHRfcmVncyAqcmVn cyk7Cj4+Pj4+IMKgIGFzbWxpbmthZ2Ugdm9pZCBfX2luaXQgc2V0dXBfdm0odWludHB0cl90IGR0 Yl9wYSk7Cj4+Pj4+ICsjaWZkZWYgQ09ORklHX1hJUF9LRVJORUwKPj4+Pj4gK2FzbWxpbmthZ2Ug dm9pZCBfX2luaXQgX19jb3B5X2RhdGEodm9pZCk7Cj4+Pj4+ICsjZW5kaWYKPj4+Pj4KPj4+Pj4g wqAgZXh0ZXJuIHZvaWQgKl9fY3B1X3VwX3N0YWNrX3BvaW50ZXJbXTsKPj4+Pj4gwqAgZXh0ZXJu IHZvaWQgKl9fY3B1X3VwX3Rhc2tfcG9pbnRlcltdOwo+Pj4+PiBkaWZmIC0tZ2l0IGEvYXJjaC9y aXNjdi9rZXJuZWwvc2V0dXAuYyBiL2FyY2gvcmlzY3Yva2VybmVsL3NldHVwLmMKPj4+Pj4gaW5k ZXggZTg1YmFjZmYxYjUwLi5hMDM4NGM3MmMyNzIgMTAwNjQ0Cj4+Pj4+IC0tLSBhL2FyY2gvcmlz Y3Yva2VybmVsL3NldHVwLmMKPj4+Pj4gKysrIGIvYXJjaC9yaXNjdi9rZXJuZWwvc2V0dXAuYwo+ Pj4+PiBAQCAtNTAsNyArNTAsMTEgQEAgc3RydWN0IHNjcmVlbl9pbmZvIHNjcmVlbl9pbmZvIAo+ Pj4+PiBfX3NlY3Rpb24oIi5kYXRhIikgPSB7Cj4+Pj4+IMKgwqAgKiBUaGlzIGlzIHVzZWQgYmVm b3JlIHRoZSBrZXJuZWwgaW5pdGlhbGl6ZXMgdGhlIEJTUyBzbyBpdCBjYW4ndCAKPj4+Pj4gYmUg aW4gdGhlCj4+Pj4+IMKgwqAgKiBCU1MuCj4+Pj4+IMKgwqAgKi8KPj4+Pj4gLWF0b21pY190IGhh cnRfbG90dGVyeSBfX3NlY3Rpb24oIi5zZGF0YSIpOwo+Pj4+PiArYXRvbWljX3QgaGFydF9sb3R0 ZXJ5IF9fc2VjdGlvbigiLnNkYXRhIikKPj4+Pj4gKyNpZmRlZiBDT05GSUdfWElQX0tFUk5FTAo+ Pj4+PiArPSBBVE9NSUNfSU5JVCgweEMwMDFCRUVGKQo+Pj4+PiArI2VuZGlmCj4+Pj4+ICs7Cj4+ Pj4+IMKgIHVuc2lnbmVkIGxvbmcgYm9vdF9jcHVfaGFydGlkOwo+Pj4+PiDCoCBzdGF0aWMgREVG SU5FX1BFUl9DUFUoc3RydWN0IGNwdSwgY3B1X2RldmljZXMpOwo+Pj4+Pgo+Pj4+PiBAQCAtMjU0 LDcgKzI1OCw3IEBAIHZvaWQgX19pbml0IHNldHVwX2FyY2goY2hhciAqKmNtZGxpbmVfcCkKPj4+ Pj4gwqAgI2lmIElTX0VOQUJMRUQoQ09ORklHX0JVSUxUSU5fRFRCKQo+Pj4+PiDCoMKgwqDCoMKg wqAgdW5mbGF0dGVuX2FuZF9jb3B5X2RldmljZV90cmVlKCk7Cj4+Pj4+IMKgICNlbHNlCj4+Pj4+ IC3CoMKgwqDCoCBpZiAoZWFybHlfaW5pdF9kdF92ZXJpZnkoX192YShkdGJfZWFybHlfcGEpKSkK Pj4+Pj4gK8KgwqDCoMKgIGlmIChlYXJseV9pbml0X2R0X3ZlcmlmeShfX3ZhKFhJUF9GSVhVUChk dGJfZWFybHlfcGEpKSkpCj4+Pj4+IMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqAgdW5mbGF0 dGVuX2RldmljZV90cmVlKCk7Cj4+Pj4+IMKgwqDCoMKgwqDCoCBlbHNlCj4+Pj4+IMKgwqDCoMKg wqDCoMKgwqDCoMKgwqDCoMKgwqAgcHJfZXJyKCJObyBEVEIgZm91bmQgaW4ga2VybmVsIG1hcHBp bmdzXG4iKTsKPj4+Pj4gZGlmZiAtLWdpdCBhL2FyY2gvcmlzY3Yva2VybmVsL3ZtbGludXgteGlw Lmxkcy5TIAo+Pj4+PiBiL2FyY2gvcmlzY3Yva2VybmVsL3ZtbGludXgteGlwLmxkcy5TCj4+Pj4+ IG5ldyBmaWxlIG1vZGUgMTAwNjQ0Cj4+Pj4+IGluZGV4IDAwMDAwMDAwMDAwMC4uOWYwZjA4YzM0 Y2QzCj4+Pj4+IC0tLSAvZGV2L251bGwKPj4+Pj4gKysrIGIvYXJjaC9yaXNjdi9rZXJuZWwvdm1s aW51eC14aXAubGRzLlMKPj4+Pj4gQEAgLTAsMCArMSwxMzIgQEAKPj4+Pj4gKy8qIFNQRFgtTGlj ZW5zZS1JZGVudGlmaWVyOiBHUEwtMi4wLW9ubHkgKi8KPj4+Pj4gKy8qCj4+Pj4+ICsgKiBDb3B5 cmlnaHQgKEMpIDIwMTIgUmVnZW50cyBvZiB0aGUgVW5pdmVyc2l0eSBvZiBDYWxpZm9ybmlhCj4+ Pj4+ICsgKiBDb3B5cmlnaHQgKEMpIDIwMTcgU2lGaXZlCj4+Pj4+ICsgKiBDb3B5cmlnaHQgKEMp IDIwMjAgVml0YWx5IFdvb2wsIEtvbnN1bGtvIEFCCj4+Pj4+ICsgKi8KPj4+Pj4gKwo+Pj4+PiAr I2RlZmluZSBMT0FEX09GRlNFVCBYSVBfVklSVF9BRERSKENPTkZJR19YSVBfUEhZU19BRERSKQo+ Pj4+PiArLyogTm8gX19yb19hZnRlcl9pbml0IGRhdGEgaW4gdGhlIC5yb2RhdGEgc2VjdGlvbiAt IHdoaWNoIHdpbGwgCj4+Pj4+IGFsd2F5cyBiZSBybyAqLwo+Pj4+PiArI2RlZmluZSBST19BRlRF Ul9JTklUX0RBVEEKPj4+Pj4gKwo+Pj4+PiArI2luY2x1ZGUgPGFzbS92bWxpbnV4Lmxkcy5oPgo+ Pj4+PiArI2luY2x1ZGUgPGFzbS9wYWdlLmg+Cj4+Pj4+ICsjaW5jbHVkZSA8YXNtL3BndGFibGUu aD4KPj4+Pj4gKyNpbmNsdWRlIDxhc20vY2FjaGUuaD4KPj4+Pj4gKyNpbmNsdWRlIDxhc20vdGhy ZWFkX2luZm8uaD4KPj4+Pj4gKwo+Pj4+PiArT1VUUFVUX0FSQ0gocmlzY3YpCj4+Pj4+ICtFTlRS WShfc3RhcnQpCj4+Pj4+ICsKPj4+Pj4gK2ppZmZpZXMgPSBqaWZmaWVzXzY0Owo+Pj4+PiArCj4+ Pj4+ICtTRUNUSU9OUwo+Pj4+PiArewo+Pj4+PiArwqDCoMKgwqAgLyogQmVnaW5uaW5nIG9mIGNv ZGUgYW5kIHRleHQgc2VnbWVudCAqLwo+Pj4+PiArwqDCoMKgwqAgLiA9IFhJUF9WSVJUX0FERFIo Q09ORklHX1hJUF9QSFlTX0FERFIpOwo+Pj4+PiArwqDCoMKgwqAgX3hpcHJvbSA9IC47Cj4+Pj4+ ICvCoMKgwqDCoCBfc3RhcnQgPSAuOwo+Pj4+PiArwqDCoMKgwqAgSEVBRF9URVhUX1NFQ1RJT04K Pj4+Pj4gK8KgwqDCoMKgIElOSVRfVEVYVF9TRUNUSU9OKFBBR0VfU0laRSkKPj4+Pj4gK8KgwqDC oMKgIC8qIHdlIGhhdmUgdG8gZGlzY2FyZCBleGl0IHRleHQgYW5kIHN1Y2ggYXQgcnVudGltZSwg bm90IGxpbmsgCj4+Pj4+IHRpbWUgKi8KPj4+Pj4gK8KgwqDCoMKgIC5leGl0LnRleHQgOgo+Pj4+ PiArwqDCoMKgwqAgewo+Pj4+PiArwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgIEVYSVRfVEVYVAo+ Pj4+PiArwqDCoMKgwqAgfQo+Pj4+PiArCj4+Pj4+ICvCoMKgwqDCoCAudGV4dCA6IHsKPj4+Pj4g K8KgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoCBfdGV4dCA9IC47Cj4+Pj4+ICvCoMKgwqDCoMKgwqDC oMKgwqDCoMKgwqAgX3N0ZXh0ID0gLjsKPj4+Pj4gK8KgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoCBU RVhUX1RFWFQKPj4+Pj4gK8KgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoCBTQ0hFRF9URVhUCj4+Pj4+ ICvCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqAgQ1BVSURMRV9URVhUCj4+Pj4+ICvCoMKgwqDCoMKg wqDCoMKgwqDCoMKgwqAgTE9DS19URVhUCj4+Pj4+ICvCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqAg S1BST0JFU19URVhUCj4+Pj4+ICvCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqAgRU5UUllfVEVYVAo+ Pj4+PiArwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgIElSUUVOVFJZX1RFWFQKPj4+Pj4gK8KgwqDC oMKgwqDCoMKgwqDCoMKgwqDCoCBTT0ZUSVJRRU5UUllfVEVYVAo+Pj4+PiArwqDCoMKgwqDCoMKg wqDCoMKgwqDCoMKgICooLmZpeHVwKQo+Pj4+PiArwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgIF9l dGV4dCA9IC47Cj4+Pj4+ICvCoMKgwqDCoCB9Cj4+Pj4+ICvCoMKgwqDCoCBST19EQVRBKEwxX0NB Q0hFX0JZVEVTKQo+Pj4+PiArwqDCoMKgwqAgLnNyb2RhdGEgOiB7Cj4+Pj4+ICvCoMKgwqDCoMKg wqDCoMKgwqDCoMKgwqAgKiguc3JvZGF0YSopCj4+Pj4+ICvCoMKgwqDCoCB9Cj4+Pj4+ICvCoMKg wqDCoCAuaW5pdC5yb2RhdGEgOiB7Cj4+Pj4+ICvCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqAgSU5J VF9TRVRVUCgxNikKPj4+Pj4gK8KgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoCBJTklUX0NBTExTCj4+ Pj4+ICvCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqAgQ09OX0lOSVRDQUxMCj4+Pj4+ICvCoMKgwqDC oMKgwqDCoMKgwqDCoMKgwqAgSU5JVF9SQU1fRlMKPj4+Pj4gK8KgwqDCoMKgIH0KPj4+Pj4gK8Kg wqDCoMKgIF9leGlwcm9tID0gLjvCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqAg LyogRW5kIG9mIFhJUCBST00gYXJlYSAqLwo+Pj4+PiArCj4+Pj4+ICsKPj4+Pj4gKy8qCj4+Pj4+ ICsgKiBGcm9tIHRoaXMgcG9pbnQsIHN0dWZmIGlzIGNvbnNpZGVyZWQgd3JpdGFibGUgYW5kIHdp bGwgYmUgCj4+Pj4+IGNvcGllZCB0byBSQU0KPj4+Pj4gKyAqLwo+Pj4+PiArwqDCoMKgwqAgX19k YXRhX2xvYyA9IEFMSUdOKDE2KTvCoMKgwqDCoMKgwqDCoMKgIC8qIGxvY2F0aW9uIGluIGZpbGUg Ki8KPj4+Pj4gK8KgwqDCoMKgIC4gPSBQQUdFX09GRlNFVDvCoMKgwqDCoMKgwqDCoMKgwqDCoMKg wqDCoMKgwqAgLyogbG9jYXRpb24gaW4gbWVtb3J5ICovCj4+Pj4+ICsKPj4+Pj4gK8KgwqDCoMKg IF9zZGF0YSA9IC47wqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoCAvKiBT dGFydCBvZiBkYXRhIHNlY3Rpb24gKi8KPj4+Pj4gK8KgwqDCoMKgIF9kYXRhID0gLjsKPj4+Pj4g K8KgwqDCoMKgIFJXX0RBVEEoTDFfQ0FDSEVfQllURVMsIFBBR0VfU0laRSwgVEhSRUFEX1NJWkUp Cj4+Pj4+ICvCoMKgwqDCoCBfZWRhdGEgPSAuOwo+Pj4+PiArwqDCoMKgwqAgX19zdGFydF9yb19h ZnRlcl9pbml0ID0gLjsKPj4+Pj4gK8KgwqDCoMKgIC5kYXRhLnJvX2FmdGVyX2luaXQgOiBBVChB RERSKC5kYXRhLnJvX2FmdGVyX2luaXQpIC0gCj4+Pj4+IExPQURfT0ZGU0VUKSB7Cj4+Pj4+ICvC oMKgwqDCoMKgwqDCoMKgwqDCoMKgwqAgKiguZGF0YS4ucm9fYWZ0ZXJfaW5pdCkKPj4+Pj4gK8Kg wqDCoMKgIH0KPj4+Pj4gK8KgwqDCoMKgIF9fZW5kX3JvX2FmdGVyX2luaXQgPSAuOwo+Pj4+PiAr Cj4+Pj4+ICvCoMKgwqDCoCAuID0gQUxJR04oUEFHRV9TSVpFKTsKPj4+Pj4gK8KgwqDCoMKgIF9f aW5pdF9iZWdpbiA9IC47Cj4+Pj4+ICvCoMKgwqDCoCAuaW5pdC5kYXRhIDogewo+Pj4+PiArwqDC oMKgwqDCoMKgwqDCoMKgwqDCoMKgIElOSVRfREFUQQo+Pj4+PiArwqDCoMKgwqAgfQo+Pj4+PiAr wqDCoMKgwqAgLmV4aXQuZGF0YSA6IHsKPj4+Pj4gK8KgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoCBF WElUX0RBVEEKPj4+Pj4gK8KgwqDCoMKgIH0KPj4+Pj4gK8KgwqDCoMKgIC4gPSBBTElHTig4KTsK Pj4+Pj4gK8KgwqDCoMKgIF9fc29jX2Vhcmx5X2luaXRfdGFibGUgOiB7Cj4+Pj4+ICvCoMKgwqDC oMKgwqDCoMKgwqDCoMKgwqAgX19zb2NfZWFybHlfaW5pdF90YWJsZV9zdGFydCA9IC47Cj4+Pj4+ ICvCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqAgS0VFUCgqKF9fc29jX2Vhcmx5X2luaXRfdGFibGUp KQo+Pj4+PiArwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgIF9fc29jX2Vhcmx5X2luaXRfdGFibGVf ZW5kID0gLjsKPj4+Pj4gK8KgwqDCoMKgIH0KPj4+Pj4gK8KgwqDCoMKgIF9fc29jX2J1aWx0aW5f ZHRiX3RhYmxlIDogewo+Pj4+PiArwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgIF9fc29jX2J1aWx0 aW5fZHRiX3RhYmxlX3N0YXJ0ID0gLjsKPj4+Pj4gK8KgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoCBL RUVQKCooX19zb2NfYnVpbHRpbl9kdGJfdGFibGUpKQo+Pj4+PiArwqDCoMKgwqDCoMKgwqDCoMKg wqDCoMKgIF9fc29jX2J1aWx0aW5fZHRiX3RhYmxlX2VuZCA9IC47Cj4+Pj4+ICvCoMKgwqDCoCB9 Cj4+Pj4+ICvCoMKgwqDCoCBQRVJDUFVfU0VDVElPTihMMV9DQUNIRV9CWVRFUykKPj4+Pj4gKwo+ Pj4+PiArwqDCoMKgwqAgLiA9IEFMSUdOKFBBR0VfU0laRSk7Cj4+Pj4+ICvCoMKgwqDCoCBfX2lu aXRfZW5kID0gLjsKPj4+Pj4gKwo+Pj4+PiArwqDCoMKgwqAgLnNkYXRhIDogewo+Pj4+PiArwqDC oMKgwqDCoMKgwqDCoMKgwqDCoMKgIF9fZ2xvYmFsX3BvaW50ZXIkID0gLiArIDB4ODAwOwo+Pj4+ PiArwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgICooLnNkYXRhKikKPj4+Pj4gK8KgwqDCoMKgwqDC oMKgwqDCoMKgwqDCoCAqKC5zYnNzKikKPj4+Pj4gK8KgwqDCoMKgIH0KPj4+Pj4gKwo+Pj4+PiAr wqDCoMKgwqAgQlNTX1NFQ1RJT04oUEFHRV9TSVpFLCBQQUdFX1NJWkUsIDApCj4+Pj4+ICvCoMKg wqDCoCBFWENFUFRJT05fVEFCTEUoMHgxMCkKPj4+Pj4gKwo+Pj4+PiArwqDCoMKgwqAgLnJlbC5k eW4gOiBBVChBRERSKC5yZWwuZHluKSAtIExPQURfT0ZGU0VUKSB7Cj4+Pj4+ICvCoMKgwqDCoMKg wqDCoMKgwqDCoMKgwqAgKigucmVsLmR5biopCj4+Pj4+ICvCoMKgwqDCoCB9Cj4+Pj4+ICsKPj4+ Pj4gK8KgwqDCoMKgIC8qCj4+Pj4+ICvCoMKgwqDCoMKgICogRW5kIG9mIGNvcGllZCBkYXRhLiBX ZSBuZWVkIGEgZHVtbXkgc2VjdGlvbiB0byBnZXQgaXRzIExNQS4KPj4+Pj4gK8KgwqDCoMKgwqAg KiBBbHNvIGxvY2F0ZWQgYmVmb3JlIGZpbmFsIEFMSUdOKCkgYXMgdHJhaWxpbmcgcGFkZGluZyBp cyAKPj4+Pj4gbm90IHN0b3JlZAo+Pj4+PiArwqDCoMKgwqDCoCAqIGluIHRoZSByZXN1bHRpbmcg YmluYXJ5IGZpbGUgYW5kIHVzZWxlc3MgdG8gY29weS4KPj4+Pj4gK8KgwqDCoMKgwqAgKi8KPj4+ Pj4gK8KgwqDCoMKgIC5kYXRhLmVuZG1hcmsgOiBBVChBRERSKC5kYXRhLmVuZG1hcmspIC0gTE9B RF9PRkZTRVQpIHsgfQo+Pj4+PiArwqDCoMKgwqAgX2VkYXRhX2xvYyA9IExPQURBRERSKC5kYXRh LmVuZG1hcmspOwo+Pj4+PiArCj4+Pj4+ICvCoMKgwqDCoCAuID0gQUxJR04oUEFHRV9TSVpFKTsK Pj4+Pj4gK8KgwqDCoMKgIF9lbmQgPSAuOwo+Pj4+PiArCj4+Pj4+ICvCoMKgwqDCoCBTVEFCU19E RUJVRwo+Pj4+PiArwqDCoMKgwqAgRFdBUkZfREVCVUcKPj4+Pj4gKwo+Pj4+PiArwqDCoMKgwqAg RElTQ0FSRFMKPj4+Pj4gK30KPj4+Pj4gZGlmZiAtLWdpdCBhL2FyY2gvcmlzY3Yva2VybmVsL3Zt bGludXgubGRzLlMgCj4+Pj4+IGIvYXJjaC9yaXNjdi9rZXJuZWwvdm1saW51eC5sZHMuUwo+Pj4+ PiBpbmRleCBkZTAzY2IyMmQwZTkuLjY3NDVlYzMyNTkzMCAxMDA2NDQKPj4+Pj4gLS0tIGEvYXJj aC9yaXNjdi9rZXJuZWwvdm1saW51eC5sZHMuUwo+Pj4+PiArKysgYi9hcmNoL3Jpc2N2L2tlcm5l bC92bWxpbnV4Lmxkcy5TCj4+Pj4+IEBAIC00LDcgKzQsMTIgQEAKPj4+Pj4gwqDCoCAqIENvcHly aWdodCAoQykgMjAxNyBTaUZpdmUKPj4+Pj4gwqDCoCAqLwo+Pj4+Pgo+Pj4+PiArI2lmZGVmIENP TkZJR19YSVBfS0VSTkVMCj4+Pj4+ICsjaW5jbHVkZSAidm1saW51eC14aXAubGRzLlMiCj4+Pj4+ ICsjZWxzZQo+Pj4+PiArCj4+Pj4+IMKgICNkZWZpbmUgTE9BRF9PRkZTRVQgUEFHRV9PRkZTRVQK Pj4+Pj4gKwo+Pj4+PiDCoCAjaW5jbHVkZSA8YXNtL3ZtbGludXgubGRzLmg+Cj4+Pj4+IMKgICNp bmNsdWRlIDxhc20vcGFnZS5oPgo+Pj4+PiDCoCAjaW5jbHVkZSA8YXNtL2NhY2hlLmg+Cj4+Pj4+ IEBAIC0xMzIsMyArMTM3LDQgQEAgU0VDVElPTlMKPj4+Pj4KPj4+Pj4gwqDCoMKgwqDCoMKgIERJ U0NBUkRTCj4+Pj4+IMKgIH0KPj4+Pj4gKyNlbmRpZiAvKiBDT05GSUdfWElQX0tFUk5FTCAqLwo+ Pj4+PiBkaWZmIC0tZ2l0IGEvYXJjaC9yaXNjdi9tbS9pbml0LmMgYi9hcmNoL3Jpc2N2L21tL2lu aXQuYwo+Pj4+PiBpbmRleCA3ZjUwMzZmYmVlOGMuLmVmZTY0OWQ0MWY5NSAxMDA2NDQKPj4+Pj4g LS0tIGEvYXJjaC9yaXNjdi9tbS9pbml0LmMKPj4+Pj4gKysrIGIvYXJjaC9yaXNjdi9tbS9pbml0 LmMKPj4+Pj4gQEAgLTMxLDggKzMxLDggQEAgRVhQT1JUX1NZTUJPTChlbXB0eV96ZXJvX3BhZ2Up Owo+Pj4+Pgo+Pj4+PiDCoCBleHRlcm4gY2hhciBfc3RhcnRbXTsKPj4+Pj4gwqAgI2RlZmluZSBE VEJfRUFSTFlfQkFTRV9WQcKgwqDCoMKgwqAgUEdESVJfU0laRQo+Pj4+PiAtdm9pZCAqZHRiX2Vh cmx5X3ZhIF9faW5pdGRhdGE7Cj4+Pj4+IC11aW50cHRyX3QgZHRiX2Vhcmx5X3BhIF9faW5pdGRh dGE7Cj4+Pj4+ICt2b2lkICpfZHRiX2Vhcmx5X3ZhIF9faW5pdGRhdGE7Cj4+Pj4+ICt1aW50cHRy X3QgX2R0Yl9lYXJseV9wYSBfX2luaXRkYXRhOwo+Pj4+Pgo+Pj4+PiDCoCBzdHJ1Y3QgcHRfYWxs b2Nfb3BzIHsKPj4+Pj4gwqDCoMKgwqDCoMKgIHB0ZV90ICooKmdldF9wdGVfdmlydCkocGh5c19h ZGRyX3QgcGEpOwo+Pj4+PiBAQCAtODgsNiArODgsMTAgQEAgc3RhdGljIHZvaWQgcHJpbnRfdm1f bGF5b3V0KHZvaWQpCj4+Pj4+IMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgICh1bnNp Z25lZCBsb25nKVZNQUxMT0NfRU5EKTsKPj4+Pj4gwqDCoMKgwqDCoMKgIHByaW50X21sbSgibG93 bWVtIiwgKHVuc2lnbmVkIGxvbmcpUEFHRV9PRkZTRVQsCj4+Pj4+IMKgwqDCoMKgwqDCoMKgwqDC oMKgwqDCoMKgwqDCoMKgICh1bnNpZ25lZCBsb25nKWhpZ2hfbWVtb3J5KTsKPj4+Pj4gKyNpZmRl ZiBDT05GSUdfWElQX0tFUk5FTAo+Pj4+PiArwqDCoMKgwqAgcHJpbnRfbWxtKCJ4aXAiLCAodW5z aWduZWQgbG9uZylYSVBfVklSVF9BRERSX1NUQVJULAo+Pj4+PiArwqDCoMKgwqDCoMKgwqDCoMKg wqDCoMKgwqDCoCAodW5zaWduZWQgbG9uZylYSVBfVklSVF9BRERSX1NUQVJUICsgU1pfMTZNKTsK Pj4+Pj4gKyNlbmRpZiAvKiBDT05GSUdfWElQX0tFUk5FTCAqLwo+Pj4+PiDCoCB9Cj4+Pj4+IMKg ICNlbHNlCj4+Pj4+IMKgIHN0YXRpYyB2b2lkIHByaW50X3ZtX2xheW91dCh2b2lkKSB7IH0KPj4+ Pj4gQEAgLTExMyw2ICsxMTcsMTAgQEAgdm9pZCBfX2luaXQgc2V0dXBfYm9vdG1lbSh2b2lkKQo+ Pj4+PiDCoMKgwqDCoMKgwqAgcGh5c19hZGRyX3QgZHJhbV9lbmQgPSBtZW1ibG9ja19lbmRfb2Zf RFJBTSgpOwo+Pj4+PiDCoMKgwqDCoMKgwqAgcGh5c19hZGRyX3QgbWF4X21hcHBlZF9hZGRyID0g X19wYSh+KHVsb25nKTApOwo+Pj4+Pgo+Pj4+PiArI2lmZGVmIENPTkZJR19YSVBfS0VSTkVMCj4+ Pj4+ICvCoMKgwqDCoCB2bWxpbnV4X3N0YXJ0ID0gX19wYV9zeW1ib2woJl9zZGF0YSk7Cj4+Pj4+ ICsjZW5kaWYKPj4+Pj4gKwo+Pj4+PiDCoMKgwqDCoMKgwqAgLyogVGhlIG1heGltYWwgcGh5c2lj YWwgbWVtb3J5IHNpemUgaXMgLVBBR0VfT0ZGU0VULiAqLwo+Pj4+PiDCoMKgwqDCoMKgwqAgbWVt YmxvY2tfZW5mb3JjZV9tZW1vcnlfbGltaXQoLVBBR0VfT0ZGU0VUKTsKPj4+Pj4KPj4+Pj4gQEAg LTE0OSwxMSArMTU3LDI3IEBAIHZvaWQgX19pbml0IHNldHVwX2Jvb3RtZW0odm9pZCkKPj4+Pj4g wqDCoMKgwqDCoMKgIG1lbWJsb2NrX2FsbG93X3Jlc2l6ZSgpOwo+Pj4+PiDCoCB9Cj4+Pj4+Cj4+ Pj4+ICsjaWZkZWYgQ09ORklHX1hJUF9LRVJORUwKPj4+Pj4gKwo+Pj4+PiArZXh0ZXJuIGNoYXIg X3hpcHJvbVtdLCBfZXhpcHJvbVtdOwo+Pj4+PiArZXh0ZXJuIGNoYXIgX3NkYXRhW10sIF9lZGF0 YVtdOwo+Pj4+PiArCj4+Pj4+ICsjZW5kaWYgLyogQ09ORklHX1hJUF9LRVJORUwgKi8KPj4+Pj4g Kwo+Pj4+PiDCoCAjaWZkZWYgQ09ORklHX01NVQo+Pj4+PiAtc3RhdGljIHN0cnVjdCBwdF9hbGxv Y19vcHMgcHRfb3BzOwo+Pj4+PiArc3RhdGljIHN0cnVjdCBwdF9hbGxvY19vcHMgX3B0X29wczsK Pj4+Pj4gKwo+Pj4+PiArI2lmZGVmIENPTkZJR19YSVBfS0VSTkVMCj4+Pj4+ICsjZGVmaW5lIHB0 X29wcyAoKihzdHJ1Y3QgcHRfYWxsb2Nfb3BzICopWElQX0ZJWFVQKCZfcHRfb3BzKSkKPj4+Pj4g KyNlbHNlCj4+Pj4+ICsjZGVmaW5lIHB0X29wc8KgwqDCoMKgwqDCoCBfcHRfb3BzCj4+Pj4+ICsj ZW5kaWYKPj4+Pj4KPj4+Pj4gwqAgdW5zaWduZWQgbG9uZyB2YV9wYV9vZmZzZXQ7Cj4+Pj4+IMKg IEVYUE9SVF9TWU1CT0wodmFfcGFfb2Zmc2V0KTsKPj4+Pj4gKyNpZmRlZiBDT05GSUdfWElQX0tF Uk5FTAo+Pj4+PiArI2RlZmluZSB2YV9wYV9vZmZzZXQgKCooKHVuc2lnbmVkIGxvbmcgKilYSVBf RklYVVAoJnZhX3BhX29mZnNldCkpKQo+Pj4+PiArI2VuZGlmCj4+Pj4+IMKgIHVuc2lnbmVkIGxv bmcgcGZuX2Jhc2U7Cj4+Pj4+IMKgIEVYUE9SVF9TWU1CT0wocGZuX2Jhc2UpOwo+Pj4+Pgo+Pj4+ PiBAQCAtMTYzLDYgKzE4NywxMiBAQCBwdGVfdCBmaXhtYXBfcHRlW1BUUlNfUEVSX1BURV0gCj4+ Pj4+IF9fcGFnZV9hbGlnbmVkX2JzczsKPj4+Pj4KPj4+Pj4gwqAgcGdkX3QgZWFybHlfcGdfZGly W1BUUlNfUEVSX1BHRF0gX19pbml0ZGF0YSBfX2FsaWduZWQoUEFHRV9TSVpFKTsKPj4+Pj4KPj4+ Pj4gKyNpZmRlZiBDT05GSUdfWElQX0tFUk5FTAo+Pj4+PiArI2RlZmluZSB0cmFtcG9saW5lX3Bn X2RpcsKgwqDCoCAoKHBnZF90ICopWElQX0ZJWFVQKHRyYW1wb2xpbmVfcGdfZGlyKSkKPj4+Pj4g KyNkZWZpbmUgZml4bWFwX3B0ZcKgwqDCoMKgwqDCoMKgwqDCoMKgICgocHRlX3QgKilYSVBfRklY VVAoZml4bWFwX3B0ZSkpCj4+Pj4+ICsjZGVmaW5lIGVhcmx5X3BnX2RpcsKgwqDCoMKgwqDCoMKg wqAgKChwZ2RfdCAqKVhJUF9GSVhVUChlYXJseV9wZ19kaXIpKQo+Pj4+PiArI2VuZGlmIC8qIENP TkZJR19YSVBfS0VSTkVMICovCj4+Pj4+ICsKPj4+Pj4gwqAgdm9pZCBfX3NldF9maXhtYXAoZW51 bSBmaXhlZF9hZGRyZXNzZXMgaWR4LCBwaHlzX2FkZHJfdCBwaHlzLCAKPj4+Pj4gcGdwcm90X3Qg cHJvdCkKPj4+Pj4gwqAgewo+Pj4+PiDCoMKgwqDCoMKgwqAgdW5zaWduZWQgbG9uZyBhZGRyID0g X19maXhfdG9fdmlydChpZHgpOwo+Pj4+PiBAQCAtMjM4LDYgKzI2OCwxNSBAQCBwbWRfdCBmaXht YXBfcG1kW1BUUlNfUEVSX1BNRF0gCj4+Pj4+IF9fcGFnZV9hbGlnbmVkX2JzczsKPj4+Pj4gwqAg cG1kX3QgZWFybHlfcG1kW1BUUlNfUEVSX1BNRF0gX19pbml0ZGF0YSBfX2FsaWduZWQoUEFHRV9T SVpFKTsKPj4+Pj4gwqAgcG1kX3QgZWFybHlfZHRiX3BtZFtQVFJTX1BFUl9QTURdIF9faW5pdGRh dGEgX19hbGlnbmVkKFBBR0VfU0laRSk7Cj4+Pj4+Cj4+Pj4+ICsjaWZkZWYgQ09ORklHX1hJUF9L RVJORUwKPj4+Pj4gK3BtZF90IHhpcF9wbWRbUFRSU19QRVJfUE1EXSBfX3BhZ2VfYWxpZ25lZF9i c3M7Cj4+Pj4+ICsKPj4+Pj4gKyNkZWZpbmUgdHJhbXBvbGluZV9wbWTCoMKgwqDCoMKgwqAgKChw bWRfdCAqKVhJUF9GSVhVUCh0cmFtcG9saW5lX3BtZCkpCj4+Pj4+ICsjZGVmaW5lIGZpeG1hcF9w bWTCoMKgICgocG1kX3QgKilYSVBfRklYVVAoZml4bWFwX3BtZCkpCj4+Pj4+ICsjZGVmaW5lIHhp cF9wbWTCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoCAoKHBtZF90ICopWElQX0ZJWFVQKHhpcF9w bWQpKQo+Pj4+PiArI2RlZmluZSBlYXJseV9wbWTCoMKgwqAgKChwbWRfdCAqKVhJUF9GSVhVUChl YXJseV9wbWQpKQo+Pj4+PiArI2VuZGlmIC8qIENPTkZJR19YSVBfS0VSTkVMICovCj4+Pj4+ICsK Pj4+Pj4gwqAgc3RhdGljIHBtZF90ICpfX2luaXQgZ2V0X3BtZF92aXJ0X2Vhcmx5KHBoeXNfYWRk cl90IHBhKQo+Pj4+PiDCoCB7Cj4+Pj4+IMKgwqDCoMKgwqDCoCAvKiBCZWZvcmUgTU1VIGlzIGVu YWJsZWQgKi8KPj4+Pj4gQEAgLTM1NCw2ICszOTMsMTkgQEAgc3RhdGljIHVpbnRwdHJfdCBfX2lu aXQgCj4+Pj4+IGJlc3RfbWFwX3NpemUocGh5c19hZGRyX3QgYmFzZSwgcGh5c19hZGRyX3Qgc2l6 ZSkKPj4+Pj4gwqDCoMKgwqDCoMKgIHJldHVybiBQTURfU0laRTsKPj4+Pj4gwqAgfQo+Pj4+Pgo+ Pj4+PiArI2lmZGVmIENPTkZJR19YSVBfS0VSTkVMCj4+Pj4+ICsvKiBjYWxsZWQgZnJvbSBoZWFk LlMgd2l0aCBNTVUgb2ZmICovCj4+Pj4+ICthc21saW5rYWdlIHZvaWQgX19pbml0IF9fY29weV9k YXRhKHZvaWQpCj4+Pj4+ICt7Cj4+Pj4+ICvCoMKgwqDCoCB2b2lkICpmcm9tID0gKHZvaWQgKiko Jl9zZGF0YSk7Cj4+Pj4+ICvCoMKgwqDCoCB2b2lkICplbmQgPSAodm9pZCAqKSgmX2VuZCk7Cj4+ Pj4+ICvCoMKgwqDCoCB2b2lkICp0byA9ICh2b2lkICopQ09ORklHX1BIWVNfUkFNX0JBU0U7Cj4+ Pj4+ICvCoMKgwqDCoCBzaXplX3Qgc3ogPSAoc2l6ZV90KShlbmQgLSBmcm9tKTsKPj4+Pj4gKwo+ Pj4+PiArwqDCoMKgwqAgbWVtY3B5KHRvLCBmcm9tLCBzeik7Cj4+Pj4+ICt9Cj4+Pj4+ICsjZW5k aWYKPj4+Pj4gKwo+Pj4+PiDCoCAvKgo+Pj4+PiDCoMKgICogc2V0dXBfdm0oKSBpcyBjYWxsZWQg ZnJvbSBoZWFkLlMgd2l0aCBNTVUtb2ZmLgo+Pj4+PiDCoMKgICoKPj4+Pj4gQEAgLTM3NCw3ICs0 MjYsOCBAQCBzdGF0aWMgdWludHB0cl90IF9faW5pdCAKPj4+Pj4gYmVzdF9tYXBfc2l6ZShwaHlz X2FkZHJfdCBiYXNlLCBwaHlzX2FkZHJfdCBzaXplKQo+Pj4+Pgo+Pj4+PiDCoCBhc21saW5rYWdl IHZvaWQgX19pbml0IHNldHVwX3ZtKHVpbnRwdHJfdCBkdGJfcGEpCj4+Pj4+IMKgIHsKPj4+Pj4g LcKgwqDCoMKgIHVpbnRwdHJfdCB2YSwgcGEsIGVuZF92YTsKPj4+Pj4gK8KgwqDCoMKgIHVpbnRw dHJfdCB2YSwgZW5kX3ZhOwo+Pj4+PiArwqDCoMKgwqAgdWludHB0cl90IF9fbWF5YmVfdW51c2Vk IHBhOwo+Pj4+PiDCoMKgwqDCoMKgwqAgdWludHB0cl90IGxvYWRfcGEgPSAodWludHB0cl90KSgm X3N0YXJ0KTsKPj4+Pj4gwqDCoMKgwqDCoMKgIHVpbnRwdHJfdCBsb2FkX3N6ID0gKHVpbnRwdHJf dCkoJl9lbmQpIC0gbG9hZF9wYTsKPj4+Pj4gwqDCoMKgwqDCoMKgIHVpbnRwdHJfdCBtYXBfc2l6 ZTsKPj4+Pj4gQEAgLTM4Miw2ICs0MzUsMTMgQEAgYXNtbGlua2FnZSB2b2lkIF9faW5pdCBzZXR1 cF92bSh1aW50cHRyX3QgZHRiX3BhKQo+Pj4+PiDCoMKgwqDCoMKgwqAgcG1kX3QgZml4X2JtYXBf c3BtZCwgZml4X2JtYXBfZXBtZDsKPj4+Pj4gwqAgI2VuZGlmCj4+Pj4+Cj4+Pj4+ICsjaWZkZWYg Q09ORklHX1hJUF9LRVJORUwKPj4+Pj4gK8KgwqDCoMKgIHVpbnRwdHJfdCB4aXByb20gPSAodWlu dHB0cl90KUNPTkZJR19YSVBfUEhZU19BRERSOwo+Pj4+PiArwqDCoMKgwqAgdWludHB0cl90IHhp cHJvbV9zeiA9ICh1aW50cHRyX3QpKCZfZXhpcHJvbSkgLSAKPj4+Pj4gKHVpbnRwdHJfdCkoJl94 aXByb20pOwo+Pj4+PiArCj4+Pj4+ICvCoMKgwqDCoCBsb2FkX3BhID0gKHVpbnRwdHJfdClDT05G SUdfUEhZU19SQU1fQkFTRTsKPj4+Pj4gK8KgwqDCoMKgIGxvYWRfc3ogPSAodWludHB0cl90KSgm X2VuZCkgLSAodWludHB0cl90KSgmX3NkYXRhKTsKPj4+Pj4gKyNlbmRpZgo+Pj4+PiDCoMKgwqDC oMKgwqAgdmFfcGFfb2Zmc2V0ID0gUEFHRV9PRkZTRVQgLSBsb2FkX3BhOwo+Pgo+PiBJIHNob3Vs ZCBoYXZlIHNlZW4gdGhpcyBiZWZvcmUsIEkgd2FzIHRvbyBmb2N1c2VkIG9uIGhhdmluZyBhIFhJ UCBrZXJuZWwKPj4gYm9vdC4gSSBhbHJlYWR5IG1vdmVkIHRoZSBrZXJuZWwgbWFwcGluZyBpbiB0 aGUgdm1hbGxvYyB6b25lOiB0aGUKPj4gdmlydHVhbCB0byBwaHlzaWNhbCB0cmFuc2xhdGlvbnMg bmVlZCB0byBiZSBoYW5kbGVkIGRpZmZlcmVudGx5IG5vdyB0aGF0Cj4+IHRoZSBrZXJuZWwgbWFw cGluZyBkb2VzIG5vdCBsaWUgaW50byBsaW5lYXIgbWFwcGluZyBhbnltb3JlLCB3ZSBjYW4ndAo+ PiB1c2UgdmFfcGFfb2Zmc2V0IGRlZmluZWQgYWJvdmUgZm9yIGJvdGggbWFwcGluZ3MuCj4+Cj4+ IEkgd2FzIHJlYmFzaW5nIG15IHBhdGNoc2V0IG9uIHRoZSBYSVAgcGF0Y2ggYnV0IEkgYmVsaWV2 ZSB0aGF0IGRvaW5nIHRoZQo+PiBvdGhlciB3YXkgYXJvdW5kIHdvdWxkIGdyZWF0bHkgc2ltcGxp ZnkgdGhlIFhJUCBwYXRjaCBhcyB0aGUga2VybmVsCj4+IG1hcHBpbmcgd291bGQgYWxyZWFkeSBi ZSBtb3ZlZCBvdXRzaWRlIHRoZSBsaW5lYXIgbWFwcGluZywgdGhlcmUgd291bGQKPj4gYmUgbm8g bmVlZCB0byByZXNlcnZlIGEgem9uZSBpbiB2bWFsbG9jIGFueW1vcmUgKHRoYXQgc2ltcGxpZmll cwo+PiBwZ3RhYmxlLmggcXVpdGUgYSBsb3QpLiBBbmQgdGhlIFhJUCBrZXJuZWwgbWFwcGluZyBj b3VsZCBiZSBpbXBsZW1lbnRlZAo+PiBpbiBhIG5ldyBjcmVhdGVfa2VybmVsX3BhZ2VfdGFibGUg KHRoYXQgd291bGQgYWxzbyBzaW1wbGlmeSBtbS9pbml0LmMpLgo+Pgo+PiBJIGNhbiBoZWxwIHRv IGRvIHRoYXQgYnV0IEkgZG9uJ3QgdGhpbmsgd2Ugc2hvdWxkIG1lcmdlIHRoaXMgcGF0Y2ggYXMg aXMKPj4gbm93Lgo+IAo+IEkgdGhpbmsgdGhhdCdzIHRoZSByaWdodCB3YXkgdG8gZ28gZm9yIG5v dzogaXQncyBhIGxvdCBoYXJkZXIgdG8gdGVzdCAKPiB0aGUgWElQIHN0dWZmLCBhcyBpdCByZXF1 aXJlcyBhIGJ1bmNoIG9mIGhhcm5lc3MgY2hhbmdlcy7CoCBTbyBsZXQncyB0YWtlIAo+IHRoZSBw YWdlIHRhYmxlIHJlZmFjdG9yaW5nIGluIG5vdyBhbmQgcmViYXNlIHRoaXMgc3R1ZmYgb24gdG9w IG9mIGl0LiAKPiBUaGVyZSdzIHJlYWxseSBubyB3YXkgdG8gZG8gYm90aCB3aXRob3V0IG1ha2lu ZyBtb3JlIHdvcmsgZm9yIHNvbWVvbmUsIAo+IGl0J3MganVzdCBhIGhlYWRhY2hlIG9uIHRpbWlu Zy4KPiAKPiBBbGV4OiBpZiB5b3Ugd2FudCB0byBzaWduIHVwIHRvIHNwZW5kIHNvbWUgdGltZSB0 aGVyZSB0aGF0J2QgYmUgZ3JlYXQsIAo+IG90aGVyd2lzZSBJIHdpbGwuCgpJIGNhbiB0YWtlIGNh cmUgb2YgdGhhdCwgbm8gcHJvYmxlbS4KCj4gRWl0aGVyIHdheSwgY2FuIHlvdSBwb2ludCBtZSAo ZWl0aGVyIGp1c3QgaW5kaWNhdGUgCj4gdGhlIG9sZCB2ZXJzaW9uIGlzIE9LIG9yIHNlbmQgYSBu ZXcgb25lKSB0byB3aGF0IHlvdSB3YW50IG1lIHRvIGxvb2sgYXQgCj4gV1JUIHRoZSBwYWdlIHRh YmxlIGNvZGU/wqAgSUlSQyBpdCBsb29rZWQgcHJldHR5IG11Y2ggZmluZSwgYnV0IEknbGwgdGFr ZSAKPiBhbm90aGVyIGxvb2sgQVNBUCBzbyB3ZSBjYW4gYXZvaWQgc2VyaWFsaXppbmcgZXZlcnl0 aGluZy4KClRoZSB2MyBpcyBmaW5lIGZvciBtZTogCmh0dHBzOi8vcGF0Y2h3b3JrLmtlcm5lbC5v cmcvcHJvamVjdC9saW51eC1yaXNjdi9saXN0Lz9zZXJpZXM9NDQ3Njk5Cgo+IAo+Pgo+PiBBbGV4 Cj4+Cj4+Pj4+IMKgwqDCoMKgwqDCoCBwZm5fYmFzZSA9IFBGTl9ET1dOKGxvYWRfcGEpOwo+Pj4+ Pgo+Pj4+PiBAQCAtNDIwLDYgKzQ4MCwyMSBAQCBhc21saW5rYWdlIHZvaWQgX19pbml0IHNldHVw X3ZtKHVpbnRwdHJfdCBkdGJfcGEpCj4+Pj4+IMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDC oMKgwqDCoMKgwqDCoMKgwqDCoMKgIGxvYWRfcGEsIFBHRElSX1NJWkUsIFBBR0VfS0VSTkVMX0VY RUMpOwo+Pj4+PiDCoCAjZW5kaWYKPj4+Pj4KPj4+Pj4gKyNpZmRlZiBDT05GSUdfWElQX0tFUk5F TAo+Pj4+PiArwqDCoMKgwqAgY3JlYXRlX3BnZF9tYXBwaW5nKHRyYW1wb2xpbmVfcGdfZGlyLCBY SVBfVklSVF9BRERSX1NUQVJULAo+Pj4+PiArwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKg wqDCoMKgwqDCoMKgwqDCoCAodWludHB0cl90KXhpcF9wbWQsIFBHRElSX1NJWkUsIFBBR0VfVEFC TEUpOwo+Pj4+PiArwqDCoMKgwqAgZm9yICh2YSA9IFhJUF9WSVJUX0FERFJfU1RBUlQ7Cj4+Pj4+ ICvCoMKgwqDCoMKgwqDCoMKgwqAgdmEgPCBYSVBfVklSVF9BRERSX1NUQVJUICsgeGlwcm9tX3N6 Owo+Pj4+PiArwqDCoMKgwqDCoMKgwqDCoMKgIHZhICs9IFBNRF9TSVpFKSB7Cj4+Pj4+ICvCoMKg wqDCoMKgwqDCoMKgwqDCoMKgwqAgY3JlYXRlX3BtZF9tYXBwaW5nKHhpcF9wbWQsIHZhLAo+Pj4+ PiArwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKg wqDCoMKgwqAgeGlwcm9tICsgKHZhIC0gWElQX1ZJUlRfQUREUl9TVEFSVCksCj4+Pj4+ICvCoMKg wqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDC oCBQTURfU0laRSwgUEFHRV9LRVJORUxfRVhFQyk7Cj4+Pj4+ICvCoMKgwqDCoCB9Cj4+Pj4+ICsK Pj4+Pj4gK8KgwqDCoMKgIGNyZWF0ZV9wZ2RfbWFwcGluZyhlYXJseV9wZ19kaXIsIFhJUF9WSVJU X0FERFJfU1RBUlQsCj4+Pj4+ICvCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDC oMKgwqDCoMKgICh1aW50cHRyX3QpeGlwX3BtZCwgUEdESVJfU0laRSwgUEFHRV9UQUJMRSk7Cj4+ Pj4+ICsjZW5kaWYKPj4+Pj4gKwo+Pj4+PiDCoMKgwqDCoMKgwqAgLyoKPj4+Pj4gwqDCoMKgwqDC oMKgwqAgKiBTZXR1cCBlYXJseSBQR0QgY292ZXJpbmcgZW50aXJlIGtlcm5lbCB3aGljaCB3aWxs IGFsbG93cwo+Pj4+PiDCoMKgwqDCoMKgwqDCoCAqIHVzIHRvIHJlYWNoIHBhZ2luZ19pbml0KCku IFdlIG1hcCBhbGwgbWVtb3J5IGJhbmtzIGxhdGVyCj4+Pj4+IEBAIC00NDQsNyArNTE5LDcgQEAg YXNtbGlua2FnZSB2b2lkIF9faW5pdCBzZXR1cF92bSh1aW50cHRyX3QgZHRiX3BhKQo+Pj4+PiDC oMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoCBwYSArIFBN RF9TSVpFLCBQTURfU0laRSwgUEFHRV9LRVJORUwpOwo+Pj4+PiDCoMKgwqDCoMKgwqAgZHRiX2Vh cmx5X3ZhID0gKHZvaWQgKilEVEJfRUFSTFlfQkFTRV9WQSArIChkdGJfcGEgJiAKPj4+Pj4gKFBN RF9TSVpFIC0gMSkpOwo+Pj4+PiDCoCAjZWxzZSAvKiBDT05GSUdfQlVJTFRJTl9EVEIgKi8KPj4+ Pj4gLcKgwqDCoMKgIGR0Yl9lYXJseV92YSA9IF9fdmEoZHRiX3BhKTsKPj4+Pj4gK8KgwqDCoMKg IGR0Yl9lYXJseV92YSA9IF9fdmEoWElQX0ZJWFVQKGR0Yl9wYSkpOwo+Pj4+PiDCoCAjZW5kaWYg LyogQ09ORklHX0JVSUxUSU5fRFRCICovCj4+Pj4+IMKgICNlbHNlCj4+Pj4+IMKgICNpZm5kZWYg Q09ORklHX0JVSUxUSU5fRFRCCj4+Pj4+IEBAIC00NTYsNyArNTMxLDcgQEAgYXNtbGlua2FnZSB2 b2lkIF9faW5pdCBzZXR1cF92bSh1aW50cHRyX3QgZHRiX3BhKQo+Pj4+PiDCoMKgwqDCoMKgwqDC oMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoCBwYSArIFBHRElSX1NJWkUsIFBH RElSX1NJWkUsIFBBR0VfS0VSTkVMKTsKPj4+Pj4gwqDCoMKgwqDCoMKgIGR0Yl9lYXJseV92YSA9 ICh2b2lkICopRFRCX0VBUkxZX0JBU0VfVkEgKyAoZHRiX3BhICYgCj4+Pj4+IChQR0RJUl9TSVpF IC0gMSkpOwo+Pj4+PiDCoCAjZWxzZSAvKiBDT05GSUdfQlVJTFRJTl9EVEIgKi8KPj4+Pj4gLcKg wqDCoMKgIGR0Yl9lYXJseV92YSA9IF9fdmEoZHRiX3BhKTsKPj4+Pj4gK8KgwqDCoMKgIGR0Yl9l YXJseV92YSA9IF9fdmEoWElQX0ZJWFVQKGR0Yl9wYSkpOwo+Pj4+PiDCoCAjZW5kaWYgLyogQ09O RklHX0JVSUxUSU5fRFRCICovCj4+Pj4+IMKgICNlbmRpZgo+Pj4+PiDCoMKgwqDCoMKgwqAgZHRi X2Vhcmx5X3BhID0gZHRiX3BhOwo+Pj4+PiBAQCAtNDk3LDYgKzU3Miw5IEBAIHN0YXRpYyB2b2lk IF9faW5pdCBzZXR1cF92bV9maW5hbCh2b2lkKQo+Pj4+PiDCoMKgwqDCoMKgwqAgdWludHB0cl90 IHZhLCBtYXBfc2l6ZTsKPj4+Pj4gwqDCoMKgwqDCoMKgIHBoeXNfYWRkcl90IHBhLCBzdGFydCwg ZW5kOwo+Pj4+PiDCoMKgwqDCoMKgwqAgdTY0IGk7Cj4+Pj4+ICsjaWZkZWYgQ09ORklHX1hJUF9L RVJORUwKPj4+Pj4gK8KgwqDCoMKgIHVpbnRwdHJfdCB4aXByb21fc3ogPSAodWludHB0cl90KSgm X2V4aXByb20pIC0gCj4+Pj4+ICh1aW50cHRyX3QpKCZfeGlwcm9tKTsKPj4+Pj4gKyNlbmRpZgo+ Pj4+Pgo+Pj4+PiDCoMKgwqDCoMKgwqAgLyoqCj4+Pj4+IMKgwqDCoMKgwqDCoMKgICogTU1VIGlz IGVuYWJsZWQgYXQgdGhpcyBwb2ludC4gQnV0IHBhZ2UgdGFibGUgc2V0dXAgaXMgbm90IAo+Pj4+ PiBjb21wbGV0ZSB5ZXQuCj4+Pj4+IEBAIC01MjgsNiArNjA2LDE2IEBAIHN0YXRpYyB2b2lkIF9f aW5pdCBzZXR1cF92bV9maW5hbCh2b2lkKQo+Pj4+PiDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDC oMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKg IG1hcF9zaXplLCBQQUdFX0tFUk5FTF9FWEVDKTsKPj4+Pj4gwqDCoMKgwqDCoMKgwqDCoMKgwqDC oMKgwqDCoCB9Cj4+Pj4+IMKgwqDCoMKgwqDCoCB9Cj4+Pj4+ICsjaWZkZWYgQ09ORklHX1hJUF9L RVJORUwKPj4+Pj4gK8KgwqDCoMKgIG1hcF9zaXplID0gYmVzdF9tYXBfc2l6ZShDT05GSUdfWElQ X1BIWVNfQUREUiwgeGlwcm9tX3N6KTsKPj4+Pj4gK8KgwqDCoMKgIGZvciAodmEgPSBYSVBfVklS VF9BRERSX1NUQVJUOwo+Pj4+PiArwqDCoMKgwqDCoMKgwqDCoMKgIHZhIDwgWElQX1ZJUlRfQURE Ul9TVEFSVCArIHhpcHJvbV9zejsKPj4+Pj4gK8KgwqDCoMKgwqDCoMKgwqDCoCB2YSArPSBtYXBf c2l6ZSkKPj4+Pj4gK8KgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoCBjcmVhdGVfcGdkX21hcHBpbmco c3dhcHBlcl9wZ19kaXIsIHZhLAo+Pj4+PiArwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKg wqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqAgQ09ORklHX1hJUF9QSFlTX0FERFIgKyAo dmEgLSAKPj4+Pj4gWElQX1ZJUlRfQUREUl9TVEFSVCksCj4+Pj4+ICvCoMKgwqDCoMKgwqDCoMKg wqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoCBtYXBfc2l6ZSwg UEFHRV9LRVJORUxfRVhFQyk7Cj4+Pj4+ICsKPj4+Pj4gKyNlbmRpZgo+Pj4+Pgo+Pj4+PiDCoMKg wqDCoMKgwqAgLyogQ2xlYXIgZml4bWFwIFBURSBhbmQgUE1EIG1hcHBpbmdzICovCj4+Pj4+IMKg wqDCoMKgwqDCoCBjbGVhcl9maXhtYXAoRklYX1BURSk7Cj4+Pgo+Pj4gX19fX19fX19fX19fX19f X19fX19fX19fX19fX19fX19fX19fX19fX19fX19fX18KPj4+IGxpbnV4LXJpc2N2IG1haWxpbmcg bGlzdAo+Pj4gbGludXgtcmlzY3ZAbGlzdHMuaW5mcmFkZWFkLm9yZwo+Pj4gaHR0cDovL2xpc3Rz LmluZnJhZGVhZC5vcmcvbWFpbG1hbi9saXN0aW5mby9saW51eC1yaXNjdgo+Pj4KPiAKPiBfX19f X19fX19fX19fX19fX19fX19fX19fX19fX19fX19fX19fX19fX19fX19fXwo+IGxpbnV4LXJpc2N2 IG1haWxpbmcgbGlzdAo+IGxpbnV4LXJpc2N2QGxpc3RzLmluZnJhZGVhZC5vcmcKPiBodHRwOi8v bGlzdHMuaW5mcmFkZWFkLm9yZy9tYWlsbWFuL2xpc3RpbmZvL2xpbnV4LXJpc2N2CgpfX19fX19f X19fX19fX19fX19fX19fX19fX19fX19fX19fX19fX19fX19fX19fXwpsaW51eC1yaXNjdiBtYWls aW5nIGxpc3QKbGludXgtcmlzY3ZAbGlzdHMuaW5mcmFkZWFkLm9yZwpodHRwOi8vbGlzdHMuaW5m cmFkZWFkLm9yZy9tYWlsbWFuL2xpc3RpbmZvL2xpbnV4LXJpc2N2Cg==