LyoKICogUGFydCBvZiB0aGlzIGNvZGUgaGFzIGJlZW4gZGVyaXZlZCBmcm9tIGxpbnV4OgogKiBVbml2ZXJzYWwgSG9zdCBDb250cm9sbGVyIEludGVyZmFjZSBkcml2ZXIgZm9yIFVTQiAodGFrZSBJSSkuCiAqCiAqIChjKSAxOTk5LTIwMDEgR2VvcmcgQWNoZXIsIGFjaGVyQGluLnR1bS5kZSAoZXhlY3V0aXZlIHNsYXZlKSAoYmFzZSBndWl0YXIpCiAqICAgICAgICAgICAgICAgRGV0aSBGbGllZ2wsIGRldGlAZmxpZWdsLmRlIChleGVjdXRpdmUgc2xhdmUpIChsZWFkIHZvaWNlKQogKiAgICAgICAgICAgICAgIFRob21hcyBTYWlsZXIsIHNhaWxlckBpZmUuZWUuZXRoei5jaCAoY2hpZWYgY29uc3VsdGFudCkgKGNoZWVyIGxlYWRlcikKICogICAgICAgICAgICAgICBSb21hbiBXZWlzc2dhZXJiZXIsIHdlaXNzZ0B2aWVubmEuYXQgKHZpcnQgcm9vdCBodWIpIChzdHVkaW8gcG9ydGVyKQogKiAoYykgMjAwMCAgICAgIFlnZ2RyYXNpbCBDb21wdXRpbmcsIEluYy4gKHBvcnQgb2YgbmV3IFBDSSBpbnRlcmZhY2Ugc3VwcG9ydAogKiAgICAgICAgICAgICAgIGZyb20gdXNiLW9oY2kuYyBieSBBZGFtIFJpY2h0ZXIsIGFkYW1AeWdnZHJhc2lsLmNvbSkuCiAqIChDKSAyMDAwICAgICAgRGF2aWQgQnJvd25lbGwsIGRhdmlkLWJAcGFjYmVsbC5uZXQgKHVzYi1vaGNpLmMpCiAqCiAqIEhXLWluaXRhbGl6YXRpb24gYmFzZWQgb24gbWF0ZXJpYWwgb2YKICoKICogKEMpIENvcHlyaWdodCAxOTk5IExpbnVzIFRvcnZhbGRzCiAqIChDKSBDb3B5cmlnaHQgMTk5OSBKb2hhbm5lcyBFcmRmZWx0CiAqIChDKSBDb3B5cmlnaHQgMTk5OSBSYW5keSBEdW5sYXAKICogKEMpIENvcHlyaWdodCAxOTk5IEdyZWdvcnkgUC4gU21pdGgKICoKICoKICogQWRhcHRlZCBmb3IgVS1Cb290OgogKiAoQykgQ29weXJpZ2h0IDIwMDEgRGVuaXMgUGV0ZXIsIE1QTCBBRyBTd2l0emVybGFuZAogKiAoQykgQ29weXJpZ2h0IDIwMDgsIERhbmllbCBIZWxsc3Ry9m0sIGRhbmllbEBnYWlzbGVyLmNvbQogKiAgICAgQWRkZWQgQU1CQSBQbHVnJlBsYXkgZGV0ZWN0aW9uIG9mIEdSVVNCLCBtb2RpZmllZCBpbnRlcnJ1cHQgaGFuZGxlci4KICogICAgIEFkZGVkIGNhY2hlIGZsdXNoZXMgd2hlcmUgbmVlZGVkLgogKgogKiBTZWUgZmlsZSBDUkVESVRTIGZvciBsaXN0IG9mIHBlb3BsZSB3aG8gY29udHJpYnV0ZWQgdG8gdGhpcwogKiBwcm9qZWN0LgogKgogKiBUaGlzIHByb2dyYW0gaXMgZnJlZSBzb2Z0d2FyZTsgeW91IGNhbiByZWRpc3RyaWJ1dGUgaXQgYW5kL29yCiAqIG1vZGlmeSBpdCB1bmRlciB0aGUgdGVybXMgb2YgdGhlIEdOVSBHZW5lcmFsIFB1YmxpYyBMaWNlbnNlIGFzCiAqIHB1Ymxpc2hlZCBieSB0aGUgRnJlZSBTb2Z0d2FyZSBGb3VuZGF0aW9uOyBlaXRoZXIgdmVyc2lvbiAyIG9mCiAqIHRoZSBMaWNlbnNlLCBvciAoYXQgeW91ciBvcHRpb24pIGFueSBsYXRlciB2ZXJzaW9uLgogKgogKiBUaGlzIHByb2dyYW0gaXMgZGlzdHJpYnV0ZWQgaW4gdGhlIGhvcGUgdGhhdCBpdCB3aWxsIGJlIHVzZWZ1bCwKICogYnV0IFdJVEhPVVQgQU5ZIFdBUlJBTlRZOyB3aXRob3V0IGV2ZW4gdGhlIGltcGxpZWQgd2FycmFudHkgb2YKICogTUVSQ0hBTlRBQklMSVRZIG9yIEZJVE5FU1MgRk9SIEEgUEFSVElDVUxBUiBQVVJQT1NFLiAgU2VlIHRoZQogKiBHTlUgR2VuZXJhbCBQdWJsaWMgTGljZW5zZSBmb3IgbW9yZSBkZXRhaWxzLgogKgogKiBZb3Ugc2hvdWxkIGhhdmUgcmVjZWl2ZWQgYSBjb3B5IG9mIHRoZSBHTlUgR2VuZXJhbCBQdWJsaWMgTGljZW5zZQogKiBhbG9uZyB3aXRoIHRoaXMgcHJvZ3JhbTsgaWYgbm90LCB3cml0ZSB0byB0aGUgRnJlZSBTb2Z0d2FyZQogKiBGb3VuZGF0aW9uLCBJbmMuLCA1OSBUZW1wbGUgUGxhY2UsIFN1aXRlIDMzMCwgQm9zdG9uLAogKiBNQSAwMjExMS0xMzA3IFVTQQogKgogKgogKi8KCi8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqCiAqIEhvdyBpdCB3b3JrczoKICogLS0tLS0tLS0tLS0tLQogKiBUaGUgZnJhbWVsaXN0IC8gVHJhbnNmZXIgZGVzY3JpcHRvciAvIFF1ZXVlIEhlYWRzIGFyZSBzaW1pbGFyIGxpa2UKICogaW4gdGhlIGxpbnV4IHVzYl91aGNpLmMuCiAqCiAqIER1cmluZyBpbml0aWFsaXphdGlvbiwgdGhlIGZvbGxvd2luZyBza2VsZXRvbiBpcyBhbGxvY2F0ZWQgaW4gaW5pdF9za2VsOgogKgogKiAgICAgICAgIGZyYW1lc3BlY2lmaWMgICAgICAgICAgIHwgICAgICAgICAgIGNvbW1vbiBjaGFpbgogKgogKiBmcmFtZWxpc3RbXQogKiBbICAwIF0tLS0tLT4gVEQgLS0tLS0tLS0tXAogKiBbICAxIF0tLS0tLT4gVEQgLS0tLS0tLS0tLT4gVEQgLS0tLS0tPiBRSCAtLS0tLS0tPiBRSCAtLS0tLS0tPiBRSCAtLS0+IE5VTEwKICogICAuLi4gICAgICAgIFREIC0tLS0tLS0tLS8KICogWzEwMjNdLS0tLS0+IFREIC0tLS0tLS0tLwogKgogKiAgICAgICAgICAgICAgXl4gICAgICAgICAgICAgXl4gICAgICAgICBeXiAgICAgICAgICBeXiAgICAgICAgICBeXgogKiAgICAgICAgICAgICAgNyBURHMgZm9yICAgICAgMSBURCBmb3IgICBTdGFydCBvZiAgICBTdGFydCBvZiAgICBFbmQgQ2hhaW4KICogICAgICAgICAgICAgIElOVCAoMi0xMjhtcykgIDFtcy1JTlQgICAgQ1RSTCBDaGFpbiAgQlVMSyBDaGFpbgogKgogKgogKiBTaW5jZSB0aGlzIGlzIGEgYm9vdGxvYWRlciwgdGhlIGlzb2Nocm9ub3VzIHRyYW5zZmVyIGRlc2NyaXB0b3IgaGF2ZSBiZWVuIHJlbW92ZWQuCiAqCiAqIEludGVycnVwdCBUcmFuc2ZlcnMuCiAqIC0tLS0tLS0tLS0tLS0tLS0tLS0tCiAqIEZvciBJbnRlcnVwdCB0cmFuc2ZlcnMgVVNCX01BWF9URU1QX0lOVF9URCBUcmFuc2ZlciBkZXNjcmlwdG9yIGFyZSBhdmFpbGFibGUuIFRoZXkKICogd2lsbCBiZSBpbnNlcnRlZCBhZnRlciB0aGUgYXBwcm9wcmlhdGUgKGRlcGVuZGluZyB0aGUgaW50ZXJ2YWwgc2V0dGluZykgc2tlbGV0b24gVEQuCiAqIElmIGFuIGludGVycnVwdCBoYXMgYmVlbiBkZXRlY3RlZCB0aGUgZGV2LT5pcnFoYW5kbGVyIGlzIGNhbGxlZC4gVGhlIHN0YXR1cyBhbmQgbnVtYmVyCiAqIG9mIHRyYW5zZmVyZWQgYnl0ZXMgaXMgc3RvcmVkIGluIGRldi0+aXJxX3N0YXR1cyByZXNwLiBkZXYtPmlycV9hY3RfbGVuLiBJZiB0aGUKICogZGV2LT5pcnFoYW5kbGVyIHJldHVybnMgMCwgdGhlIGludGVycnVwdCBURCBpcyByZW1vdmVkIGFuZCBkaXNhYmxlZC4gSWYgYW4gMSBpcyByZXR1cm5lZCwKICogdGhlIGludGVycnVwdCBURCB3aWxsIGJlIHJlYWN0aXZhdGVkLgogKgogKiBDb250cm9sIFRyYW5zZmVycwogKiAtLS0tLS0tLS0tLS0tLS0tLQogKiBDb250cm9sIFRyYW5zZmVycyBhcmUgaXNzdWVkIGJ5IGZpbGxpbmcgdGhlIHRtcF90ZCB3aXRoIHRoZSBhcHByb3ByaWF0ZSBkYXRhIGFuZCBjb25uZWN0CiAqIHRoZW0gdG8gdGhlIHFoX2NudHJsIHF1ZXVlIGhlYWRlci4gQmVmb3JlIG90aGVyIGNvbnRyb2wvYnVsayB0cmFuc2ZlcnMgY2FuIGJlIGlzc3VlZCwKICogdGhlIHByb2dyYW1tIGhhcyB0byB3YWl0IGZvciBjb21wbGV0aW9uLiBUaGlzIGRvZXMgbm90IGFsbG93cyBhc3luY2hyb25vdXMgZGF0YSB0cmFuc2Zlci4KICoKICogQnVsayBUcmFuc2ZlcnMKICogLS0tLS0tLS0tLS0tLS0KICogQnVsayBUcmFuc2ZlcnMgYXJlIGlzc3VlZCBieSBmaWxsaW5nIHRoZSB0bXBfdGQgd2l0aCB0aGUgYXBwcm9wcmlhdGUgZGF0YSBhbmQgY29ubmVjdAogKiB0aGVtIHRvIHRoZSBxaF9idWxrIHF1ZXVlIGhlYWRlci4gQmVmb3JlIG90aGVyIGNvbnRyb2wvYnVsayB0cmFuc2ZlcnMgY2FuIGJlIGlzc3VlZCwKICogdGhlIHByb2dyYW1tIGhhcyB0byB3YWl0IGZvciBjb21wbGV0aW9uLiBUaGlzIGRvZXMgbm90IGFsbG93cyBhc3luY2hyb25vdXMgZGF0YSB0cmFuc2Zlci4KICoKICoKICovCgojaW5jbHVkZSA8Y29tbW9uLmg+CiNpbmNsdWRlIDxhbWJhcHAuaD4KI2luY2x1ZGUgPGFzbS9sZW9uLmg+CiNpbmNsdWRlIDxhc20vbGVvbjMuaD4KI2luY2x1ZGUgPGFzbS9wcm9jZXNzb3IuaD4KCiNpZmRlZiBDT05GSUdfVVNCX1VIQ0kKCiNpbmNsdWRlIDx1c2IuaD4KI2luY2x1ZGUgInVzYl91aGNpLmgiCgojZGVmaW5lIFVTQl9NQVhfVEVNUF9URCAgICAgIDEyOAkvKiBudW1iZXIgb2YgdGVtcG9yYXJ5IFREcyBmb3IgYnVsayBhbmQgY29udHJvbCB0cmFuc2ZlcnMgKi8KI2RlZmluZSBVU0JfTUFYX1RFTVBfSU5UX1REICAzMgkvKiBudW1iZXIgb2YgdGVtcG9yYXJ5IFREcyBmb3IgSW50ZXJydXB0IHRyYW5zZmVycyAqLwoKZXh0ZXJuIGludCBsZW9uM19zbm9vcGluZ19hdmFpbDsKLyoKI2RlZmluZSBvdXQxNnIoYWRkcmVzcyxkYXRhKSAoKih1bnNpZ25lZCBzaG9ydCAqKShhZGRyZXNzKSA9IFwKICh1bnNpZ25lZCBzaG9ydCkoIFwKICgoKHVuc2lnbmVkIHNob3J0KShkYXRhKSYweGZmKTw8OCkgfCBcCiAoKCh1bnNpZ25lZCBzaG9ydCkoZGF0YSkmMHhmZjAwKT4+OCkgXAogKSkKICovCiNkZWZpbmUgb3V0MTZyKGFkZHJlc3MsZGF0YSkgX291dDE2cigodW5zaWduZWQgaW50KShhZGRyZXNzKSwgKHVuc2lnbmVkIHNob3J0KShkYXRhKSkKdm9pZCBfb3V0MTZyKHVuc2lnbmVkIGludCBhZGRyZXNzLCB1bnNpZ25lZCBzaG9ydCBkYXRhKQp7Cgl1bnNpZ25lZCBzaG9ydCB2YWwgPSAodW5zaWduZWQgc2hvcnQpKCgoKHVuc2lnbmVkIHNob3J0KShkYXRhKSAmIDB4ZmYpCgkJCQkJICAgICAgIDw8IDgpIHwgKCgodW5zaWduZWQgc2hvcnQpKGRhdGEpCgkJCQkJCQkgJiAweGZmMDApID4+IDgpKTsKI2lmZGVmIFVIQ0lfREVCVUdfUkVHUwoJcHJpbnRmKCJvdXQxNnIoMHglbHgsMHglMDR4ID0gMHglMDR4KVxuIiwgYWRkcmVzcywgdmFsLCBkYXRhKTsKI2VuZGlmCgkqKHVuc2lnbmVkIHNob3J0ICopKGFkZHJlc3MpID0gdmFsOwp9CgojZGVmaW5lIG91dDMycihhZGRyZXNzLGRhdGEpIF9vdXQzMnIoKHVuc2lnbmVkIGludCkoYWRkcmVzcyksICh1bnNpZ25lZCBpbnQpKGRhdGEpKQp2b2lkIF9vdXQzMnIodW5zaWduZWQgaW50IGFkZHJlc3MsIHVuc2lnbmVkIGludCBkYXRhKQp7Cgl1bnNpZ25lZCBpbnQgdmFsID0gKHVuc2lnbmVkIGludCkoKCgodW5zaWduZWQgaW50KShkYXRhKSAmIDB4MDAwMDAwZmYpCgkJCQkJICAgPDwgMjQpIHwgKCgodW5zaWduZWQgaW50KShkYXRhKSAmCgkJCQkJCSAgICAgIDB4MDAwMGZmMDApIDw8IDgpIHwKCQkJCQkgICgoKHVuc2lnbmVkIGludCkoZGF0YSkgJiAweDAwZmYwMDAwKQoJCQkJCSAgID4+IDgpIHwgKCgodW5zaWduZWQgaW50KShkYXRhKSAmCgkJCQkJCSAgICAgMHhmZjAwMDAwMCkgPj4gMjQpKTsKI2lmZGVmIFVIQ0lfREVCVUdfUkVHUwoJcHJpbnRmKCJvdXQzMnIoMHglbHgsMHglbHggPSAweCVseClcbiIsIGFkZHJlc3MsIHZhbCwgZGF0YSk7CiNlbmRpZgoJKih1bnNpZ25lZCBpbnQgKilhZGRyZXNzID0gdmFsOwp9CgojZGVmaW5lIGluMTZyKGFkZHJlc3MpIF9pbjE2cigodW5zaWduZWQgaW50KShhZGRyZXNzKSkKdW5zaWduZWQgc2hvcnQgX2luMTZyKHVuc2lnbmVkIGludCBhZGRyZXNzKQp7Cgl1bnNpZ25lZCBzaG9ydCB2YWwgPSBzcGFyY19sb2FkX3JlZ19jYWNoZW1pc3Nfd29yZChhZGRyZXNzKTsKCXZhbCA9ICgodmFsIDw8IDgpICYgMHhmZjAwKSB8ICgodmFsID4+IDgpICYgMHhmZik7CiNpZmRlZiBVSENJX0RFQlVHX1JFR1MKCXByaW50ZigiaW4xNnIoMHglbHgpOiAweCUwNHhcbiIsIGFkZHJlc3MsIHZhbCk7CiNlbmRpZgoJcmV0dXJuIHZhbDsKfQoKI2RlZmluZSBpbjMycihhZGRyZXNzKSBfaW4zMnIoKHVuc2lnbmVkIGludCkoYWRkcmVzcykpCnVuc2lnbmVkIGludCBfaW4zMnIodW5zaWduZWQgaW50IGFkZHJlc3MpCnsKCXVuc2lnbmVkIGludCB2YWwgPSBzcGFyY19sb2FkX3JlZ19jYWNoZW1pc3MoYWRkcmVzcyk7Cgl2YWwgPQoJICAgICgodmFsIDw8IDI0KSAmIDB4ZmYwMDAwMDApIHwgKCh2YWwgPDwgOCkgJiAweGZmMDAwMCkgfCAoKHZhbCA+PiA4KSAmCgkJCQkJCQkJICAgIDB4ZmYwMCkgfAoJICAgICgodmFsID4+IDI0KSAmIDB4ZmYpOwojaWZkZWYgVUhDSV9ERUJVR19SRUdTCglwcmludGYoImluMzJyKDB4JWx4KTogMHglMDh4XG4iLCBhZGRyZXNzLCB2YWwpOwojZW5kaWYKCXJldHVybiB2YWw7Cn0KCiNkZWZpbmUgUkVBRDMyKGFkZHJlc3MpIHNwYXJjX2xvYWRfcmVnX2NhY2hlbWlzcygodW5zaWduZWQgaW50KShhZGRyZXNzKSkKCi8qI2RlZmluZSBVU0JfVUhDSV9ERUJVRyovCiN1bmRlZiBVU0JfVUhDSV9ERUJVRwoKdm9pZCB1c2Jfc2hvd190ZChpbnQgbWF4KTsKI2lmZGVmCVVTQl9VSENJX0RFQlVHCnZvaWQgZ3J1c2Jfc2hvd19yZWdzKHZvaWQpOwojZGVmaW5lCVVTQl9VSENJX1BSSU5URihmbXQsYXJncy4uLikJcHJpbnRmIChmbXQgLCMjYXJncykKI2Vsc2UKI2RlZmluZSBVU0JfVUhDSV9QUklOVEYoZm10LGFyZ3MuLi4pCiNlbmRpZgoKc3RhdGljIGludCBncnVzYl9pcnEgPSAtMTsJLyogaXJxIHZlY3RvciwgaWYgLTEgdWhjaSBpcyBzdG9wcGVkIC8gcmVzZXRlZCAqLwp1bnNpZ25lZCBpbnQgdXNiX2Jhc2VfYWRkcjsJLyogYmFzZSBhZGRyZXNzICovCgpzdGF0aWMgdWhjaV90ZF90IHRkX2ludFs4XSBfX2F0dHJpYnV0ZV9fICgoYWxpZ25lZCgxNikpKTsJLyogSW50ZXJydXB0IFRyYW5zZmVyIGRlc2NyaXB0b3JzICovCnN0YXRpYyB1aGNpX3FoX3QgcWhfY250cmwgX19hdHRyaWJ1dGVfXyAoKGFsaWduZWQoMTYpKSk7CS8qIGNvbnRyb2wgUXVldWUgSGVhZCAqLwpzdGF0aWMgdWhjaV9xaF90IHFoX2J1bGsgX19hdHRyaWJ1dGVfXyAoKGFsaWduZWQoMTYpKSk7CS8qICBidWxrIFF1ZXVlIEhlYWQgKi8Kc3RhdGljIHVoY2lfcWhfdCBxaF9lbmQgX19hdHRyaWJ1dGVfXyAoKGFsaWduZWQoMTYpKSk7CS8qIGVuZCBRdWV1ZSBIZWFkICovCnN0YXRpYyB1aGNpX3RkX3QgdGRfbGFzdCBfX2F0dHJpYnV0ZV9fICgoYWxpZ25lZCgxNikpKTsJLyogbGFzdCBURCAobGlua2VkIHdpdGggZW5kIGNoYWluKSAqLwoKLyogdGVtcG9yYXJ5IHRkcyAqLwpzdGF0aWMgdWhjaV90ZF90IHRtcF90ZFtVU0JfTUFYX1RFTVBfVERdIF9fYXR0cmlidXRlX18gKChhbGlnbmVkKDE2KSkpOwkvKiB0ZW1wb3JhcnkgYnVsay9jb250cm9sIHRkJ3MgICovCnN0YXRpYyB1aGNpX3RkX3QgdG1wX2ludF90ZFtVU0JfTUFYX1RFTVBfSU5UX1REXSBfX2F0dHJpYnV0ZV9fICgoYWxpZ25lZCgxNikpKTsJLyogdGVtcG9yYXJ5IGludGVycnVwdCB0ZCdzICAqLwoKc3RhdGljIHVuc2lnbmVkIGxvbmcgZnJhbWVsaXN0WzEwMjRdIF9fYXR0cmlidXRlX18gKChhbGlnbmVkKDB4MTAwMCkpKTsJLyogZnJhbWUgbGlzdCAqLwoKc3RhdGljIHN0cnVjdCB2aXJ0X3Jvb3RfaHViIHJoOwkvKiBzdHJ1Y3QgZm9yIHJvb3QgaHViICovCgovKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKgogKiBzb21lIGZvcndhcmQgZGVjbGVyYXRpb24KICovCmludCB1aGNpX3N1Ym1pdF9yaF9tc2coc3RydWN0IHVzYl9kZXZpY2UgKmRldiwgdW5zaWduZWQgbG9uZyBwaXBlLAoJCSAgICAgICB2b2lkICpidWZmZXIsIGludCB0cmFuc2Zlcl9sZW4sCgkJICAgICAgIHN0cnVjdCBkZXZyZXF1ZXN0ICpzZXR1cCk7CgovKiBmaWxsIGEgdGQgd2l0aCB0aGUgYXBwcm9wcm9pYXRlIGRhdGEuIExpbmssIHN0YXR1cywgaW5mbyBhbmQgYnVmZmVyCiAqIGFyZSB1c2VkIGJ5IHRoZSBVU0IgY29udHJvbGxlciBpdHNlbGZlcywgZGV2IGlzIHVzZWQgdG8gaWRlbnRpZnkgdGhlCiAqICJjb25uZWN0ZWQiIGRldmljZQogKi8Kdm9pZCB1c2JfZmlsbF90ZCh1aGNpX3RkX3QgKiB0ZCwgdW5zaWduZWQgbG9uZyBsaW5rLCB1bnNpZ25lZCBsb25nIHN0YXR1cywKCQkgdW5zaWduZWQgbG9uZyBpbmZvLCB1bnNpZ25lZCBsb25nIGJ1ZmZlciwgdW5zaWduZWQgbG9uZyBkZXYpCnsKCXRkLT5saW5rID0gc3dhcF8zMihsaW5rKTsKCXRkLT5zdGF0dXMgPSBzd2FwXzMyKHN0YXR1cyk7CglpZiAoKGluZm8gJiBVSENJX1BJRCkgPT0gMCkKCQlpbmZvIHw9IFVTQl9QSURfT1VUOwoJdGQtPmluZm8gPSBzd2FwXzMyKGluZm8pOwoJdGQtPmJ1ZmZlciA9IHN3YXBfMzIoYnVmZmVyKTsKCXRkLT5kZXZfcHRyID0gZGV2Owp9CgovKiBmaWxsIGEgcWggd2l0aCB0aGUgYXBwcm9wcm9pYXRlIGRhdGEuIEhlYWQgYW5kIGVsZW1lbnQgYXJlIHVzZWQgYnkgdGhlIFVTQiBjb250cm9sbGVyCiAqIGl0c2VsZmVzLiBBcyBzb29uIGFzIGEgdmFsaWQgZGV2X3B0ciBpcyBmaWxsZWQsIGEgdGQgY2hhaW4gaXMgY29ubmVjdGVkIHRvIHRoZSBxaC4KICogUGxlYXNlIG5vdGUsIHRoYXQgYWZ0ZXIgY29tcGxldGlvbiBvZiB0aGUgdGQgY2hhaW4sIHRoZSBlbnRyeSBlbGVtZW50IGlzIHJlbW92ZWQgLwogKiBtYXJrZWQgaW52YWxpZCBieSB0aGUgVVNCIGNvbnRyb2xsZXIuCiAqLwp2b2lkIHVzYl9maWxsX3FoKHVoY2lfcWhfdCAqIHFoLCB1bnNpZ25lZCBsb25nIGhlYWQsIHVuc2lnbmVkIGxvbmcgZWxlbWVudCkKewoJcWgtPmhlYWQgPSBzd2FwXzMyKGhlYWQpOwoJcWgtPmVsZW1lbnQgPSBzd2FwXzMyKGVsZW1lbnQpOwoJcWgtPmRldl9wdHIgPSAwTDsKfQoKLyogZ2V0IHRoZSBzdGF0dXMgb2YgYSB0ZC0+c3RhdHVzCiAqLwp1bnNpZ25lZCBsb25nIHVzYl91aGNpX3RkX3N0YXQodW5zaWduZWQgbG9uZyBzdGF0dXMpCnsKCXVuc2lnbmVkIGxvbmcgcmVzdWx0ID0gMDsKCXJlc3VsdCB8PSAoc3RhdHVzICYgVERfQ1RSTF9OQUspID8gVVNCX1NUX05BS19SRUMgOiAwOwoJcmVzdWx0IHw9IChzdGF0dXMgJiBURF9DVFJMX1NUQUxMRUQpID8gVVNCX1NUX1NUQUxMRUQgOiAwOwoJcmVzdWx0IHw9IChzdGF0dXMgJiBURF9DVFJMX0RCVUZFUlIpID8gVVNCX1NUX0JVRl9FUlIgOiAwOwoJcmVzdWx0IHw9IChzdGF0dXMgJiBURF9DVFJMX0JBQkJMRSkgPyBVU0JfU1RfQkFCQkxFX0RFVCA6IDA7CglyZXN1bHQgfD0gKHN0YXR1cyAmIFREX0NUUkxfQ1JDVElNRU8pID8gVVNCX1NUX0NSQ19FUlIgOiAwOwoJcmVzdWx0IHw9IChzdGF0dXMgJiBURF9DVFJMX0JJVFNUVUZGKSA/IFVTQl9TVF9CSVRfRVJSIDogMDsKCXJlc3VsdCB8PSAoc3RhdHVzICYgVERfQ1RSTF9BQ1RJVkUpID8gVVNCX1NUX05PVF9QUk9DIDogMDsKCXJldHVybiByZXN1bHQ7Cn0KCi8qIGdldCB0aGUgc3RhdHVzIGFuZCB0aGUgdHJhbnNmZXJlZCBsZW4gb2YgYSB0ZCBjaGFpbi4KICogY2FsbGVkIGZyb20gdGhlIGNvbXBsZXRpb24gaGFuZGxlcgogKi8KaW50IHVzYl9nZXRfdGRfc3RhdHVzKHVoY2lfdGRfdCAqIHRkLCBzdHJ1Y3QgdXNiX2RldmljZSAqZGV2KQp7Cgl1bnNpZ25lZCBsb25nIHRlbXAsIGluZm87Cgl1bnNpZ25lZCBsb25nIHN0YXQ7Cgl1aGNpX3RkX3QgKm15dGQgPSB0ZDsKCglpZiAoZGV2LT5kZXZudW0gPT0gcmguZGV2bnVtKQoJCXJldHVybiAwOwoJZGV2LT5hY3RfbGVuID0gMDsKCXN0YXQgPSAwOwoJZG8gewoJCXRlbXAgPSBzd2FwXzMyKCh1bnNpZ25lZCBsb25nKVJFQUQzMigmbXl0ZC0+c3RhdHVzKSk7CgkJc3RhdCA9IHVzYl91aGNpX3RkX3N0YXQodGVtcCk7CgkJaW5mbyA9IHN3YXBfMzIoKHVuc2lnbmVkIGxvbmcpUkVBRDMyKCZteXRkLT5pbmZvKSk7CgkJaWYgKCgoaW5mbyAmIDB4ZmYpICE9IFVTQl9QSURfU0VUVVApICYmICgoKGluZm8gPj4gMjEpICYgMHg3ZmYpICE9IDB4N2ZmKSAmJiAodGVtcCAmIDB4N0ZGKSAhPSAweDdmZikgewkvKiBpZiBub3Qgc2V0dXAgYW5kIG5vdCBudWxsIGRhdGEgcGFjayAqLwoJCQlkZXYtPmFjdF9sZW4gKz0gKHRlbXAgJiAweDdGRikgKyAxOwkvKiB0aGUgdHJhbnNmZXJlZCBsZW4gaXMgYWN0X2xlbiArIDEgKi8KCQl9CgkJaWYgKHN0YXQpIHsJLyogc3RhdHVzIG5vIG9rICovCgkJCWRldi0+c3RhdHVzID0gc3RhdDsKCQkJcmV0dXJuIC0xOwoJCX0KCQl0ZW1wID0gc3dhcF8zMigodW5zaWduZWQgbG9uZylSRUFEMzIoJm15dGQtPmxpbmspKTsKCQlteXRkID0gKHVoY2lfdGRfdCAqKSAodGVtcCAmIDB4ZmZmZmZmZjApOwoJfSB3aGlsZSAoKHRlbXAgJiAweDEpID09IDApOwkvKiBwcm9jZXNzIGFsbCBURHMgKi8KCWRldi0+c3RhdHVzID0gc3RhdDsKCXJldHVybiAwOwkJLyogT2sgKi8KfQoKLyotLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tCiAqICAgICAgICAgICAgICAgICAgICAgICAgIExPVyBMRVZFTCBTVFVGRgogKiAgICAgICAgICBhc3NlbWJsZXMgUUhzIHVuZCBURHMgZm9yIGNvbnRyb2wsIGJ1bGsgYW5kIGlzbwogKi0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0qLwppbnQgZHVtbXkodm9pZCkKewoJVVNCX1VIQ0lfUFJJTlRGKCJEVU1NWVxuIik7CglyZXR1cm4gMDsKfQoKLyogU3VibWl0cyBhIGNvbnRyb2wgbWVzc2FnZS4gVGhhdCBpcyBhIFNldHVwLCBEYXRhIGFuZCBTdGF0dXMgdHJhbnNmZXIuCiAqIFJvdXRpbmUgZG9lcyBub3Qgd2FpdCBmb3IgY29tcGxldGlvbi4KICovCmludCBzdWJtaXRfY29udHJvbF9tc2coc3RydWN0IHVzYl9kZXZpY2UgKmRldiwgdW5zaWduZWQgbG9uZyBwaXBlLCB2b2lkICpidWZmZXIsCgkJICAgICAgIGludCB0cmFuc2Zlcl9sZW4sIHN0cnVjdCBkZXZyZXF1ZXN0ICpzZXR1cCkKewoJdW5zaWduZWQgbG9uZyBkZXN0aW5hdGlvbiwgc3RhdHVzOwoJaW50IG1heHN6ZSA9IHVzYl9tYXhwYWNrZXQoZGV2LCBwaXBlKTsKCXVuc2lnbmVkIGxvbmcgZGF0YXB0cjsKCWludCBsZW47CglpbnQgcGt0c3plOwoJaW50IGkgPSAwOwoKCWlmICghbWF4c3plKSB7CgkJVVNCX1VIQ0lfUFJJTlRGCgkJICAgICgidWhjaV9zdWJtaXRfY29udHJvbF91cmI6IHBpcGVzaXplIGZvciBwaXBlICVseCBpcyB6ZXJvXG4iLAoJCSAgICAgcGlwZSk7CgkJcmV0dXJuIC0xOwoJfQoJaWYgKCgocGlwZSA+PiA4KSAmIDB4N2YpID09IHJoLmRldm51bSkgewoJCS8qIHRoaXMgaXMgdGhlIHJvb3QgaHViIC0+IHJlZGlyZWN0IGl0ICovCgkJcmV0dXJuIHVoY2lfc3VibWl0X3JoX21zZyhkZXYsIHBpcGUsIGJ1ZmZlciwgdHJhbnNmZXJfbGVuLAoJCQkJCSAgc2V0dXApOwoJfQoJVVNCX1VIQ0lfUFJJTlRGKCJ1aGNpX3N1Ym1pdF9jb250cm9sIHN0YXJ0IGxlbiAleCwgbWF4c2l6ZSAleFxuIiwKCQkJdHJhbnNmZXJfbGVuLCBtYXhzemUpOwoJLyogVGhlICJwaXBlIiB0aGluZyBjb250YWlucyB0aGUgZGVzdGluYXRpb24gaW4gYml0cyA4LS0xOCAqLwoJZGVzdGluYXRpb24gPSAocGlwZSAmIFBJUEVfREVWRVBfTUFTSykgfCBVU0JfUElEX1NFVFVQOwkvKiBTZXR1cCBzdGFnZSAqLwoJLyogMyBlcnJvcnMgKi8KCXN0YXR1cyA9IChwaXBlICYgVERfQ1RSTF9MUykgfCBURF9DVFJMX0FDVElWRSB8ICgzIDw8IDI3KTsKCS8qICh1cmItPnRyYW5zZmVyX2ZsYWdzICYgVVNCX0RJU0FCTEVfU1BEID8gMCA6IFREX0NUUkxfU1BEKTsgKi8KCS8qICBCdWlsZCB0aGUgVEQgZm9yIHRoZSBjb250cm9sIHJlcXVlc3QsIHRyeSBmb3JldmVyLCA4IGJ5dGVzIG9mIGRhdGEgKi8KCXVzYl9maWxsX3RkKCZ0bXBfdGRbaV0sIFVIQ0lfUFRSX1RFUk0sIHN0YXR1cywgZGVzdGluYXRpb24gfCAoNyA8PCAyMSksCgkJICAgICh1bnNpZ25lZCBsb25nKXNldHVwLCAodW5zaWduZWQgbG9uZylkZXYpOwojaWZkZWYgREVCVUdfRVhUUkEKCXsKCQljaGFyICpzcCA9IChjaGFyICopc2V0dXA7CgkJcHJpbnRmKCJTRVRVUCB0byBwaXBlICVseDogJXggJXggJXggJXggJXggJXggJXggJXhcbiIsIHBpcGUsCgkJICAgICAgIHNwWzBdLCBzcFsxXSwgc3BbMl0sIHNwWzNdLCBzcFs0XSwgc3BbNV0sIHNwWzZdLCBzcFs3XSk7Cgl9CiNlbmRpZgoJZGF0YXB0ciA9ICh1bnNpZ25lZCBsb25nKWJ1ZmZlcjsKCWxlbiA9IHRyYW5zZmVyX2xlbjsKCgkvKiBJZiBkaXJlY3Rpb24gaXMgInNlbmQiLCBjaGFuZ2UgdGhlIGZyYW1lIGZyb20gU0VUVVAgKDB4MkQpCgkgICB0byBPVVQgKDB4RTEpLiBFbHNlIGNoYW5nZSBpdCBmcm9tIFNFVFVQIHRvIElOICgweDY5KS4gKi8KCWRlc3RpbmF0aW9uID0KCSAgICAocGlwZSAmIFBJUEVfREVWRVBfTUFTSykgfCAoKHBpcGUgJiBVU0JfRElSX0lOKSA9PQoJCQkJCTAgPyBVU0JfUElEX09VVCA6IFVTQl9QSURfSU4pOwoJd2hpbGUgKGxlbiA+IDApIHsKCQkvKiBkYXRhIHN0YWdlICovCgkJcGt0c3plID0gbGVuOwoJCWkrKzsKCQlpZiAocGt0c3plID4gbWF4c3plKQoJCQlwa3RzemUgPSBtYXhzemU7CgkJZGVzdGluYXRpb24gXj0gMSA8PCBURF9UT0tFTl9UT0dHTEU7CS8qIHRvZ2dsZSBEQVRBMC8xICovCgkJdXNiX2ZpbGxfdGQoJnRtcF90ZFtpXSwgVUhDSV9QVFJfVEVSTSwgc3RhdHVzLCBkZXN0aW5hdGlvbiB8ICgocGt0c3plIC0gMSkgPDwgMjEpLCBkYXRhcHRyLCAodW5zaWduZWQgbG9uZylkZXYpOwkvKiBTdGF0dXMsIHBrdHN6ZSBieXRlcyBvZiBkYXRhICovCgkJdG1wX3RkW2kgLSAxXS5saW5rID0gc3dhcF8zMigodW5zaWduZWQgbG9uZykmdG1wX3RkW2ldKTsKCgkJZGF0YXB0ciArPSBwa3RzemU7CgkJbGVuIC09IHBrdHN6ZTsKCX0KCgkvKiAgQnVpbGQgdGhlIGZpbmFsIFREIGZvciBjb250cm9sIHN0YXR1cyAqLwoJLyogSXQncyBvbmx5IElOIGlmIHRoZSBwaXBlIGlzIG91dCBBTkQgd2UgYXJlbid0IGV4cGVjdGluZyBkYXRhICovCgoJZGVzdGluYXRpb24gJj0gflVIQ0lfUElEOwoJaWYgKCgocGlwZSAmIFVTQl9ESVJfSU4pID09IDApIHx8ICh0cmFuc2Zlcl9sZW4gPT0gMCkpCgkJZGVzdGluYXRpb24gfD0gVVNCX1BJRF9JTjsKCWVsc2UKCQlkZXN0aW5hdGlvbiB8PSBVU0JfUElEX09VVDsKCWRlc3RpbmF0aW9uIHw9IDEgPDwgVERfVE9LRU5fVE9HR0xFOwkvKiBFbmQgaW4gRGF0YTEgKi8KCWkrKzsKCXN0YXR1cyAmPSB+VERfQ1RSTF9TUEQ7CgkvKiBubyBsaW1pdCBvbiBlcnJvcnMgb24gZmluYWwgcGFja2V0ICwgMCBieXRlcyBvZiBkYXRhICovCgl1c2JfZmlsbF90ZCgmdG1wX3RkW2ldLCBVSENJX1BUUl9URVJNLCBzdGF0dXMgfCBURF9DVFJMX0lPQywKCQkgICAgZGVzdGluYXRpb24gfCAoVUhDSV9OVUxMX0RBVEFfU0laRSA8PCAyMSksIDAsCgkJICAgICh1bnNpZ25lZCBsb25nKWRldik7Cgl0bXBfdGRbaSAtIDFdLmxpbmsgPSBzd2FwXzMyKCh1bnNpZ25lZCBsb25nKSZ0bXBfdGRbaV0pOwkvKiBxdWV1ZSBzdGF0dXMgdGQgKi8KCS8qIHVzYl9zaG93X3RkKGkrMSk7ICovCglVU0JfVUhDSV9QUklOVEYoInVoY2lfc3VibWl0X2NvbnRyb2wgZW5kICglZCB0bXBfdGRzIHVzZWQpXG4iLCBpKTsKCS8qIGZpcnN0IG1hcmsgdGhlIGNvbnRyb2wgUUggZWxlbWVudCB0ZXJtaW5hdGVkICovCglxaF9jbnRybC5lbGVtZW50ID0gMHhmZmZmZmZmZkw7CgkvKiBzZXQgcWggYWN0aXZlICovCglxaF9jbnRybC5kZXZfcHRyID0gKHVuc2lnbmVkIGxvbmcpZGV2OwoJLyogZmlsbCBpbiB0bXBfdGRfY2hhaW4gKi8KCWR1bW15KCk7CglxaF9jbnRybC5lbGVtZW50ID0gc3dhcF8zMigodW5zaWduZWQgbG9uZykmdG1wX3RkWzBdKTsKCXJldHVybiAwOwp9CgovKi0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0KICogUHJlcGFyZSBURHMgZm9yIGJ1bGsgdHJhbnNmZXJzLgogKi8KaW50IHN1Ym1pdF9idWxrX21zZyhzdHJ1Y3QgdXNiX2RldmljZSAqZGV2LCB1bnNpZ25lZCBsb25nIHBpcGUsIHZvaWQgKmJ1ZmZlciwKCQkgICAgaW50IHRyYW5zZmVyX2xlbikKewoJdW5zaWduZWQgbG9uZyBkZXN0aW5hdGlvbiwgc3RhdHVzLCBpbmZvOwoJdW5zaWduZWQgbG9uZyBkYXRhcHRyOwoJaW50IG1heHN6ZSA9IHVzYl9tYXhwYWNrZXQoZGV2LCBwaXBlKTsKCWludCBsZW47CglpbnQgaSA9IDA7CgoJaWYgKHRyYW5zZmVyX2xlbiA8IDApIHsKCQlwcmludGYoIk5lZ2F0aXZlIHRyYW5zZmVyIGxlbmd0aCBpbiBzdWJtaXRfYnVsa1xuIik7CgkJcmV0dXJuIC0xOwoJfQoJaWYgKCFtYXhzemUpCgkJcmV0dXJuIC0xOwoJLyogVGhlICJwaXBlIiB0aGluZyBjb250YWlucyB0aGUgZGVzdGluYXRpb24gaW4gYml0cyA4LS0xOC4gKi8KCWRlc3RpbmF0aW9uID0gKHBpcGUgJiBQSVBFX0RFVkVQX01BU0spIHwgdXNiX3BhY2tldGlkKHBpcGUpOwoJLyogMyBlcnJvcnMgKi8KCXN0YXR1cyA9IChwaXBlICYgVERfQ1RSTF9MUykgfCBURF9DVFJMX0FDVElWRSB8ICgzIDw8IDI3KTsKCS8qICAgICAgKCh1cmItPnRyYW5zZmVyX2ZsYWdzICYgVVNCX0RJU0FCTEVfU1BEKSA/IDAgOiBURF9DVFJMX1NQRCkgfCAoMyA8PCAyNyk7ICovCgkvKiBCdWlsZCB0aGUgVERzIGZvciB0aGUgYnVsayByZXF1ZXN0ICovCglsZW4gPSB0cmFuc2Zlcl9sZW47CglkYXRhcHRyID0gKHVuc2lnbmVkIGxvbmcpYnVmZmVyOwoJZG8gewoJCWludCBwa3RzemUgPSBsZW47CgkJaWYgKHBrdHN6ZSA+IG1heHN6ZSkKCQkJcGt0c3plID0gbWF4c3plOwoJCS8qIHBrdHN6ZSBieXRlcyBvZiBkYXRhICAqLwoJCWluZm8gPQoJCSAgICBkZXN0aW5hdGlvbiB8ICgoKHBrdHN6ZSAtIDEpICYgVUhDSV9OVUxMX0RBVEFfU0laRSkgPDwgMjEpIHwKCQkgICAgKHVzYl9nZXR0b2dnbGUKCQkgICAgIChkZXYsIHVzYl9waXBlZW5kcG9pbnQocGlwZSksCgkJICAgICAgdXNiX3BpcGVvdXQocGlwZSkpIDw8IFREX1RPS0VOX1RPR0dMRSk7CgoJCWlmICgobGVuIC0gcGt0c3plKSA9PSAwKQoJCQlzdGF0dXMgfD0gVERfQ1RSTF9JT0M7CS8qIGxhc3Qgb25lIGdlbmVyYXRlcyBJTlQgKi8KCgkJdXNiX2ZpbGxfdGQoJnRtcF90ZFtpXSwgVUhDSV9QVFJfVEVSTSwgc3RhdHVzLCBpbmZvLCBkYXRhcHRyLCAodW5zaWduZWQgbG9uZylkZXYpOwkvKiBTdGF0dXMsIHBrdHN6ZSBieXRlcyBvZiBkYXRhICovCgkJaWYgKGkgPiAwKQoJCQl0bXBfdGRbaSAtIDFdLmxpbmsgPSBzd2FwXzMyKCh1bnNpZ25lZCBsb25nKSZ0bXBfdGRbaV0pOwoJCWkrKzsKCQlkYXRhcHRyICs9IHBrdHN6ZTsKCQlsZW4gLT0gcGt0c3plOwoJCXVzYl9kb3RvZ2dsZShkZXYsIHVzYl9waXBlZW5kcG9pbnQocGlwZSksIHVzYl9waXBlb3V0KHBpcGUpKTsKCX0gd2hpbGUgKGxlbiA+IDApOwoJLyogZmlyc3QgbWFyayB0aGUgYnVsayBRSCBlbGVtZW50IHRlcm1pbmF0ZWQgKi8KCXFoX2J1bGsuZWxlbWVudCA9IDB4ZmZmZmZmZmZMOwoJLyogc2V0IHFoIGFjdGl2ZSAqLwoJcWhfYnVsay5kZXZfcHRyID0gKHVuc2lnbmVkIGxvbmcpZGV2OwoJLyogZmlsbCBpbiB0bXBfdGRfY2hhaW4gKi8KCXFoX2J1bGsuZWxlbWVudCA9IHN3YXBfMzIoKHVuc2lnbmVkIGxvbmcpJnRtcF90ZFswXSk7CglyZXR1cm4gMDsKfQoKLyogc2VhcmNoIGEgZnJlZSBpbnRlcnJ1cHQgdGQKICovCnVoY2lfdGRfdCAqdWhjaV9hbGxvY19pbnRfdGQodm9pZCkKewoJaW50IGk7Cglmb3IgKGkgPSAwOyBpIDwgVVNCX01BWF9URU1QX0lOVF9URDsgaSsrKSB7CgkJaWYgKHRtcF9pbnRfdGRbaV0uZGV2X3B0ciA9PSAwKQkvKiBubyBkZXZpY2UgYXNzaWduZWQgLT4gZnJlZSBURCAqLwoJCQlyZXR1cm4gJnRtcF9pbnRfdGRbaV07Cgl9CglyZXR1cm4gTlVMTDsKfQoKLyotLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tCiAqIHN1Ym1pdHMgVVNCIGludGVycnVwdCAoaWUuIHBvbGxpbmcgOy0pCiAqLwppbnQgc3VibWl0X2ludF9tc2coc3RydWN0IHVzYl9kZXZpY2UgKmRldiwgdW5zaWduZWQgbG9uZyBwaXBlLCB2b2lkICpidWZmZXIsCgkJICAgaW50IHRyYW5zZmVyX2xlbiwgaW50IGludGVydmFsKQp7CglpbnQgbmludCwgbjsKCXVuc2lnbmVkIGxvbmcgc3RhdHVzLCBkZXN0aW5hdGlvbjsKCXVuc2lnbmVkIGxvbmcgaW5mbywgdG1wOwoJdWhjaV90ZF90ICpteXRkOwoJaWYgKGludGVydmFsIDwgMCB8fCBpbnRlcnZhbCA+PSAyNTYpCgkJcmV0dXJuIC0xOwoKCWlmIChpbnRlcnZhbCA9PSAwKQoJCW5pbnQgPSAwOwoJZWxzZSB7CgkJZm9yIChuaW50ID0gMCwgbiA9IDE7IG5pbnQgPD0gODsgbmludCsrLCBuICs9IG4pIHsJLyogcm91bmQgaW50ZXJ2YWwgZG93biB0byAyXm4gKi8KCQkJaWYgKGludGVydmFsIDwgbikgewoJCQkJaW50ZXJ2YWwgPSBuIC8gMjsKCQkJCWJyZWFrOwoJCQl9CgkJfQoJCW5pbnQtLTsKCX0KCglVU0JfVUhDSV9QUklOVEYoIlJvdW5kZWQgaW50ZXJ2YWwgdG8gJWksIGNoYWluICAlaVxuIiwgaW50ZXJ2YWwsIG5pbnQpOwoJbXl0ZCA9IHVoY2lfYWxsb2NfaW50X3RkKCk7CglpZiAobXl0ZCA9PSBOVUxMKSB7CgkJcHJpbnRmKCJObyBmcmVlIElOVCBURHMgZm91bmRcbiIpOwoJCXJldHVybiAtMTsKCX0KCXN0YXR1cyA9IChwaXBlICYgVERfQ1RSTF9MUykgfCBURF9DVFJMX0FDVElWRSB8IFREX0NUUkxfSU9DIHwgKDMgPDwgMjcpOwovKgkJKHVyYi0+dHJhbnNmZXJfZmxhZ3MgJiBVU0JfRElTQUJMRV9TUEQgPyAwIDogVERfQ1RSTF9TUEQpIHwgKDMgPDwgMjcpOwoqLwoKCWRlc3RpbmF0aW9uID0KCSAgICAocGlwZSAmIFBJUEVfREVWRVBfTUFTSykgfCB1c2JfcGFja2V0aWQocGlwZSkgfAoJICAgICgoKHRyYW5zZmVyX2xlbiAtIDEpICYgMHg3ZmYpIDw8IDIxKTsKCglpbmZvID0KCSAgICBkZXN0aW5hdGlvbiB8CgkgICAgKHVzYl9nZXR0b2dnbGUoZGV2LCB1c2JfcGlwZWVuZHBvaW50KHBpcGUpLCB1c2JfcGlwZW91dChwaXBlKSkgPDwKCSAgICAgVERfVE9LRU5fVE9HR0xFKTsKCXRtcCA9IHN3YXBfMzIodGRfaW50W25pbnRdLmxpbmspOwoJdXNiX2ZpbGxfdGQobXl0ZCwgdG1wLCBzdGF0dXMsIGluZm8sICh1bnNpZ25lZCBsb25nKWJ1ZmZlciwKCQkgICAgKHVuc2lnbmVkIGxvbmcpZGV2KTsKCS8qIExpbmsgaXQgKi8KCXRtcCA9IHN3YXBfMzIoKHVuc2lnbmVkIGxvbmcpbXl0ZCk7Cgl0ZF9pbnRbbmludF0ubGluayA9IHRtcDsKCgl1c2JfZG90b2dnbGUoZGV2LCB1c2JfcGlwZWVuZHBvaW50KHBpcGUpLCB1c2JfcGlwZW91dChwaXBlKSk7CgoJcmV0dXJuIDA7Cn0KCi8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqCiAqIExvdyBMZXZlbCBmdW5jdGlvbnMKICovCgp2b2lkIHJlc2V0X2hjKHZvaWQpCnsKCgkvKiBHbG9iYWwgcmVzZXQgZm9yIDEwMG1zICovCglvdXQxNnIodXNiX2Jhc2VfYWRkciArIFVTQlBPUlRTQzEsIDB4MDIwNCk7CglvdXQxNnIodXNiX2Jhc2VfYWRkciArIFVTQlBPUlRTQzIsIDB4MDIwNCk7CglvdXQxNnIodXNiX2Jhc2VfYWRkciArIFVTQkNNRCwgVVNCQ01EX0dSRVNFVCB8IFVTQkNNRF9SUyk7CgkvKiBUdXJuIG9mZiBhbGwgaW50ZXJydXB0cyAqLwoJb3V0MTZyKHVzYl9iYXNlX2FkZHIgKyBVU0JJTlRSLCAwKTsKCXdhaXRfbXMoNTApOwoJb3V0MTZyKHVzYl9iYXNlX2FkZHIgKyBVU0JDTUQsIDApOwoJd2FpdF9tcygxMCk7Cn0KCnZvaWQgc3RhcnRfaGModm9pZCkKewoJaW50IHRpbWVvdXQgPSAxMDAwOwoKCXdoaWxlIChpbjE2cih1c2JfYmFzZV9hZGRyICsgVVNCQ01EKSAmIFVTQkNNRF9IQ1JFU0VUKSB7CgkJaWYgKCEtLXRpbWVvdXQpIHsKCQkJcHJpbnRmKCJVU0JDTURfSENSRVNFVCB0aW1lZCBvdXQhXG4iKTsKCQkJYnJlYWs7CgkJfQoJfQoJLyogVHVybiBvbiBhbGwgaW50ZXJydXB0cyAqLwoJb3V0MTZyKHVzYl9iYXNlX2FkZHIgKyBVU0JJTlRSLAoJICAgICAgIFVTQklOVFJfVElNRU9VVCB8IFVTQklOVFJfUkVTVU1FIHwgVVNCSU5UUl9JT0MgfCBVU0JJTlRSX1NQKTsKCS8qIFN0YXJ0IGF0IGZyYW1lIDAgKi8KCW91dDE2cih1c2JfYmFzZV9hZGRyICsgVVNCRlJOVU0sIDApOwoJLyogc2V0IEZyYW1lYnVmZmVyIGJhc2UgYWRkcmVzcyAqLwoJb3V0MzJyKHVzYl9iYXNlX2FkZHIgKyBVU0JGTEJBU0VBREQsICh1bnNpZ25lZCBsb25nKSZmcmFtZWxpc3QpOwoJLyogUnVuIGFuZCBtYXJrIGl0IGNvbmZpZ3VyZWQgd2l0aCBhIDY0LWJ5dGUgbWF4IHBhY2tldCAqLwoJb3V0MTZyKHVzYl9iYXNlX2FkZHIgKyBVU0JDTUQsIFVTQkNNRF9SUyB8IFVTQkNNRF9DRiB8IFVTQkNNRF9NQVhQKTsKfQoKLyogSW5pdGlhbGl6ZSB0aGUgc2tlbGV0b24KICovCnZvaWQgdXNiX2luaXRfc2tlbCh2b2lkKQp7Cgl1bnNpZ25lZCBsb25nIHRlbXA7CglpbnQgbjsKCglmb3IgKG4gPSAwOyBuIDwgVVNCX01BWF9URU1QX0lOVF9URDsgbisrKQoJCXRtcF9pbnRfdGRbbl0uZGV2X3B0ciA9IDBMOwkvKiBubyBkZXZpY2VzIGNvbm5lY3RlZCAqLwoJLyogbGFzdCB0ZCAqLwoJdXNiX2ZpbGxfdGQoJnRkX2xhc3QsIFVIQ0lfUFRSX1RFUk0sIFREX0NUUkxfSU9DLCBVU0JfUElEX09VVCwgMCwgMEwpOwoJLyogdXNiX2ZpbGxfdGQoJnRkX2xhc3QsVUhDSV9QVFJfVEVSTSwwLDAsMCk7ICovCgkvKiBFbmQgUXVldWUgSGVhZGVyICovCgl1c2JfZmlsbF9xaCgmcWhfZW5kLCBVSENJX1BUUl9URVJNLCAodW5zaWduZWQgbG9uZykmdGRfbGFzdCk7CgkvKiBCdWxrIFF1ZXVlIEhlYWRlciAqLwoJdGVtcCA9ICh1bnNpZ25lZCBsb25nKSZxaF9lbmQ7Cgl1c2JfZmlsbF9xaCgmcWhfYnVsaywgdGVtcCB8IFVIQ0lfUFRSX1FILCBVSENJX1BUUl9URVJNKTsKCS8qIENvbnRyb2wgUXVldWUgSGVhZGVyICovCgl0ZW1wID0gKHVuc2lnbmVkIGxvbmcpJnFoX2J1bGs7Cgl1c2JfZmlsbF9xaCgmcWhfY250cmwsIHRlbXAgfCBVSENJX1BUUl9RSCwgVUhDSV9QVFJfVEVSTSk7CgkvKiAxbXMgSW50ZXJydXB0IHRkICovCgl0ZW1wID0gKHVuc2lnbmVkIGxvbmcpJnFoX2NudHJsOwoJdXNiX2ZpbGxfdGQoJnRkX2ludFswXSwgdGVtcCB8IFVIQ0lfUFRSX1FILCAwLCBVU0JfUElEX09VVCwgMCwgMEwpOwoJdGVtcCA9ICh1bnNpZ25lZCBsb25nKSZ0ZF9pbnRbMF07Cglmb3IgKG4gPSAxOyBuIDwgODsgbisrKQoJCXVzYl9maWxsX3RkKCZ0ZF9pbnRbbl0sIHRlbXAsIDAsIFVTQl9QSURfT1VULCAwLCAwTCk7Cglmb3IgKG4gPSAwOyBuIDwgMTAyNDsgbisrKSB7CgkJLyogbGluayBhbGwgZnJhbWVsaXN0IHBvaW50ZXJzIHRvIG9uZSBvZiB0aGUgaW50ZXJydXB0cyAqLwoJCWludCBtLCBvOwoJCWlmICgobiAmIDEyNykgPT0gMTI3KQoJCQlmcmFtZWxpc3Rbbl0gPSBzd2FwXzMyKCh1bnNpZ25lZCBsb25nKSZ0ZF9pbnRbMF0pOwoJCWVsc2UKCQkJZm9yIChvID0gMSwgbSA9IDI7IG0gPD0gMTI4OyBvKyssIG0gKz0gbSkKCQkJCWlmICgobiAmIChtIC0gMSkpID09ICgobSAtIDEpIC8gMikpCgkJCQkJZnJhbWVsaXN0W25dID0KCQkJCQkgICAgc3dhcF8zMigodW5zaWduZWQgbG9uZykmdGRfaW50W29dKTsKCgl9Cn0KCi8qIGNoZWNrIHRoZSBjb21tb24gc2tlbGV0b24gZm9yIGNvbXBsZXRlZCB0cmFuc2ZlcnMsIGFuZCB1cGRhdGUgdGhlIHN0YXR1cwogKiBvZiB0aGUgImNvbm5lY3RlZCIgZGV2aWNlLiBDYWxsZWQgZnJvbSB0aGUgSVJRIHJvdXRpbmUuCiAqLwp2b2lkIHVzYl9jaGVja19za2VsKHZvaWQpCnsKCXN0cnVjdCB1c2JfZGV2aWNlICpkZXY7CgkvKiBzdGFydCB3aXRoIHRoZSBjb250cm9sIHFoICovCglpZiAocWhfY250cmwuZGV2X3B0ciAhPSAwKSB7CS8qIGl0J3MgYSBkZXZpY2UgYXNzaWduZWQgY2hlY2sgaWYgdGhpcyBjYXVzZWQgSVJRICovCgkJZGV2ID0gKHN0cnVjdCB1c2JfZGV2aWNlICopcWhfY250cmwuZGV2X3B0cjsKCQkvKiBGbHVzaCBjYWNoZSBub3cgdGhhdCBoYXJkd2FyZSB1cGRhdGVkIERBVEEgYW5kIFREcy9RSHMgKi8KCQlpZiAoIWxlb24zX3Nub29waW5nX2F2YWlsKQoJCQlzcGFyY19kY2FjaGVfZmx1c2hfYWxsKCk7CgkJdXNiX2dldF90ZF9zdGF0dXMoJnRtcF90ZFswXSwgZGV2KTsJLyogdXBkYXRlIHN0YXR1cyAqLwoJCWlmICghKGRldi0+c3RhdHVzICYgVVNCX1NUX05PVF9QUk9DKSkgewkvKiBpcyBub3QgYWN0aXZlIGFueW1vcmUsIGRpc2Nvbm5lY3QgZGV2aWNlcyAqLwoJCQlxaF9jbnRybC5kZXZfcHRyID0gMDsKCQl9Cgl9CgkvKiBub3cgcHJvY2VzcyB0aGUgYnVsayAqLwoJaWYgKHFoX2J1bGsuZGV2X3B0ciAhPSAwKSB7CS8qIGl0J3MgYSBkZXZpY2UgYXNzaWduZWQgY2hlY2sgaWYgdGhpcyBjYXVzZWQgSVJRICovCgkJZGV2ID0gKHN0cnVjdCB1c2JfZGV2aWNlICopcWhfYnVsay5kZXZfcHRyOwoJCS8qIEZsdXNoIGNhY2hlIG5vdyB0aGF0IGhhcmR3YXJlIHVwZGF0ZWQgREFUQSBhbmQgVERzL1FIcyAqLwoJCWlmICghbGVvbjNfc25vb3BpbmdfYXZhaWwpCgkJCXNwYXJjX2RjYWNoZV9mbHVzaF9hbGwoKTsKCQl1c2JfZ2V0X3RkX3N0YXR1cygmdG1wX3RkWzBdLCBkZXYpOwkvKiB1cGRhdGUgc3RhdHVzICovCgkJaWYgKCEoZGV2LT5zdGF0dXMgJiBVU0JfU1RfTk9UX1BST0MpKSB7CS8qIGlzIG5vdCBhY3RpdmUgYW55bW9yZSwgZGlzY29ubmVjdCBkZXZpY2VzICovCgkJCXFoX2J1bGsuZGV2X3B0ciA9IDA7CgkJfQoJfQp9CgovKiBjaGVjayB0aGUgaW50ZXJydXB0IGNoYWluLCB1YmRhdGUgdGhlIHN0YXR1cyBvZiB0aGUgYXBwcm9wcmlhdGUgZGV2aWNlLAogKiBjYWxsIHRoZSBhcHByb3ByaWF0ZSBpcnFoYW5kbGVyIGFuZCByZWFjdGl2YXRlIHRoZSBURCBpZiB0aGUgaXJxaGFuZGxlcgogKiByZXR1cm5zIHdpdGggMQogKi8Kdm9pZCB1c2JfY2hlY2tfaW50X2NoYWluKHZvaWQpCnsKCWludCBpLCByZXM7Cgl1bnNpZ25lZCBsb25nIGxpbmssIHN0YXR1czsKCXN0cnVjdCB1c2JfZGV2aWNlICpkZXY7Cgl1aGNpX3RkX3QgKnRkLCAqcHJldnRkOwoKCWZvciAoaSA9IDA7IGkgPCA4OyBpKyspIHsKCQlwcmV2dGQgPSAmdGRfaW50W2ldOwkvKiB0aGUgZmlyc3QgcHJldmlvdXMgdGQgaXMgdGhlIHNrZWxldG9uIHRkICovCgkJbGluayA9IHN3YXBfMzIoUkVBRDMyKCZ0ZF9pbnRbaV0ubGluaykpICYgMHhmZmZmZmZmMDsJLyogbmV4dCBpbiBjaGFpbiAqLwoJCXRkID0gKHVoY2lfdGRfdCAqKSBsaW5rOwkvKiBhc3NpZ24gaXQgKi8KCQkvKiBhbGwgaW50ZXJydXB0IFREcyBhcmUgZmluYWxseSBsaW5rZWQgdG8gdGhlIHRkX2ludFswXS4KCQkgKiBzbyB3ZSBwcm9jZXNzIGFsbCB1bnRpbCB3ZSBmaW5kIHRoZSB0ZF9pbnRbMF0uCgkJICogaWYgaW50MCBjaGFpbiBwb2ludHMgdG8gYSBRSCwgd2UncmUgYWxzbyBkb25lCgkJICovCgkJd2hpbGUgKCgoaSA+IDApICYmIChsaW5rICE9ICh1bnNpZ25lZCBsb25nKSZ0ZF9pbnRbMF0pKSB8fAoJCSAgICAgICAoKGkgPT0gMCkKCQkJJiYgIShzd2FwXzMyKFJFQUQzMigmdGQtPmxpbmspKSAmIFVIQ0lfUFRSX1FIKSkpIHsKCQkJLyogY2hlY2sgaWYgYSBkZXZpY2UgaXMgYXNzaWduZWQgd2l0aCB0aGlzIHRkICovCgkJCXN0YXR1cyA9IHN3YXBfMzIoUkVBRDMyKCZ0ZC0+c3RhdHVzKSk7CgkJCWlmICgodGQtPmRldl9wdHIgIT0gMEwpICYmICEoc3RhdHVzICYgVERfQ1RSTF9BQ1RJVkUpKSB7CgkJCQkvKiB0ZCBpcyBub3QgYWN0aXZlIGFuZCBhIGRldmljZSBpcyBhc3NpZ25lZCAtPiBjYWxsIGlycWhhbmRsZXIgKi8KCQkJCWRldiA9IChzdHJ1Y3QgdXNiX2RldmljZSAqKXRkLT5kZXZfcHRyOwoJCQkJZGV2LT5pcnFfYWN0X2xlbiA9ICgoc3RhdHVzICYgMHg3RkYpID09IDB4N0ZGKSA/IDAgOiAoc3RhdHVzICYgMHg3RkYpICsgMTsJLyogdHJhbnNmZXJlZCBsZW5ndGggKi8KCQkJCWRldi0+aXJxX3N0YXR1cyA9IHVzYl91aGNpX3RkX3N0YXQoc3RhdHVzKTsJLyogZ2V0IHN0YXR1cyAqLwoJCQkJcmVzID0gZGV2LT5pcnFfaGFuZGxlKGRldik7CS8qIGNhbGwgaXJxaGFuZGxlciAqLwoJCQkJaWYgKHJlcyA9PSAxKSB7CgkJCQkJLyogcmVhY3RpdmF0ZSAqLwoJCQkJCXN0YXR1cyB8PSBURF9DVFJMX0FDVElWRTsKCQkJCQl0ZC0+c3RhdHVzID0gc3dhcF8zMihzdGF0dXMpOwoJCQkJCXByZXZ0ZCA9IHRkOwkvKiBwcmV2aW91cyB0ZCA9IHRoaXMgdGQgKi8KCQkJCX0gZWxzZSB7CgkJCQkJcHJldnRkLT5saW5rID0gUkVBRDMyKCZ0ZC0+bGluayk7CS8qIGxpbmsgcHJldmlvdXMgdGQgZGlyZWN0bHkgdG8gdGhlIG5leCB0ZCAtPiB1bmxpbmtlZCAqLwoJCQkJCS8qIHJlbW92ZSBkZXZpY2UgcG9pbnRlciAqLwoJCQkJCXRkLT5kZXZfcHRyID0gMEw7CgkJCQl9CgkJCX0JLyogaWYgd2UgY2FsbCB0aGUgaXJxIGhhbmRsZXIgKi8KCQkJbGluayA9IHN3YXBfMzIoUkVBRDMyKCZ0ZC0+bGluaykpICYgMHhmZmZmZmZmMDsJLyogbmV4dCBpbiBjaGFpbiAqLwoJCQl0ZCA9ICh1aGNpX3RkX3QgKikgbGluazsJLyogYXNzaWduIGl0ICovCgkJfQkJLyogcHJvY2VzcyBhbGwgdGQgaW4gdGhpcyBpbnQgY2hhaW4gKi8KCX0JCQkvKiBuZXh0IGludGVycnVwdCBjaGFpbiAqLwp9CgovKiB1c2IgaW50ZXJydXB0IHNlcnZpY2Ugcm91dGluZS4KICovCnZvaWQgaGFuZGxlX3VzYl9pbnRlcnJ1cHQodm9pZCkKewoJdW5zaWduZWQgc2hvcnQgc3RhdHVzOwoJc3RhdGljIGludCBlcnJvciA9IDA7CgoJLyoKCSAqIFJlYWQgdGhlIGludGVycnVwdCBzdGF0dXMsIGFuZCB3cml0ZSBpdCBiYWNrIHRvIGNsZWFyIHRoZQoJICogaW50ZXJydXB0IGNhdXNlCgkgKi8KCglzdGF0dXMgPSBpbjE2cih1c2JfYmFzZV9hZGRyICsgVVNCU1RTKTsKCglpZiAoIXN0YXR1cykJCS8qIHNoYXJlZCBpbnRlcnJ1cHQsIG5vdCBtaW5lICovCgkJcmV0dXJuOwoJaWYgKHN0YXR1cyAhPSAxKSB7CgkJLyogcmVtb3ZlIGhvc3QgY29udHJvbGxlciBoYWx0ZWQgc3RhdGUgKi8KCQlpZiAoKHN0YXR1cyAmIChVU0JTVFNfSENQRSB8IFVTQlNUU19IQ0gpKSA9PQoJCSAgICAoVVNCU1RTX0hDUEUgfCBVU0JTVFNfSENIKSkgewoJCQkvKiBTdG9wIGR1ZSB0byBidWcgaW4gZHJpdmVyLCBvciBoYXJkd2FyZSAqLwoJCQlvdXQxNnIodXNiX2Jhc2VfYWRkciArIFVTQlNUUywgc3RhdHVzKTsKCQkJb3V0MTZyKHVzYl9iYXNlX2FkZHIgKyBVU0JDTUQsCgkJCSAgICAgICBVU0JDTURfSENSRVNFVCB8IFVTQkNNRF9HUkVTRVQpOwoJCQlwcmludGYKCQkJICAgICgiR1JVU0I6IEhXIGRldGVjdGVkIGVycm9yKHMpIGluIFVTQiBEZXNjcmlwdG9ycyAoU1RTOiAweCV4KVxuIiwKCQkJICAgICBzdGF0dXMpOwoJCQl1c2Jfc2hvd190ZCg4KTsKCQkJcmV0dXJuOwoJCX0gZWxzZSBpZiAoKHN0YXR1cyAmIDB4MjApCgkJCSAgICYmICgoaW4xNnIodXNiX2Jhc2VfYWRkciArIFVTQkNNRCkgJiBVU0JDTURfUlMpID09CgkJCSAgICAgICAwKSkgewoJCQlpZiAoZXJyb3IgPCAxMCkgewoJCQkJb3V0MTZyKHVzYl9iYXNlX2FkZHIgKyBVU0JDTUQsCgkJCQkgICAgICAgVVNCQ01EX1JTIHwgaW4xNnIodXNiX2Jhc2VfYWRkciArCgkJCQkJCQkgVVNCQ01EKSk7CgkJCQllcnJvcisrOwoJCQl9CgkJfSBlbHNlCgkJCWVycm9yID0gMDsKCX0KCXVzYl9jaGVja19pbnRfY2hhaW4oKTsJLyogY2FsbCBpbnRlcnJ1cHQgaGFuZGxlcnMgZm9yIGludCB0ZHMgKi8KCXVzYl9jaGVja19za2VsKCk7CS8qIGNhbGwgY29tcGxldGlvbiBoYW5kbGVyIGZvciBjb21tb24gdHJhbnNmZXIgcm91dGluZXMgKi8KCW91dDE2cih1c2JfYmFzZV9hZGRyICsgVVNCU1RTLCBzdGF0dXMpOwp9CgovKiBpbml0IHVoY2kKICovCmludCB1c2JfbG93bGV2ZWxfaW5pdCh2b2lkKQp7Cgl1bnNpZ25lZCBjaGFyIHRlbXA7CglhbWJhcHBfYWhiZGV2IGFoYmRldjsKCgkvKiBGaW5kIEdSVVNCIGNvcmUgdXNpbmcgQU1CQSBQbHVnJlBsYXkgaW5mb3JtYXRpb24gKi8KCWlmIChhbWJhcHBfYWhic2x2X2ZpcnN0KFZFTkRPUl9HQUlTTEVSLCBHQUlTTEVSX1VIQ0ksICZhaGJkZXYpICE9IDEpIHsKCQlwcmludGYoIlVTQiBVSENJOiBGYWlsZWQgdG8gZmluZCBHUlVTQiBjb250cm9sbGVyXG4iKTsKCQlyZXR1cm4gLTE7Cgl9Cgl1c2JfYmFzZV9hZGRyID0gYWhiZGV2LmFkZHJlc3NbMF07CglncnVzYl9pcnEgPSBhaGJkZXYuaXJxOwoJLyoKCSAgIHVzYl9iYXNlX2FkZHIgPSAweGZmZmEwMDAwOwoJICAgZ3J1c2JfaXJxID0gMTA7CgkgKi8KI2lmZGVmIFVTQl9VSENJX0RFQlVHCglncnVzYl9zaG93X3JlZ3MoKTsKI2VuZGlmCgltZW1zZXQodGRfaW50LCAwLCBzaXplb2YodGRfaW50KSk7CgltZW1zZXQodG1wX3RkLCAwLCBzaXplb2YodG1wX3RkKSk7CgltZW1zZXQodG1wX2ludF90ZCwgMCwgc2l6ZW9mKHRtcF9pbnRfdGQpKTsKCW1lbXNldCgmcWhfY250cmwsIDAsIHNpemVvZihxaF9jbnRybCkpOwoJbWVtc2V0KCZxaF9lbmQsIDAsIHNpemVvZihxaF9lbmQpKTsKCW1lbXNldCgmdGRfbGFzdCwgMCwgc2l6ZW9mKHRkX2xhc3QpKTsKCglpcnFfZnJlZV9oYW5kbGVyKGdydXNiX2lycSk7CglVU0JfVUhDSV9QUklOVEYoIkdSVVNCOiBhdCAweCVseCBpcnEgJWRcbiIsIHVzYl9iYXNlX2FkZHIsIGdydXNiX2lycSk7CglyaC5kZXZudW0gPSAwOwoJdXNiX2luaXRfc2tlbCgpOwoJcmVzZXRfaGMoKTsKCXN0YXJ0X2hjKCk7CglpcnFfaW5zdGFsbF9oYW5kbGVyKGdydXNiX2lycSwKCQkJICAgIChpbnRlcnJ1cHRfaGFuZGxlcl90ICopIGhhbmRsZV91c2JfaW50ZXJydXB0LCBOVUxMKTsKCXJldHVybiAwOwp9CgovKiBzdG9wIHVoY2kKICovCmludCB1c2JfbG93bGV2ZWxfc3RvcCh2b2lkKQp7CglpZiAoZ3J1c2JfaXJxID09IC0xKQoJCXJldHVybiAxOwoJaXJxX2ZyZWVfaGFuZGxlcihncnVzYl9pcnEpOwoJcmVzZXRfaGMoKTsKCWdydXNiX2lycSA9IC0xOwoJcmV0dXJuIDA7Cn0KCi8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqCiAqIFZpcnR1YWwgUm9vdCBIdWIKICogU2luY2UgdGhlIHVoY2kgZG9lcyBub3QgaGF2ZSBhIHJlYWwgSFVCLCB3ZSBzaW11bGF0ZSBvbmUgOy0pCiAqLwojdW5kZWYJVVNCX1JIX0RFQlVHCgojaWZkZWYJVVNCX1JIX0RFQlVHCiNkZWZpbmUJVVNCX1JIX1BSSU5URihmbXQsYXJncy4uLikJcHJpbnRmIChmbXQgLCMjYXJncykKc3RhdGljIHZvaWQgdXNiX2Rpc3BsYXlfd1ZhbHVlKHVuc2lnbmVkIHNob3J0IHdWYWx1ZSwgdW5zaWduZWQgc2hvcnQgd0luZGV4KTsKc3RhdGljIHZvaWQgdXNiX2Rpc3BsYXlfUmVxKHVuc2lnbmVkIHNob3J0IHJlcSk7CiNlbHNlCiNkZWZpbmUgVVNCX1JIX1BSSU5URihmbXQsYXJncy4uLikKc3RhdGljIHZvaWQgdXNiX2Rpc3BsYXlfd1ZhbHVlKHVuc2lnbmVkIHNob3J0IHdWYWx1ZSwgdW5zaWduZWQgc2hvcnQgd0luZGV4KQp7Cn0Kc3RhdGljIHZvaWQgdXNiX2Rpc3BsYXlfUmVxKHVuc2lnbmVkIHNob3J0IHJlcSkKewp9CiNlbmRpZgoKc3RhdGljIHVuc2lnbmVkIGNoYXIgcm9vdF9odWJfZGV2X2Rlc1tdID0gewoJMHgxMiwJCQkvKiAgX191OCAgYkxlbmd0aDsgKi8KCTB4MDEsCQkJLyogIF9fdTggIGJEZXNjcmlwdG9yVHlwZTsgRGV2aWNlICovCgkweDAwLAkJCS8qICBfX3UxNiBiY2RVU0I7IHYxLjAgKi8KCTB4MDEsCgkweDA5LAkJCS8qICBfX3U4ICBiRGV2aWNlQ2xhc3M7IEhVQl9DTEFTU0NPREUgKi8KCTB4MDAsCQkJLyogIF9fdTggIGJEZXZpY2VTdWJDbGFzczsgKi8KCTB4MDAsCQkJLyogIF9fdTggIGJEZXZpY2VQcm90b2NvbDsgKi8KCTB4MDgsCQkJLyogIF9fdTggIGJNYXhQYWNrZXRTaXplMDsgOCBCeXRlcyAqLwoJMHgwMCwJCQkvKiAgX191MTYgaWRWZW5kb3I7ICovCgkweDAwLAoJMHgwMCwJCQkvKiAgX191MTYgaWRQcm9kdWN0OyAqLwoJMHgwMCwKCTB4MDAsCQkJLyogIF9fdTE2IGJjZERldmljZTsgKi8KCTB4MDAsCgkweDAxLAkJCS8qICBfX3U4ICBpTWFudWZhY3R1cmVyOyAqLwoJMHgwMCwJCQkvKiAgX191OCAgaVByb2R1Y3Q7ICovCgkweDAwLAkJCS8qICBfX3U4ICBpU2VyaWFsTnVtYmVyOyAqLwoJMHgwMQkJCS8qICBfX3U4ICBiTnVtQ29uZmlndXJhdGlvbnM7ICovCn07CgovKiBDb25maWd1cmF0aW9uIGRlc2NyaXB0b3IgKi8Kc3RhdGljIHVuc2lnbmVkIGNoYXIgcm9vdF9odWJfY29uZmlnX2Rlc1tdID0gewoJMHgwOSwJCQkvKiAgX191OCAgYkxlbmd0aDsgKi8KCTB4MDIsCQkJLyogIF9fdTggIGJEZXNjcmlwdG9yVHlwZTsgQ29uZmlndXJhdGlvbiAqLwoJMHgxOSwJCQkvKiAgX191MTYgd1RvdGFsTGVuZ3RoOyAqLwoJMHgwMCwKCTB4MDEsCQkJLyogIF9fdTggIGJOdW1JbnRlcmZhY2VzOyAqLwoJMHgwMSwJCQkvKiAgX191OCAgYkNvbmZpZ3VyYXRpb25WYWx1ZTsgKi8KCTB4MDAsCQkJLyogIF9fdTggIGlDb25maWd1cmF0aW9uOyAqLwoJMHg0MCwJCQkvKiAgX191OCAgYm1BdHRyaWJ1dGVzOwoJCQkJICAgQml0IDc6IEJ1cy1wb3dlcmVkLCA2OiBTZWxmLXBvd2VyZWQsIDUgUmVtb3RlLXdha3d1cCwgNC4uMDogcmVzdmQgKi8KCTB4MDAsCQkJLyogIF9fdTggIE1heFBvd2VyOyAqLwoKCS8qIGludGVyZmFjZSAqLwoJMHgwOSwJCQkvKiAgX191OCAgaWZfYkxlbmd0aDsgKi8KCTB4MDQsCQkJLyogIF9fdTggIGlmX2JEZXNjcmlwdG9yVHlwZTsgSW50ZXJmYWNlICovCgkweDAwLAkJCS8qICBfX3U4ICBpZl9iSW50ZXJmYWNlTnVtYmVyOyAqLwoJMHgwMCwJCQkvKiAgX191OCAgaWZfYkFsdGVybmF0ZVNldHRpbmc7ICovCgkweDAxLAkJCS8qICBfX3U4ICBpZl9iTnVtRW5kcG9pbnRzOyAqLwoJMHgwOSwJCQkvKiAgX191OCAgaWZfYkludGVyZmFjZUNsYXNzOyBIVUJfQ0xBU1NDT0RFICovCgkweDAwLAkJCS8qICBfX3U4ICBpZl9iSW50ZXJmYWNlU3ViQ2xhc3M7ICovCgkweDAwLAkJCS8qICBfX3U4ICBpZl9iSW50ZXJmYWNlUHJvdG9jb2w7ICovCgkweDAwLAkJCS8qICBfX3U4ICBpZl9pSW50ZXJmYWNlOyAqLwoKCS8qIGVuZHBvaW50ICovCgkweDA3LAkJCS8qICBfX3U4ICBlcF9iTGVuZ3RoOyAqLwoJMHgwNSwJCQkvKiAgX191OCAgZXBfYkRlc2NyaXB0b3JUeXBlOyBFbmRwb2ludCAqLwoJMHg4MSwJCQkvKiAgX191OCAgZXBfYkVuZHBvaW50QWRkcmVzczsgSU4gRW5kcG9pbnQgMSAqLwoJMHgwMywJCQkvKiAgX191OCAgZXBfYm1BdHRyaWJ1dGVzOyBJbnRlcnJ1cHQgKi8KCTB4MDgsCQkJLyogIF9fdTE2IGVwX3dNYXhQYWNrZXRTaXplOyA4IEJ5dGVzICovCgkweDAwLAoJMHhmZgkJCS8qICBfX3U4ICBlcF9iSW50ZXJ2YWw7IDI1NSBtcyAqLwp9OwoKc3RhdGljIHVuc2lnbmVkIGNoYXIgcm9vdF9odWJfaHViX2Rlc1tdID0gewoJMHgwOSwJCQkvKiAgX191OCAgYkxlbmd0aDsgKi8KCTB4MjksCQkJLyogIF9fdTggIGJEZXNjcmlwdG9yVHlwZTsgSHViLWRlc2NyaXB0b3IgKi8KCTB4MDIsCQkJLyogIF9fdTggIGJOYnJQb3J0czsgKi8KCTB4MDAsCQkJLyogX191MTYgIHdIdWJDaGFyYWN0ZXJpc3RpY3M7ICovCgkweDAwLAoJMHgwMSwJCQkvKiAgX191OCAgYlB3ck9uMnB3ckdvb2Q7IDJtcyAqLwoJMHgwMCwJCQkvKiAgX191OCAgYkh1YkNvbnRyQ3VycmVudDsgMCBtQSAqLwoJMHgwMCwJCQkvKiAgX191OCAgRGV2aWNlUmVtb3ZhYmxlOyAqKiogNyBQb3J0cyBtYXggKioqICovCgkweGZmCQkJLyogIF9fdTggIFBvcnRQd3JDdHJsTWFzazsgKioqIDcgcG9ydHMgbWF4ICoqKiAqLwp9OwoKc3RhdGljIHVuc2lnbmVkIGNoYXIgcm9vdF9odWJfc3RyX2luZGV4MFtdID0gewoJMHgwNCwJCQkvKiAgX191OCAgYkxlbmd0aDsgKi8KCTB4MDMsCQkJLyogIF9fdTggIGJEZXNjcmlwdG9yVHlwZTsgU3RyaW5nLWRlc2NyaXB0b3IgKi8KCTB4MDksCQkJLyogIF9fdTggIGxhbmcgSUQgKi8KCTB4MDQsCQkJLyogIF9fdTggIGxhbmcgSUQgKi8KfTsKCnN0YXRpYyB1bnNpZ25lZCBjaGFyIHJvb3RfaHViX3N0cl9pbmRleDFbXSA9IHsKCTI4LAkJCS8qICBfX3U4ICBiTGVuZ3RoOyAqLwoJMHgwMywJCQkvKiAgX191OCAgYkRlc2NyaXB0b3JUeXBlOyBTdHJpbmctZGVzY3JpcHRvciAqLwoJJ1UnLAkJCS8qICBfX3U4ICBVbmljb2RlICovCgkwLAkJCS8qICBfX3U4ICBVbmljb2RlICovCgknSCcsCQkJLyogIF9fdTggIFVuaWNvZGUgKi8KCTAsCQkJLyogIF9fdTggIFVuaWNvZGUgKi8KCSdDJywJCQkvKiAgX191OCAgVW5pY29kZSAqLwoJMCwJCQkvKiAgX191OCAgVW5pY29kZSAqLwoJJ0knLAkJCS8qICBfX3U4ICBVbmljb2RlICovCgkwLAkJCS8qICBfX3U4ICBVbmljb2RlICovCgknICcsCQkJLyogIF9fdTggIFVuaWNvZGUgKi8KCTAsCQkJLyogIF9fdTggIFVuaWNvZGUgKi8KCSdSJywJCQkvKiAgX191OCAgVW5pY29kZSAqLwoJMCwJCQkvKiAgX191OCAgVW5pY29kZSAqLwoJJ28nLAkJCS8qICBfX3U4ICBVbmljb2RlICovCgkwLAkJCS8qICBfX3U4ICBVbmljb2RlICovCgknbycsCQkJLyogIF9fdTggIFVuaWNvZGUgKi8KCTAsCQkJLyogIF9fdTggIFVuaWNvZGUgKi8KCSd0JywJCQkvKiAgX191OCAgVW5pY29kZSAqLwoJMCwJCQkvKiAgX191OCAgVW5pY29kZSAqLwoJJyAnLAkJCS8qICBfX3U4ICBVbmljb2RlICovCgkwLAkJCS8qICBfX3U4ICBVbmljb2RlICovCgknSCcsCQkJLyogIF9fdTggIFVuaWNvZGUgKi8KCTAsCQkJLyogIF9fdTggIFVuaWNvZGUgKi8KCSd1JywJCQkvKiAgX191OCAgVW5pY29kZSAqLwoJMCwJCQkvKiAgX191OCAgVW5pY29kZSAqLwoJJ2InLAkJCS8qICBfX3U4ICBVbmljb2RlICovCgkwLAkJCS8qICBfX3U4ICBVbmljb2RlICovCn07CgovKgogKiBSb290IEh1YiBDb250cm9sIFBpcGUgKGludGVycnVwdCBQaXBlcyBhcmUgbm90IHN1cHBvcnRlZCkKICovCgppbnQgdWhjaV9zdWJtaXRfcmhfbXNnKHN0cnVjdCB1c2JfZGV2aWNlICpkZXYsIHVuc2lnbmVkIGxvbmcgcGlwZSwgdm9pZCAqYnVmZmVyLAoJCSAgICAgICBpbnQgdHJhbnNmZXJfbGVuLCBzdHJ1Y3QgZGV2cmVxdWVzdCAqY21kKQp7Cgl2b2lkICpkYXRhID0gYnVmZmVyOwoJaW50IGxlbmkgPSB0cmFuc2Zlcl9sZW47CglpbnQgbGVuID0gMDsKCWludCBzdGF0dXMgPSAwOwoJaW50IHN0YXQgPSAwOwoJaW50IGk7CgoJdW5zaWduZWQgc2hvcnQgY3N0YXR1czsKCgl1bnNpZ25lZCBzaG9ydCBibVJUeXBlX2JSZXE7Cgl1bnNpZ25lZCBzaG9ydCB3VmFsdWU7Cgl1bnNpZ25lZCBzaG9ydCB3SW5kZXg7Cgl1bnNpZ25lZCBzaG9ydCB3TGVuZ3RoOwoKCWlmICh1c2JfcGlwZWludChwaXBlKSkgewoJCXByaW50ZigiUm9vdC1IdWIgc3VibWl0IElSUTogTk9UIGltcGxlbWVudGVkXG4iKTsKCQlyZXR1cm4gMDsKCX0KCWJtUlR5cGVfYlJlcSA9IGNtZC0+cmVxdWVzdHR5cGUgfCBjbWQtPnJlcXVlc3QgPDwgODsKCXdWYWx1ZSA9IHN3YXBfMTYoY21kLT52YWx1ZSk7Cgl3SW5kZXggPSBzd2FwXzE2KGNtZC0+aW5kZXgpOwoJd0xlbmd0aCA9IHN3YXBfMTYoY21kLT5sZW5ndGgpOwoJdXNiX2Rpc3BsYXlfUmVxKGJtUlR5cGVfYlJlcSk7Cglmb3IgKGkgPSAwOyBpIDwgODsgaSsrKQoJCXJoLmNfcF9yW2ldID0gMDsKCVVTQl9SSF9QUklOVEYoIlJvb3QtSHViOiBhZHI6ICUyeCBjbWQoJTF4KTogJTAyeCUwMnggJTA0eCAlMDR4ICUwNHhcbiIsCgkJICAgICAgZGV2LT5kZXZudW0sIDgsIGNtZC0+cmVxdWVzdHR5cGUsIGNtZC0+cmVxdWVzdCwgd1ZhbHVlLAoJCSAgICAgIHdJbmRleCwgd0xlbmd0aCk7CgoJc3dpdGNoIChibVJUeXBlX2JSZXEpIHsKCQkvKiBSZXF1ZXN0IERlc3RpbmF0aW9uOgoJCSAgIHdpdGhvdXQgZmxhZ3M6IERldmljZSwKCQkgICBSSF9JTlRFUkZBQ0U6IGludGVyZmFjZSwKCQkgICBSSF9FTkRQT0lOVDogZW5kcG9pbnQsCgkJICAgUkhfQ0xBU1MgbWVhbnMgSFVCIGhlcmUsCgkJICAgUkhfT1RIRVIgfCBSSF9DTEFTUyAgYWxtb3N0IGV2ZXIgbWVhbnMgSFVCX1BPUlQgaGVyZQoJCSAqLwoKCWNhc2UgUkhfR0VUX1NUQVRVUzoKCQkqKHVuc2lnbmVkIHNob3J0ICopZGF0YSA9IHN3YXBfMTYoMSk7CgkJbGVuID0gMjsKCQlicmVhazsKCWNhc2UgUkhfR0VUX1NUQVRVUyB8IFJIX0lOVEVSRkFDRToKCQkqKHVuc2lnbmVkIHNob3J0ICopZGF0YSA9IHN3YXBfMTYoMCk7CgkJbGVuID0gMjsKCQlicmVhazsKCWNhc2UgUkhfR0VUX1NUQVRVUyB8IFJIX0VORFBPSU5UOgoJCSoodW5zaWduZWQgc2hvcnQgKilkYXRhID0gc3dhcF8xNigwKTsKCQlsZW4gPSAyOwoJCWJyZWFrOwoJY2FzZSBSSF9HRVRfU1RBVFVTIHwgUkhfQ0xBU1M6CgkJKih1bnNpZ25lZCBsb25nICopZGF0YSA9IHN3YXBfMzIoMCk7CgkJbGVuID0gNDsKCQlicmVhazsJCS8qIGh1YiBwb3dlciAqKiAqLwoJY2FzZSBSSF9HRVRfU1RBVFVTIHwgUkhfT1RIRVIgfCBSSF9DTEFTUzoKCgkJc3RhdHVzID0gaW4xNnIodXNiX2Jhc2VfYWRkciArIFVTQlBPUlRTQzEgKyAyICogKHdJbmRleCAtIDEpKTsKCQljc3RhdHVzID0gKChzdGF0dXMgJiBVU0JQT1JUU0NfQ1NDKSA+PiAoMSAtIDApKSB8CgkJICAgICgoc3RhdHVzICYgVVNCUE9SVFNDX1BFQykgPj4gKDMgLSAxKSkgfAoJCSAgICAocmguY19wX3Jbd0luZGV4IC0gMV0gPDwgKDAgKyA0KSk7CgkJc3RhdHVzID0gKHN0YXR1cyAmIFVTQlBPUlRTQ19DQ1MpIHwgKChzdGF0dXMgJiBVU0JQT1JUU0NfUEUpID4+ICgyIC0gMSkpIHwgKChzdGF0dXMgJiBVU0JQT1JUU0NfU1VTUCkgPj4gKDEyIC0gMikpIHwgKChzdGF0dXMgJiBVU0JQT1JUU0NfUFIpID4+ICg5IC0gNCkpIHwgKDEgPDwgOCkgfAkvKiBwb3dlciBvbiAqKiAqLwoJCSAgICAoKHN0YXR1cyAmIFVTQlBPUlRTQ19MU0RBKSA8PCAoLTggKyA5KSk7CgoJCSoodW5zaWduZWQgc2hvcnQgKilkYXRhID0gc3dhcF8xNihzdGF0dXMpOwoJCSoodW5zaWduZWQgc2hvcnQgKikoZGF0YSArIDIpID0gc3dhcF8xNihjc3RhdHVzKTsKCQlsZW4gPSA0OwoJCWJyZWFrOwoJY2FzZSBSSF9DTEVBUl9GRUFUVVJFIHwgUkhfRU5EUE9JTlQ6CgkJc3dpdGNoICh3VmFsdWUpIHsKCQljYXNlIChSSF9FTkRQT0lOVF9TVEFMTCk6CgkJCWxlbiA9IDA7CgkJCWJyZWFrOwoJCX0KCQlicmVhazsKCgljYXNlIFJIX0NMRUFSX0ZFQVRVUkUgfCBSSF9DTEFTUzoKCQlzd2l0Y2ggKHdWYWx1ZSkgewoJCWNhc2UgKFJIX0NfSFVCX09WRVJfQ1VSUkVOVCk6CgkJCWxlbiA9IDA7CS8qIGh1YiBwb3dlciBvdmVyIGN1cnJlbnQgKiogKi8KCQkJYnJlYWs7CgkJfQoJCWJyZWFrOwoKCWNhc2UgUkhfQ0xFQVJfRkVBVFVSRSB8IFJIX09USEVSIHwgUkhfQ0xBU1M6CgkJdXNiX2Rpc3BsYXlfd1ZhbHVlKHdWYWx1ZSwgd0luZGV4KTsKCQlzd2l0Y2ggKHdWYWx1ZSkgewoJCWNhc2UgKFJIX1BPUlRfRU5BQkxFKToKCQkJc3RhdHVzID0KCQkJICAgIGluMTZyKHVzYl9iYXNlX2FkZHIgKyBVU0JQT1JUU0MxICsKCQkJCSAgMiAqICh3SW5kZXggLSAxKSk7CgkJCXN0YXR1cyA9IChzdGF0dXMgJiAweGZmZjUpICYgflVTQlBPUlRTQ19QRTsKCQkJb3V0MTZyKHVzYl9iYXNlX2FkZHIgKyBVU0JQT1JUU0MxICsgMiAqICh3SW5kZXggLSAxKSwKCQkJICAgICAgIHN0YXR1cyk7CgkJCWxlbiA9IDA7CgkJCWJyZWFrOwoJCWNhc2UgKFJIX1BPUlRfU1VTUEVORCk6CgkJCXN0YXR1cyA9CgkJCSAgICBpbjE2cih1c2JfYmFzZV9hZGRyICsgVVNCUE9SVFNDMSArCgkJCQkgIDIgKiAod0luZGV4IC0gMSkpOwoJCQlzdGF0dXMgPSAoc3RhdHVzICYgMHhmZmY1KSAmIH5VU0JQT1JUU0NfU1VTUDsKCQkJb3V0MTZyKHVzYl9iYXNlX2FkZHIgKyBVU0JQT1JUU0MxICsgMiAqICh3SW5kZXggLSAxKSwKCQkJICAgICAgIHN0YXR1cyk7CgkJCWxlbiA9IDA7CgkJCWJyZWFrOwoJCWNhc2UgKFJIX1BPUlRfUE9XRVIpOgoJCQlsZW4gPSAwOwkvKiBwb3J0IHBvd2VyICoqICovCgkJCWJyZWFrOwoJCWNhc2UgKFJIX0NfUE9SVF9DT05ORUNUSU9OKToKCQkJc3RhdHVzID0KCQkJICAgIGluMTZyKHVzYl9iYXNlX2FkZHIgKyBVU0JQT1JUU0MxICsKCQkJCSAgMiAqICh3SW5kZXggLSAxKSk7CgkJCXN0YXR1cyA9IChzdGF0dXMgJiAweGZmZjUpIHwgVVNCUE9SVFNDX0NTQzsKCQkJb3V0MTZyKHVzYl9iYXNlX2FkZHIgKyBVU0JQT1JUU0MxICsgMiAqICh3SW5kZXggLSAxKSwKCQkJICAgICAgIHN0YXR1cyk7CgkJCWxlbiA9IDA7CgkJCWJyZWFrOwoJCWNhc2UgKFJIX0NfUE9SVF9FTkFCTEUpOgoJCQlzdGF0dXMgPQoJCQkgICAgaW4xNnIodXNiX2Jhc2VfYWRkciArIFVTQlBPUlRTQzEgKwoJCQkJICAyICogKHdJbmRleCAtIDEpKTsKCQkJc3RhdHVzID0gKHN0YXR1cyAmIDB4ZmZmNSkgfCBVU0JQT1JUU0NfUEVDOwoJCQlvdXQxNnIodXNiX2Jhc2VfYWRkciArIFVTQlBPUlRTQzEgKyAyICogKHdJbmRleCAtIDEpLAoJCQkgICAgICAgc3RhdHVzKTsKCQkJbGVuID0gMDsKCQkJYnJlYWs7CgkJY2FzZSAoUkhfQ19QT1JUX1NVU1BFTkQpOgovKioqIFdSX1JIX1BPUlRTVEFUKFJIX1BTX1BTU0MpOyAqLwoJCQlsZW4gPSAwOwoJCQlicmVhazsKCQljYXNlIChSSF9DX1BPUlRfT1ZFUl9DVVJSRU5UKToKCQkJbGVuID0gMDsKCQkJYnJlYWs7CgkJY2FzZSAoUkhfQ19QT1JUX1JFU0VUKToKCQkJcmguY19wX3Jbd0luZGV4IC0gMV0gPSAwOwoJCQlsZW4gPSAwOwoJCQlicmVhazsKCQl9CgkJYnJlYWs7CgljYXNlIFJIX1NFVF9GRUFUVVJFIHwgUkhfT1RIRVIgfCBSSF9DTEFTUzoKCQl1c2JfZGlzcGxheV93VmFsdWUod1ZhbHVlLCB3SW5kZXgpOwoJCXN3aXRjaCAod1ZhbHVlKSB7CgkJY2FzZSAoUkhfUE9SVF9TVVNQRU5EKToKCQkJc3RhdHVzID0KCQkJICAgIGluMTZyKHVzYl9iYXNlX2FkZHIgKyBVU0JQT1JUU0MxICsKCQkJCSAgMiAqICh3SW5kZXggLSAxKSk7CgkJCXN0YXR1cyA9IChzdGF0dXMgJiAweGZmZjUpIHwgVVNCUE9SVFNDX1NVU1A7CgkJCW91dDE2cih1c2JfYmFzZV9hZGRyICsgVVNCUE9SVFNDMSArIDIgKiAod0luZGV4IC0gMSksCgkJCSAgICAgICBzdGF0dXMpOwoJCQlsZW4gPSAwOwoJCQlicmVhazsKCQljYXNlIChSSF9QT1JUX1JFU0VUKToKCQkJc3RhdHVzID0KCQkJICAgIGluMTZyKHVzYl9iYXNlX2FkZHIgKyBVU0JQT1JUU0MxICsKCQkJCSAgMiAqICh3SW5kZXggLSAxKSk7CgkJCXN0YXR1cyA9IChzdGF0dXMgJiAweGZmZjUpIHwgVVNCUE9SVFNDX1BSOwoJCQlvdXQxNnIodXNiX2Jhc2VfYWRkciArIFVTQlBPUlRTQzEgKyAyICogKHdJbmRleCAtIDEpLAoJCQkgICAgICAgc3RhdHVzKTsKCQkJd2FpdF9tcygxMCk7CgkJCXN0YXR1cyA9IChzdGF0dXMgJiAweGZmZjUpICYgflVTQlBPUlRTQ19QUjsKCQkJb3V0MTZyKHVzYl9iYXNlX2FkZHIgKyBVU0JQT1JUU0MxICsgMiAqICh3SW5kZXggLSAxKSwKCQkJICAgICAgIHN0YXR1cyk7CgkJCXVkZWxheSgxMCk7CgkJCXN0YXR1cyA9IChzdGF0dXMgJiAweGZmZjUpIHwgVVNCUE9SVFNDX1BFOwoJCQlvdXQxNnIodXNiX2Jhc2VfYWRkciArIFVTQlBPUlRTQzEgKyAyICogKHdJbmRleCAtIDEpLAoJCQkgICAgICAgc3RhdHVzKTsKCQkJd2FpdF9tcygxMCk7CgkJCXN0YXR1cyA9IChzdGF0dXMgJiAweGZmZjUpIHwgMHhhOwoJCQlvdXQxNnIodXNiX2Jhc2VfYWRkciArIFVTQlBPUlRTQzEgKyAyICogKHdJbmRleCAtIDEpLAoJCQkgICAgICAgc3RhdHVzKTsKCQkJbGVuID0gMDsKCQkJYnJlYWs7CgkJY2FzZSAoUkhfUE9SVF9QT1dFUik6CgkJCWxlbiA9IDA7CS8qIHBvcnQgcG93ZXIgKiogKi8KCQkJYnJlYWs7CgkJY2FzZSAoUkhfUE9SVF9FTkFCTEUpOgoJCQlzdGF0dXMgPQoJCQkgICAgaW4xNnIodXNiX2Jhc2VfYWRkciArIFVTQlBPUlRTQzEgKwoJCQkJICAyICogKHdJbmRleCAtIDEpKTsKCQkJc3RhdHVzID0gKHN0YXR1cyAmIDB4ZmZmNSkgfCBVU0JQT1JUU0NfUEU7CgkJCW91dDE2cih1c2JfYmFzZV9hZGRyICsgVVNCUE9SVFNDMSArIDIgKiAod0luZGV4IC0gMSksCgkJCSAgICAgICBzdGF0dXMpOwoJCQlsZW4gPSAwOwoJCQlicmVhazsKCQl9CgkJYnJlYWs7CgoJY2FzZSBSSF9TRVRfQUREUkVTUzoKCQlyaC5kZXZudW0gPSB3VmFsdWU7CgkJbGVuID0gMDsKCQlicmVhazsKCWNhc2UgUkhfR0VUX0RFU0NSSVBUT1I6CgkJc3dpdGNoICgod1ZhbHVlICYgMHhmZjAwKSA+PiA4KSB7CgkJY2FzZSAoMHgwMSk6CS8qIGRldmljZSBkZXNjcmlwdG9yICovCgkJCWkgPSBzaXplb2Yocm9vdF9odWJfY29uZmlnX2Rlcyk7CgkJCXN0YXR1cyA9IGkgPiB3TGVuZ3RoID8gd0xlbmd0aCA6IGk7CgkJCWxlbiA9IGxlbmkgPiBzdGF0dXMgPyBzdGF0dXMgOiBsZW5pOwoJCQltZW1jcHkoZGF0YSwgcm9vdF9odWJfZGV2X2RlcywgbGVuKTsKCQkJYnJlYWs7CgkJY2FzZSAoMHgwMik6CS8qIGNvbmZpZ3VyYXRpb24gZGVzY3JpcHRvciAqLwoJCQlpID0gc2l6ZW9mKHJvb3RfaHViX2NvbmZpZ19kZXMpOwoJCQlzdGF0dXMgPSBpID4gd0xlbmd0aCA/IHdMZW5ndGggOiBpOwoJCQlsZW4gPSBsZW5pID4gc3RhdHVzID8gc3RhdHVzIDogbGVuaTsKCQkJbWVtY3B5KGRhdGEsIHJvb3RfaHViX2NvbmZpZ19kZXMsIGxlbik7CgkJCWJyZWFrOwoJCWNhc2UgKDB4MDMpOgkvKnN0cmluZyBkZXNjcmlwdG9ycyAqLwoJCQlpZiAod1ZhbHVlID09IDB4MDMwMCkgewoJCQkJaSA9IHNpemVvZihyb290X2h1Yl9zdHJfaW5kZXgwKTsKCQkJCXN0YXR1cyA9IGkgPiB3TGVuZ3RoID8gd0xlbmd0aCA6IGk7CgkJCQlsZW4gPSBsZW5pID4gc3RhdHVzID8gc3RhdHVzIDogbGVuaTsKCQkJCW1lbWNweShkYXRhLCByb290X2h1Yl9zdHJfaW5kZXgwLCBsZW4pOwoJCQkJYnJlYWs7CgkJCX0KCQkJaWYgKHdWYWx1ZSA9PSAweDAzMDEpIHsKCQkJCWkgPSBzaXplb2Yocm9vdF9odWJfc3RyX2luZGV4MSk7CgkJCQlzdGF0dXMgPSBpID4gd0xlbmd0aCA/IHdMZW5ndGggOiBpOwoJCQkJbGVuID0gbGVuaSA+IHN0YXR1cyA/IHN0YXR1cyA6IGxlbmk7CgkJCQltZW1jcHkoZGF0YSwgcm9vdF9odWJfc3RyX2luZGV4MSwgbGVuKTsKCQkJCWJyZWFrOwoJCQl9CgkJCXN0YXQgPSBVU0JfU1RfU1RBTExFRDsKCQl9CgkJYnJlYWs7CgoJY2FzZSBSSF9HRVRfREVTQ1JJUFRPUiB8IFJIX0NMQVNTOgoJCXJvb3RfaHViX2h1Yl9kZXNbMl0gPSAyOwoJCWkgPSBzaXplb2Yocm9vdF9odWJfaHViX2Rlcyk7CgkJc3RhdHVzID0gaSA+IHdMZW5ndGggPyB3TGVuZ3RoIDogaTsKCQlsZW4gPSBsZW5pID4gc3RhdHVzID8gc3RhdHVzIDogbGVuaTsKCQltZW1jcHkoZGF0YSwgcm9vdF9odWJfaHViX2RlcywgbGVuKTsKCQlicmVhazsKCWNhc2UgUkhfR0VUX0NPTkZJR1VSQVRJT046CgkJKih1bnNpZ25lZCBjaGFyICopZGF0YSA9IDB4MDE7CgkJbGVuID0gMTsKCQlicmVhazsKCWNhc2UgUkhfU0VUX0NPTkZJR1VSQVRJT046CgkJbGVuID0gMDsKCQlicmVhazsKCWRlZmF1bHQ6CgkJc3RhdCA9IFVTQl9TVF9TVEFMTEVEOwoJfQoJVVNCX1JIX1BSSU5URigiUm9vdC1IdWIgc3RhdCAlbHggcG9ydDE6ICV4IHBvcnQyOiAleFxuXG4iLCBzdGF0LAoJCSAgICAgIGluMTZyKHVzYl9iYXNlX2FkZHIgKyBVU0JQT1JUU0MxKSwKCQkgICAgICBpbjE2cih1c2JfYmFzZV9hZGRyICsgVVNCUE9SVFNDMikpOwoJZGV2LT5hY3RfbGVuID0gbGVuOwoJZGV2LT5zdGF0dXMgPSBzdGF0OwoJcmV0dXJuIHN0YXQ7Cgp9CgovKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKICogU29tZSBEZWJ1ZyBSb3V0aW5lcwogKi8KCiNpZmRlZglVU0JfUkhfREVCVUcKCnN0YXRpYyB2b2lkIHVzYl9kaXNwbGF5X1JlcSh1bnNpZ25lZCBzaG9ydCByZXEpCnsKCVVTQl9SSF9QUklOVEYoIi0gUm9vdC1IdWIgUmVxdWVzdDogIik7Cglzd2l0Y2ggKHJlcSkgewoJY2FzZSBSSF9HRVRfU1RBVFVTOgoJCVVTQl9SSF9QUklOVEYoIkdldCBTdGF0dXMgIik7CgkJYnJlYWs7CgljYXNlIFJIX0dFVF9TVEFUVVMgfCBSSF9JTlRFUkZBQ0U6CgkJVVNCX1JIX1BSSU5URigiR2V0IFN0YXR1cyBJbnRlcmZhY2UgIik7CgkJYnJlYWs7CgljYXNlIFJIX0dFVF9TVEFUVVMgfCBSSF9FTkRQT0lOVDoKCQlVU0JfUkhfUFJJTlRGKCJHZXQgU3RhdHVzIEVuZHBvaW50ICIpOwoJCWJyZWFrOwoJY2FzZSBSSF9HRVRfU1RBVFVTIHwgUkhfQ0xBU1M6CgkJVVNCX1JIX1BSSU5URigiR2V0IFN0YXR1cyBDbGFzcyIpOwoJCWJyZWFrOwkJLyogaHViIHBvd2VyICoqICovCgljYXNlIFJIX0dFVF9TVEFUVVMgfCBSSF9PVEhFUiB8IFJIX0NMQVNTOgoJCVVTQl9SSF9QUklOVEYoIkdldCBTdGF0dXMgQ2xhc3MgT3RoZXJzIik7CgkJYnJlYWs7CgljYXNlIFJIX0NMRUFSX0ZFQVRVUkUgfCBSSF9FTkRQT0lOVDoKCQlVU0JfUkhfUFJJTlRGKCJDbGVhciBGZWF0dXJlIEVuZHBvaW50ICIpOwoJCWJyZWFrOwoJY2FzZSBSSF9DTEVBUl9GRUFUVVJFIHwgUkhfQ0xBU1M6CgkJVVNCX1JIX1BSSU5URigiQ2xlYXIgRmVhdHVyZSBDbGFzcyAiKTsKCQlicmVhazsKCWNhc2UgUkhfQ0xFQVJfRkVBVFVSRSB8IFJIX09USEVSIHwgUkhfQ0xBU1M6CgkJVVNCX1JIX1BSSU5URigiQ2xlYXIgRmVhdHVyZSBPdGhlciBDbGFzcyAiKTsKCQlicmVhazsKCWNhc2UgUkhfU0VUX0ZFQVRVUkUgfCBSSF9PVEhFUiB8IFJIX0NMQVNTOgoJCVVTQl9SSF9QUklOVEYoIlNldCBGZWF0dXJlIE90aGVyIENsYXNzICIpOwoJCWJyZWFrOwoJY2FzZSBSSF9TRVRfQUREUkVTUzoKCQlVU0JfUkhfUFJJTlRGKCJTZXQgQWRkcmVzcyAiKTsKCQlicmVhazsKCWNhc2UgUkhfR0VUX0RFU0NSSVBUT1I6CgkJVVNCX1JIX1BSSU5URigiR2V0IERlc2NyaXB0b3IgIik7CgkJYnJlYWs7CgljYXNlIFJIX0dFVF9ERVNDUklQVE9SIHwgUkhfQ0xBU1M6CgkJVVNCX1JIX1BSSU5URigiR2V0IERlc2NyaXB0b3IgQ2xhc3MgIik7CgkJYnJlYWs7CgljYXNlIFJIX0dFVF9DT05GSUdVUkFUSU9OOgoJCVVTQl9SSF9QUklOVEYoIkdldCBDb25maWd1cmF0aW9uICIpOwoJCWJyZWFrOwoJY2FzZSBSSF9TRVRfQ09ORklHVVJBVElPTjoKCQlVU0JfUkhfUFJJTlRGKCJHZXQgQ29uZmlndXJhdGlvbiAiKTsKCQlicmVhazsKCWRlZmF1bHQ6CgkJVVNCX1JIX1BSSU5URigiKioqKlVOS05PV04qKioqIDB4JTA0WCAiLCByZXEpOwoJfQoJVVNCX1JIX1BSSU5URigiXG4iKTsKCn0KCnN0YXRpYyB2b2lkIHVzYl9kaXNwbGF5X3dWYWx1ZSh1bnNpZ25lZCBzaG9ydCB3VmFsdWUsIHVuc2lnbmVkIHNob3J0IHdJbmRleCkKewoJc3dpdGNoICh3VmFsdWUpIHsKCWNhc2UgKFJIX1BPUlRfRU5BQkxFKToKCQlVU0JfUkhfUFJJTlRGKCJSb290LUh1YjogRW5hYmxlIFBvcnQgJWRcbiIsIHdJbmRleCk7CgkJYnJlYWs7CgljYXNlIChSSF9QT1JUX1NVU1BFTkQpOgoJCVVTQl9SSF9QUklOVEYoIlJvb3QtSHViOiBTdXNwZW5kIFBvcnQgJWRcbiIsIHdJbmRleCk7CgkJYnJlYWs7CgljYXNlIChSSF9QT1JUX1BPV0VSKToKCQlVU0JfUkhfUFJJTlRGKCJSb290LUh1YjogUG9ydCBQb3dlciAlZFxuIiwgd0luZGV4KTsKCQlicmVhazsKCWNhc2UgKFJIX0NfUE9SVF9DT05ORUNUSU9OKToKCQlVU0JfUkhfUFJJTlRGKCJSb290LUh1YjogQyBQb3J0IENvbm5lY3Rpb24gUG9ydCAlZFxuIiwgd0luZGV4KTsKCQlicmVhazsKCWNhc2UgKFJIX0NfUE9SVF9FTkFCTEUpOgoJCVVTQl9SSF9QUklOVEYoIlJvb3QtSHViOiBDIFBvcnQgRW5hYmxlIFBvcnQgJWRcbiIsIHdJbmRleCk7CgkJYnJlYWs7CgljYXNlIChSSF9DX1BPUlRfU1VTUEVORCk6CgkJVVNCX1JIX1BSSU5URigiUm9vdC1IdWI6IEMgUG9ydCBTdXNwZW5kIFBvcnQgJWRcbiIsIHdJbmRleCk7CgkJYnJlYWs7CgljYXNlIChSSF9DX1BPUlRfT1ZFUl9DVVJSRU5UKToKCQlVU0JfUkhfUFJJTlRGKCJSb290LUh1YjogQyBQb3J0IE92ZXIgQ3VycmVudCBQb3J0ICVkXG4iLAoJCQkgICAgICB3SW5kZXgpOwoJCWJyZWFrOwoJY2FzZSAoUkhfQ19QT1JUX1JFU0VUKToKCQlVU0JfUkhfUFJJTlRGKCJSb290LUh1YjogQyBQb3J0IHJlc2V0IFBvcnQgJWRcbiIsIHdJbmRleCk7CgkJYnJlYWs7CglkZWZhdWx0OgoJCVVTQl9SSF9QUklOVEYoIlJvb3QtSHViOiB1bmtub3duICV4ICV4XG4iLCB3VmFsdWUsIHdJbmRleCk7CgkJYnJlYWs7Cgl9Cn0KCiNlbmRpZgoKLyojaWZkZWYJVVNCX1VIQ0lfREVCVUcqLwoKc3RhdGljIGludCB1c2JfZGlzcGxheV90ZCh1aGNpX3RkX3QgKiB0ZCkKewoJdW5zaWduZWQgbG9uZyB0bXA7CglpbnQgdmFsaWQ7CgoJcHJpbnRmKCJURCBhdCAlcDpcbiIsIHRkKTsKCgl0bXAgPSBzd2FwXzMyKFJFQUQzMigmdGQtPmxpbmspKTsKCXByaW50ZigiTGluayBwb2ludHMgdG8gMHglMDhsWCwgJXMgZmlyc3QsICVzLCAlc1xuIiwgdG1wICYgMHhmZmZmZmZmMCwKCSAgICAgICAoKHRtcCAmIDB4NCkgPT0gMHg0KSA/ICJEZXB0aCIgOiAiQnJlYXRoIiwKCSAgICAgICAoKHRtcCAmIDB4MikgPT0gMHgyKSA/ICJRSCIgOiAiVEQiLAoJICAgICAgICgodG1wICYgMHgxKSA9PSAweDEpID8gImludmFsaWQiIDogInZhbGlkIik7Cgl2YWxpZCA9ICgodG1wICYgMHgxKSA9PSAweDApOwoJdG1wID0gc3dhcF8zMihSRUFEMzIoJnRkLT5zdGF0dXMpKTsKCXByaW50ZgoJICAgICgiICAgICAlcyAlbGQgRXJyb3JzICVzICVzICVzIFxuICAgICAlcyAlcyAlcyAlcyAlcyAlc1xuICAgICBMZW4gMHglbFhcbiIsCgkgICAgICgoKHRtcCA+PiAyOSkgJiAweDEpID09IDB4MSkgPyAiU1BEIEVuYWJsZSIgOiAiU1BEIERpc2FibGUiLAoJICAgICAoKHRtcCA+PiAyOCkgJiAweDMpLAoJICAgICAoKCh0bXAgPj4gMjYpICYgMHgxKSA9PSAweDEpID8gIkxvdyBTcGVlZCIgOiAiRnVsbCBTcGVlZCIsCgkgICAgICgoKHRtcCA+PiAyNSkgJiAweDEpID09IDB4MSkgPyAiSVNPICIgOiAiIiwKCSAgICAgKCgodG1wID4+IDI0KSAmIDB4MSkgPT0gMHgxKSA/ICJJT0MgIiA6ICIiLAoJICAgICAoKCh0bXAgPj4gMjMpICYgMHgxKSA9PSAweDEpID8gIkFjdGl2ZSAiIDogIkluYWN0aXZlICIsCgkgICAgICgoKHRtcCA+PiAyMikgJiAweDEpID09IDB4MSkgPyAiU3RhbGxlZCIgOiAiIiwKCSAgICAgKCgodG1wID4+IDIxKSAmIDB4MSkgPT0gMHgxKSA/ICJEYXRhIEJ1ZmZlciBFcnJvciIgOiAiIiwKCSAgICAgKCgodG1wID4+IDIwKSAmIDB4MSkgPT0gMHgxKSA/ICJCYWJibGUiIDogIiIsCgkgICAgICgoKHRtcCA+PiAxOSkgJiAweDEpID09IDB4MSkgPyAiTkFLIiA6ICIiLAoJICAgICAoKCh0bXAgPj4gMTgpICYgMHgxKSA9PSAweDEpID8gIkJpdHN0dWZmIEVycm9yIiA6ICIiLAoJICAgICAodG1wICYgMHg3ZmYpKTsKCXRtcCA9IHN3YXBfMzIoUkVBRDMyKCZ0ZC0+aW5mbykpOwoJcHJpbnRmKCIgICAgIE1heExlbiAweCVsWFxuIiwgKCh0bXAgPj4gMjEpICYgMHg3RkYpKTsKCXByaW50ZigiICAgICAlc0VuZHBvaW50IDB4JWxYIERldiBBZGRyIDB4JWxYIFBJRCAweCVsWFxuIiwKCSAgICAgICAoKHRtcCA+PiAxOSkgJiAweDEpID09IDB4MSA/ICJUT0dHTEUgIiA6ICIiLCAoKHRtcCA+PiAxNSkgJiAweEYpLAoJICAgICAgICgodG1wID4+IDgpICYgMHg3RiksIHRtcCAmIDB4RkYpOwoJdG1wID0gc3dhcF8zMihSRUFEMzIoJnRkLT5idWZmZXIpKTsKCXByaW50ZigiICAgICBCdWZmZXIgMHglMDhsWFxuIiwgdG1wKTsKCXByaW50ZigiICAgICBERVYgJTA4bFhcbiIsIHRkLT5kZXZfcHRyKTsKCXJldHVybiB2YWxpZDsKfQoKdm9pZCB1c2Jfc2hvd190ZChpbnQgbWF4KQp7CglpbnQgaTsKCWlmIChtYXggPiAwKSB7CgkJZm9yIChpID0gMDsgaSA8IG1heDsgaSsrKSB7CgkJCXVzYl9kaXNwbGF5X3RkKCZ0bXBfdGRbaV0pOwoJCX0KCX0gZWxzZSB7CgkJaSA9IDA7CgkJZG8gewoJCQlwcmludGYoInRtcF90ZFslZF1cbiIsIGkpOwoJCX0gd2hpbGUgKHVzYl9kaXNwbGF5X3RkKCZ0bXBfdGRbaSsrXSkpOwoJfQp9Cgp2b2lkIGdydXNiX3Nob3dfcmVncyh2b2lkKQp7Cgl1bnNpZ25lZCBpbnQgdG1wOwoKCXRtcCA9IGluMTZyKHVzYl9iYXNlX2FkZHIgKyBVU0JDTUQpOwoJcHJpbnRmKCIgVVNCQ01EOiAgIDB4JTA0eFxuIiwgdG1wKTsKCXRtcCA9IGluMTZyKHVzYl9iYXNlX2FkZHIgKyBVU0JTVFMpOwoJcHJpbnRmKCIgVVNCU1RTOiAgIDB4JTA0eFxuIiwgdG1wKTsKCXRtcCA9IGluMTZyKHVzYl9iYXNlX2FkZHIgKyBVU0JJTlRSKTsKCXByaW50ZigiIFVTQklOVFI6ICAgMHglMDR4XG4iLCB0bXApOwoJdG1wID0gaW4xNnIodXNiX2Jhc2VfYWRkciArIFVTQkZSTlVNKTsKCXByaW50ZigiIEZSTlVNOiAgIDB4JTA0eFxuIiwgdG1wKTsKCXRtcCA9IGluMzJyKHVzYl9iYXNlX2FkZHIgKyBVU0JGTEJBU0VBREQpOwoJcHJpbnRmKCIgRkxCQVNFQUREOiAgIDB4JTA4eFxuIiwgdG1wKTsKCXRtcCA9IGluMTZyKHVzYl9iYXNlX2FkZHIgKyBVU0JTT0YpOwoJcHJpbnRmKCIgU09GTU9EOiAgIDB4JTA0eFxuIiwgdG1wKTsKCXRtcCA9IGluMTZyKHVzYl9iYXNlX2FkZHIgKyBVU0JQT1JUU0MxKTsKCXByaW50ZigiIFBPUlRTQzE6ICAgMHglMDR4XG4iLCB0bXApOwp9CgovKiNlbmRpZiovCiNlbmRpZgkJCQkvKiBDT05GSUdfVVNCX1VIQ0kgKi8KCi8qIEVPRiAqLwo=