From mboxrd@z Thu Jan 1 00:00:00 1970 From: Sibi Sankar Subject: Re: [PATCH RFC 1/2] PM / devfreq: Generic CPU frequency to device frequency mapping governor Date: Thu, 20 Jun 2019 15:11:21 +0530 Message-ID: <04bbd518efef8296e450e984e6afdba2@codeaurora.org> References: <20190618041433.245629-1-hsinyi@chromium.org> <20190618041433.245629-2-hsinyi@chromium.org> <958b27ff-6e64-b4e2-44e6-bc342e3606bc@samsung.com> Mime-Version: 1.0 Content-Type: text/plain; charset=UTF-8; format=flowed Content-Transfer-Encoding: 8bit Return-path: In-Reply-To: Sender: linux-kernel-owner@vger.kernel.org To: Hsin-Yi Wang Cc: Chanwoo Choi , "moderated list:ARM/FREESCALE IMX / MXC ARM ARCHITECTURE" , Saravana Kannan , MyungJoo Ham , Kyungmin Park , Matthias Brugger , linux-pm@vger.kernel.org, linux-mediatek@lists.infradead.org, lkml , "Andrew-sh . Cheng" , linux-kernel-owner@vger.kernel.org List-Id: linux-mediatek@lists.infradead.org Hey Hsin-Yi, Chanwoo On 2019-06-20 15:02, Hsin-Yi Wang wrote: > Hi Chanwoo Choi, Saravana Kannan and Sibi Sankar, > > I've also tested Sibi Sankar's patch[1] locally with mt8183-cci, and > it works fine too! > It'd be great if Sibi Sankar or anyone who is familiar with the > original design can finish this implementation. But if no one has time > to do that, I think I can also help on address the comments. Thanks! Now that we have a user :) I am happy to repost the patch with the comments addressed. https://lkml.org/lkml/2019/6/14/4 Also with ^^ patch and few more in the series the dt parsing of required-opps should get further simplified. > > > [1] > [RFC,2/9] OPP: Export a number of helpers to prevent code duplication > - https://patchwork.kernel.org/patch/10875199/ > [RFC,3/9] PM / devfreq: Add cpu based scaling support to > passive_governor > - https://patchwork.kernel.org/patch/10875195/ > > Hsin-Yi > > On Thu, Jun 20, 2019 at 2:56 PM Chanwoo Choi > wrote: >> >> + Sibi Sankar >> >> Hi, Hsin-Yi Wang, Saravana Kannan and Sibi Sankar >> >> I summarized the history of the related patch about this title. >> >> Firstly, >> As I knew, Saravana sent the patch[1] which contains >> 'governor_cpufreq_map.c' last year. According to the Myungoo's >> comment, >> >> Secondly, >> Sibi Sankar modified the 'governor_passive.c'[2] in order to support >> the mapping between cpu frequency and device frequency. >> Unfortunately, Sibi Sankar stopped the development about this >> because he had found the other method to get his purpose as I knew. >> >> Thirdly, >> Hsin-Yi Wang send the original patch of Saravana without modification. >> >> >> Sincerely, I think that the mapping between cpu frequency and device >> frequency is necessary. And I prefer the Sibi's approach which >> implements >> stuff to the existing 'passive' governor. >> >> We need to discuss about how to implement them by whom. >> >> >> [1] [v3,1/2] PM / devfreq: Generic CPU frequency to device frequency >> mapping governor >> - https://patchwork.kernel.org/patch/10553171/ >> >> [2] >> [PATCH RFC 0/9] Add CPU based scaling support to Passive governor >> - >> https://lore.kernel.org/lkml/08c3cff8c39e3d82e044db93e992da72@codeaurora.org/T/ >> [PATCH RFC 3/9] PM / devfreq: Add cpu based scaling support to >> passive_governor >> - >> https://lore.kernel.org/lkml/08c3cff8c39e3d82e044db93e992da72@codeaurora.org/T/#m1cafb7baf687d2a680d39c85d3ec7d1b590b68fc >> >> >> Best Regards, >> Chanwoo Choi >> >> On 19. 6. 18. 오후 1:14, Hsin-Yi Wang wrote: >> > From: Saravana Kannan >> > >> > From: Saravana Kannan >> > >> > Many CPU architectures have caches that can scale independent of the CPUs. >> > Frequency scaling of the caches is necessary to make sure the cache is not >> > a performance bottleneck that leads to poor performance and power. The same >> > idea applies for RAM/DDR. >> > >> > To achieve this, this patch adds a generic devfreq governor that takes the >> > current frequency of each CPU frequency domain and then adjusts the >> > frequency of the cache (or any devfreq device) based on the frequency of >> > the CPUs. It listens to CPU frequency transition notifiers to keep itself >> > up to date on the current CPU frequency. >> > >> > To decide the frequency of the device, the governor does one of the >> > following: >> > >> > * Uses a CPU frequency to device frequency mapping table >> > - Either one mapping table used for all CPU freq policies (typically used >> > for system with homogeneous cores/clusters that have the same OPPs). >> > - One mapping table per CPU freq policy (typically used for ASMP systems >> > with heterogeneous CPUs with different OPPs) >> > >> > OR >> > >> > * Scales the device frequency in proportion to the CPU frequency. So, if >> > the CPUs are running at their max frequency, the device runs at its max >> > frequency. If the CPUs are running at their min frequency, the device >> > runs at its min frequency. And interpolated for frequencies in between. >> > >> > Signed-off-by: Saravana Kannan >> > Signed-off-by: Hsin-Yi Wang >> > --- >> > .../bindings/devfreq/devfreq-cpufreq-map.txt | 53 ++ >> > drivers/devfreq/Kconfig | 8 + >> > drivers/devfreq/Makefile | 1 + >> > drivers/devfreq/governor_cpufreq_map.c | 583 ++++++++++++++++++ >> > 4 files changed, 645 insertions(+) >> > create mode 100644 Documentation/devicetree/bindings/devfreq/devfreq-cpufreq-map.txt >> > create mode 100644 drivers/devfreq/governor_cpufreq_map.c >> > >> > diff --git a/Documentation/devicetree/bindings/devfreq/devfreq-cpufreq-map.txt b/Documentation/devicetree/bindings/devfreq/devfreq-cpufreq-map.txt >> > new file mode 100644 >> > index 000000000000..982a30bcfc86 >> > --- /dev/null >> > +++ b/Documentation/devicetree/bindings/devfreq/devfreq-cpufreq-map.txt >> > @@ -0,0 +1,53 @@ >> > +Devfreq CPUfreq governor >> > + >> > +devfreq-cpufreq-map is a parent device that contains one or more child devices. >> > +Each child device provides CPU frequency to device frequency mapping for a >> > +specific device. Examples of devices that could use this are: DDR, cache and >> > +CCI. >> > + >> > +Parent device name shall be "devfreq-cpufreq-map". >> > + >> > +Required child device properties: >> > +- cpu-to-dev-map, or cpu-to-dev-map-: >> > + A list of tuples where each tuple consists of a >> > + CPU frequency (KHz) and the corresponding device >> > + frequency. CPU frequencies not listed in the table >> > + will use the device frequency that corresponds to the >> > + next rounded up CPU frequency. >> > + Use "cpu-to-dev-map" if all CPUs in the system should >> > + share same mapping. >> > + Use cpu-to-dev-map- to describe different >> > + mappings for different CPUs. The property should be >> > + listed only for the first CPU if multiple CPUs are >> > + synchronous. >> > +- target-dev: Phandle to device that this mapping applies to. >> > + >> > +Example: >> > + devfreq-cpufreq-map { >> > + cpubw-cpufreq { >> > + target-dev = <&cpubw>; >> > + cpu-to-dev-map = >> > + < 300000 1144000 >, >> > + < 422400 2288000 >, >> > + < 652800 3051000 >, >> > + < 883200 5996000 >, >> > + < 1190400 8056000 >, >> > + < 1497600 10101000 >, >> > + < 1728000 12145000 >, >> > + < 2649600 16250000 >; >> > + }; >> > + >> > + cache-cpufreq { >> > + target-dev = <&cache>; >> > + cpu-to-dev-map = >> > + < 300000 300000 >, >> > + < 422400 422400 >, >> > + < 652800 499200 >, >> > + < 883200 576000 >, >> > + < 960000 960000 >, >> > + < 1497600 1036800 >, >> > + < 1574400 1574400 >, >> > + < 1728000 1651200 >, >> > + < 2649600 1728000 >; >> > + }; >> > + }; >> > diff --git a/drivers/devfreq/Kconfig b/drivers/devfreq/Kconfig >> > index 0c8204d6b78a..0303f5a400b6 100644 >> > --- a/drivers/devfreq/Kconfig >> > +++ b/drivers/devfreq/Kconfig >> > @@ -74,6 +74,14 @@ config DEVFREQ_GOV_PASSIVE >> > through sysfs entries. The passive governor recommends that >> > devfreq device uses the OPP table to get the frequency/voltage. >> > >> > +config DEVFREQ_GOV_CPUFREQ_MAP >> > + tristate "CPUfreq Map" >> > + depends on CPU_FREQ >> > + help >> > + Chooses frequency based on the online CPUs' current frequency and a >> > + CPU frequency to device frequency mapping table(s). This governor >> > + can be useful for controlling devices such as DDR, cache, CCI, etc. >> > + >> > comment "DEVFREQ Drivers" >> > >> > config ARM_EXYNOS_BUS_DEVFREQ >> > diff --git a/drivers/devfreq/Makefile b/drivers/devfreq/Makefile >> > index 817dde779f16..81141e2c784f 100644 >> > --- a/drivers/devfreq/Makefile >> > +++ b/drivers/devfreq/Makefile >> > @@ -6,6 +6,7 @@ obj-$(CONFIG_DEVFREQ_GOV_PERFORMANCE) += governor_performance.o >> > obj-$(CONFIG_DEVFREQ_GOV_POWERSAVE) += governor_powersave.o >> > obj-$(CONFIG_DEVFREQ_GOV_USERSPACE) += governor_userspace.o >> > obj-$(CONFIG_DEVFREQ_GOV_PASSIVE) += governor_passive.o >> > +obj-$(CONFIG_DEVFREQ_GOV_CPUFREQ_MAP) += governor_cpufreq_map.o >> > >> > # DEVFREQ Drivers >> > obj-$(CONFIG_ARM_EXYNOS_BUS_DEVFREQ) += exynos-bus.o >> > diff --git a/drivers/devfreq/governor_cpufreq_map.c b/drivers/devfreq/governor_cpufreq_map.c >> > new file mode 100644 >> > index 000000000000..084a3ffb8f54 >> > --- /dev/null >> > +++ b/drivers/devfreq/governor_cpufreq_map.c >> > @@ -0,0 +1,583 @@ >> > +// SPDX-License-Identifier: GPL-2.0 >> > +/* >> > + * Copyright (c) 2014-2015, 2018, The Linux Foundation. All rights reserved. >> > + */ >> > + >> > +#define pr_fmt(fmt) "dev-cpufreq-map: " fmt >> > + >> > +#include >> > +#include >> > +#include >> > +#include >> > +#include >> > +#include >> > +#include >> > +#include >> > +#include "governor.h" >> > + >> > +struct cpu_state { >> > + unsigned int freq; >> > + unsigned int min_freq; >> > + unsigned int max_freq; >> > + unsigned int first_cpu; >> > +}; >> > +static struct cpu_state *state[NR_CPUS]; >> > +static int cpufreq_cnt; >> > + >> > +struct freq_map { >> > + unsigned int cpu_khz; >> > + unsigned int target_freq; >> > +}; >> > + >> > +struct devfreq_node { >> > + struct devfreq *df; >> > + void *orig_data; >> > + struct device *dev; >> > + struct device_node *of_node; >> > + struct list_head list; >> > + struct freq_map **map; >> > + struct freq_map *common_map; >> > +}; >> > +static LIST_HEAD(devfreq_list); >> > +static DEFINE_MUTEX(state_lock); >> > +static DEFINE_MUTEX(cpufreq_reg_lock); >> > + >> > +static void update_all_devfreqs(void) >> > +{ >> > + struct devfreq_node *node; >> > + >> > + list_for_each_entry(node, &devfreq_list, list) { >> > + struct devfreq *df = node->df; >> > + >> > + if (!node->df) >> > + continue; >> > + mutex_lock(&df->lock); >> > + update_devfreq(df); >> > + mutex_unlock(&df->lock); >> > + >> > + } >> > +} >> > + >> > +static struct devfreq_node *find_devfreq_node(struct device *dev) >> > +{ >> > + struct devfreq_node *node; >> > + >> > + list_for_each_entry(node, &devfreq_list, list) >> > + if (node->dev == dev || node->of_node == dev->of_node) >> > + return node; >> > + >> > + return NULL; >> > +} >> > + >> > +/* ==================== cpufreq part ==================== */ >> > +static struct cpu_state *add_policy(struct cpufreq_policy *policy) >> > +{ >> > + struct cpu_state *new_state; >> > + unsigned int cpu, first_cpu; >> > + >> > + new_state = kzalloc(sizeof(struct cpu_state), GFP_KERNEL); >> > + if (!new_state) >> > + return NULL; >> > + >> > + first_cpu = cpumask_first(policy->related_cpus); >> > + new_state->first_cpu = first_cpu; >> > + new_state->freq = policy->cur; >> > + new_state->min_freq = policy->cpuinfo.min_freq; >> > + new_state->max_freq = policy->cpuinfo.max_freq; >> > + >> > + for_each_cpu(cpu, policy->related_cpus) >> > + state[cpu] = new_state; >> > + >> > + return new_state; >> > +} >> > + >> > +static int cpufreq_trans_notifier(struct notifier_block *nb, >> > + unsigned long event, void *data) >> > +{ >> > + struct cpufreq_freqs *freq = data; >> > + struct cpu_state *s; >> > + struct cpufreq_policy *policy = NULL; >> > + >> > + if (event != CPUFREQ_POSTCHANGE) >> > + return 0; >> > + >> > + mutex_lock(&state_lock); >> > + >> > + s = state[freq->cpu]; >> > + if (!s) { >> > + policy = cpufreq_cpu_get(freq->cpu); >> > + if (policy) { >> > + s = add_policy(policy); >> > + cpufreq_cpu_put(policy); >> > + } >> > + } >> > + if (!s) >> > + goto out; >> > + >> > + if (s->freq != freq->new || policy) { >> > + s->freq = freq->new; >> > + update_all_devfreqs(); >> > + } >> > + >> > +out: >> > + mutex_unlock(&state_lock); >> > + return 0; >> > +} >> > + >> > +static struct notifier_block cpufreq_trans_nb = { >> > + .notifier_call = cpufreq_trans_notifier >> > +}; >> > + >> > +static int register_cpufreq(void) >> > +{ >> > + int ret = 0; >> > + unsigned int cpu; >> > + struct cpufreq_policy *policy; >> > + >> > + mutex_lock(&cpufreq_reg_lock); >> > + >> > + if (cpufreq_cnt) >> > + goto cnt_not_zero; >> > + >> > + get_online_cpus(); >> > + ret = cpufreq_register_notifier(&cpufreq_trans_nb, >> > + CPUFREQ_TRANSITION_NOTIFIER); >> > + if (ret) >> > + goto out; >> > + >> > + for_each_online_cpu(cpu) { >> > + policy = cpufreq_cpu_get(cpu); >> > + if (policy) { >> > + add_policy(policy); >> > + cpufreq_cpu_put(policy); >> > + } >> > + } >> > +out: >> > + put_online_cpus(); >> > +cnt_not_zero: >> > + if (!ret) >> > + cpufreq_cnt++; >> > + mutex_unlock(&cpufreq_reg_lock); >> > + return ret; >> > +} >> > + >> > +static int unregister_cpufreq(void) >> > +{ >> > + int ret = 0; >> > + int cpu; >> > + >> > + mutex_lock(&cpufreq_reg_lock); >> > + >> > + if (cpufreq_cnt > 1) >> > + goto out; >> > + >> > + cpufreq_unregister_notifier(&cpufreq_trans_nb, >> > + CPUFREQ_TRANSITION_NOTIFIER); >> > + >> > + for (cpu = ARRAY_SIZE(state) - 1; cpu >= 0; cpu--) { >> > + if (!state[cpu]) >> > + continue; >> > + if (state[cpu]->first_cpu == cpu) >> > + kfree(state[cpu]); >> > + state[cpu] = NULL; >> > + } >> > + >> > +out: >> > + cpufreq_cnt--; >> > + mutex_unlock(&cpufreq_reg_lock); >> > + return ret; >> > +} >> > + >> > +/* ==================== devfreq part ==================== */ >> > + >> > +static unsigned int interpolate_freq(struct devfreq *df, unsigned int cpu) >> > +{ >> > + unsigned long *freq_table = df->profile->freq_table; >> > + unsigned int cpu_min = state[cpu]->min_freq; >> > + unsigned int cpu_max = state[cpu]->max_freq; >> > + unsigned int cpu_freq = state[cpu]->freq; >> > + unsigned int dev_min, dev_max, cpu_percent; >> > + >> > + if (freq_table) { >> > + dev_min = freq_table[0]; >> > + dev_max = freq_table[df->profile->max_state - 1]; >> > + } else { >> > + if (df->max_freq <= df->min_freq) >> > + return 0; >> > + dev_min = df->min_freq; >> > + dev_max = df->max_freq; >> > + } >> > + >> > + cpu_percent = ((cpu_freq - cpu_min) * 100) / (cpu_max - cpu_min); >> > + return dev_min + mult_frac(dev_max - dev_min, cpu_percent, 100); >> > +} >> > + >> > +static unsigned int cpu_to_dev_freq(struct devfreq *df, unsigned int cpu) >> > +{ >> > + struct freq_map *map = NULL; >> > + unsigned int cpu_khz = 0, freq; >> > + struct devfreq_node *n = df->data; >> > + >> > + if (!state[cpu] || state[cpu]->first_cpu != cpu) { >> > + freq = 0; >> > + goto out; >> > + } >> > + >> > + if (n->common_map) >> > + map = n->common_map; >> > + else if (n->map) >> > + map = n->map[cpu]; >> > + >> > + cpu_khz = state[cpu]->freq; >> > + >> > + if (!map) { >> > + freq = interpolate_freq(df, cpu); >> > + goto out; >> > + } >> > + >> > + while (map->cpu_khz && map->cpu_khz < cpu_khz) >> > + map++; >> > + if (!map->cpu_khz) >> > + map--; >> > + freq = map->target_freq; >> > + >> > +out: >> > + dev_dbg(df->dev.parent, "CPU%u: %d -> dev: %u\n", cpu, cpu_khz, freq); >> > + return freq; >> > +} >> > + >> > +static int devfreq_cpufreq_get_freq(struct devfreq *df, >> > + unsigned long *freq) >> > +{ >> > + unsigned int cpu, tgt_freq = 0; >> > + struct devfreq_node *node; >> > + >> > + node = df->data; >> > + if (!node) { >> > + pr_err("Unable to find devfreq node!\n"); >> > + return -ENODEV; >> > + } >> > + >> > + for_each_possible_cpu(cpu) >> > + tgt_freq = max(tgt_freq, cpu_to_dev_freq(df, cpu)); >> > + >> > + *freq = tgt_freq; >> > + return 0; >> > +} >> > + >> > +static unsigned int show_table(char *buf, unsigned int len, >> > + struct freq_map *map) >> > +{ >> > + unsigned int cnt = 0; >> > + >> > + cnt += snprintf(buf + cnt, len - cnt, "CPU freq\tDevice freq\n"); >> > + >> > + while (map->cpu_khz && cnt < len) { >> > + cnt += snprintf(buf + cnt, len - cnt, "%8u\t%11u\n", >> > + map->cpu_khz, map->target_freq); >> > + map++; >> > + } >> > + if (cnt < len) >> > + cnt += snprintf(buf + cnt, len - cnt, "\n"); >> > + >> > + return cnt; >> > +} >> > + >> > +static ssize_t freq_map_show(struct device *dev, struct device_attribute *attr, >> > + char *buf) >> > +{ >> > + struct devfreq *df = to_devfreq(dev); >> > + struct devfreq_node *n = df->data; >> > + struct freq_map *map; >> > + unsigned int cnt = 0, cpu; >> > + >> > + mutex_lock(&state_lock); >> > + if (n->common_map) { >> > + map = n->common_map; >> > + cnt += snprintf(buf + cnt, PAGE_SIZE - cnt, >> > + "Common table for all CPUs:\n"); >> > + cnt += show_table(buf + cnt, PAGE_SIZE - cnt, map); >> > + } else if (n->map) { >> > + for_each_possible_cpu(cpu) { >> > + map = n->map[cpu]; >> > + if (!map) >> > + continue; >> > + cnt += snprintf(buf + cnt, PAGE_SIZE - cnt, >> > + "CPU %u:\n", cpu); >> > + if (cnt >= PAGE_SIZE) >> > + break; >> > + cnt += show_table(buf + cnt, PAGE_SIZE - cnt, map); >> > + if (cnt >= PAGE_SIZE) >> > + break; >> > + } >> > + } else { >> > + cnt += snprintf(buf + cnt, PAGE_SIZE - cnt, >> > + "Device freq interpolated based on CPU freq\n"); >> > + } >> > + mutex_unlock(&state_lock); >> > + >> > + return cnt; >> > +} >> > + >> > +static DEVICE_ATTR_RO(freq_map); >> > +static struct attribute *dev_attr[] = { >> > + &dev_attr_freq_map.attr, >> > + NULL, >> > +}; >> > + >> > +static struct attribute_group dev_attr_group = { >> > + .name = "cpufreq-map", >> > + .attrs = dev_attr, >> > +}; >> > + >> > +static int devfreq_cpufreq_gov_start(struct devfreq *devfreq) >> > +{ >> > + int ret = 0; >> > + struct devfreq_node *node; >> > + bool alloc = false; >> > + >> > + ret = register_cpufreq(); >> > + if (ret) >> > + return ret; >> > + >> > + ret = sysfs_create_group(&devfreq->dev.kobj, &dev_attr_group); >> > + if (ret) { >> > + unregister_cpufreq(); >> > + return ret; >> > + } >> > + >> > + mutex_lock(&state_lock); >> > + >> > + node = find_devfreq_node(devfreq->dev.parent); >> > + if (node == NULL) { >> > + node = kzalloc(sizeof(struct devfreq_node), GFP_KERNEL); >> > + if (!node) { >> > + ret = -ENOMEM; >> > + goto alloc_fail; >> > + } >> > + alloc = true; >> > + node->dev = devfreq->dev.parent; >> > + list_add_tail(&node->list, &devfreq_list); >> > + } >> > + node->df = devfreq; >> > + node->orig_data = devfreq->data; >> > + devfreq->data = node; >> > + >> > + mutex_lock(&devfreq->lock); >> > + ret = update_devfreq(devfreq); >> > + mutex_unlock(&devfreq->lock); >> > + if (ret) { >> > + pr_err("Freq update failed!\n"); >> > + goto update_fail; >> > + } >> > + >> > + mutex_unlock(&state_lock); >> > + return 0; >> > + >> > +update_fail: >> > + devfreq->data = node->orig_data; >> > + if (alloc) { >> > + list_del(&node->list); >> > + kfree(node); >> > + } >> > +alloc_fail: >> > + mutex_unlock(&state_lock); >> > + sysfs_remove_group(&devfreq->dev.kobj, &dev_attr_group); >> > + unregister_cpufreq(); >> > + return ret; >> > +} >> > + >> > +static void devfreq_cpufreq_gov_stop(struct devfreq *devfreq) >> > +{ >> > + struct devfreq_node *node = devfreq->data; >> > + >> > + mutex_lock(&state_lock); >> > + devfreq->data = node->orig_data; >> > + if (node->map || node->common_map) { >> > + node->df = NULL; >> > + } else { >> > + list_del(&node->list); >> > + kfree(node); >> > + } >> > + mutex_unlock(&state_lock); >> > + >> > + sysfs_remove_group(&devfreq->dev.kobj, &dev_attr_group); >> > + unregister_cpufreq(); >> > +} >> > + >> > +static int devfreq_cpufreq_ev_handler(struct devfreq *devfreq, >> > + unsigned int event, void *data) >> > +{ >> > + int ret; >> > + >> > + switch (event) { >> > + case DEVFREQ_GOV_START: >> > + >> > + ret = devfreq_cpufreq_gov_start(devfreq); >> > + if (ret) { >> > + pr_err("Governor start failed!\n"); >> > + return ret; >> > + } >> > + pr_debug("Enabled CPUfreq-map governor\n"); >> > + break; >> > + >> > + case DEVFREQ_GOV_STOP: >> > + >> > + devfreq_cpufreq_gov_stop(devfreq); >> > + pr_debug("Disabled dev CPUfreq-map governor\n"); >> > + break; >> > + } >> > + >> > + return 0; >> > +} >> > + >> > +static struct devfreq_governor devfreq_cpufreq = { >> > + .name = "cpufreq-map", >> > + .get_target_freq = devfreq_cpufreq_get_freq, >> > + .event_handler = devfreq_cpufreq_ev_handler, >> > +}; >> > + >> > +#define NUM_COLS 2 >> > +static struct freq_map *read_tbl(struct device_node *of_node, char *prop_name) >> > +{ >> > + int len, nf, i, j; >> > + u32 data; >> > + struct freq_map *tbl; >> > + >> > + if (!of_find_property(of_node, prop_name, &len)) >> > + return NULL; >> > + len /= sizeof(data); >> > + >> > + if (len % NUM_COLS || len == 0) >> > + return NULL; >> > + nf = len / NUM_COLS; >> > + >> > + tbl = kzalloc((nf + 1) * sizeof(*tbl), GFP_KERNEL); >> > + if (!tbl) >> > + return NULL; >> > + >> > + for (i = 0, j = 0; i < nf; i++, j += 2) { >> > + of_property_read_u32_index(of_node, prop_name, j, &data); >> > + tbl[i].cpu_khz = data; >> > + >> > + of_property_read_u32_index(of_node, prop_name, j + 1, &data); >> > + tbl[i].target_freq = data; >> > + } >> > + tbl[i].cpu_khz = 0; >> > + >> > + return tbl; >> > +} >> > + >> > +#define PROP_TARGET "target-dev" >> > +#define PROP_TABLE "cpu-to-dev-map" >> > +static int add_table_from_of(struct device_node *of_node) >> > +{ >> > + struct device_node *target_of_node; >> > + struct devfreq_node *node; >> > + struct freq_map *common_tbl; >> > + struct freq_map **tbl_list = NULL; >> > + static char prop_name[] = PROP_TABLE "-999999"; >> > + int cpu, ret, cnt = 0, prop_sz = ARRAY_SIZE(prop_name); >> > + >> > + target_of_node = of_parse_phandle(of_node, PROP_TARGET, 0); >> > + if (!target_of_node) >> > + return -EINVAL; >> > + >> > + node = kzalloc(sizeof(struct devfreq_node), GFP_KERNEL); >> > + if (!node) >> > + return -ENOMEM; >> > + >> > + common_tbl = read_tbl(of_node, PROP_TABLE); >> > + if (!common_tbl) { >> > + tbl_list = kzalloc(sizeof(*tbl_list) * NR_CPUS, GFP_KERNEL); >> > + if (!tbl_list) { >> > + ret = -ENOMEM; >> > + goto err_list; >> > + } >> > + >> > + for_each_possible_cpu(cpu) { >> > + ret = snprintf(prop_name, prop_sz, "%s-%d", >> > + PROP_TABLE, cpu); >> > + if (ret >= prop_sz) { >> > + pr_warn("More CPUs than I can handle!\n"); >> > + pr_warn("Skipping rest of the tables!\n"); >> > + break; >> > + } >> > + tbl_list[cpu] = read_tbl(of_node, prop_name); >> > + if (tbl_list[cpu]) >> > + cnt++; >> > + } >> > + } >> > + if (!common_tbl && !cnt) { >> > + ret = -EINVAL; >> > + goto err_tbl; >> > + } >> > + >> > + mutex_lock(&state_lock); >> > + node->of_node = target_of_node; >> > + node->map = tbl_list; >> > + node->common_map = common_tbl; >> > + list_add_tail(&node->list, &devfreq_list); >> > + mutex_unlock(&state_lock); >> > + >> > + return 0; >> > +err_tbl: >> > + kfree(tbl_list); >> > +err_list: >> > + kfree(node); >> > + return ret; >> > +} >> > + >> > +static int __init devfreq_cpufreq_init(void) >> > +{ >> > + int ret; >> > + struct device_node *of_par, *of_child; >> > + >> > + of_par = of_find_node_by_name(NULL, "devfreq-cpufreq-map"); >> > + if (of_par) { >> > + for_each_child_of_node(of_par, of_child) { >> > + ret = add_table_from_of(of_child); >> > + if (ret) >> > + pr_err("Parsing %s failed!\n", of_child->name); >> > + else >> > + pr_debug("Parsed %s.\n", of_child->name); >> > + } >> > + of_node_put(of_par); >> > + } else { >> > + pr_info("No tables parsed from DT.\n"); >> > + } >> > + >> > + ret = devfreq_add_governor(&devfreq_cpufreq); >> > + if (ret) { >> > + pr_err("cpufreq-map governor add failed!\n"); >> > + return ret; >> > + } >> > + >> > + return 0; >> > +} >> > +subsys_initcall(devfreq_cpufreq_init); >> > + >> > +static void __exit devfreq_cpufreq_exit(void) >> > +{ >> > + int ret, cpu; >> > + struct devfreq_node *node, *tmp; >> > + >> > + ret = devfreq_remove_governor(&devfreq_cpufreq); >> > + if (ret) >> > + pr_err("cpufreq-map governor remove failed!\n"); >> > + >> > + mutex_lock(&state_lock); >> > + list_for_each_entry_safe(node, tmp, &devfreq_list, list) { >> > + kfree(node->common_map); >> > + for_each_possible_cpu(cpu) >> > + kfree(node->map[cpu]); >> > + kfree(node->map); >> > + list_del(&node->list); >> > + kfree(node); >> > + } >> > + mutex_unlock(&state_lock); >> > +} >> > +module_exit(devfreq_cpufreq_exit); >> > + >> > +MODULE_DESCRIPTION("devfreq gov that sets dev freq based on current CPU freq"); >> > +MODULE_LICENSE("GPL v2"); >> > -- -- Sibi Sankar -- Qualcomm Innovation Center, Inc. is a member of Code Aurora Forum, a Linux Foundation Collaborative Project. From mboxrd@z Thu Jan 1 00:00:00 1970 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=-6.8 required=3.0 tests=DKIMWL_WL_HIGH,DKIM_SIGNED, DKIM_VALID,HEADER_FROM_DIFFERENT_DOMAINS,INCLUDES_PATCH,MAILING_LIST_MULTI, SIGNED_OFF_BY,SPF_HELO_NONE,SPF_PASS,URIBL_BLOCKED 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 40748C43613 for ; Thu, 20 Jun 2019 09:41:37 +0000 (UTC) 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 mail.kernel.org (Postfix) with ESMTPS id 1511A2080C for ; Thu, 20 Jun 2019 09:41:37 +0000 (UTC) Authentication-Results: mail.kernel.org; dkim=pass (2048-bit key) header.d=lists.infradead.org header.i=@lists.infradead.org header.b="ZIOEOGZ8"; dkim=fail reason="key not found in DNS" (0-bit key) header.d=codeaurora.org header.i=@codeaurora.org header.b="AKaTYmSX"; dkim=fail reason="key not found in DNS" (0-bit key) header.d=codeaurora.org header.i=@codeaurora.org header.b="d78XEtsy" DMARC-Filter: OpenDMARC Filter v1.3.2 mail.kernel.org 1511A2080C Authentication-Results: mail.kernel.org; dmarc=none (p=none dis=none) header.from=codeaurora.org Authentication-Results: mail.kernel.org; spf=none smtp.mailfrom=linux-arm-kernel-bounces+infradead-linux-arm-kernel=archiver.kernel.org@lists.infradead.org DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; d=lists.infradead.org; s=bombadil.20170209; h=Sender:Content-Type: Content-Transfer-Encoding:Cc:List-Subscribe:List-Help:List-Post:List-Archive: List-Unsubscribe:List-Id:Message-ID:References:In-Reply-To:Subject:To:From: Date:MIME-Version:Reply-To:Content-ID:Content-Description:Resent-Date: Resent-From:Resent-Sender:Resent-To:Resent-Cc:Resent-Message-ID:List-Owner; bh=QFNFhTMbqpIllJGmZvM2TWMBTpM6N9KoFFYcRkEfw9A=; b=ZIOEOGZ8W6GClIYMugNvsL5PZ Mys0/Om8wnxSUqHQqmJgs5M+RnGB6ea5aJ76VwMmjxrMsmn9TRZ5zVX1/M+KxHGfbdpDRK13bx9pg Ort7xNPd2G78WLDIdEqT5q/HmUwqVwNsLmn8gqgfRhUttMk5mUtnjxhN+EwMKFdEsJndsbTMhIS+e KLPkWqRHRMk/7V+MSkHjI77J7BdVn89WLv3YIC5SyUfBXIB4wmdI4PTqCJsEZEVeliH68pczRXkJw Pz0moD5wKE56/UnimuOMPOQaTomzGw1bE7moDrTWJFGYDJkAtEmSH99qhxwX/XiJOZ2q4O6nuyTSb Zoe3jcGag==; Received: from localhost ([127.0.0.1] helo=bombadil.infradead.org) by bombadil.infradead.org with esmtp (Exim 4.92 #3 (Red Hat Linux)) id 1hdtZR-0003dK-5L; Thu, 20 Jun 2019 09:41:29 +0000 Received: from smtp.codeaurora.org ([198.145.29.96]) by bombadil.infradead.org with esmtps (Exim 4.92 #3 (Red Hat Linux)) id 1hdtZM-0003cw-II; Thu, 20 Jun 2019 09:41:27 +0000 Received: by smtp.codeaurora.org (Postfix, from userid 1000) id 96B04608BA; Thu, 20 Jun 2019 09:41:23 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=codeaurora.org; s=default; t=1561023683; bh=d8ku4HlKW6w5JiIUGgc4JFXqVt30K6lu2rcxNnePSuo=; h=Date:From:To:Cc:Subject:In-Reply-To:References:From; b=AKaTYmSXyGkBTHvayVvIWVnhzyS6xIb29F8Ak7hLhND4hWEwm6IMCYgYdkmYXXvUC +CNQov8wCdLnkTY3LLrnHAMCD0i0XjPKPweuTJWRRWzRhrMfoNlz98ZezJpdTamxHD VydRd0a6fpi1PE8BusMq4zgIsOQpSJLAWRRCdc24= Received: from mail.codeaurora.org (localhost.localdomain [127.0.0.1]) by smtp.codeaurora.org (Postfix) with ESMTP id 9CD4D602F4; Thu, 20 Jun 2019 09:41:21 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=codeaurora.org; s=default; t=1561023681; bh=d8ku4HlKW6w5JiIUGgc4JFXqVt30K6lu2rcxNnePSuo=; h=Date:From:To:Cc:Subject:In-Reply-To:References:From; b=d78XEtsy4HmI8qtqh0bZ7kxsyJdAhbq/2DvDPxq6l8Nd6nCah64MM3spJHpg7C4P6 4EeNAK9RhzjyfKilPna4wJdBeeJg0rqFb/dSCz3UJPWTgIxNNFti3uH/teCbKkNOtt SxBmZQZk+mlCQHb/cI3pFLnOcRxMbUgG7NScOw8o= MIME-Version: 1.0 Date: Thu, 20 Jun 2019 15:11:21 +0530 From: Sibi Sankar To: Hsin-Yi Wang Subject: Re: [PATCH RFC 1/2] PM / devfreq: Generic CPU frequency to device frequency mapping governor In-Reply-To: References: <20190618041433.245629-1-hsinyi@chromium.org> <20190618041433.245629-2-hsinyi@chromium.org> <958b27ff-6e64-b4e2-44e6-bc342e3606bc@samsung.com> Message-ID: <04bbd518efef8296e450e984e6afdba2@codeaurora.org> X-Sender: sibis@codeaurora.org User-Agent: Roundcube Webmail/1.2.5 X-CRM114-Version: 20100106-BlameMichelson ( TRE 0.8.0 (BSD) ) MR-646709E3 X-CRM114-CacheID: sfid-20190620_024124_641165_E1BF7132 X-CRM114-Status: GOOD ( 33.91 ) X-BeenThere: linux-arm-kernel@lists.infradead.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Cc: linux-kernel-owner@vger.kernel.org, "Andrew-sh . Cheng" , linux-pm@vger.kernel.org, lkml , Chanwoo Choi , Kyungmin Park , Saravana Kannan , linux-mediatek@lists.infradead.org, MyungJoo Ham , Matthias Brugger , "moderated list:ARM/FREESCALE IMX / MXC ARM ARCHITECTURE" Content-Transfer-Encoding: base64 Content-Type: text/plain; charset="utf-8"; Format="flowed" Sender: "linux-arm-kernel" Errors-To: linux-arm-kernel-bounces+infradead-linux-arm-kernel=archiver.kernel.org@lists.infradead.org SGV5IEhzaW4tWWksIENoYW53b28KCk9uIDIwMTktMDYtMjAgMTU6MDIsIEhzaW4tWWkgV2FuZyB3 cm90ZToKPiBIaSBDaGFud29vIENob2ksIFNhcmF2YW5hIEthbm5hbiBhbmQgU2liaSBTYW5rYXIs Cj4gCj4gSSd2ZSBhbHNvIHRlc3RlZCBTaWJpIFNhbmthcidzIHBhdGNoWzFdIGxvY2FsbHkgd2l0 aCBtdDgxODMtY2NpLCBhbmQKPiBpdCB3b3JrcyBmaW5lIHRvbyEKPiBJdCdkIGJlIGdyZWF0IGlm IFNpYmkgU2Fua2FyIG9yIGFueW9uZSB3aG8gaXMgZmFtaWxpYXIgd2l0aCB0aGUKPiBvcmlnaW5h bCBkZXNpZ24gY2FuIGZpbmlzaCB0aGlzIGltcGxlbWVudGF0aW9uLiBCdXQgaWYgbm8gb25lIGhh cyB0aW1lCj4gdG8gZG8gdGhhdCwgSSB0aGluayBJIGNhbiBhbHNvIGhlbHAgb24gYWRkcmVzcyB0 aGUgY29tbWVudHMuIFRoYW5rcyEKCk5vdyB0aGF0IHdlIGhhdmUgYSB1c2VyIDopIEkgYW0gaGFw cHkKdG8gcmVwb3N0IHRoZSBwYXRjaCB3aXRoIHRoZSBjb21tZW50cwphZGRyZXNzZWQuCgpodHRw czovL2xrbWwub3JnL2xrbWwvMjAxOS82LzE0LzQKQWxzbyB3aXRoIF5eIHBhdGNoIGFuZCBmZXcg bW9yZSBpbiB0aGUKc2VyaWVzIHRoZSBkdCBwYXJzaW5nIG9mIHJlcXVpcmVkLW9wcHMKc2hvdWxk IGdldCBmdXJ0aGVyIHNpbXBsaWZpZWQuCgo+IAo+IAo+IFsxXQo+IFtSRkMsMi85XSBPUFA6IEV4 cG9ydCBhIG51bWJlciBvZiBoZWxwZXJzIHRvIHByZXZlbnQgY29kZSBkdXBsaWNhdGlvbgo+IC0g aHR0cHM6Ly9wYXRjaHdvcmsua2VybmVsLm9yZy9wYXRjaC8xMDg3NTE5OS8KPiBbUkZDLDMvOV0g UE0gLyBkZXZmcmVxOiBBZGQgY3B1IGJhc2VkIHNjYWxpbmcgc3VwcG9ydCB0byAKPiBwYXNzaXZl X2dvdmVybm9yCj4gLSBodHRwczovL3BhdGNod29yay5rZXJuZWwub3JnL3BhdGNoLzEwODc1MTk1 Lwo+IAo+IEhzaW4tWWkKPiAKPiBPbiBUaHUsIEp1biAyMCwgMjAxOSBhdCAyOjU2IFBNIENoYW53 b28gQ2hvaSA8Y3cwMC5jaG9pQHNhbXN1bmcuY29tPiAKPiB3cm90ZToKPj4gCj4+ICsgU2liaSBT YW5rYXIKPj4gCj4+IEhpLCBIc2luLVlpIFdhbmcsIFNhcmF2YW5hIEthbm5hbiBhbmQgU2liaSBT YW5rYXIKPj4gCj4+IEkgc3VtbWFyaXplZCB0aGUgaGlzdG9yeSBvZiB0aGUgcmVsYXRlZCBwYXRj aCBhYm91dCB0aGlzIHRpdGxlLgo+PiAKPj4gRmlyc3RseSwKPj4gQXMgSSBrbmV3LCBTYXJhdmFu YSBzZW50IHRoZSBwYXRjaFsxXSB3aGljaCBjb250YWlucwo+PiAnZ292ZXJub3JfY3B1ZnJlcV9t YXAuYycgbGFzdCB5ZWFyLiBBY2NvcmRpbmcgdG8gdGhlIE15dW5nb28ncyAKPj4gY29tbWVudCwK Pj4gCj4+IFNlY29uZGx5LAo+PiBTaWJpIFNhbmthciBtb2RpZmllZCB0aGUgJ2dvdmVybm9yX3Bh c3NpdmUuYydbMl0gaW4gb3JkZXIgdG8gc3VwcG9ydAo+PiB0aGUgbWFwcGluZyBiZXR3ZWVuIGNw dSBmcmVxdWVuY3kgYW5kIGRldmljZSBmcmVxdWVuY3kuCj4+IFVuZm9ydHVuYXRlbHksIFNpYmkg U2Fua2FyIHN0b3BwZWQgdGhlIGRldmVsb3BtZW50IGFib3V0IHRoaXMKPj4gYmVjYXVzZSBoZSBo YWQgZm91bmQgdGhlIG90aGVyIG1ldGhvZCB0byBnZXQgaGlzIHB1cnBvc2UgYXMgSSBrbmV3Lgo+ PiAKPj4gVGhpcmRseSwKPj4gSHNpbi1ZaSBXYW5nIHNlbmQgdGhlIG9yaWdpbmFsIHBhdGNoIG9m IFNhcmF2YW5hIHdpdGhvdXQgbW9kaWZpY2F0aW9uLgo+PiAKPj4gCj4+IFNpbmNlcmVseSwgSSB0 aGluayB0aGF0IHRoZSBtYXBwaW5nIGJldHdlZW4gY3B1IGZyZXF1ZW5jeSBhbmQgZGV2aWNlCj4+ IGZyZXF1ZW5jeSBpcyBuZWNlc3NhcnkuIEFuZCBJIHByZWZlciB0aGUgU2liaSdzIGFwcHJvYWNo IHdoaWNoIAo+PiBpbXBsZW1lbnRzCj4+IHN0dWZmIHRvIHRoZSBleGlzdGluZyAncGFzc2l2ZScg Z292ZXJub3IuCj4+IAo+PiBXZSBuZWVkIHRvIGRpc2N1c3MgYWJvdXQgaG93IHRvIGltcGxlbWVu dCB0aGVtIGJ5IHdob20uCj4+IAo+PiAKPj4gWzFdIFt2MywxLzJdIFBNIC8gZGV2ZnJlcTogR2Vu ZXJpYyBDUFUgZnJlcXVlbmN5IHRvIGRldmljZSBmcmVxdWVuY3kgCj4+IG1hcHBpbmcgZ292ZXJu b3IKPj4gLSBodHRwczovL3BhdGNod29yay5rZXJuZWwub3JnL3BhdGNoLzEwNTUzMTcxLwo+PiAK Pj4gWzJdCj4+IFtQQVRDSCBSRkMgMC85XSBBZGQgQ1BVIGJhc2VkIHNjYWxpbmcgc3VwcG9ydCB0 byBQYXNzaXZlIGdvdmVybm9yCj4+IC0gCj4+IGh0dHBzOi8vbG9yZS5rZXJuZWwub3JnL2xrbWwv MDhjM2NmZjhjMzllM2Q4MmUwNDRkYjkzZTk5MmRhNzJAY29kZWF1cm9yYS5vcmcvVC8KPj4gW1BB VENIIFJGQyAzLzldIFBNIC8gZGV2ZnJlcTogQWRkIGNwdSBiYXNlZCBzY2FsaW5nIHN1cHBvcnQg dG8gCj4+IHBhc3NpdmVfZ292ZXJub3IKPj4gLSAKPj4gaHR0cHM6Ly9sb3JlLmtlcm5lbC5vcmcv bGttbC8wOGMzY2ZmOGMzOWUzZDgyZTA0NGRiOTNlOTkyZGE3MkBjb2RlYXVyb3JhLm9yZy9ULyNt MWNhZmI3YmFmNjg3ZDJhNjgwZDM5Yzg1ZDNlYzdkMWI1OTBiNjhmYwo+PiAKPj4gCj4+IEJlc3Qg UmVnYXJkcywKPj4gQ2hhbndvbyBDaG9pCj4+IAo+PiBPbiAxOS4gNi4gMTguIOyYpO2bhCAxOjE0 LCBIc2luLVlpIFdhbmcgd3JvdGU6Cj4+ID4gRnJvbTogU2FyYXZhbmEgS2FubmFuIDxza2FubmFu QGNvZGVhdXJvcmEub3JnPgo+PiA+Cj4+ID4gRnJvbTogU2FyYXZhbmEgS2FubmFuIDxza2FubmFu QGNvZGVhdXJvcmEub3JnPgo+PiA+Cj4+ID4gTWFueSBDUFUgYXJjaGl0ZWN0dXJlcyBoYXZlIGNh Y2hlcyB0aGF0IGNhbiBzY2FsZSBpbmRlcGVuZGVudCBvZiB0aGUgQ1BVcy4KPj4gPiBGcmVxdWVu Y3kgc2NhbGluZyBvZiB0aGUgY2FjaGVzIGlzIG5lY2Vzc2FyeSB0byBtYWtlIHN1cmUgdGhlIGNh Y2hlIGlzIG5vdAo+PiA+IGEgcGVyZm9ybWFuY2UgYm90dGxlbmVjayB0aGF0IGxlYWRzIHRvIHBv b3IgcGVyZm9ybWFuY2UgYW5kIHBvd2VyLiBUaGUgc2FtZQo+PiA+IGlkZWEgYXBwbGllcyBmb3Ig UkFNL0REUi4KPj4gPgo+PiA+IFRvIGFjaGlldmUgdGhpcywgdGhpcyBwYXRjaCBhZGRzIGEgZ2Vu ZXJpYyBkZXZmcmVxIGdvdmVybm9yIHRoYXQgdGFrZXMgdGhlCj4+ID4gY3VycmVudCBmcmVxdWVu Y3kgb2YgZWFjaCBDUFUgZnJlcXVlbmN5IGRvbWFpbiBhbmQgdGhlbiBhZGp1c3RzIHRoZQo+PiA+ IGZyZXF1ZW5jeSBvZiB0aGUgY2FjaGUgKG9yIGFueSBkZXZmcmVxIGRldmljZSkgYmFzZWQgb24g dGhlIGZyZXF1ZW5jeSBvZgo+PiA+IHRoZSBDUFVzLiBJdCBsaXN0ZW5zIHRvIENQVSBmcmVxdWVu Y3kgdHJhbnNpdGlvbiBub3RpZmllcnMgdG8ga2VlcCBpdHNlbGYKPj4gPiB1cCB0byBkYXRlIG9u IHRoZSBjdXJyZW50IENQVSBmcmVxdWVuY3kuCj4+ID4KPj4gPiBUbyBkZWNpZGUgdGhlIGZyZXF1 ZW5jeSBvZiB0aGUgZGV2aWNlLCB0aGUgZ292ZXJub3IgZG9lcyBvbmUgb2YgdGhlCj4+ID4gZm9s bG93aW5nOgo+PiA+Cj4+ID4gKiBVc2VzIGEgQ1BVIGZyZXF1ZW5jeSB0byBkZXZpY2UgZnJlcXVl bmN5IG1hcHBpbmcgdGFibGUKPj4gPiAgIC0gRWl0aGVyIG9uZSBtYXBwaW5nIHRhYmxlIHVzZWQg Zm9yIGFsbCBDUFUgZnJlcSBwb2xpY2llcyAodHlwaWNhbGx5IHVzZWQKPj4gPiAgICAgZm9yIHN5 c3RlbSB3aXRoIGhvbW9nZW5lb3VzIGNvcmVzL2NsdXN0ZXJzIHRoYXQgaGF2ZSB0aGUgc2FtZSBP UFBzKS4KPj4gPiAgIC0gT25lIG1hcHBpbmcgdGFibGUgcGVyIENQVSBmcmVxIHBvbGljeSAodHlw aWNhbGx5IHVzZWQgZm9yIEFTTVAgc3lzdGVtcwo+PiA+ICAgICB3aXRoIGhldGVyb2dlbmVvdXMg Q1BVcyB3aXRoIGRpZmZlcmVudCBPUFBzKQo+PiA+Cj4+ID4gT1IKPj4gPgo+PiA+ICogU2NhbGVz IHRoZSBkZXZpY2UgZnJlcXVlbmN5IGluIHByb3BvcnRpb24gdG8gdGhlIENQVSBmcmVxdWVuY3ku IFNvLCBpZgo+PiA+ICAgdGhlIENQVXMgYXJlIHJ1bm5pbmcgYXQgdGhlaXIgbWF4IGZyZXF1ZW5j eSwgdGhlIGRldmljZSBydW5zIGF0IGl0cyBtYXgKPj4gPiAgIGZyZXF1ZW5jeS4gIElmIHRoZSBD UFVzIGFyZSBydW5uaW5nIGF0IHRoZWlyIG1pbiBmcmVxdWVuY3ksIHRoZSBkZXZpY2UKPj4gPiAg IHJ1bnMgYXQgaXRzIG1pbiBmcmVxdWVuY3kuIEFuZCBpbnRlcnBvbGF0ZWQgZm9yIGZyZXF1ZW5j aWVzIGluIGJldHdlZW4uCj4+ID4KPj4gPiBTaWduZWQtb2ZmLWJ5OiBTYXJhdmFuYSBLYW5uYW4g PHNrYW5uYW5AY29kZWF1cm9yYS5vcmc+Cj4+ID4gU2lnbmVkLW9mZi1ieTogSHNpbi1ZaSBXYW5n IDxoc2lueWlAY2hyb21pdW0ub3JnPgo+PiA+IC0tLQo+PiA+ICAuLi4vYmluZGluZ3MvZGV2ZnJl cS9kZXZmcmVxLWNwdWZyZXEtbWFwLnR4dCAgfCAgNTMgKysKPj4gPiAgZHJpdmVycy9kZXZmcmVx L0tjb25maWcgICAgICAgICAgICAgICAgICAgICAgIHwgICA4ICsKPj4gPiAgZHJpdmVycy9kZXZm cmVxL01ha2VmaWxlICAgICAgICAgICAgICAgICAgICAgIHwgICAxICsKPj4gPiAgZHJpdmVycy9k ZXZmcmVxL2dvdmVybm9yX2NwdWZyZXFfbWFwLmMgICAgICAgIHwgNTgzICsrKysrKysrKysrKysr KysrKwo+PiA+ICA0IGZpbGVzIGNoYW5nZWQsIDY0NSBpbnNlcnRpb25zKCspCj4+ID4gIGNyZWF0 ZSBtb2RlIDEwMDY0NCBEb2N1bWVudGF0aW9uL2RldmljZXRyZWUvYmluZGluZ3MvZGV2ZnJlcS9k ZXZmcmVxLWNwdWZyZXEtbWFwLnR4dAo+PiA+ICBjcmVhdGUgbW9kZSAxMDA2NDQgZHJpdmVycy9k ZXZmcmVxL2dvdmVybm9yX2NwdWZyZXFfbWFwLmMKPj4gPgo+PiA+IGRpZmYgLS1naXQgYS9Eb2N1 bWVudGF0aW9uL2RldmljZXRyZWUvYmluZGluZ3MvZGV2ZnJlcS9kZXZmcmVxLWNwdWZyZXEtbWFw LnR4dCBiL0RvY3VtZW50YXRpb24vZGV2aWNldHJlZS9iaW5kaW5ncy9kZXZmcmVxL2RldmZyZXEt Y3B1ZnJlcS1tYXAudHh0Cj4+ID4gbmV3IGZpbGUgbW9kZSAxMDA2NDQKPj4gPiBpbmRleCAwMDAw MDAwMDAwMDAuLjk4MmEzMGJjZmM4Ngo+PiA+IC0tLSAvZGV2L251bGwKPj4gPiArKysgYi9Eb2N1 bWVudGF0aW9uL2RldmljZXRyZWUvYmluZGluZ3MvZGV2ZnJlcS9kZXZmcmVxLWNwdWZyZXEtbWFw LnR4dAo+PiA+IEBAIC0wLDAgKzEsNTMgQEAKPj4gPiArRGV2ZnJlcSBDUFVmcmVxIGdvdmVybm9y Cj4+ID4gKwo+PiA+ICtkZXZmcmVxLWNwdWZyZXEtbWFwIGlzIGEgcGFyZW50IGRldmljZSB0aGF0 IGNvbnRhaW5zIG9uZSBvciBtb3JlIGNoaWxkIGRldmljZXMuCj4+ID4gK0VhY2ggY2hpbGQgZGV2 aWNlIHByb3ZpZGVzIENQVSBmcmVxdWVuY3kgdG8gZGV2aWNlIGZyZXF1ZW5jeSBtYXBwaW5nIGZv ciBhCj4+ID4gK3NwZWNpZmljIGRldmljZS4gRXhhbXBsZXMgb2YgZGV2aWNlcyB0aGF0IGNvdWxk IHVzZSB0aGlzIGFyZTogRERSLCBjYWNoZSBhbmQKPj4gPiArQ0NJLgo+PiA+ICsKPj4gPiArUGFy ZW50IGRldmljZSBuYW1lIHNoYWxsIGJlICJkZXZmcmVxLWNwdWZyZXEtbWFwIi4KPj4gPiArCj4+ ID4gK1JlcXVpcmVkIGNoaWxkIGRldmljZSBwcm9wZXJ0aWVzOgo+PiA+ICstIGNwdS10by1kZXYt bWFwLCBvciBjcHUtdG8tZGV2LW1hcC08WD46Cj4+ID4gKyAgICAgICAgICAgICAgICAgICAgIEEg bGlzdCBvZiB0dXBsZXMgd2hlcmUgZWFjaCB0dXBsZSBjb25zaXN0cyBvZiBhCj4+ID4gKyAgICAg ICAgICAgICAgICAgICAgIENQVSBmcmVxdWVuY3kgKEtIeikgYW5kIHRoZSBjb3JyZXNwb25kaW5n IGRldmljZQo+PiA+ICsgICAgICAgICAgICAgICAgICAgICBmcmVxdWVuY3kuIENQVSBmcmVxdWVu Y2llcyBub3QgbGlzdGVkIGluIHRoZSB0YWJsZQo+PiA+ICsgICAgICAgICAgICAgICAgICAgICB3 aWxsIHVzZSB0aGUgZGV2aWNlIGZyZXF1ZW5jeSB0aGF0IGNvcnJlc3BvbmRzIHRvIHRoZQo+PiA+ ICsgICAgICAgICAgICAgICAgICAgICBuZXh0IHJvdW5kZWQgdXAgQ1BVIGZyZXF1ZW5jeS4KPj4g PiArICAgICAgICAgICAgICAgICAgICAgVXNlICJjcHUtdG8tZGV2LW1hcCIgaWYgYWxsIENQVXMg aW4gdGhlIHN5c3RlbSBzaG91bGQKPj4gPiArICAgICAgICAgICAgICAgICAgICAgc2hhcmUgc2Ft ZSBtYXBwaW5nLgo+PiA+ICsgICAgICAgICAgICAgICAgICAgICBVc2UgY3B1LXRvLWRldi1tYXAt PGNwdWlkPiB0byBkZXNjcmliZSBkaWZmZXJlbnQKPj4gPiArICAgICAgICAgICAgICAgICAgICAg bWFwcGluZ3MgZm9yIGRpZmZlcmVudCBDUFVzLiBUaGUgcHJvcGVydHkgc2hvdWxkIGJlCj4+ID4g KyAgICAgICAgICAgICAgICAgICAgIGxpc3RlZCBvbmx5IGZvciB0aGUgZmlyc3QgQ1BVIGlmIG11 bHRpcGxlIENQVXMgYXJlCj4+ID4gKyAgICAgICAgICAgICAgICAgICAgIHN5bmNocm9ub3VzLgo+ PiA+ICstIHRhcmdldC1kZXY6ICAgICAgICAgICAgICAgIFBoYW5kbGUgdG8gZGV2aWNlIHRoYXQg dGhpcyBtYXBwaW5nIGFwcGxpZXMgdG8uCj4+ID4gKwo+PiA+ICtFeGFtcGxlOgo+PiA+ICsgICAg IGRldmZyZXEtY3B1ZnJlcS1tYXAgewo+PiA+ICsgICAgICAgICAgICAgY3B1YnctY3B1ZnJlcSB7 Cj4+ID4gKyAgICAgICAgICAgICAgICAgICAgIHRhcmdldC1kZXYgPSA8JmNwdWJ3PjsKPj4gPiAr ICAgICAgICAgICAgICAgICAgICAgY3B1LXRvLWRldi1tYXAgPQo+PiA+ICsgICAgICAgICAgICAg ICAgICAgICAgICAgICAgIDwgIDMwMDAwMCAgMTE0NDAwMCA+LAo+PiA+ICsgICAgICAgICAgICAg ICAgICAgICAgICAgICAgIDwgIDQyMjQwMCAgMjI4ODAwMCA+LAo+PiA+ICsgICAgICAgICAgICAg ICAgICAgICAgICAgICAgIDwgIDY1MjgwMCAgMzA1MTAwMCA+LAo+PiA+ICsgICAgICAgICAgICAg ICAgICAgICAgICAgICAgIDwgIDg4MzIwMCAgNTk5NjAwMCA+LAo+PiA+ICsgICAgICAgICAgICAg ICAgICAgICAgICAgICAgIDwgMTE5MDQwMCAgODA1NjAwMCA+LAo+PiA+ICsgICAgICAgICAgICAg ICAgICAgICAgICAgICAgIDwgMTQ5NzYwMCAxMDEwMTAwMCA+LAo+PiA+ICsgICAgICAgICAgICAg ICAgICAgICAgICAgICAgIDwgMTcyODAwMCAxMjE0NTAwMCA+LAo+PiA+ICsgICAgICAgICAgICAg ICAgICAgICAgICAgICAgIDwgMjY0OTYwMCAxNjI1MDAwMCA+Owo+PiA+ICsgICAgICAgICAgICAg fTsKPj4gPiArCj4+ID4gKyAgICAgICAgICAgICBjYWNoZS1jcHVmcmVxIHsKPj4gPiArICAgICAg ICAgICAgICAgICAgICAgdGFyZ2V0LWRldiA9IDwmY2FjaGU+Owo+PiA+ICsgICAgICAgICAgICAg ICAgICAgICBjcHUtdG8tZGV2LW1hcCA9Cj4+ID4gKyAgICAgICAgICAgICAgICAgICAgICAgICAg ICAgPCAgMzAwMDAwICAzMDAwMDAgPiwKPj4gPiArICAgICAgICAgICAgICAgICAgICAgICAgICAg ICA8ICA0MjI0MDAgIDQyMjQwMCA+LAo+PiA+ICsgICAgICAgICAgICAgICAgICAgICAgICAgICAg IDwgIDY1MjgwMCAgNDk5MjAwID4sCj4+ID4gKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAg PCAgODgzMjAwICA1NzYwMDAgPiwKPj4gPiArICAgICAgICAgICAgICAgICAgICAgICAgICAgICA8 ICA5NjAwMDAgIDk2MDAwMCA+LAo+PiA+ICsgICAgICAgICAgICAgICAgICAgICAgICAgICAgIDwg MTQ5NzYwMCAxMDM2ODAwID4sCj4+ID4gKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgPCAx NTc0NDAwIDE1NzQ0MDAgPiwKPj4gPiArICAgICAgICAgICAgICAgICAgICAgICAgICAgICA8IDE3 MjgwMDAgMTY1MTIwMCA+LAo+PiA+ICsgICAgICAgICAgICAgICAgICAgICAgICAgICAgIDwgMjY0 OTYwMCAxNzI4MDAwID47Cj4+ID4gKyAgICAgICAgICAgICB9Owo+PiA+ICsgICAgIH07Cj4+ID4g ZGlmZiAtLWdpdCBhL2RyaXZlcnMvZGV2ZnJlcS9LY29uZmlnIGIvZHJpdmVycy9kZXZmcmVxL0tj b25maWcKPj4gPiBpbmRleCAwYzgyMDRkNmI3OGEuLjAzMDNmNWE0MDBiNiAxMDA2NDQKPj4gPiAt LS0gYS9kcml2ZXJzL2RldmZyZXEvS2NvbmZpZwo+PiA+ICsrKyBiL2RyaXZlcnMvZGV2ZnJlcS9L Y29uZmlnCj4+ID4gQEAgLTc0LDYgKzc0LDE0IEBAIGNvbmZpZyBERVZGUkVRX0dPVl9QQVNTSVZF Cj4+ID4gICAgICAgICB0aHJvdWdoIHN5c2ZzIGVudHJpZXMuIFRoZSBwYXNzaXZlIGdvdmVybm9y IHJlY29tbWVuZHMgdGhhdAo+PiA+ICAgICAgICAgZGV2ZnJlcSBkZXZpY2UgdXNlcyB0aGUgT1BQ IHRhYmxlIHRvIGdldCB0aGUgZnJlcXVlbmN5L3ZvbHRhZ2UuCj4+ID4KPj4gPiArY29uZmlnIERF VkZSRVFfR09WX0NQVUZSRVFfTUFQCj4+ID4gKyAgICAgdHJpc3RhdGUgIkNQVWZyZXEgTWFwIgo+ PiA+ICsgICAgIGRlcGVuZHMgb24gQ1BVX0ZSRVEKPj4gPiArICAgICBoZWxwCj4+ID4gKyAgICAg ICBDaG9vc2VzIGZyZXF1ZW5jeSBiYXNlZCBvbiB0aGUgb25saW5lIENQVXMnIGN1cnJlbnQgZnJl cXVlbmN5IGFuZCBhCj4+ID4gKyAgICAgICBDUFUgZnJlcXVlbmN5IHRvIGRldmljZSBmcmVxdWVu Y3kgbWFwcGluZyB0YWJsZShzKS4gVGhpcyBnb3Zlcm5vcgo+PiA+ICsgICAgICAgY2FuIGJlIHVz ZWZ1bCBmb3IgY29udHJvbGxpbmcgZGV2aWNlcyBzdWNoIGFzIEREUiwgY2FjaGUsIENDSSwgZXRj Lgo+PiA+ICsKPj4gPiAgY29tbWVudCAiREVWRlJFUSBEcml2ZXJzIgo+PiA+Cj4+ID4gIGNvbmZp ZyBBUk1fRVhZTk9TX0JVU19ERVZGUkVRCj4+ID4gZGlmZiAtLWdpdCBhL2RyaXZlcnMvZGV2ZnJl cS9NYWtlZmlsZSBiL2RyaXZlcnMvZGV2ZnJlcS9NYWtlZmlsZQo+PiA+IGluZGV4IDgxN2RkZTc3 OWYxNi4uODExNDFlMmM3ODRmIDEwMDY0NAo+PiA+IC0tLSBhL2RyaXZlcnMvZGV2ZnJlcS9NYWtl ZmlsZQo+PiA+ICsrKyBiL2RyaXZlcnMvZGV2ZnJlcS9NYWtlZmlsZQo+PiA+IEBAIC02LDYgKzYs NyBAQCBvYmotJChDT05GSUdfREVWRlJFUV9HT1ZfUEVSRk9STUFOQ0UpICs9IGdvdmVybm9yX3Bl cmZvcm1hbmNlLm8KPj4gPiAgb2JqLSQoQ09ORklHX0RFVkZSRVFfR09WX1BPV0VSU0FWRSkgICs9 IGdvdmVybm9yX3Bvd2Vyc2F2ZS5vCj4+ID4gIG9iai0kKENPTkZJR19ERVZGUkVRX0dPVl9VU0VS U1BBQ0UpICArPSBnb3Zlcm5vcl91c2Vyc3BhY2Uubwo+PiA+ICBvYmotJChDT05GSUdfREVWRlJF UV9HT1ZfUEFTU0lWRSkgICAgKz0gZ292ZXJub3JfcGFzc2l2ZS5vCj4+ID4gK29iai0kKENPTkZJ R19ERVZGUkVRX0dPVl9DUFVGUkVRX01BUCkgICAgICAgICs9IGdvdmVybm9yX2NwdWZyZXFfbWFw Lm8KPj4gPgo+PiA+ICAjIERFVkZSRVEgRHJpdmVycwo+PiA+ICBvYmotJChDT05GSUdfQVJNX0VY WU5PU19CVVNfREVWRlJFUSkgKz0gZXh5bm9zLWJ1cy5vCj4+ID4gZGlmZiAtLWdpdCBhL2RyaXZl cnMvZGV2ZnJlcS9nb3Zlcm5vcl9jcHVmcmVxX21hcC5jIGIvZHJpdmVycy9kZXZmcmVxL2dvdmVy bm9yX2NwdWZyZXFfbWFwLmMKPj4gPiBuZXcgZmlsZSBtb2RlIDEwMDY0NAo+PiA+IGluZGV4IDAw MDAwMDAwMDAwMC4uMDg0YTNmZmI4ZjU0Cj4+ID4gLS0tIC9kZXYvbnVsbAo+PiA+ICsrKyBiL2Ry aXZlcnMvZGV2ZnJlcS9nb3Zlcm5vcl9jcHVmcmVxX21hcC5jCj4+ID4gQEAgLTAsMCArMSw1ODMg QEAKPj4gPiArLy8gU1BEWC1MaWNlbnNlLUlkZW50aWZpZXI6IEdQTC0yLjAKPj4gPiArLyoKPj4g PiArICogQ29weXJpZ2h0IChjKSAyMDE0LTIwMTUsIDIwMTgsIFRoZSBMaW51eCBGb3VuZGF0aW9u LiBBbGwgcmlnaHRzIHJlc2VydmVkLgo+PiA+ICsgKi8KPj4gPiArCj4+ID4gKyNkZWZpbmUgcHJf Zm10KGZtdCkgImRldi1jcHVmcmVxLW1hcDogIiBmbXQKPj4gPiArCj4+ID4gKyNpbmNsdWRlIDxs aW51eC9kZXZmcmVxLmg+Cj4+ID4gKyNpbmNsdWRlIDxsaW51eC9jcHUuaD4KPj4gPiArI2luY2x1 ZGUgPGxpbnV4L2NwdWZyZXEuaD4KPj4gPiArI2luY2x1ZGUgPGxpbnV4L2NwdW1hc2suaD4KPj4g PiArI2luY2x1ZGUgPGxpbnV4L3NsYWIuaD4KPj4gPiArI2luY2x1ZGUgPGxpbnV4L3BsYXRmb3Jt X2RldmljZS5oPgo+PiA+ICsjaW5jbHVkZSA8bGludXgvb2YuaD4KPj4gPiArI2luY2x1ZGUgPGxp bnV4L21vZHVsZS5oPgo+PiA+ICsjaW5jbHVkZSAiZ292ZXJub3IuaCIKPj4gPiArCj4+ID4gK3N0 cnVjdCBjcHVfc3RhdGUgewo+PiA+ICsgICAgIHVuc2lnbmVkIGludCBmcmVxOwo+PiA+ICsgICAg IHVuc2lnbmVkIGludCBtaW5fZnJlcTsKPj4gPiArICAgICB1bnNpZ25lZCBpbnQgbWF4X2ZyZXE7 Cj4+ID4gKyAgICAgdW5zaWduZWQgaW50IGZpcnN0X2NwdTsKPj4gPiArfTsKPj4gPiArc3RhdGlj IHN0cnVjdCBjcHVfc3RhdGUgKnN0YXRlW05SX0NQVVNdOwo+PiA+ICtzdGF0aWMgaW50IGNwdWZy ZXFfY250Owo+PiA+ICsKPj4gPiArc3RydWN0IGZyZXFfbWFwIHsKPj4gPiArICAgICB1bnNpZ25l ZCBpbnQgY3B1X2toejsKPj4gPiArICAgICB1bnNpZ25lZCBpbnQgdGFyZ2V0X2ZyZXE7Cj4+ID4g K307Cj4+ID4gKwo+PiA+ICtzdHJ1Y3QgZGV2ZnJlcV9ub2RlIHsKPj4gPiArICAgICBzdHJ1Y3Qg ZGV2ZnJlcSAqZGY7Cj4+ID4gKyAgICAgdm9pZCAqb3JpZ19kYXRhOwo+PiA+ICsgICAgIHN0cnVj dCBkZXZpY2UgKmRldjsKPj4gPiArICAgICBzdHJ1Y3QgZGV2aWNlX25vZGUgKm9mX25vZGU7Cj4+ ID4gKyAgICAgc3RydWN0IGxpc3RfaGVhZCBsaXN0Owo+PiA+ICsgICAgIHN0cnVjdCBmcmVxX21h cCAqKm1hcDsKPj4gPiArICAgICBzdHJ1Y3QgZnJlcV9tYXAgKmNvbW1vbl9tYXA7Cj4+ID4gK307 Cj4+ID4gK3N0YXRpYyBMSVNUX0hFQUQoZGV2ZnJlcV9saXN0KTsKPj4gPiArc3RhdGljIERFRklO RV9NVVRFWChzdGF0ZV9sb2NrKTsKPj4gPiArc3RhdGljIERFRklORV9NVVRFWChjcHVmcmVxX3Jl Z19sb2NrKTsKPj4gPiArCj4+ID4gK3N0YXRpYyB2b2lkIHVwZGF0ZV9hbGxfZGV2ZnJlcXModm9p ZCkKPj4gPiArewo+PiA+ICsgICAgIHN0cnVjdCBkZXZmcmVxX25vZGUgKm5vZGU7Cj4+ID4gKwo+ PiA+ICsgICAgIGxpc3RfZm9yX2VhY2hfZW50cnkobm9kZSwgJmRldmZyZXFfbGlzdCwgbGlzdCkg ewo+PiA+ICsgICAgICAgICAgICAgc3RydWN0IGRldmZyZXEgKmRmID0gbm9kZS0+ZGY7Cj4+ID4g Kwo+PiA+ICsgICAgICAgICAgICAgaWYgKCFub2RlLT5kZikKPj4gPiArICAgICAgICAgICAgICAg ICAgICAgY29udGludWU7Cj4+ID4gKyAgICAgICAgICAgICBtdXRleF9sb2NrKCZkZi0+bG9jayk7 Cj4+ID4gKyAgICAgICAgICAgICB1cGRhdGVfZGV2ZnJlcShkZik7Cj4+ID4gKyAgICAgICAgICAg ICBtdXRleF91bmxvY2soJmRmLT5sb2NrKTsKPj4gPiArCj4+ID4gKyAgICAgfQo+PiA+ICt9Cj4+ ID4gKwo+PiA+ICtzdGF0aWMgc3RydWN0IGRldmZyZXFfbm9kZSAqZmluZF9kZXZmcmVxX25vZGUo c3RydWN0IGRldmljZSAqZGV2KQo+PiA+ICt7Cj4+ID4gKyAgICAgc3RydWN0IGRldmZyZXFfbm9k ZSAqbm9kZTsKPj4gPiArCj4+ID4gKyAgICAgbGlzdF9mb3JfZWFjaF9lbnRyeShub2RlLCAmZGV2 ZnJlcV9saXN0LCBsaXN0KQo+PiA+ICsgICAgICAgICAgICAgaWYgKG5vZGUtPmRldiA9PSBkZXYg fHwgbm9kZS0+b2Zfbm9kZSA9PSBkZXYtPm9mX25vZGUpCj4+ID4gKyAgICAgICAgICAgICAgICAg ICAgIHJldHVybiBub2RlOwo+PiA+ICsKPj4gPiArICAgICByZXR1cm4gTlVMTDsKPj4gPiArfQo+ PiA+ICsKPj4gPiArLyogPT09PT09PT09PT09PT09PT09PT0gY3B1ZnJlcSBwYXJ0ID09PT09PT09 PT09PT09PT09PT09ICovCj4+ID4gK3N0YXRpYyBzdHJ1Y3QgY3B1X3N0YXRlICphZGRfcG9saWN5 KHN0cnVjdCBjcHVmcmVxX3BvbGljeSAqcG9saWN5KQo+PiA+ICt7Cj4+ID4gKyAgICAgc3RydWN0 IGNwdV9zdGF0ZSAqbmV3X3N0YXRlOwo+PiA+ICsgICAgIHVuc2lnbmVkIGludCBjcHUsIGZpcnN0 X2NwdTsKPj4gPiArCj4+ID4gKyAgICAgbmV3X3N0YXRlID0ga3phbGxvYyhzaXplb2Yoc3RydWN0 IGNwdV9zdGF0ZSksIEdGUF9LRVJORUwpOwo+PiA+ICsgICAgIGlmICghbmV3X3N0YXRlKQo+PiA+ ICsgICAgICAgICAgICAgcmV0dXJuIE5VTEw7Cj4+ID4gKwo+PiA+ICsgICAgIGZpcnN0X2NwdSA9 IGNwdW1hc2tfZmlyc3QocG9saWN5LT5yZWxhdGVkX2NwdXMpOwo+PiA+ICsgICAgIG5ld19zdGF0 ZS0+Zmlyc3RfY3B1ID0gZmlyc3RfY3B1Owo+PiA+ICsgICAgIG5ld19zdGF0ZS0+ZnJlcSA9IHBv bGljeS0+Y3VyOwo+PiA+ICsgICAgIG5ld19zdGF0ZS0+bWluX2ZyZXEgPSBwb2xpY3ktPmNwdWlu Zm8ubWluX2ZyZXE7Cj4+ID4gKyAgICAgbmV3X3N0YXRlLT5tYXhfZnJlcSA9IHBvbGljeS0+Y3B1 aW5mby5tYXhfZnJlcTsKPj4gPiArCj4+ID4gKyAgICAgZm9yX2VhY2hfY3B1KGNwdSwgcG9saWN5 LT5yZWxhdGVkX2NwdXMpCj4+ID4gKyAgICAgICAgICAgICBzdGF0ZVtjcHVdID0gbmV3X3N0YXRl Owo+PiA+ICsKPj4gPiArICAgICByZXR1cm4gbmV3X3N0YXRlOwo+PiA+ICt9Cj4+ID4gKwo+PiA+ ICtzdGF0aWMgaW50IGNwdWZyZXFfdHJhbnNfbm90aWZpZXIoc3RydWN0IG5vdGlmaWVyX2Jsb2Nr ICpuYiwKPj4gPiArICAgICAgICAgICAgIHVuc2lnbmVkIGxvbmcgZXZlbnQsIHZvaWQgKmRhdGEp Cj4+ID4gK3sKPj4gPiArICAgICBzdHJ1Y3QgY3B1ZnJlcV9mcmVxcyAqZnJlcSA9IGRhdGE7Cj4+ ID4gKyAgICAgc3RydWN0IGNwdV9zdGF0ZSAqczsKPj4gPiArICAgICBzdHJ1Y3QgY3B1ZnJlcV9w b2xpY3kgKnBvbGljeSA9IE5VTEw7Cj4+ID4gKwo+PiA+ICsgICAgIGlmIChldmVudCAhPSBDUFVG UkVRX1BPU1RDSEFOR0UpCj4+ID4gKyAgICAgICAgICAgICByZXR1cm4gMDsKPj4gPiArCj4+ID4g KyAgICAgbXV0ZXhfbG9jaygmc3RhdGVfbG9jayk7Cj4+ID4gKwo+PiA+ICsgICAgIHMgPSBzdGF0 ZVtmcmVxLT5jcHVdOwo+PiA+ICsgICAgIGlmICghcykgewo+PiA+ICsgICAgICAgICAgICAgcG9s aWN5ID0gY3B1ZnJlcV9jcHVfZ2V0KGZyZXEtPmNwdSk7Cj4+ID4gKyAgICAgICAgICAgICBpZiAo cG9saWN5KSB7Cj4+ID4gKyAgICAgICAgICAgICAgICAgICAgIHMgPSBhZGRfcG9saWN5KHBvbGlj eSk7Cj4+ID4gKyAgICAgICAgICAgICAgICAgICAgIGNwdWZyZXFfY3B1X3B1dChwb2xpY3kpOwo+ PiA+ICsgICAgICAgICAgICAgfQo+PiA+ICsgICAgIH0KPj4gPiArICAgICBpZiAoIXMpCj4+ID4g KyAgICAgICAgICAgICBnb3RvIG91dDsKPj4gPiArCj4+ID4gKyAgICAgaWYgKHMtPmZyZXEgIT0g ZnJlcS0+bmV3IHx8IHBvbGljeSkgewo+PiA+ICsgICAgICAgICAgICAgcy0+ZnJlcSA9IGZyZXEt Pm5ldzsKPj4gPiArICAgICAgICAgICAgIHVwZGF0ZV9hbGxfZGV2ZnJlcXMoKTsKPj4gPiArICAg ICB9Cj4+ID4gKwo+PiA+ICtvdXQ6Cj4+ID4gKyAgICAgbXV0ZXhfdW5sb2NrKCZzdGF0ZV9sb2Nr KTsKPj4gPiArICAgICByZXR1cm4gMDsKPj4gPiArfQo+PiA+ICsKPj4gPiArc3RhdGljIHN0cnVj dCBub3RpZmllcl9ibG9jayBjcHVmcmVxX3RyYW5zX25iID0gewo+PiA+ICsgICAgIC5ub3RpZmll cl9jYWxsID0gY3B1ZnJlcV90cmFuc19ub3RpZmllcgo+PiA+ICt9Owo+PiA+ICsKPj4gPiArc3Rh dGljIGludCByZWdpc3Rlcl9jcHVmcmVxKHZvaWQpCj4+ID4gK3sKPj4gPiArICAgICBpbnQgcmV0 ID0gMDsKPj4gPiArICAgICB1bnNpZ25lZCBpbnQgY3B1Owo+PiA+ICsgICAgIHN0cnVjdCBjcHVm cmVxX3BvbGljeSAqcG9saWN5Owo+PiA+ICsKPj4gPiArICAgICBtdXRleF9sb2NrKCZjcHVmcmVx X3JlZ19sb2NrKTsKPj4gPiArCj4+ID4gKyAgICAgaWYgKGNwdWZyZXFfY250KQo+PiA+ICsgICAg ICAgICAgICAgZ290byBjbnRfbm90X3plcm87Cj4+ID4gKwo+PiA+ICsgICAgIGdldF9vbmxpbmVf Y3B1cygpOwo+PiA+ICsgICAgIHJldCA9IGNwdWZyZXFfcmVnaXN0ZXJfbm90aWZpZXIoJmNwdWZy ZXFfdHJhbnNfbmIsCj4+ID4gKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgQ1BVRlJFUV9U UkFOU0lUSU9OX05PVElGSUVSKTsKPj4gPiArICAgICBpZiAocmV0KQo+PiA+ICsgICAgICAgICAg ICAgZ290byBvdXQ7Cj4+ID4gKwo+PiA+ICsgICAgIGZvcl9lYWNoX29ubGluZV9jcHUoY3B1KSB7 Cj4+ID4gKyAgICAgICAgICAgICBwb2xpY3kgPSBjcHVmcmVxX2NwdV9nZXQoY3B1KTsKPj4gPiAr ICAgICAgICAgICAgIGlmIChwb2xpY3kpIHsKPj4gPiArICAgICAgICAgICAgICAgICAgICAgYWRk X3BvbGljeShwb2xpY3kpOwo+PiA+ICsgICAgICAgICAgICAgICAgICAgICBjcHVmcmVxX2NwdV9w dXQocG9saWN5KTsKPj4gPiArICAgICAgICAgICAgIH0KPj4gPiArICAgICB9Cj4+ID4gK291dDoK Pj4gPiArICAgICBwdXRfb25saW5lX2NwdXMoKTsKPj4gPiArY250X25vdF96ZXJvOgo+PiA+ICsg ICAgIGlmICghcmV0KQo+PiA+ICsgICAgICAgICAgICAgY3B1ZnJlcV9jbnQrKzsKPj4gPiArICAg ICBtdXRleF91bmxvY2soJmNwdWZyZXFfcmVnX2xvY2spOwo+PiA+ICsgICAgIHJldHVybiByZXQ7 Cj4+ID4gK30KPj4gPiArCj4+ID4gK3N0YXRpYyBpbnQgdW5yZWdpc3Rlcl9jcHVmcmVxKHZvaWQp Cj4+ID4gK3sKPj4gPiArICAgICBpbnQgcmV0ID0gMDsKPj4gPiArICAgICBpbnQgY3B1Owo+PiA+ ICsKPj4gPiArICAgICBtdXRleF9sb2NrKCZjcHVmcmVxX3JlZ19sb2NrKTsKPj4gPiArCj4+ID4g KyAgICAgaWYgKGNwdWZyZXFfY250ID4gMSkKPj4gPiArICAgICAgICAgICAgIGdvdG8gb3V0Owo+ PiA+ICsKPj4gPiArICAgICBjcHVmcmVxX3VucmVnaXN0ZXJfbm90aWZpZXIoJmNwdWZyZXFfdHJh bnNfbmIsCj4+ID4gKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgQ1BVRlJFUV9UUkFOU0lU SU9OX05PVElGSUVSKTsKPj4gPiArCj4+ID4gKyAgICAgZm9yIChjcHUgPSBBUlJBWV9TSVpFKHN0 YXRlKSAtIDE7IGNwdSA+PSAwOyBjcHUtLSkgewo+PiA+ICsgICAgICAgICAgICAgaWYgKCFzdGF0 ZVtjcHVdKQo+PiA+ICsgICAgICAgICAgICAgICAgICAgICBjb250aW51ZTsKPj4gPiArICAgICAg ICAgICAgIGlmIChzdGF0ZVtjcHVdLT5maXJzdF9jcHUgPT0gY3B1KQo+PiA+ICsgICAgICAgICAg ICAgICAgICAgICBrZnJlZShzdGF0ZVtjcHVdKTsKPj4gPiArICAgICAgICAgICAgIHN0YXRlW2Nw dV0gPSBOVUxMOwo+PiA+ICsgICAgIH0KPj4gPiArCj4+ID4gK291dDoKPj4gPiArICAgICBjcHVm cmVxX2NudC0tOwo+PiA+ICsgICAgIG11dGV4X3VubG9jaygmY3B1ZnJlcV9yZWdfbG9jayk7Cj4+ ID4gKyAgICAgcmV0dXJuIHJldDsKPj4gPiArfQo+PiA+ICsKPj4gPiArLyogPT09PT09PT09PT09 PT09PT09PT0gZGV2ZnJlcSBwYXJ0ID09PT09PT09PT09PT09PT09PT09ICovCj4+ID4gKwo+PiA+ ICtzdGF0aWMgdW5zaWduZWQgaW50IGludGVycG9sYXRlX2ZyZXEoc3RydWN0IGRldmZyZXEgKmRm LCB1bnNpZ25lZCBpbnQgY3B1KQo+PiA+ICt7Cj4+ID4gKyAgICAgdW5zaWduZWQgbG9uZyAqZnJl cV90YWJsZSA9IGRmLT5wcm9maWxlLT5mcmVxX3RhYmxlOwo+PiA+ICsgICAgIHVuc2lnbmVkIGlu dCBjcHVfbWluID0gc3RhdGVbY3B1XS0+bWluX2ZyZXE7Cj4+ID4gKyAgICAgdW5zaWduZWQgaW50 IGNwdV9tYXggPSBzdGF0ZVtjcHVdLT5tYXhfZnJlcTsKPj4gPiArICAgICB1bnNpZ25lZCBpbnQg Y3B1X2ZyZXEgPSBzdGF0ZVtjcHVdLT5mcmVxOwo+PiA+ICsgICAgIHVuc2lnbmVkIGludCBkZXZf bWluLCBkZXZfbWF4LCBjcHVfcGVyY2VudDsKPj4gPiArCj4+ID4gKyAgICAgaWYgKGZyZXFfdGFi bGUpIHsKPj4gPiArICAgICAgICAgICAgIGRldl9taW4gPSBmcmVxX3RhYmxlWzBdOwo+PiA+ICsg ICAgICAgICAgICAgZGV2X21heCA9IGZyZXFfdGFibGVbZGYtPnByb2ZpbGUtPm1heF9zdGF0ZSAt IDFdOwo+PiA+ICsgICAgIH0gZWxzZSB7Cj4+ID4gKyAgICAgICAgICAgICBpZiAoZGYtPm1heF9m cmVxIDw9IGRmLT5taW5fZnJlcSkKPj4gPiArICAgICAgICAgICAgICAgICAgICAgcmV0dXJuIDA7 Cj4+ID4gKyAgICAgICAgICAgICBkZXZfbWluID0gZGYtPm1pbl9mcmVxOwo+PiA+ICsgICAgICAg ICAgICAgZGV2X21heCA9IGRmLT5tYXhfZnJlcTsKPj4gPiArICAgICB9Cj4+ID4gKwo+PiA+ICsg ICAgIGNwdV9wZXJjZW50ID0gKChjcHVfZnJlcSAtIGNwdV9taW4pICogMTAwKSAvIChjcHVfbWF4 IC0gY3B1X21pbik7Cj4+ID4gKyAgICAgcmV0dXJuIGRldl9taW4gKyBtdWx0X2ZyYWMoZGV2X21h eCAtIGRldl9taW4sIGNwdV9wZXJjZW50LCAxMDApOwo+PiA+ICt9Cj4+ID4gKwo+PiA+ICtzdGF0 aWMgdW5zaWduZWQgaW50IGNwdV90b19kZXZfZnJlcShzdHJ1Y3QgZGV2ZnJlcSAqZGYsIHVuc2ln bmVkIGludCBjcHUpCj4+ID4gK3sKPj4gPiArICAgICBzdHJ1Y3QgZnJlcV9tYXAgKm1hcCA9IE5V TEw7Cj4+ID4gKyAgICAgdW5zaWduZWQgaW50IGNwdV9raHogPSAwLCBmcmVxOwo+PiA+ICsgICAg IHN0cnVjdCBkZXZmcmVxX25vZGUgKm4gPSBkZi0+ZGF0YTsKPj4gPiArCj4+ID4gKyAgICAgaWYg KCFzdGF0ZVtjcHVdIHx8IHN0YXRlW2NwdV0tPmZpcnN0X2NwdSAhPSBjcHUpIHsKPj4gPiArICAg ICAgICAgICAgIGZyZXEgPSAwOwo+PiA+ICsgICAgICAgICAgICAgZ290byBvdXQ7Cj4+ID4gKyAg ICAgfQo+PiA+ICsKPj4gPiArICAgICBpZiAobi0+Y29tbW9uX21hcCkKPj4gPiArICAgICAgICAg ICAgIG1hcCA9IG4tPmNvbW1vbl9tYXA7Cj4+ID4gKyAgICAgZWxzZSBpZiAobi0+bWFwKQo+PiA+ ICsgICAgICAgICAgICAgbWFwID0gbi0+bWFwW2NwdV07Cj4+ID4gKwo+PiA+ICsgICAgIGNwdV9r aHogPSBzdGF0ZVtjcHVdLT5mcmVxOwo+PiA+ICsKPj4gPiArICAgICBpZiAoIW1hcCkgewo+PiA+ ICsgICAgICAgICAgICAgZnJlcSA9IGludGVycG9sYXRlX2ZyZXEoZGYsIGNwdSk7Cj4+ID4gKyAg ICAgICAgICAgICBnb3RvIG91dDsKPj4gPiArICAgICB9Cj4+ID4gKwo+PiA+ICsgICAgIHdoaWxl IChtYXAtPmNwdV9raHogJiYgbWFwLT5jcHVfa2h6IDwgY3B1X2toeikKPj4gPiArICAgICAgICAg ICAgIG1hcCsrOwo+PiA+ICsgICAgIGlmICghbWFwLT5jcHVfa2h6KQo+PiA+ICsgICAgICAgICAg ICAgbWFwLS07Cj4+ID4gKyAgICAgZnJlcSA9IG1hcC0+dGFyZ2V0X2ZyZXE7Cj4+ID4gKwo+PiA+ ICtvdXQ6Cj4+ID4gKyAgICAgZGV2X2RiZyhkZi0+ZGV2LnBhcmVudCwgIkNQVSV1OiAlZCAtPiBk ZXY6ICV1XG4iLCBjcHUsIGNwdV9raHosIGZyZXEpOwo+PiA+ICsgICAgIHJldHVybiBmcmVxOwo+ PiA+ICt9Cj4+ID4gKwo+PiA+ICtzdGF0aWMgaW50IGRldmZyZXFfY3B1ZnJlcV9nZXRfZnJlcShz dHJ1Y3QgZGV2ZnJlcSAqZGYsCj4+ID4gKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAg ICAgICB1bnNpZ25lZCBsb25nICpmcmVxKQo+PiA+ICt7Cj4+ID4gKyAgICAgdW5zaWduZWQgaW50 IGNwdSwgdGd0X2ZyZXEgPSAwOwo+PiA+ICsgICAgIHN0cnVjdCBkZXZmcmVxX25vZGUgKm5vZGU7 Cj4+ID4gKwo+PiA+ICsgICAgIG5vZGUgPSBkZi0+ZGF0YTsKPj4gPiArICAgICBpZiAoIW5vZGUp IHsKPj4gPiArICAgICAgICAgICAgIHByX2VycigiVW5hYmxlIHRvIGZpbmQgZGV2ZnJlcSBub2Rl IVxuIik7Cj4+ID4gKyAgICAgICAgICAgICByZXR1cm4gLUVOT0RFVjsKPj4gPiArICAgICB9Cj4+ ID4gKwo+PiA+ICsgICAgIGZvcl9lYWNoX3Bvc3NpYmxlX2NwdShjcHUpCj4+ID4gKyAgICAgICAg ICAgICB0Z3RfZnJlcSA9IG1heCh0Z3RfZnJlcSwgY3B1X3RvX2Rldl9mcmVxKGRmLCBjcHUpKTsK Pj4gPiArCj4+ID4gKyAgICAgKmZyZXEgPSB0Z3RfZnJlcTsKPj4gPiArICAgICByZXR1cm4gMDsK Pj4gPiArfQo+PiA+ICsKPj4gPiArc3RhdGljIHVuc2lnbmVkIGludCBzaG93X3RhYmxlKGNoYXIg KmJ1ZiwgdW5zaWduZWQgaW50IGxlbiwKPj4gPiArICAgICAgICAgICAgICAgICAgICAgICAgICAg ICBzdHJ1Y3QgZnJlcV9tYXAgKm1hcCkKPj4gPiArewo+PiA+ICsgICAgIHVuc2lnbmVkIGludCBj bnQgPSAwOwo+PiA+ICsKPj4gPiArICAgICBjbnQgKz0gc25wcmludGYoYnVmICsgY250LCBsZW4g LSBjbnQsICJDUFUgZnJlcVx0RGV2aWNlIGZyZXFcbiIpOwo+PiA+ICsKPj4gPiArICAgICB3aGls ZSAobWFwLT5jcHVfa2h6ICYmIGNudCA8IGxlbikgewo+PiA+ICsgICAgICAgICAgICAgY250ICs9 IHNucHJpbnRmKGJ1ZiArIGNudCwgbGVuIC0gY250LCAiJTh1XHQlMTF1XG4iLAo+PiA+ICsgICAg ICAgICAgICAgICAgICAgICAgICAgICAgIG1hcC0+Y3B1X2toeiwgbWFwLT50YXJnZXRfZnJlcSk7 Cj4+ID4gKyAgICAgICAgICAgICBtYXArKzsKPj4gPiArICAgICB9Cj4+ID4gKyAgICAgaWYgKGNu dCA8IGxlbikKPj4gPiArICAgICAgICAgICAgIGNudCArPSBzbnByaW50ZihidWYgKyBjbnQsIGxl biAtIGNudCwgIlxuIik7Cj4+ID4gKwo+PiA+ICsgICAgIHJldHVybiBjbnQ7Cj4+ID4gK30KPj4g PiArCj4+ID4gK3N0YXRpYyBzc2l6ZV90IGZyZXFfbWFwX3Nob3coc3RydWN0IGRldmljZSAqZGV2 LCBzdHJ1Y3QgZGV2aWNlX2F0dHJpYnV0ZSAqYXR0ciwKPj4gPiArICAgICAgICAgICAgICAgICAg ICAgY2hhciAqYnVmKQo+PiA+ICt7Cj4+ID4gKyAgICAgc3RydWN0IGRldmZyZXEgKmRmID0gdG9f ZGV2ZnJlcShkZXYpOwo+PiA+ICsgICAgIHN0cnVjdCBkZXZmcmVxX25vZGUgKm4gPSBkZi0+ZGF0 YTsKPj4gPiArICAgICBzdHJ1Y3QgZnJlcV9tYXAgKm1hcDsKPj4gPiArICAgICB1bnNpZ25lZCBp bnQgY250ID0gMCwgY3B1Owo+PiA+ICsKPj4gPiArICAgICBtdXRleF9sb2NrKCZzdGF0ZV9sb2Nr KTsKPj4gPiArICAgICBpZiAobi0+Y29tbW9uX21hcCkgewo+PiA+ICsgICAgICAgICAgICAgbWFw ID0gbi0+Y29tbW9uX21hcDsKPj4gPiArICAgICAgICAgICAgIGNudCArPSBzbnByaW50ZihidWYg KyBjbnQsIFBBR0VfU0laRSAtIGNudCwKPj4gPiArICAgICAgICAgICAgICAgICAgICAgICAgICAg ICAiQ29tbW9uIHRhYmxlIGZvciBhbGwgQ1BVczpcbiIpOwo+PiA+ICsgICAgICAgICAgICAgY250 ICs9IHNob3dfdGFibGUoYnVmICsgY250LCBQQUdFX1NJWkUgLSBjbnQsIG1hcCk7Cj4+ID4gKyAg ICAgfSBlbHNlIGlmIChuLT5tYXApIHsKPj4gPiArICAgICAgICAgICAgIGZvcl9lYWNoX3Bvc3Np YmxlX2NwdShjcHUpIHsKPj4gPiArICAgICAgICAgICAgICAgICAgICAgbWFwID0gbi0+bWFwW2Nw dV07Cj4+ID4gKyAgICAgICAgICAgICAgICAgICAgIGlmICghbWFwKQo+PiA+ICsgICAgICAgICAg ICAgICAgICAgICAgICAgICAgIGNvbnRpbnVlOwo+PiA+ICsgICAgICAgICAgICAgICAgICAgICBj bnQgKz0gc25wcmludGYoYnVmICsgY250LCBQQUdFX1NJWkUgLSBjbnQsCj4+ID4gKyAgICAgICAg ICAgICAgICAgICAgICAgICAgICAgICAgICAgICAiQ1BVICV1OlxuIiwgY3B1KTsKPj4gPiArICAg ICAgICAgICAgICAgICAgICAgaWYgKGNudCA+PSBQQUdFX1NJWkUpCj4+ID4gKyAgICAgICAgICAg ICAgICAgICAgICAgICAgICAgYnJlYWs7Cj4+ID4gKyAgICAgICAgICAgICAgICAgICAgIGNudCAr PSBzaG93X3RhYmxlKGJ1ZiArIGNudCwgUEFHRV9TSVpFIC0gY250LCBtYXApOwo+PiA+ICsgICAg ICAgICAgICAgICAgICAgICBpZiAoY250ID49IFBBR0VfU0laRSkKPj4gPiArICAgICAgICAgICAg ICAgICAgICAgICAgICAgICBicmVhazsKPj4gPiArICAgICAgICAgICAgIH0KPj4gPiArICAgICB9 IGVsc2Ugewo+PiA+ICsgICAgICAgICAgICAgY250ICs9IHNucHJpbnRmKGJ1ZiArIGNudCwgUEFH RV9TSVpFIC0gY250LAo+PiA+ICsgICAgICAgICAgICAgICAgICAgICAgICAgICAgICJEZXZpY2Ug ZnJlcSBpbnRlcnBvbGF0ZWQgYmFzZWQgb24gQ1BVIGZyZXFcbiIpOwo+PiA+ICsgICAgIH0KPj4g PiArICAgICBtdXRleF91bmxvY2soJnN0YXRlX2xvY2spOwo+PiA+ICsKPj4gPiArICAgICByZXR1 cm4gY250Owo+PiA+ICt9Cj4+ID4gKwo+PiA+ICtzdGF0aWMgREVWSUNFX0FUVFJfUk8oZnJlcV9t YXApOwo+PiA+ICtzdGF0aWMgc3RydWN0IGF0dHJpYnV0ZSAqZGV2X2F0dHJbXSA9IHsKPj4gPiAr ICAgICAmZGV2X2F0dHJfZnJlcV9tYXAuYXR0ciwKPj4gPiArICAgICBOVUxMLAo+PiA+ICt9Owo+ PiA+ICsKPj4gPiArc3RhdGljIHN0cnVjdCBhdHRyaWJ1dGVfZ3JvdXAgZGV2X2F0dHJfZ3JvdXAg PSB7Cj4+ID4gKyAgICAgLm5hbWUgPSAiY3B1ZnJlcS1tYXAiLAo+PiA+ICsgICAgIC5hdHRycyA9 IGRldl9hdHRyLAo+PiA+ICt9Owo+PiA+ICsKPj4gPiArc3RhdGljIGludCBkZXZmcmVxX2NwdWZy ZXFfZ292X3N0YXJ0KHN0cnVjdCBkZXZmcmVxICpkZXZmcmVxKQo+PiA+ICt7Cj4+ID4gKyAgICAg aW50IHJldCA9IDA7Cj4+ID4gKyAgICAgc3RydWN0IGRldmZyZXFfbm9kZSAqbm9kZTsKPj4gPiAr ICAgICBib29sIGFsbG9jID0gZmFsc2U7Cj4+ID4gKwo+PiA+ICsgICAgIHJldCA9IHJlZ2lzdGVy X2NwdWZyZXEoKTsKPj4gPiArICAgICBpZiAocmV0KQo+PiA+ICsgICAgICAgICAgICAgcmV0dXJu IHJldDsKPj4gPiArCj4+ID4gKyAgICAgcmV0ID0gc3lzZnNfY3JlYXRlX2dyb3VwKCZkZXZmcmVx LT5kZXYua29iaiwgJmRldl9hdHRyX2dyb3VwKTsKPj4gPiArICAgICBpZiAocmV0KSB7Cj4+ID4g KyAgICAgICAgICAgICB1bnJlZ2lzdGVyX2NwdWZyZXEoKTsKPj4gPiArICAgICAgICAgICAgIHJl dHVybiByZXQ7Cj4+ID4gKyAgICAgfQo+PiA+ICsKPj4gPiArICAgICBtdXRleF9sb2NrKCZzdGF0 ZV9sb2NrKTsKPj4gPiArCj4+ID4gKyAgICAgbm9kZSA9IGZpbmRfZGV2ZnJlcV9ub2RlKGRldmZy ZXEtPmRldi5wYXJlbnQpOwo+PiA+ICsgICAgIGlmIChub2RlID09IE5VTEwpIHsKPj4gPiArICAg ICAgICAgICAgIG5vZGUgPSBremFsbG9jKHNpemVvZihzdHJ1Y3QgZGV2ZnJlcV9ub2RlKSwgR0ZQ X0tFUk5FTCk7Cj4+ID4gKyAgICAgICAgICAgICBpZiAoIW5vZGUpIHsKPj4gPiArICAgICAgICAg ICAgICAgICAgICAgcmV0ID0gLUVOT01FTTsKPj4gPiArICAgICAgICAgICAgICAgICAgICAgZ290 byBhbGxvY19mYWlsOwo+PiA+ICsgICAgICAgICAgICAgfQo+PiA+ICsgICAgICAgICAgICAgYWxs b2MgPSB0cnVlOwo+PiA+ICsgICAgICAgICAgICAgbm9kZS0+ZGV2ID0gZGV2ZnJlcS0+ZGV2LnBh cmVudDsKPj4gPiArICAgICAgICAgICAgIGxpc3RfYWRkX3RhaWwoJm5vZGUtPmxpc3QsICZkZXZm cmVxX2xpc3QpOwo+PiA+ICsgICAgIH0KPj4gPiArICAgICBub2RlLT5kZiA9IGRldmZyZXE7Cj4+ ID4gKyAgICAgbm9kZS0+b3JpZ19kYXRhID0gZGV2ZnJlcS0+ZGF0YTsKPj4gPiArICAgICBkZXZm cmVxLT5kYXRhID0gbm9kZTsKPj4gPiArCj4+ID4gKyAgICAgbXV0ZXhfbG9jaygmZGV2ZnJlcS0+ bG9jayk7Cj4+ID4gKyAgICAgcmV0ID0gdXBkYXRlX2RldmZyZXEoZGV2ZnJlcSk7Cj4+ID4gKyAg ICAgbXV0ZXhfdW5sb2NrKCZkZXZmcmVxLT5sb2NrKTsKPj4gPiArICAgICBpZiAocmV0KSB7Cj4+ ID4gKyAgICAgICAgICAgICBwcl9lcnIoIkZyZXEgdXBkYXRlIGZhaWxlZCFcbiIpOwo+PiA+ICsg ICAgICAgICAgICAgZ290byB1cGRhdGVfZmFpbDsKPj4gPiArICAgICB9Cj4+ID4gKwo+PiA+ICsg ICAgIG11dGV4X3VubG9jaygmc3RhdGVfbG9jayk7Cj4+ID4gKyAgICAgcmV0dXJuIDA7Cj4+ID4g Kwo+PiA+ICt1cGRhdGVfZmFpbDoKPj4gPiArICAgICBkZXZmcmVxLT5kYXRhID0gbm9kZS0+b3Jp Z19kYXRhOwo+PiA+ICsgICAgIGlmIChhbGxvYykgewo+PiA+ICsgICAgICAgICAgICAgbGlzdF9k ZWwoJm5vZGUtPmxpc3QpOwo+PiA+ICsgICAgICAgICAgICAga2ZyZWUobm9kZSk7Cj4+ID4gKyAg ICAgfQo+PiA+ICthbGxvY19mYWlsOgo+PiA+ICsgICAgIG11dGV4X3VubG9jaygmc3RhdGVfbG9j ayk7Cj4+ID4gKyAgICAgc3lzZnNfcmVtb3ZlX2dyb3VwKCZkZXZmcmVxLT5kZXYua29iaiwgJmRl dl9hdHRyX2dyb3VwKTsKPj4gPiArICAgICB1bnJlZ2lzdGVyX2NwdWZyZXEoKTsKPj4gPiArICAg ICByZXR1cm4gcmV0Owo+PiA+ICt9Cj4+ID4gKwo+PiA+ICtzdGF0aWMgdm9pZCBkZXZmcmVxX2Nw dWZyZXFfZ292X3N0b3Aoc3RydWN0IGRldmZyZXEgKmRldmZyZXEpCj4+ID4gK3sKPj4gPiArICAg ICBzdHJ1Y3QgZGV2ZnJlcV9ub2RlICpub2RlID0gZGV2ZnJlcS0+ZGF0YTsKPj4gPiArCj4+ID4g KyAgICAgbXV0ZXhfbG9jaygmc3RhdGVfbG9jayk7Cj4+ID4gKyAgICAgZGV2ZnJlcS0+ZGF0YSA9 IG5vZGUtPm9yaWdfZGF0YTsKPj4gPiArICAgICBpZiAobm9kZS0+bWFwIHx8IG5vZGUtPmNvbW1v bl9tYXApIHsKPj4gPiArICAgICAgICAgICAgIG5vZGUtPmRmID0gTlVMTDsKPj4gPiArICAgICB9 IGVsc2Ugewo+PiA+ICsgICAgICAgICAgICAgbGlzdF9kZWwoJm5vZGUtPmxpc3QpOwo+PiA+ICsg ICAgICAgICAgICAga2ZyZWUobm9kZSk7Cj4+ID4gKyAgICAgfQo+PiA+ICsgICAgIG11dGV4X3Vu bG9jaygmc3RhdGVfbG9jayk7Cj4+ID4gKwo+PiA+ICsgICAgIHN5c2ZzX3JlbW92ZV9ncm91cCgm ZGV2ZnJlcS0+ZGV2LmtvYmosICZkZXZfYXR0cl9ncm91cCk7Cj4+ID4gKyAgICAgdW5yZWdpc3Rl cl9jcHVmcmVxKCk7Cj4+ID4gK30KPj4gPiArCj4+ID4gK3N0YXRpYyBpbnQgZGV2ZnJlcV9jcHVm cmVxX2V2X2hhbmRsZXIoc3RydWN0IGRldmZyZXEgKmRldmZyZXEsCj4+ID4gKyAgICAgICAgICAg ICAgICAgICAgICAgICAgICAgICAgICAgICB1bnNpZ25lZCBpbnQgZXZlbnQsIHZvaWQgKmRhdGEp Cj4+ID4gK3sKPj4gPiArICAgICBpbnQgcmV0Owo+PiA+ICsKPj4gPiArICAgICBzd2l0Y2ggKGV2 ZW50KSB7Cj4+ID4gKyAgICAgY2FzZSBERVZGUkVRX0dPVl9TVEFSVDoKPj4gPiArCj4+ID4gKyAg ICAgICAgICAgICByZXQgPSBkZXZmcmVxX2NwdWZyZXFfZ292X3N0YXJ0KGRldmZyZXEpOwo+PiA+ ICsgICAgICAgICAgICAgaWYgKHJldCkgewo+PiA+ICsgICAgICAgICAgICAgICAgICAgICBwcl9l cnIoIkdvdmVybm9yIHN0YXJ0IGZhaWxlZCFcbiIpOwo+PiA+ICsgICAgICAgICAgICAgICAgICAg ICByZXR1cm4gcmV0Owo+PiA+ICsgICAgICAgICAgICAgfQo+PiA+ICsgICAgICAgICAgICAgcHJf ZGVidWcoIkVuYWJsZWQgQ1BVZnJlcS1tYXAgZ292ZXJub3JcbiIpOwo+PiA+ICsgICAgICAgICAg ICAgYnJlYWs7Cj4+ID4gKwo+PiA+ICsgICAgIGNhc2UgREVWRlJFUV9HT1ZfU1RPUDoKPj4gPiAr Cj4+ID4gKyAgICAgICAgICAgICBkZXZmcmVxX2NwdWZyZXFfZ292X3N0b3AoZGV2ZnJlcSk7Cj4+ ID4gKyAgICAgICAgICAgICBwcl9kZWJ1ZygiRGlzYWJsZWQgZGV2IENQVWZyZXEtbWFwIGdvdmVy bm9yXG4iKTsKPj4gPiArICAgICAgICAgICAgIGJyZWFrOwo+PiA+ICsgICAgIH0KPj4gPiArCj4+ ID4gKyAgICAgcmV0dXJuIDA7Cj4+ID4gK30KPj4gPiArCj4+ID4gK3N0YXRpYyBzdHJ1Y3QgZGV2 ZnJlcV9nb3Zlcm5vciBkZXZmcmVxX2NwdWZyZXEgPSB7Cj4+ID4gKyAgICAgLm5hbWUgPSAiY3B1 ZnJlcS1tYXAiLAo+PiA+ICsgICAgIC5nZXRfdGFyZ2V0X2ZyZXEgPSBkZXZmcmVxX2NwdWZyZXFf Z2V0X2ZyZXEsCj4+ID4gKyAgICAgLmV2ZW50X2hhbmRsZXIgPSBkZXZmcmVxX2NwdWZyZXFfZXZf aGFuZGxlciwKPj4gPiArfTsKPj4gPiArCj4+ID4gKyNkZWZpbmUgTlVNX0NPTFMgICAgIDIKPj4g PiArc3RhdGljIHN0cnVjdCBmcmVxX21hcCAqcmVhZF90Ymwoc3RydWN0IGRldmljZV9ub2RlICpv Zl9ub2RlLCBjaGFyICpwcm9wX25hbWUpCj4+ID4gK3sKPj4gPiArICAgICBpbnQgbGVuLCBuZiwg aSwgajsKPj4gPiArICAgICB1MzIgZGF0YTsKPj4gPiArICAgICBzdHJ1Y3QgZnJlcV9tYXAgKnRi bDsKPj4gPiArCj4+ID4gKyAgICAgaWYgKCFvZl9maW5kX3Byb3BlcnR5KG9mX25vZGUsIHByb3Bf bmFtZSwgJmxlbikpCj4+ID4gKyAgICAgICAgICAgICByZXR1cm4gTlVMTDsKPj4gPiArICAgICBs ZW4gLz0gc2l6ZW9mKGRhdGEpOwo+PiA+ICsKPj4gPiArICAgICBpZiAobGVuICUgTlVNX0NPTFMg fHwgbGVuID09IDApCj4+ID4gKyAgICAgICAgICAgICByZXR1cm4gTlVMTDsKPj4gPiArICAgICBu ZiA9IGxlbiAvIE5VTV9DT0xTOwo+PiA+ICsKPj4gPiArICAgICB0YmwgPSBremFsbG9jKChuZiAr IDEpICogc2l6ZW9mKCp0YmwpLCBHRlBfS0VSTkVMKTsKPj4gPiArICAgICBpZiAoIXRibCkKPj4g PiArICAgICAgICAgICAgIHJldHVybiBOVUxMOwo+PiA+ICsKPj4gPiArICAgICBmb3IgKGkgPSAw LCBqID0gMDsgaSA8IG5mOyBpKyssIGogKz0gMikgewo+PiA+ICsgICAgICAgICAgICAgb2ZfcHJv cGVydHlfcmVhZF91MzJfaW5kZXgob2Zfbm9kZSwgcHJvcF9uYW1lLCBqLCAmZGF0YSk7Cj4+ID4g KyAgICAgICAgICAgICB0YmxbaV0uY3B1X2toeiA9IGRhdGE7Cj4+ID4gKwo+PiA+ICsgICAgICAg ICAgICAgb2ZfcHJvcGVydHlfcmVhZF91MzJfaW5kZXgob2Zfbm9kZSwgcHJvcF9uYW1lLCBqICsg MSwgJmRhdGEpOwo+PiA+ICsgICAgICAgICAgICAgdGJsW2ldLnRhcmdldF9mcmVxID0gZGF0YTsK Pj4gPiArICAgICB9Cj4+ID4gKyAgICAgdGJsW2ldLmNwdV9raHogPSAwOwo+PiA+ICsKPj4gPiAr ICAgICByZXR1cm4gdGJsOwo+PiA+ICt9Cj4+ID4gKwo+PiA+ICsjZGVmaW5lIFBST1BfVEFSR0VU ICJ0YXJnZXQtZGV2Igo+PiA+ICsjZGVmaW5lIFBST1BfVEFCTEUgImNwdS10by1kZXYtbWFwIgo+ PiA+ICtzdGF0aWMgaW50IGFkZF90YWJsZV9mcm9tX29mKHN0cnVjdCBkZXZpY2Vfbm9kZSAqb2Zf bm9kZSkKPj4gPiArewo+PiA+ICsgICAgIHN0cnVjdCBkZXZpY2Vfbm9kZSAqdGFyZ2V0X29mX25v ZGU7Cj4+ID4gKyAgICAgc3RydWN0IGRldmZyZXFfbm9kZSAqbm9kZTsKPj4gPiArICAgICBzdHJ1 Y3QgZnJlcV9tYXAgKmNvbW1vbl90Ymw7Cj4+ID4gKyAgICAgc3RydWN0IGZyZXFfbWFwICoqdGJs X2xpc3QgPSBOVUxMOwo+PiA+ICsgICAgIHN0YXRpYyBjaGFyIHByb3BfbmFtZVtdID0gUFJPUF9U QUJMRSAiLTk5OTk5OSI7Cj4+ID4gKyAgICAgaW50IGNwdSwgcmV0LCBjbnQgPSAwLCBwcm9wX3N6 ID0gQVJSQVlfU0laRShwcm9wX25hbWUpOwo+PiA+ICsKPj4gPiArICAgICB0YXJnZXRfb2Zfbm9k ZSA9IG9mX3BhcnNlX3BoYW5kbGUob2Zfbm9kZSwgUFJPUF9UQVJHRVQsIDApOwo+PiA+ICsgICAg IGlmICghdGFyZ2V0X29mX25vZGUpCj4+ID4gKyAgICAgICAgICAgICByZXR1cm4gLUVJTlZBTDsK Pj4gPiArCj4+ID4gKyAgICAgbm9kZSA9IGt6YWxsb2Moc2l6ZW9mKHN0cnVjdCBkZXZmcmVxX25v ZGUpLCBHRlBfS0VSTkVMKTsKPj4gPiArICAgICBpZiAoIW5vZGUpCj4+ID4gKyAgICAgICAgICAg ICByZXR1cm4gLUVOT01FTTsKPj4gPiArCj4+ID4gKyAgICAgY29tbW9uX3RibCA9IHJlYWRfdGJs KG9mX25vZGUsIFBST1BfVEFCTEUpOwo+PiA+ICsgICAgIGlmICghY29tbW9uX3RibCkgewo+PiA+ ICsgICAgICAgICAgICAgdGJsX2xpc3QgPSBremFsbG9jKHNpemVvZigqdGJsX2xpc3QpICogTlJf Q1BVUywgR0ZQX0tFUk5FTCk7Cj4+ID4gKyAgICAgICAgICAgICBpZiAoIXRibF9saXN0KSB7Cj4+ ID4gKyAgICAgICAgICAgICAgICAgICAgIHJldCA9IC1FTk9NRU07Cj4+ID4gKyAgICAgICAgICAg ICAgICAgICAgIGdvdG8gZXJyX2xpc3Q7Cj4+ID4gKyAgICAgICAgICAgICB9Cj4+ID4gKwo+PiA+ ICsgICAgICAgICAgICAgZm9yX2VhY2hfcG9zc2libGVfY3B1KGNwdSkgewo+PiA+ICsgICAgICAg ICAgICAgICAgICAgICByZXQgPSBzbnByaW50Zihwcm9wX25hbWUsIHByb3Bfc3osICIlcy0lZCIs Cj4+ID4gKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBQUk9QX1RBQkxFLCBj cHUpOwo+PiA+ICsgICAgICAgICAgICAgICAgICAgICBpZiAocmV0ID49IHByb3Bfc3opIHsKPj4g PiArICAgICAgICAgICAgICAgICAgICAgICAgICAgICBwcl93YXJuKCJNb3JlIENQVXMgdGhhbiBJ IGNhbiBoYW5kbGUhXG4iKTsKPj4gPiArICAgICAgICAgICAgICAgICAgICAgICAgICAgICBwcl93 YXJuKCJTa2lwcGluZyByZXN0IG9mIHRoZSB0YWJsZXMhXG4iKTsKPj4gPiArICAgICAgICAgICAg ICAgICAgICAgICAgICAgICBicmVhazsKPj4gPiArICAgICAgICAgICAgICAgICAgICAgfQo+PiA+ ICsgICAgICAgICAgICAgICAgICAgICB0YmxfbGlzdFtjcHVdID0gcmVhZF90Ymwob2Zfbm9kZSwg cHJvcF9uYW1lKTsKPj4gPiArICAgICAgICAgICAgICAgICAgICAgaWYgKHRibF9saXN0W2NwdV0p Cj4+ID4gKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgY250Kys7Cj4+ID4gKyAgICAgICAg ICAgICB9Cj4+ID4gKyAgICAgfQo+PiA+ICsgICAgIGlmICghY29tbW9uX3RibCAmJiAhY250KSB7 Cj4+ID4gKyAgICAgICAgICAgICByZXQgPSAtRUlOVkFMOwo+PiA+ICsgICAgICAgICAgICAgZ290 byBlcnJfdGJsOwo+PiA+ICsgICAgIH0KPj4gPiArCj4+ID4gKyAgICAgbXV0ZXhfbG9jaygmc3Rh dGVfbG9jayk7Cj4+ID4gKyAgICAgbm9kZS0+b2Zfbm9kZSA9IHRhcmdldF9vZl9ub2RlOwo+PiA+ ICsgICAgIG5vZGUtPm1hcCA9IHRibF9saXN0Owo+PiA+ICsgICAgIG5vZGUtPmNvbW1vbl9tYXAg PSBjb21tb25fdGJsOwo+PiA+ICsgICAgIGxpc3RfYWRkX3RhaWwoJm5vZGUtPmxpc3QsICZkZXZm cmVxX2xpc3QpOwo+PiA+ICsgICAgIG11dGV4X3VubG9jaygmc3RhdGVfbG9jayk7Cj4+ID4gKwo+ PiA+ICsgICAgIHJldHVybiAwOwo+PiA+ICtlcnJfdGJsOgo+PiA+ICsgICAgIGtmcmVlKHRibF9s aXN0KTsKPj4gPiArZXJyX2xpc3Q6Cj4+ID4gKyAgICAga2ZyZWUobm9kZSk7Cj4+ID4gKyAgICAg cmV0dXJuIHJldDsKPj4gPiArfQo+PiA+ICsKPj4gPiArc3RhdGljIGludCBfX2luaXQgZGV2ZnJl cV9jcHVmcmVxX2luaXQodm9pZCkKPj4gPiArewo+PiA+ICsgICAgIGludCByZXQ7Cj4+ID4gKyAg ICAgc3RydWN0IGRldmljZV9ub2RlICpvZl9wYXIsICpvZl9jaGlsZDsKPj4gPiArCj4+ID4gKyAg ICAgb2ZfcGFyID0gb2ZfZmluZF9ub2RlX2J5X25hbWUoTlVMTCwgImRldmZyZXEtY3B1ZnJlcS1t YXAiKTsKPj4gPiArICAgICBpZiAob2ZfcGFyKSB7Cj4+ID4gKyAgICAgICAgICAgICBmb3JfZWFj aF9jaGlsZF9vZl9ub2RlKG9mX3Bhciwgb2ZfY2hpbGQpIHsKPj4gPiArICAgICAgICAgICAgICAg ICAgICAgcmV0ID0gYWRkX3RhYmxlX2Zyb21fb2Yob2ZfY2hpbGQpOwo+PiA+ICsgICAgICAgICAg ICAgICAgICAgICBpZiAocmV0KQo+PiA+ICsgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHBy X2VycigiUGFyc2luZyAlcyBmYWlsZWQhXG4iLCBvZl9jaGlsZC0+bmFtZSk7Cj4+ID4gKyAgICAg ICAgICAgICAgICAgICAgIGVsc2UKPj4gPiArICAgICAgICAgICAgICAgICAgICAgICAgICAgICBw cl9kZWJ1ZygiUGFyc2VkICVzLlxuIiwgb2ZfY2hpbGQtPm5hbWUpOwo+PiA+ICsgICAgICAgICAg ICAgfQo+PiA+ICsgICAgICAgICAgICAgb2Zfbm9kZV9wdXQob2ZfcGFyKTsKPj4gPiArICAgICB9 IGVsc2Ugewo+PiA+ICsgICAgICAgICAgICAgcHJfaW5mbygiTm8gdGFibGVzIHBhcnNlZCBmcm9t IERULlxuIik7Cj4+ID4gKyAgICAgfQo+PiA+ICsKPj4gPiArICAgICByZXQgPSBkZXZmcmVxX2Fk ZF9nb3Zlcm5vcigmZGV2ZnJlcV9jcHVmcmVxKTsKPj4gPiArICAgICBpZiAocmV0KSB7Cj4+ID4g KyAgICAgICAgICAgICBwcl9lcnIoImNwdWZyZXEtbWFwIGdvdmVybm9yIGFkZCBmYWlsZWQhXG4i KTsKPj4gPiArICAgICAgICAgICAgIHJldHVybiByZXQ7Cj4+ID4gKyAgICAgfQo+PiA+ICsKPj4g PiArICAgICByZXR1cm4gMDsKPj4gPiArfQo+PiA+ICtzdWJzeXNfaW5pdGNhbGwoZGV2ZnJlcV9j cHVmcmVxX2luaXQpOwo+PiA+ICsKPj4gPiArc3RhdGljIHZvaWQgX19leGl0IGRldmZyZXFfY3B1 ZnJlcV9leGl0KHZvaWQpCj4+ID4gK3sKPj4gPiArICAgICBpbnQgcmV0LCBjcHU7Cj4+ID4gKyAg ICAgc3RydWN0IGRldmZyZXFfbm9kZSAqbm9kZSwgKnRtcDsKPj4gPiArCj4+ID4gKyAgICAgcmV0 ID0gZGV2ZnJlcV9yZW1vdmVfZ292ZXJub3IoJmRldmZyZXFfY3B1ZnJlcSk7Cj4+ID4gKyAgICAg aWYgKHJldCkKPj4gPiArICAgICAgICAgICAgIHByX2VycigiY3B1ZnJlcS1tYXAgZ292ZXJub3Ig cmVtb3ZlIGZhaWxlZCFcbiIpOwo+PiA+ICsKPj4gPiArICAgICBtdXRleF9sb2NrKCZzdGF0ZV9s b2NrKTsKPj4gPiArICAgICBsaXN0X2Zvcl9lYWNoX2VudHJ5X3NhZmUobm9kZSwgdG1wLCAmZGV2 ZnJlcV9saXN0LCBsaXN0KSB7Cj4+ID4gKyAgICAgICAgICAgICBrZnJlZShub2RlLT5jb21tb25f bWFwKTsKPj4gPiArICAgICAgICAgICAgIGZvcl9lYWNoX3Bvc3NpYmxlX2NwdShjcHUpCj4+ID4g KyAgICAgICAgICAgICAgICAgICAgIGtmcmVlKG5vZGUtPm1hcFtjcHVdKTsKPj4gPiArICAgICAg ICAgICAgIGtmcmVlKG5vZGUtPm1hcCk7Cj4+ID4gKyAgICAgICAgICAgICBsaXN0X2RlbCgmbm9k ZS0+bGlzdCk7Cj4+ID4gKyAgICAgICAgICAgICBrZnJlZShub2RlKTsKPj4gPiArICAgICB9Cj4+ ID4gKyAgICAgbXV0ZXhfdW5sb2NrKCZzdGF0ZV9sb2NrKTsKPj4gPiArfQo+PiA+ICttb2R1bGVf ZXhpdChkZXZmcmVxX2NwdWZyZXFfZXhpdCk7Cj4+ID4gKwo+PiA+ICtNT0RVTEVfREVTQ1JJUFRJ T04oImRldmZyZXEgZ292IHRoYXQgc2V0cyBkZXYgZnJlcSBiYXNlZCBvbiBjdXJyZW50IENQVSBm cmVxIik7Cj4+ID4gK01PRFVMRV9MSUNFTlNFKCJHUEwgdjIiKTsKPj4gPgoKLS0gCi0tIFNpYmkg U2Fua2FyIC0tClF1YWxjb21tIElubm92YXRpb24gQ2VudGVyLCBJbmMuIGlzIGEgbWVtYmVyIG9m IENvZGUgQXVyb3JhIEZvcnVtLAphIExpbnV4IEZvdW5kYXRpb24gQ29sbGFib3JhdGl2ZSBQcm9q ZWN0LgoKX19fX19fX19fX19fX19fX19fX19fX19fX19fX19fX19fX19fX19fX19fX19fX18KbGlu dXgtYXJtLWtlcm5lbCBtYWlsaW5nIGxpc3QKbGludXgtYXJtLWtlcm5lbEBsaXN0cy5pbmZyYWRl YWQub3JnCmh0dHA6Ly9saXN0cy5pbmZyYWRlYWQub3JnL21haWxtYW4vbGlzdGluZm8vbGludXgt YXJtLWtlcm5lbAo=