From mboxrd@z Thu Jan 1 00:00:00 1970 Received: from eggs.gnu.org ([2001:4830:134:3::10]:44139) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1WvCym-0004zL-DM for qemu-devel@nongnu.org; Thu, 12 Jun 2014 17:56:21 -0400 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1WvCyh-0003Di-F5 for qemu-devel@nongnu.org; Thu, 12 Jun 2014 17:56:16 -0400 Received: from mail-qa0-f41.google.com ([209.85.216.41]:57817) by eggs.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1WvCyh-0003DX-Ar for qemu-devel@nongnu.org; Thu, 12 Jun 2014 17:56:11 -0400 Received: by mail-qa0-f41.google.com with SMTP id cm18so2411263qab.28 for ; Thu, 12 Jun 2014 14:56:10 -0700 (PDT) MIME-Version: 1.0 In-Reply-To: <1402444514-19658-12-git-send-email-aggelerf@ethz.ch> References: <1402444514-19658-1-git-send-email-aggelerf@ethz.ch> <1402444514-19658-12-git-send-email-aggelerf@ethz.ch> Date: Thu, 12 Jun 2014 16:56:10 -0500 Message-ID: From: Greg Bellows Content-Type: multipart/alternative; boundary=047d7bdc82c2fed4e204fbaaa01a Subject: Re: [Qemu-devel] [PATCH v3 11/32] target-arm: add async excp target_el&mode function List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , To: Fabian Aggeler Cc: Peter Maydell , Peter Crosthwaite , QEMU Developers , Sergey Fedorov , "Edgar E. Iglesias" , Christoffer Dall --047d7bdc82c2fed4e204fbaaa01a Content-Type: text/plain; charset=UTF-8 On 10 June 2014 18:54, Fabian Aggeler wrote: > Adds a dedicated function for IRQ and FIQ exceptions to determine > target_el and mode (Aarch32) according to tables in ARM ARMv8 and > ARM ARM v7. > > Signed-off-by: Fabian Aggeler > --- > target-arm/cpu.h | 3 ++ > target-arm/helper.c | 137 > ++++++++++++++++++++++++++++++++++++++++++++++++++++ > 2 files changed, 140 insertions(+) > > diff --git a/target-arm/cpu.h b/target-arm/cpu.h > index b786a5a..52e679f 100644 > --- a/target-arm/cpu.h > +++ b/target-arm/cpu.h > @@ -768,6 +768,9 @@ static inline bool arm_el_is_aa64(CPUARMState *env, > int el) > > void arm_cpu_list(FILE *f, fprintf_function cpu_fprintf); > unsigned int arm_excp_target_el(CPUState *cs, unsigned int excp_idx); > +inline uint32_t arm_phys_excp_target_el(CPUState *cs, uint32_t > *target_mode, > + uint32_t excp_idx, uint32_t > cur_el, > + bool secure); > > /* Interface between CPU and Interrupt controller. */ > void armv7m_nvic_set_pending(void *opaque, int irq); > diff --git a/target-arm/helper.c b/target-arm/helper.c > index 5822353..8333b52 100644 > --- a/target-arm/helper.c > +++ b/target-arm/helper.c > @@ -3224,6 +3224,21 @@ uint32_t HELPER(get_r13_banked)(CPUARMState *env, > uint32_t mode) > return 0; > } > > +inline uint32_t arm_phys_excp_target_el(CPUState *cs, uint32_t > *target_mode, > + uint32_t excp_idx, uint32_t > cur_el, > + bool secure) > +{ > + switch (excp_idx) { > + case EXCP_IRQ: > + *target_mode = ARM_CPU_MODE_IRQ; > + break; > + case EXCP_FIQ: > + *target_mode = ARM_CPU_MODE_FIQ; > + break; > + } > + return 1; > +} > + > unsigned int arm_excp_target_el(CPUState *cs, unsigned int excp_idx) > { > return 1; > @@ -3285,6 +3300,128 @@ void switch_mode(CPUARMState *env, int mode) > } > > /* > + * Determine the target EL for physical exceptions > + */ > +inline uint32_t arm_phys_excp_target_el(CPUState *cs, uint32_t > *target_mode, > + uint32_t excp_idx, uint32_t > cur_el, > + bool secure) > +{ > + CPUARMState *env = cs->env_ptr; > + uint32_t target_el = 1; > + uint32_t excp_mode = 0; > + > + bool scr_routing = 0; /* IRQ, FIQ, EA */ > + bool hcr_routing = 0; /* IMO, FMO, AMO */ > + > + switch (excp_idx) { > + case EXCP_IRQ: > + scr_routing = (env->cp15.scr_el3 & SCR_IRQ); > + hcr_routing = (env->cp15.hcr_el2 & HCR_IMO); > + excp_mode = ARM_CPU_MODE_IRQ; > + break; > + case EXCP_FIQ: > + scr_routing = (env->cp15.scr_el3 & SCR_FIQ); > + hcr_routing = (env->cp15.hcr_el2 & HCR_FMO); > + excp_mode = ARM_CPU_MODE_FIQ; > + } > + > + /* If HCR.TGE is set all exceptions that would be routed to EL1 are > + * routed to EL2 (in non-secure world). > + */ > + if (arm_feature(env, ARM_FEATURE_EL2) && (env->cp15.hcr_el2 & > HCR_TGE)) { > + hcr_routing = 1; > + } > + > + /* Determine target EL according to ARM ARMv8 tables G1-15 and G1-16 > */ > + if (arm_el_is_aa64(env, 3)) { > + /* EL3 in Aarch64 */ > + if (scr_routing) { > + /* IRQ|FIQ|EA == 1 */ > + target_el = 3; > + } else { > + if (hcr_routing) { > + /* IRQ|FIQ|EA == 0 > + * IMO|FMO|AMO == 1 */ > + if (secure) { > + /* Secure */ > + target_el = 1; > + if (!arm_el_is_aa64(env, 1)) { > + /* EL1 using Aarch32 */ > + *target_mode = ARM_CPU_MODE_ABT; > + } > + } else if (cur_el < 2) { > + /* Non-Secure goes to EL2 */ > + target_el = 2; > + if (!arm_el_is_aa64(env, 2)) { > + /* EL2 using Aarch32 */ > + *target_mode = ARM_CPU_MODE_HYP; > + } > + } > + } else if (env->cp15.scr_el3 & SCR_RW) { > + /* IRQ|FIQ|EA == 0 > + * IMO|FMO|AMO == 0 > + * RW == 1 (Next lower level is Aarch64) > + */ > + if (cur_el < 2) { > + target_el = 1; > + } else { > + /* Interrupt not taken but remains pending */ > + } > + } else { > + /* IRQ|FIQ|EA == 0 > + * IMO|FMO|AMO == 0 > + * RW == 0 (Next lower level is Aarch64) > + */ > + if (cur_el < 2) { > + target_el = 1; > + *target_mode = ARM_CPU_MODE_ABT; > According to the aforementioned tables, the target mode should be excp_mode, not always abort. > + } else if (cur_el == 2) { > + target_el = 2; > + *target_mode = ARM_CPU_MODE_HYP; > + } else { > + /* Interrupt not taken but remains pending */ > + } > + } > + } > + } else { > + /* EL3 in Aarch32 */ > + if (scr_routing) { > + /* IRQ|FIQ|EA == 1 */ > + target_el = 3; > + *target_mode = ARM_CPU_MODE_MON; > + } else { > + if (hcr_routing) { > + /* IRQ|FIQ|EA == 0 > + * IMO|FMO|AMO == 1 > + */ > + if (secure) { > + target_el = 3; > + *target_mode = excp_mode; > + } else { > + target_el = 2; > + *target_mode = ARM_CPU_MODE_HYP; > + } > + } else { > + /* IRQ|FIQ|EA == 0 > + * IMO|FMO|AMO == 0 > + */ > + if (cur_el < 2) { > + target_el = 1; > + *target_mode = excp_mode; > + } else if (cur_el == 2) { > + target_el = 2; > + *target_mode = ARM_CPU_MODE_HYP; > + } else if (secure) { > + target_el = 3; > + *target_mode = excp_mode; > + } > + } > + } > + } > + return target_el; > +} > + > +/* > * Determine the target EL for a given exception type. > */ > unsigned int arm_excp_target_el(CPUState *cs, unsigned int excp_idx) > -- > 1.8.3.2 > > --047d7bdc82c2fed4e204fbaaa01a Content-Type: text/html; charset=UTF-8 Content-Transfer-Encoding: base64 PGRpdiBkaXI9Imx0ciI+PGJyPjxkaXYgY2xhc3M9ImdtYWlsX2V4dHJhIj48YnI+PGJyPjxkaXYg Y2xhc3M9ImdtYWlsX3F1b3RlIj5PbiAxMCBKdW5lIDIwMTQgMTg6NTQsIEZhYmlhbiBBZ2dlbGVy IDxzcGFuIGRpcj0ibHRyIj4mbHQ7PGEgaHJlZj0ibWFpbHRvOmFnZ2VsZXJmQGV0aHouY2giIHRh cmdldD0iX2JsYW5rIj5hZ2dlbGVyZkBldGh6LmNoPC9hPiZndDs8L3NwYW4+IHdyb3RlOjxicj4N Cg0KPGJsb2NrcXVvdGUgY2xhc3M9ImdtYWlsX3F1b3RlIiBzdHlsZT0ibWFyZ2luOjAgMCAwIC44 ZXg7Ym9yZGVyLWxlZnQ6MXB4ICNjY2Mgc29saWQ7cGFkZGluZy1sZWZ0OjFleCI+QWRkcyBhIGRl ZGljYXRlZCBmdW5jdGlvbiBmb3IgSVJRIGFuZCBGSVEgZXhjZXB0aW9ucyB0byBkZXRlcm1pbmU8 YnI+DQp0YXJnZXRfZWwgYW5kIG1vZGUgKEFhcmNoMzIpIGFjY29yZGluZyB0byB0YWJsZXMgaW4g QVJNIEFSTXY4IGFuZDxicj4NCkFSTSBBUk0gdjcuPGJyPg0KPGJyPg0KU2lnbmVkLW9mZi1ieTog RmFiaWFuIEFnZ2VsZXIgJmx0OzxhIGhyZWY9Im1haWx0bzphZ2dlbGVyZkBldGh6LmNoIiB0YXJn ZXQ9Il9ibGFuayI+YWdnZWxlcmZAZXRoei5jaDwvYT4mZ3Q7PGJyPg0KLS0tPGJyPg0KwqB0YXJn ZXQtYXJtL2NwdS5oIMKgIMKgfCDCoCAzICsrPGJyPg0KwqB0YXJnZXQtYXJtL2hlbHBlci5jIHwg MTM3ICsrKysrKysrKysrKysrKysrKysrKysrKysrKysrKysrKysrKysrKysrKysrKysrKysrKys8 YnI+DQrCoDIgZmlsZXMgY2hhbmdlZCwgMTQwIGluc2VydGlvbnMoKyk8YnI+DQo8YnI+DQpkaWZm IC0tZ2l0IGEvdGFyZ2V0LWFybS9jcHUuaCBiL3RhcmdldC1hcm0vY3B1Lmg8YnI+DQppbmRleCBi Nzg2YTVhLi41MmU2NzlmIDEwMDY0NDxicj4NCi0tLSBhL3RhcmdldC1hcm0vY3B1Lmg8YnI+DQor KysgYi90YXJnZXQtYXJtL2NwdS5oPGJyPg0KQEAgLTc2OCw2ICs3NjgsOSBAQCBzdGF0aWMgaW5s aW5lIGJvb2wgYXJtX2VsX2lzX2FhNjQoQ1BVQVJNU3RhdGUgKmVudiwgaW50IGVsKTxicj4NCjxi cj4NCsKgdm9pZCBhcm1fY3B1X2xpc3QoRklMRSAqZiwgZnByaW50Zl9mdW5jdGlvbiBjcHVfZnBy aW50Zik7PGJyPg0KwqB1bnNpZ25lZCBpbnQgYXJtX2V4Y3BfdGFyZ2V0X2VsKENQVVN0YXRlICpj cywgdW5zaWduZWQgaW50IGV4Y3BfaWR4KTs8YnI+DQoraW5saW5lIHVpbnQzMl90IGFybV9waHlz X2V4Y3BfdGFyZ2V0X2VsKENQVVN0YXRlICpjcywgdWludDMyX3QgKnRhcmdldF9tb2RlLDxicj4N CisgwqAgwqAgwqAgwqAgwqAgwqAgwqAgwqAgwqAgwqAgwqAgwqAgwqAgwqAgwqAgwqAgwqAgwqAg wqAgwqB1aW50MzJfdCBleGNwX2lkeCwgdWludDMyX3QgY3VyX2VsLDxicj4NCisgwqAgwqAgwqAg wqAgwqAgwqAgwqAgwqAgwqAgwqAgwqAgwqAgwqAgwqAgwqAgwqAgwqAgwqAgwqAgwqBib29sIHNl Y3VyZSk7PGJyPg0KPGJyPg0KwqAvKiBJbnRlcmZhY2UgYmV0d2VlbiBDUFUgYW5kIEludGVycnVw dCBjb250cm9sbGVyLiDCoCovPGJyPg0KwqB2b2lkIGFybXY3bV9udmljX3NldF9wZW5kaW5nKHZv aWQgKm9wYXF1ZSwgaW50IGlycSk7PGJyPg0KZGlmZiAtLWdpdCBhL3RhcmdldC1hcm0vaGVscGVy LmMgYi90YXJnZXQtYXJtL2hlbHBlci5jPGJyPg0KaW5kZXggNTgyMjM1My4uODMzM2I1MiAxMDA2 NDQ8YnI+DQotLS0gYS90YXJnZXQtYXJtL2hlbHBlci5jPGJyPg0KKysrIGIvdGFyZ2V0LWFybS9o ZWxwZXIuYzxicj4NCkBAIC0zMjI0LDYgKzMyMjQsMjEgQEAgdWludDMyX3QgSEVMUEVSKGdldF9y MTNfYmFua2VkKShDUFVBUk1TdGF0ZSAqZW52LCB1aW50MzJfdCBtb2RlKTxicj4NCsKgIMKgIMKg cmV0dXJuIDA7PGJyPg0KwqB9PGJyPg0KPGJyPg0KK2lubGluZSB1aW50MzJfdCBhcm1fcGh5c19l eGNwX3RhcmdldF9lbChDUFVTdGF0ZSAqY3MsIHVpbnQzMl90ICp0YXJnZXRfbW9kZSw8YnI+DQor IMKgIMKgIMKgIMKgIMKgIMKgIMKgIMKgIMKgIMKgIMKgIMKgIMKgIMKgIMKgIMKgIMKgIMKgIMKg IMKgdWludDMyX3QgZXhjcF9pZHgsIHVpbnQzMl90IGN1cl9lbCw8YnI+DQorIMKgIMKgIMKgIMKg IMKgIMKgIMKgIMKgIMKgIMKgIMKgIMKgIMKgIMKgIMKgIMKgIMKgIMKgIMKgIMKgYm9vbCBzZWN1 cmUpPGJyPg0KK3s8YnI+DQorIMKgIMKgc3dpdGNoIChleGNwX2lkeCkgezxicj4NCisgwqAgwqBj YXNlIEVYQ1BfSVJROjxicj4NCisgwqAgwqAgwqAgwqAqdGFyZ2V0X21vZGUgPSBBUk1fQ1BVX01P REVfSVJROzxicj4NCisgwqAgwqAgwqAgwqBicmVhazs8YnI+DQorIMKgIMKgY2FzZSBFWENQX0ZJ UTo8YnI+DQorIMKgIMKgIMKgIMKgKnRhcmdldF9tb2RlID0gQVJNX0NQVV9NT0RFX0ZJUTs8YnI+ DQorIMKgIMKgIMKgIMKgYnJlYWs7PGJyPg0KKyDCoCDCoH08YnI+DQorIMKgIMKgcmV0dXJuIDE7 PGJyPg0KK308YnI+DQorPGJyPg0KwqB1bnNpZ25lZCBpbnQgYXJtX2V4Y3BfdGFyZ2V0X2VsKENQ VVN0YXRlICpjcywgdW5zaWduZWQgaW50IGV4Y3BfaWR4KTxicj4NCsKgezxicj4NCsKgIMKgIMKg cmV0dXJuIDE7PGJyPg0KQEAgLTMyODUsNiArMzMwMCwxMjggQEAgdm9pZCBzd2l0Y2hfbW9kZShD UFVBUk1TdGF0ZSAqZW52LCBpbnQgbW9kZSk8YnI+DQrCoH08YnI+DQo8YnI+DQrCoC8qPGJyPg0K KyAqIERldGVybWluZSB0aGUgdGFyZ2V0IEVMIGZvciBwaHlzaWNhbCBleGNlcHRpb25zPGJyPg0K KyAqLzxicj4NCitpbmxpbmUgdWludDMyX3QgYXJtX3BoeXNfZXhjcF90YXJnZXRfZWwoQ1BVU3Rh dGUgKmNzLCB1aW50MzJfdCAqdGFyZ2V0X21vZGUsPGJyPg0KKyDCoCDCoCDCoCDCoCDCoCDCoCDC oCDCoCDCoCDCoCDCoCDCoCDCoCDCoCDCoCDCoCDCoCDCoCDCoCDCoHVpbnQzMl90IGV4Y3BfaWR4 LCB1aW50MzJfdCBjdXJfZWwsPGJyPg0KKyDCoCDCoCDCoCDCoCDCoCDCoCDCoCDCoCDCoCDCoCDC oCDCoCDCoCDCoCDCoCDCoCDCoCDCoCDCoCDCoGJvb2wgc2VjdXJlKTxicj4NCit7PGJyPg0KKyDC oCDCoENQVUFSTVN0YXRlICplbnYgPSBjcy0mZ3Q7ZW52X3B0cjs8YnI+DQorIMKgIMKgdWludDMy X3QgdGFyZ2V0X2VsID0gMTs8YnI+DQorIMKgIMKgdWludDMyX3QgZXhjcF9tb2RlID0gMDs8YnI+ DQorPGJyPg0KKyDCoCDCoGJvb2wgc2NyX3JvdXRpbmcgPSAwOyAvKiBJUlEsIEZJUSwgRUEgKi88 YnI+DQorIMKgIMKgYm9vbCBoY3Jfcm91dGluZyA9IDA7IC8qIElNTywgRk1PLCBBTU8gKi88YnI+ DQorPGJyPg0KKyDCoCDCoHN3aXRjaCAoZXhjcF9pZHgpIHs8YnI+DQorIMKgIMKgY2FzZSBFWENQ X0lSUTo8YnI+DQorIMKgIMKgIMKgIMKgc2NyX3JvdXRpbmcgPSAoZW52LSZndDtjcDE1LnNjcl9l bDMgJmFtcDsgU0NSX0lSUSk7PGJyPg0KKyDCoCDCoCDCoCDCoGhjcl9yb3V0aW5nID0gKGVudi0m Z3Q7Y3AxNS5oY3JfZWwyICZhbXA7IEhDUl9JTU8pOzxicj4NCisgwqAgwqAgwqAgwqBleGNwX21v ZGUgPSBBUk1fQ1BVX01PREVfSVJROzxicj4NCisgwqAgwqAgwqAgwqBicmVhazs8YnI+DQorIMKg IMKgY2FzZSBFWENQX0ZJUTo8YnI+DQorIMKgIMKgIMKgIMKgc2NyX3JvdXRpbmcgPSAoZW52LSZn dDtjcDE1LnNjcl9lbDMgJmFtcDsgU0NSX0ZJUSk7PGJyPg0KKyDCoCDCoCDCoCDCoGhjcl9yb3V0 aW5nID0gKGVudi0mZ3Q7Y3AxNS5oY3JfZWwyICZhbXA7IEhDUl9GTU8pOzxicj4NCisgwqAgwqAg wqAgwqBleGNwX21vZGUgPSBBUk1fQ1BVX01PREVfRklROzxicj4NCisgwqAgwqB9PGJyPg0KKzxi cj4NCisgwqAgwqAvKiBJZiBIQ1IuVEdFIGlzIHNldCBhbGwgZXhjZXB0aW9ucyB0aGF0IHdvdWxk IGJlIHJvdXRlZCB0byBFTDEgYXJlPGJyPg0KKyDCoCDCoCAqIHJvdXRlZCB0byBFTDIgKGluIG5v bi1zZWN1cmUgd29ybGQpLjxicj4NCisgwqAgwqAgKi88YnI+DQorIMKgIMKgaWYgKGFybV9mZWF0 dXJlKGVudiwgQVJNX0ZFQVRVUkVfRUwyKSAmYW1wOyZhbXA7IChlbnYtJmd0O2NwMTUuaGNyX2Vs MiAmYW1wOyBIQ1JfVEdFKSkgezxicj4NCisgwqAgwqAgwqAgwqBoY3Jfcm91dGluZyA9IDE7PGJy Pg0KKyDCoCDCoH08YnI+DQorPGJyPg0KKyDCoCDCoC8qIERldGVybWluZSB0YXJnZXQgRUwgYWNj b3JkaW5nIHRvIEFSTSBBUk12OCB0YWJsZXMgRzEtMTUgYW5kIEcxLTE2ICovPGJyPg0KKyDCoCDC oGlmIChhcm1fZWxfaXNfYWE2NChlbnYsIDMpKSB7PGJyPg0KKyDCoCDCoCDCoCDCoC8qIEVMMyBp biBBYXJjaDY0ICovPGJyPg0KKyDCoCDCoCDCoCDCoGlmIChzY3Jfcm91dGluZykgezxicj4NCisg wqAgwqAgwqAgwqAgwqAgwqAvKiBJUlF8RklRfEVBID09IDEgKi88YnI+DQorIMKgIMKgIMKgIMKg IMKgIMKgdGFyZ2V0X2VsID0gMzs8YnI+DQorIMKgIMKgIMKgIMKgfSBlbHNlIHs8YnI+DQorIMKg IMKgIMKgIMKgIMKgIMKgaWYgKGhjcl9yb3V0aW5nKSB7PGJyPg0KKyDCoCDCoCDCoCDCoCDCoCDC oCDCoCDCoC8qIElSUXxGSVF8RUEgPT0gMDxicj4NCisgwqAgwqAgwqAgwqAgwqAgwqAgwqAgwqAg KiBJTU98Rk1PfEFNTyA9PSAxICovPGJyPg0KKyDCoCDCoCDCoCDCoCDCoCDCoCDCoCDCoGlmIChz ZWN1cmUpIHs8YnI+DQorIMKgIMKgIMKgIMKgIMKgIMKgIMKgIMKgIMKgIMKgLyogU2VjdXJlICov PGJyPg0KKyDCoCDCoCDCoCDCoCDCoCDCoCDCoCDCoCDCoCDCoHRhcmdldF9lbCA9IDE7PGJyPg0K KyDCoCDCoCDCoCDCoCDCoCDCoCDCoCDCoCDCoCDCoGlmICghYXJtX2VsX2lzX2FhNjQoZW52LCAx KSkgezxicj4NCisgwqAgwqAgwqAgwqAgwqAgwqAgwqAgwqAgwqAgwqAgwqAgwqAvKiBFTDEgdXNp bmcgQWFyY2gzMiAqLzxicj4NCisgwqAgwqAgwqAgwqAgwqAgwqAgwqAgwqAgwqAgwqAgwqAgwqAq dGFyZ2V0X21vZGUgPSBBUk1fQ1BVX01PREVfQUJUOzxicj4NCisgwqAgwqAgwqAgwqAgwqAgwqAg wqAgwqAgwqAgwqB9PGJyPg0KKyDCoCDCoCDCoCDCoCDCoCDCoCDCoCDCoH0gZWxzZSBpZiAoY3Vy X2VsICZsdDsgMikgezxicj4NCisgwqAgwqAgwqAgwqAgwqAgwqAgwqAgwqAgwqAgwqAvKiBOb24t U2VjdXJlIGdvZXMgdG8gRUwyICovPGJyPg0KKyDCoCDCoCDCoCDCoCDCoCDCoCDCoCDCoCDCoCDC oHRhcmdldF9lbCA9IDI7PGJyPg0KKyDCoCDCoCDCoCDCoCDCoCDCoCDCoCDCoCDCoCDCoGlmICgh YXJtX2VsX2lzX2FhNjQoZW52LCAyKSkgezxicj4NCisgwqAgwqAgwqAgwqAgwqAgwqAgwqAgwqAg wqAgwqAgwqAgwqAvKiBFTDIgdXNpbmcgQWFyY2gzMiAqLzxicj4NCisgwqAgwqAgwqAgwqAgwqAg wqAgwqAgwqAgwqAgwqAgwqAgwqAqdGFyZ2V0X21vZGUgPSBBUk1fQ1BVX01PREVfSFlQOzxicj4N CisgwqAgwqAgwqAgwqAgwqAgwqAgwqAgwqAgwqAgwqB9PGJyPg0KKyDCoCDCoCDCoCDCoCDCoCDC oCDCoCDCoH08YnI+DQorIMKgIMKgIMKgIMKgIMKgIMKgfSBlbHNlIGlmIChlbnYtJmd0O2NwMTUu c2NyX2VsMyAmYW1wOyBTQ1JfUlcpIHs8YnI+DQorIMKgIMKgIMKgIMKgIMKgIMKgIMKgIMKgLyog SVJRfEZJUXxFQSA9PSAwPGJyPg0KKyDCoCDCoCDCoCDCoCDCoCDCoCDCoCDCoCAqIElNT3xGTU98 QU1PID09IDA8YnI+DQorIMKgIMKgIMKgIMKgIMKgIMKgIMKgIMKgICogUlcgPT0gMSAoTmV4dCBs b3dlciBsZXZlbCBpcyBBYXJjaDY0KTxicj4NCisgwqAgwqAgwqAgwqAgwqAgwqAgwqAgwqAgKi88 YnI+DQorIMKgIMKgIMKgIMKgIMKgIMKgIMKgIMKgaWYgKGN1cl9lbCAmbHQ7IDIpIHs8YnI+DQor IMKgIMKgIMKgIMKgIMKgIMKgIMKgIMKgIMKgIMKgdGFyZ2V0X2VsID0gMTs8YnI+DQorIMKgIMKg IMKgIMKgIMKgIMKgIMKgIMKgfSBlbHNlIHs8YnI+DQorIMKgIMKgIMKgIMKgIMKgIMKgIMKgIMKg IMKgIMKgLyogSW50ZXJydXB0IG5vdCB0YWtlbiBidXQgcmVtYWlucyBwZW5kaW5nICovPGJyPg0K KyDCoCDCoCDCoCDCoCDCoCDCoCDCoCDCoH08YnI+DQorIMKgIMKgIMKgIMKgIMKgIMKgfSBlbHNl IHs8YnI+DQorIMKgIMKgIMKgIMKgIMKgIMKgIMKgIMKgLyogSVJRfEZJUXxFQSA9PSAwPGJyPg0K KyDCoCDCoCDCoCDCoCDCoCDCoCDCoCDCoCAqIElNT3xGTU98QU1PID09IDA8YnI+DQorIMKgIMKg IMKgIMKgIMKgIMKgIMKgIMKgICogUlcgPT0gMCAoTmV4dCBsb3dlciBsZXZlbCBpcyBBYXJjaDY0 KTxicj4NCisgwqAgwqAgwqAgwqAgwqAgwqAgwqAgwqAgKi88YnI+DQorIMKgIMKgIMKgIMKgIMKg IMKgIMKgIMKgaWYgKGN1cl9lbCAmbHQ7IDIpIHs8YnI+DQorIMKgIMKgIMKgIMKgIMKgIMKgIMKg IMKgIMKgIMKgdGFyZ2V0X2VsID0gMTs8YnI+DQorIMKgIMKgIMKgIMKgIMKgIMKgIMKgIMKgIMKg IMKgKnRhcmdldF9tb2RlID0gQVJNX0NQVV9NT0RFX0FCVDs8YnI+PC9ibG9ja3F1b3RlPjxkaXY+ PGJyPjwvZGl2PjxkaXY+QWNjb3JkaW5nIHRvIHRoZSBhZm9yZW1lbnRpb25lZCB0YWJsZXMsIHRo ZSB0YXJnZXQgbW9kZSBzaG91bGQgYmUgZXhjcF9tb2RlLCBub3QgYWx3YXlzIGFib3J0LjwvZGl2 PjxkaXY+wqA8L2Rpdj48YmxvY2txdW90ZSBjbGFzcz0iZ21haWxfcXVvdGUiIHN0eWxlPSJtYXJn aW46MCAwIDAgLjhleDtib3JkZXItbGVmdDoxcHggI2NjYyBzb2xpZDtwYWRkaW5nLWxlZnQ6MWV4 Ij4NCg0KDQorIMKgIMKgIMKgIMKgIMKgIMKgIMKgIMKgfSBlbHNlIGlmIChjdXJfZWwgPT0gMikg ezxicj4NCisgwqAgwqAgwqAgwqAgwqAgwqAgwqAgwqAgwqAgwqB0YXJnZXRfZWwgPSAyOzxicj4N CisgwqAgwqAgwqAgwqAgwqAgwqAgwqAgwqAgwqAgwqAqdGFyZ2V0X21vZGUgPSBBUk1fQ1BVX01P REVfSFlQOzxicj4NCisgwqAgwqAgwqAgwqAgwqAgwqAgwqAgwqB9IGVsc2Ugezxicj4NCisgwqAg wqAgwqAgwqAgwqAgwqAgwqAgwqAgwqAgwqAvKiBJbnRlcnJ1cHQgbm90IHRha2VuIGJ1dCByZW1h aW5zIHBlbmRpbmcgKi88YnI+DQorIMKgIMKgIMKgIMKgIMKgIMKgIMKgIMKgfTxicj4NCisgwqAg wqAgwqAgwqAgwqAgwqB9PGJyPg0KKyDCoCDCoCDCoCDCoH08YnI+DQorIMKgIMKgfSBlbHNlIHs8 YnI+DQorIMKgIMKgIMKgIMKgLyogRUwzIGluIEFhcmNoMzIgKi88YnI+DQorIMKgIMKgIMKgIMKg aWYgKHNjcl9yb3V0aW5nKSB7PGJyPg0KKyDCoCDCoCDCoCDCoCDCoCDCoC8qIElSUXxGSVF8RUEg PT0gMSAqLzxicj4NCisgwqAgwqAgwqAgwqAgwqAgwqB0YXJnZXRfZWwgPSAzOzxicj4NCisgwqAg wqAgwqAgwqAgwqAgwqAqdGFyZ2V0X21vZGUgPSBBUk1fQ1BVX01PREVfTU9OOzxicj4NCisgwqAg wqAgwqAgwqB9IGVsc2Ugezxicj4NCisgwqAgwqAgwqAgwqAgwqAgwqBpZiAoaGNyX3JvdXRpbmcp IHs8YnI+DQorIMKgIMKgIMKgIMKgIMKgIMKgIMKgIMKgLyogSVJRfEZJUXxFQSA9PSAwPGJyPg0K KyDCoCDCoCDCoCDCoCDCoCDCoCDCoCDCoCAqIElNT3xGTU98QU1PID09IDE8YnI+DQorIMKgIMKg IMKgIMKgIMKgIMKgIMKgIMKgICovPGJyPg0KKyDCoCDCoCDCoCDCoCDCoCDCoCDCoCDCoGlmIChz ZWN1cmUpIHs8YnI+DQorIMKgIMKgIMKgIMKgIMKgIMKgIMKgIMKgIMKgIMKgdGFyZ2V0X2VsID0g Mzs8YnI+DQorIMKgIMKgIMKgIMKgIMKgIMKgIMKgIMKgIMKgIMKgKnRhcmdldF9tb2RlID0gZXhj cF9tb2RlOzxicj4NCisgwqAgwqAgwqAgwqAgwqAgwqAgwqAgwqB9IGVsc2Ugezxicj4NCisgwqAg wqAgwqAgwqAgwqAgwqAgwqAgwqAgwqAgwqB0YXJnZXRfZWwgPSAyOzxicj4NCisgwqAgwqAgwqAg wqAgwqAgwqAgwqAgwqAgwqAgwqAqdGFyZ2V0X21vZGUgPSBBUk1fQ1BVX01PREVfSFlQOzxicj4N CisgwqAgwqAgwqAgwqAgwqAgwqAgwqAgwqB9PGJyPg0KKyDCoCDCoCDCoCDCoCDCoCDCoH0gZWxz ZSB7PGJyPg0KKyDCoCDCoCDCoCDCoCDCoCDCoCDCoCDCoC8qIElSUXxGSVF8RUEgPT0gMDxicj4N CisgwqAgwqAgwqAgwqAgwqAgwqAgwqAgwqAgKiBJTU98Rk1PfEFNTyA9PSAwPGJyPg0KKyDCoCDC oCDCoCDCoCDCoCDCoCDCoCDCoCAqLzxicj4NCisgwqAgwqAgwqAgwqAgwqAgwqAgwqAgwqBpZiAo Y3VyX2VsICZsdDsgMikgezxicj4NCisgwqAgwqAgwqAgwqAgwqAgwqAgwqAgwqAgwqAgwqB0YXJn ZXRfZWwgPSAxOzxicj4NCisgwqAgwqAgwqAgwqAgwqAgwqAgwqAgwqAgwqAgwqAqdGFyZ2V0X21v ZGUgPSBleGNwX21vZGU7PGJyPg0KKyDCoCDCoCDCoCDCoCDCoCDCoCDCoCDCoH0gZWxzZSBpZiAo Y3VyX2VsID09IDIpIHs8YnI+DQorIMKgIMKgIMKgIMKgIMKgIMKgIMKgIMKgIMKgIMKgdGFyZ2V0 X2VsID0gMjs8YnI+DQorIMKgIMKgIMKgIMKgIMKgIMKgIMKgIMKgIMKgIMKgKnRhcmdldF9tb2Rl ID0gQVJNX0NQVV9NT0RFX0hZUDs8YnI+DQorIMKgIMKgIMKgIMKgIMKgIMKgIMKgIMKgfSBlbHNl IGlmIChzZWN1cmUpIHs8YnI+DQorIMKgIMKgIMKgIMKgIMKgIMKgIMKgIMKgIMKgIMKgdGFyZ2V0 X2VsID0gMzs8YnI+DQorIMKgIMKgIMKgIMKgIMKgIMKgIMKgIMKgIMKgIMKgKnRhcmdldF9tb2Rl ID0gZXhjcF9tb2RlOzxicj4NCisgwqAgwqAgwqAgwqAgwqAgwqAgwqAgwqB9PGJyPg0KKyDCoCDC oCDCoCDCoCDCoCDCoH08YnI+DQorIMKgIMKgIMKgIMKgfTxicj4NCisgwqAgwqB9PGJyPg0KKyDC oCDCoHJldHVybiB0YXJnZXRfZWw7PGJyPg0KK308YnI+DQorPGJyPg0KKy8qPGJyPg0KwqAgKiBE ZXRlcm1pbmUgdGhlIHRhcmdldCBFTCBmb3IgYSBnaXZlbiBleGNlcHRpb24gdHlwZS48YnI+DQrC oCAqLzxicj4NCsKgdW5zaWduZWQgaW50IGFybV9leGNwX3RhcmdldF9lbChDUFVTdGF0ZSAqY3Ms IHVuc2lnbmVkIGludCBleGNwX2lkeCk8YnI+DQo8c3Bhbj48Zm9udCBjb2xvcj0iIzg4ODg4OCI+ LS08YnI+DQoxLjguMy4yPGJyPg0KPGJyPg0KPC9mb250Pjwvc3Bhbj48L2Jsb2NrcXVvdGU+PC9k aXY+PGJyPjwvZGl2PjwvZGl2Pg0K --047d7bdc82c2fed4e204fbaaa01a--