LyoKICoKICogKEMpIENvcHlyaWdodCAyMDAyCiAqIERhbmllbCBFbmdzdHL2bSwgT21pY3JvbiBDZXRpIEFCIDxkYW5pZWxAb21pY3Jvbi5zZT4uCiAqCiAqIFNlZSBmaWxlIENSRURJVFMgZm9yIGxpc3Qgb2YgcGVvcGxlIHdobyBjb250cmlidXRlZCB0byB0aGlzCiAqIHByb2plY3QuCiAqCiAqIFRoaXMgcHJvZ3JhbSBpcyBmcmVlIHNvZnR3YXJlOyB5b3UgY2FuIHJlZGlzdHJpYnV0ZSBpdCBhbmQvb3IKICogbW9kaWZ5IGl0IHVuZGVyIHRoZSB0ZXJtcyBvZiB0aGUgR05VIEdlbmVyYWwgUHVibGljIExpY2Vuc2UgYXMKICogcHVibGlzaGVkIGJ5IHRoZSBGcmVlIFNvZnR3YXJlIEZvdW5kYXRpb247IGVpdGhlciB2ZXJzaW9uIDIgb2YKICogdGhlIExpY2Vuc2UsIG9yIChhdCB5b3VyIG9wdGlvbikgYW55IGxhdGVyIHZlcnNpb24uCiAqCiAqIFRoaXMgcHJvZ3JhbSBpcyBkaXN0cmlidXRlZCBpbiB0aGUgaG9wZSB0aGF0IGl0IHdpbGwgYmUgdXNlZnVsLAogKiBidXQgV0lUSE9VVCBBTlkgV0FSUkFOVFk7IHdpdGhvdXQgZXZlbiB0aGUgaW1wbGllZCB3YXJyYW50eSBvZgogKiBNRVJDSEFOVEFCSUxJVFkgb3IgRklUTkVTUyBGT1IgQSBQQVJUSUNVTEFSIFBVUlBPU0UuICBTZWUgdGhlCiAqIEdOVSBHZW5lcmFsIFB1YmxpYyBMaWNlbnNlIGZvciBtb3JlIGRldGFpbHMuCiAqCiAqIFlvdSBzaG91bGQgaGF2ZSByZWNlaXZlZCBhIGNvcHkgb2YgdGhlIEdOVSBHZW5lcmFsIFB1YmxpYyBMaWNlbnNlCiAqIGFsb25nIHdpdGggdGhpcyBwcm9ncmFtOyBpZiBub3QsIHdyaXRlIHRvIHRoZSBGcmVlIFNvZnR3YXJlCiAqIEZvdW5kYXRpb24sIEluYy4sIDU5IFRlbXBsZSBQbGFjZSwgU3VpdGUgMzMwLCBCb3N0b24sCiAqIE1BIDAyMTExLTEzMDcgVVNBCiAqLwoKI2luY2x1ZGUgPGNvbW1vbi5oPgojaW5jbHVkZSA8cGNpLmg+CiNpbmNsdWRlIDxzc2kuaD4KI2luY2x1ZGUgPG5ldGRldi5oPgojaW5jbHVkZSA8YXNtL2lvLmg+CiNpbmNsdWRlIDxhc20vcGNpLmg+CiNpbmNsdWRlIDxhc20vaWMvc2M1MjAuaD4KCkRFQ0xBUkVfR0xPQkFMX0RBVEFfUFRSOwoKLyoKICogVGhlb3J5OgogKiBXZSBmaXJzdCBzZXQgdXAgYWxsIElSUXMgdG8gYmUgbm9uLXBjaSwgZWRnZSB0cmlnZ2VyZWQsCiAqIHdoZW4gd2UgbGF0ZXIgZW51bWVyYXRlIHRoZSBwY2kgYnVzIGFuZCBwY2lfc2M1MjBfZml4dXBfaXJxKCkgZ2V0cwogKiBjYWxsZWQgd2UgcmVhbGxvY2F0ZSBpcnFzIHRvIHRoZSBwY2kgYnVzIHdpdGggc2M1MjBfcGNpX3NldF9pcnEoKQogKiBhcyBuZWVkZWQuIFdoZSBjaG9vc2UgdGhlIGlycXMgdG8gZ3JhbSBmcm9tIGEgY29uZmlndXJhYmxlIGxpc3QKICogaW5zaWRlIHBjaV9zYzUyMF9maXh1cF9pcnEoKSAoSWYgdGhpcyBsaXN0IGNvbnRhaW5zIHN0dXBpZCBpcnEncwogKiBzdWNoIGFzIDAgdGhuZ2FzIHdpbGwgbm90IHdvcmspCiAqLwoKc3RhdGljIHZvaWQgaXJxX2luaXQodm9pZCkKewoJLyogZGlzYWJsZSBnbG9iYWwgaW50ZXJydXB0IG1vZGUgKi8KCXdyaXRlX21tY3JfYnl0ZShTQzUyMF9QSUNJQ1IsIDB4NDApOwoKCS8qIHNldCBhbGwgaXJxcyB0byBlZGdlICovCgl3cml0ZV9tbWNyX2J5dGUoU0M1MjBfTVBJQ01PREUsIDB4MDApOwoJd3JpdGVfbW1jcl9ieXRlKFNDNTIwX1NMMVBJQ01PREUsIDB4MDApOwoJd3JpdGVfbW1jcl9ieXRlKFNDNTIwX1NMMlBJQ01PREUsIDB4MDApOwoKCS8qIGFjdGl2ZSBsb3cgcG9sYXJpdHkgb24gUElDIGludGVycnVwdCBwaW5zLAoJICogIGFjdGl2ZSBoaWdoIHBvbGFyaXR5IG9uIGFsbCBvdGhlciBpcnEgcGlucyAqLwoJd3JpdGVfbW1jcl93b3JkKFNDNTIwX0lOVFBJTlBPTCwgMHgwMDAwKTsKCgkvKiBzZXQgaXJxIG51bWJlciBtYXBwaW5nICovCgl3cml0ZV9tbWNyX2J5dGUoU0M1MjBfR1BUTVIwTUFQLCBTQzUyMF9JUlFfRElTQUJMRUQpOyAgIC8qIGRpc2FibGUgR1AgdGltZXIgMCBJTlQgKi8KCXdyaXRlX21tY3JfYnl0ZShTQzUyMF9HUFRNUjFNQVAsIFNDNTIwX0lSUV9ESVNBQkxFRCk7ICAgLyogZGlzYWJsZSBHUCB0aW1lciAxIElOVCAqLwoJd3JpdGVfbW1jcl9ieXRlKFNDNTIwX0dQVE1SMk1BUCwgU0M1MjBfSVJRX0RJU0FCTEVEKTsgICAvKiBkaXNhYmxlIEdQIHRpbWVyIDIgSU5UICovCgl3cml0ZV9tbWNyX2J5dGUoU0M1MjBfUElUME1BUCwgU0M1MjBfSVJRMCk7ICAgICAgICAgICAgIC8qIFNldCBQSVQgdGltZXIgMCBJTlQgdG8gSVJRMCAqLwoJd3JpdGVfbW1jcl9ieXRlKFNDNTIwX1BJVDFNQVAsIFNDNTIwX0lSUV9ESVNBQkxFRCk7ICAgICAvKiBkaXNhYmxlIFBJVCB0aW1lciAxIElOVCAqLwoJd3JpdGVfbW1jcl9ieXRlKFNDNTIwX1BJVDJNQVAsIFNDNTIwX0lSUV9ESVNBQkxFRCk7ICAgICAvKiBkaXNhYmxlIFBJVCB0aW1lciAyIElOVCAqLwoJd3JpdGVfbW1jcl9ieXRlKFNDNTIwX1BDSUlOVEFNQVAsIFNDNTIwX0lSUV9ESVNBQkxFRCk7ICAvKiBkaXNhYmxlIFBDSSBJTlQgQSAqLwoJd3JpdGVfbW1jcl9ieXRlKFNDNTIwX1BDSUlOVEJNQVAsIFNDNTIwX0lSUV9ESVNBQkxFRCk7ICAvKiBkaXNhYmxlIFBDSSBJTlQgQiAqLwoJd3JpdGVfbW1jcl9ieXRlKFNDNTIwX1BDSUlOVENNQVAsIFNDNTIwX0lSUV9ESVNBQkxFRCk7ICAvKiBkaXNhYmxlIFBDSSBJTlQgQyAqLwoJd3JpdGVfbW1jcl9ieXRlKFNDNTIwX1BDSUlOVERNQVAsIFNDNTIwX0lSUV9ESVNBQkxFRCk7ICAvKiBkaXNhYmxlIFBDSSBJTlQgRCAqLwoJd3JpdGVfbW1jcl9ieXRlKFNDNTIwX0RNQUJDSU5UTUFQLCBTQzUyMF9JUlFfRElTQUJMRUQpOyAvKiBkaXNhYmxlIERNQSBJTlQgKi8KCXdyaXRlX21tY3JfYnl0ZShTQzUyMF9TU0lNQVAsIFNDNTIwX0lSUTYpOyAgICAgICAgICAgICAgLyogU2V0IFN5bmNocm9uaXVzIHNlcmlhbCBJTlQgdG8gSVJRNiovCgl3cml0ZV9tbWNyX2J5dGUoU0M1MjBfV0RUTUFQLCBTQzUyMF9JUlFfRElTQUJMRUQpOyAgICAgIC8qIGRpc2FibGUgV2F0Y2hkb2cgSU5UICovCgl3cml0ZV9tbWNyX2J5dGUoU0M1MjBfUlRDTUFQLCBTQzUyMF9JUlE4KTsgICAgICAgICAgICAgIC8qIFNldCBSVEMgaW50IHRvIDggKi8KCXdyaXRlX21tY3JfYnl0ZShTQzUyMF9XUFZNQVAsIFNDNTIwX0lSUV9ESVNBQkxFRCk7ICAgICAgLyogZGlzYWJsZSB3cml0ZSBwcm90ZWN0IElOVCAqLwoJd3JpdGVfbW1jcl9ieXRlKFNDNTIwX0lDRU1BUCwgU0M1MjBfSVJRMSk7ICAgICAgICAgICAgICAvKiBTZXQgSUNFIERlYnVnIFNlcmllbHBvcnQgSU5UIHRvIElSUTEgKi8KCXdyaXRlX21tY3JfYnl0ZShTQzUyMF9GRVJSTUFQLFNDNTIwX0lSUTEzKTsgICAgICAgICAgICAgLyogU2V0IEZQIGVycm9yIElOVCB0byBJUlExMyAqLwoKCXdyaXRlX21tY3JfYnl0ZShTQzUyMF9VQVJUMU1BUCwgU0M1MjBfSVJRNCk7ICAgICAgICAgICAgLyogU2V0IGludGVybmFsIFVBUlQyIElOVCB0byBJUlE0ICovCgl3cml0ZV9tbWNyX2J5dGUoU0M1MjBfVUFSVDJNQVAsIFNDNTIwX0lSUTMpOyAgICAgICAgICAgIC8qIFNldCBpbnRlcm5hbCBVQVJUMiBJTlQgdG8gSVJRMyAqLwoKCXdyaXRlX21tY3JfYnl0ZShTQzUyMF9HUDBJTUFQLCBTQzUyMF9JUlE3KTsgICAgICAgICAgICAgLyogU2V0IEdQSVJRMCAoUEMtQ2FyZCBBVVggSVJRKSB0byBJUlE3ICovCgl3cml0ZV9tbWNyX2J5dGUoU0M1MjBfR1AxSU1BUCwgU0M1MjBfSVJRMTQpOyAgICAgICAgICAgIC8qIFNldCBHUElSUTEgKENGIElSUSkgdG8gSVJRMTQgKi8KCXdyaXRlX21tY3JfYnl0ZShTQzUyMF9HUDNJTUFQLCBTQzUyMF9JUlE1KTsgICAgICAgICAgICAgLyogU2V0IEdQSVJRMyAoIENBTiBJUlEgKSB0aSBJUlE1ICovCgl3cml0ZV9tbWNyX2J5dGUoU0M1MjBfR1A0SU1BUCwgU0M1MjBfSVJRX0RJU0FCTEVEKTsgICAgIC8qIGRpc2JhbGUgR0lSUTQgKCBJUlIgSVJRICkgKi8KCXdyaXRlX21tY3JfYnl0ZShTQzUyMF9HUDVJTUFQLCBTQzUyMF9JUlFfRElTQUJMRUQpOyAgICAgLyogZGlzYWJsZSBHUElSUTUgKi8KCXdyaXRlX21tY3JfYnl0ZShTQzUyMF9HUDZJTUFQLCBTQzUyMF9JUlFfRElTQUJMRUQpOyAgICAgLyogZGlzYWJsZSBHUElSUTYgKi8KCXdyaXRlX21tY3JfYnl0ZShTQzUyMF9HUDdJTUFQLCBTQzUyMF9JUlFfRElTQUJMRUQpOyAgICAgLyogZGlzYWJsZSBHUElSUTcgKi8KCXdyaXRlX21tY3JfYnl0ZShTQzUyMF9HUDhJTUFQLCBTQzUyMF9JUlFfRElTQUJMRUQpOyAgICAgLyogZGlzYWJsZSBHUElSUTggKi8KCXdyaXRlX21tY3JfYnl0ZShTQzUyMF9HUDlJTUFQLCBTQzUyMF9JUlFfRElTQUJMRUQpOyAgICAgLyogZGlzYWJsZSBHUElSUTkgKi8KCXdyaXRlX21tY3JfYnl0ZShTQzUyMF9HUDJJTUFQLCBTQzUyMF9JUlFfRElTQUJMRUQpOyAgICAgLyogZGlzYWJsZSBHUElSUTIgKi8KCXdyaXRlX21tY3JfYnl0ZShTQzUyMF9HUDEwSU1BUCxTQzUyMF9JUlFfRElTQUJMRUQpOyAgICAgLyogZGlzYWJsZSBHUElSUTEwICovCgoJd3JpdGVfbW1jcl93b3JkKFNDNTIwX1BDSUhPU1RNQVAsIDB4MTFmKTsgICAgICAgICAgICAgICAvKiBNYXAgUENJIGhvc3RicmlkZ2UgSU5UIHRvIE5NSSAqLwoJd3JpdGVfbW1jcl93b3JkKFNDNTIwX0VDQ01BUCwgMHgxMDApOyAgICAgICAgICAgICAgICAgICAvKiBNYXAgU0RSQU0gRUNDIGZhaWx1cmUgSU5UIHRvIE5NSSAqLwoKfQoKCi8qIFBDSSBzdHVmZiAqLwpzdGF0aWMgdm9pZCBwY2lfc2M1MjBfc3B1bmtfZml4dXBfaXJxKHN0cnVjdCBwY2lfY29udHJvbGxlciAqaG9zZSwgcGNpX2Rldl90IGRldikKewoJaW50IHZlcnNpb24gPSByZWFkX21tY3JfYnl0ZShTQzUyMF9TWVNJTkZPKTsKCgkvKiBhIGNvbmZpZ3VyYWJsZSBsaXN0cyBvZiBpcnFzIHRvIHN0ZWFsCgkgKiB3aGVuIHdlIG5lZWQgb25lIChhIGJvYXJkIHdpdGggbW9yZSBwY2kgaW50ZXJydXB0IHBpbnMKCSAqIHdvdWxkIHVzZSBhIGxhcmdlciB0YWJsZSAqLwoJc3RhdGljIGludCBpcnFfbGlzdFtdID0gewoJCUNPTkZJR19TWVNfRklSU1RfUENJX0lSUSwKCQlDT05GSUdfU1lTX1NFQ09ORF9QQ0lfSVJRLAoJCUNPTkZJR19TWVNfVEhJUkRfUENJX0lSUSwKCQlDT05GSUdfU1lTX0ZPUlRIX1BDSV9JUlEKCX07CglzdGF0aWMgaW50IG5leHRfaXJxX2luZGV4PTA7CgoJY2hhciB0bXBfcGluOwoJaW50IHBpbjsKCglwY2lfaG9zZV9yZWFkX2NvbmZpZ19ieXRlKGhvc2UsIGRldiwgUENJX0lOVEVSUlVQVF9QSU4sICZ0bXBfcGluKTsKCXBpbiA9IHRtcF9waW47CgoJcGluLT0xOyAvKiBwY2kgY29uZmlnIHNwYWNlIHVzZSAxLWJhc2VkIG51bWJlcmluZyAqLwoJaWYgKC0xID09IHBpbikgewoJCXJldHVybjsgLyogZGV2aWNlIHVzZSBubyBpcnEgKi8KCX0KCgoJLyogbWFwIGRldmljZSBudW1iZXIgKyAgcGluIHRvIGEgcGluIG9uIHRoZSBzYzUyMCAqLwoJc3dpdGNoIChQQ0lfREVWKGRldikpIHsKCWNhc2UgNjogIC8qIEVUSDAgKi8KCQlwaW4rPVNDNTIwX1BDSV9JTlRBOwoJCWJyZWFrOwoKCWNhc2UgNzogIC8qIEVUSDEgKi8KCQlwaW4rPVNDNTIwX1BDSV9JTlRCOwoJCWJyZWFrOwoKCWNhc2UgODogIC8qIENyeXB0byAqLwoJCXBpbis9U0M1MjBfUENJX0lOVEM7CgkJYnJlYWs7CgoJY2FzZSA5OiAvKiBQTUMgc2xvdCAqLwoJCXBpbis9U0M1MjBfUENJX0lOVEQ7CgkJYnJlYWs7CgoJY2FzZSAxMDogLyogUEMtQ2FyZCAqLwoKCQlpZiAodmVyc2lvbiA8IDEwKSB7CgkJCXBpbis9U0M1MjBfUENJX0lOVEQ7CgkJfSBlbHNlIHsKCQkJcGluKz1TQzUyMF9QQ0lfSU5UQzsKCQl9CgkJYnJlYWs7CgoJZGVmYXVsdDoKCQlyZXR1cm47Cgl9CgoJcGluJj0zOyAvKiB3cmFwIGFyb3VuZCAqLwoKCWlmIChzYzUyMF9wY2lfaW50c1twaW5dID09IC0xKSB7CgkJLyogcmUtcm91dGUgb25lIGludGVycnVwdCBmb3IgdXMgKi8KCQlpZiAobmV4dF9pcnFfaW5kZXggPiAzKSB7CgkJCXJldHVybjsKCQl9CgkJaWYgKHBjaV9zYzUyMF9zZXRfaXJxKHBpbiwgaXJxX2xpc3RbbmV4dF9pcnFfaW5kZXhdKSkgewoJCQlyZXR1cm47CgkJfQoJCW5leHRfaXJxX2luZGV4Kys7Cgl9CgoKCWlmICgtMSAhPSBzYzUyMF9wY2lfaW50c1twaW5dKSB7CgkJcGNpX2hvc2Vfd3JpdGVfY29uZmlnX2J5dGUoaG9zZSwgZGV2LCBQQ0lfSU5URVJSVVBUX0xJTkUsCgkJCQkJICAgc2M1MjBfcGNpX2ludHNbcGluXSk7Cgl9CiNpZiAwCglwcmludGYoImZpeHVwX2lycTogZGV2aWNlICVkIHBpbiAlYyBpcnEgJWRcbiIsCgkgICAgICAgUENJX0RFVihkZXYpLCAnQScgKyBwaW4sIHNjNTIwX3BjaV9pbnRzW3Bpbl0pOwojZW5kaWYKfQoKCnN0YXRpYyB2b2lkIHBjaV9zYzUyMF9zcHVua19jb25maWd1cmVfY2FyZGJ1cyhzdHJ1Y3QgcGNpX2NvbnRyb2xsZXIgKmhvc2UsCgkJCQkJICAgICAgcGNpX2Rldl90IGRldiwgc3RydWN0IHBjaV9jb25maWdfdGFibGUgKnRlKQp7Cgl1MzIgaW9fYmFzZTsKCXUzMiB0ZW1wOwoKCXBjaWF1dG9fY29uZmlnX2RldmljZShob3NlLCBkZXYpOwoKCXBjaV9ob3NlX3dyaXRlX2NvbmZpZ193b3JkKGhvc2UsIGRldiwgUENJX0NPTU1BTkQsIDB4MDcpOyAgLyogZW5hYmxlIGRldmljZSAqLwoJcGNpX2hvc2Vfd3JpdGVfY29uZmlnX2J5dGUoaG9zZSwgZGV2LCAweDBjLCAweDEwKTsgICAgICAgICAvKiBjYWNoZWxpbmUgc2l6ZSAqLwoJcGNpX2hvc2Vfd3JpdGVfY29uZmlnX2J5dGUoaG9zZSwgZGV2LCAweDBkLCAweDQwKTsgICAgICAgICAvKiBsYXRlbmN5IHRpbWVyICovCglwY2lfaG9zZV93cml0ZV9jb25maWdfYnl0ZShob3NlLCBkZXYsIDB4MWIsIDB4NDApOyAgICAgICAgIC8qIGNhcmRidXMgbGF0ZW5jeSB0aW1lciAqLwoJcGNpX2hvc2Vfd3JpdGVfY29uZmlnX3dvcmQoaG9zZSwgZGV2LCBQQ0lfQlJJREdFX0NPTlRST0wsIDB4MDA0MCk7ICAvKiByZXNldCBjYXJkYnVzICovCglwY2lfaG9zZV93cml0ZV9jb25maWdfd29yZChob3NlLCBkZXYsIFBDSV9CUklER0VfQ09OVFJPTCwgMHgwMDgwKTsgIC8qIHJvdXRlIGludGVycnVwdHMgdGhvdWdoIEV4Q0EgKi8KCXBjaV9ob3NlX3dyaXRlX2NvbmZpZ193b3JkKGhvc2UsIGRldiwgIDB4NDQsIDB4M2UwKTsgLyogbWFwIGxlZ2FjeSBJL08gcG9ydCB0byAweDNlMCAqLwoKCXBjaV9ob3NlX3JlYWRfY29uZmlnX2R3b3JkKGhvc2UsIGRldiwgIDB4ODAsICZ0ZW1wKTsgLyogU3lzdGVtIGNvbnRyb2wgKi8KCXBjaV9ob3NlX3dyaXRlX2NvbmZpZ19kd29yZChob3NlLCBkZXYsICAweDgwLCB0ZW1wIHwgMHg2MCk7IC8qIFN5c3RlbSBjb250cm9sOiBkaXNhYmxlIGNsb2NrcnVuICovCgkvKiByb3V0ZSBNRjAgdG8gfklOVCBhbmQgTUYzIHRvIElSUTcKCSAqIHJlc2VydmUgYWxsIG90aGVycyAqLwoJcGNpX2hvc2Vfd3JpdGVfY29uZmlnX2R3b3JkKGhvc2UsIGRldiwgMHg4YywgMHgwMDAwNzAwMik7CglwY2lfaG9zZV93cml0ZV9jb25maWdfYnl0ZShob3NlLCBkZXYsIDB4OTEsIDB4MDApOyAgICAvKiBjYXJkIGNvbnRyb2wgKi8KCXBjaV9ob3NlX3dyaXRlX2NvbmZpZ19ieXRlKGhvc2UsIGRldiwgMHg5MiwgMHg2Mik7ICAgIC8qIGRldmljZSBjb250cm9sICovCgoJaWYgKHRlLT5kZXZpY2UgIT0gMHhhYzU2KSB7CgkJcGNpX2hvc2Vfd3JpdGVfY29uZmlnX2J5dGUoaG9zZSwgZGV2LCAweDkzLCAweDIxKTsgICAgLyogYXN5bmMgaW50ZXJydXB0IGVuYWJsZSAqLwoJCXBjaV9ob3NlX3dyaXRlX2NvbmZpZ193b3JkKGhvc2UsIGRldiwgMHhhOCwgMHgwMDAwKTsgIC8qIHJlc2V0IEdQSU8gKi8KCQlwY2lfaG9zZV93cml0ZV9jb25maWdfd29yZChob3NlLCBkZXYsIDB4YWMsIDB4MDAwMCk7ICAvKiByZXNldCBHUElPICovCgkJcGNpX2hvc2Vfd3JpdGVfY29uZmlnX3dvcmQoaG9zZSwgZGV2LCAweGFhLCAweDAwMDApOyAgLyogcmVzZXQgR1BJTyAqLwoJCXBjaV9ob3NlX3dyaXRlX2NvbmZpZ193b3JkKGhvc2UsIGRldiwgMHhhZSwgMHgwMDAwKTsgIC8qIHJlc2V0IEdQSU8gKi8KCX0gZWxzZSB7CgkJcGNpX2hvc2Vfd3JpdGVfY29uZmlnX2J5dGUoaG9zZSwgZGV2LCAweDkzLCAweDIwKTsgICAgLyogICovCgl9CglwY2lfaG9zZV93cml0ZV9jb25maWdfd29yZChob3NlLCBkZXYsIDB4YTQsIDB4ODAwMCk7ICAvKiByZXNldCBwb3dlciBtYW5hZ2VtZW50ICovCgoKCXBjaV9ob3NlX3JlYWRfY29uZmlnX2R3b3JkKGhvc2UsIGRldiwgUENJX0JBU0VfQUREUkVTU18wLCAmaW9fYmFzZSk7Cglpb19iYXNlICY9IH4weGZMOwoKCXdyaXRlYigweDA3LCBpb19iYXNlKzB4ODAzKTsgLyogcm91dGUgQ1NDIGlycSB0aG91Z2ggRXhDQSBhbmQgZW5hYmxlIElSUTcgKi8KCXdyaXRlbCgwLCBpb19iYXNlKzB4MTApOyAgICAgLyogQ0xLUlVOIGRlZmF1bHQgKi8KCXdyaXRlbCgwLCBpb19iYXNlKzB4MjApOyAgICAgLyogQ0xLUlVOIGRlZmF1bHQgKi8KCn0KCgpzdGF0aWMgc3RydWN0IHBjaV9jb25maWdfdGFibGUgcGNpX3NjNTIwX3NwdW5rX2NvbmZpZ190YWJsZVtdID0gewoJeyAweDEwNGMsIDB4YWM1MCwgUENJX0FOWV9JRCwgMCwgMHgwYSwgMCwgcGNpX3NjNTIwX3NwdW5rX2NvbmZpZ3VyZV9jYXJkYnVzLCB7IDAsIDAsIDB9IH0sCgl7IDB4MTA0YywgMHhhYzU2LCBQQ0lfQU5ZX0lELCAwLCAweDBhLCAwLCBwY2lfc2M1MjBfc3B1bmtfY29uZmlndXJlX2NhcmRidXMsIHsgMCwgMCwgMH0gfSwKCXsgMCwgMCwgMCwgMCwgMCwgMCwgTlVMTCwgezAsMCwwfX0KfTsKCnN0YXRpYyBzdHJ1Y3QgcGNpX2NvbnRyb2xsZXIgc2M1MjBfc3B1bmtfaG9zZSA9IHsKCWZpeHVwX2lycTogcGNpX3NjNTIwX3NwdW5rX2ZpeHVwX2lycSwKCWNvbmZpZ190YWJsZTogcGNpX3NjNTIwX3NwdW5rX2NvbmZpZ190YWJsZSwKCWZpcnN0X2J1c25vOiAweDAwLAoJbGFzdF9idXNubzogMHhmZiwKfTsKCnZvaWQgcGNpX2luaXRfYm9hcmQodm9pZCkKewoJcGNpX3NjNTIwX2luaXQoJnNjNTIwX3NwdW5rX2hvc2UpOwp9CgoKLyogc2V0IHVwIHRoZSBJU0EgYnVzIHRpbWluZyBhbmQgc3lzdGVtIGFkZHJlc3MgbWFwcGluZ3MgKi8Kc3RhdGljIHZvaWQgYnVzX2luaXQodm9pZCkKewoJLyogdmVyc2lvbnMKCSAqIDAgICBIeWdsbyB2ZXJzaW9ucyAwLjk1IGFuZCAwLjk2IChsYXJnZSBiYW9yZHMpCgkgKiA/PyAgSHlnbG8gdmVyc2lvbiAwLjk3IChzbWFsbCBib2FyZCkKCSAqIDEwICBTcHVuayBib2FyZAoJICovCglpbnQgdmVyc2lvbiA9IHJlYWRfbW1jcl9ieXRlKFNDNTIwX1NZU0lORk8pOwoKCWlmICh2ZXJzaW9uKSB7CgkJLyogc2V0IHVwIHRoZSBHUCBJTyBwaW5zIChmb3IgdGhlIFNwdW5rIGJvYXJkKSAqLwoJCXdyaXRlX21tY3Jfd29yZChTQzUyMF9QSU9QRlMzMV8xNiwgMHhmZmYwKTsJLyogc2V0IHRoZSBHUElPIHBpbiBmdW5jdGlvbiAzMS0xNiByZWcgKi8KCQl3cml0ZV9tbWNyX3dvcmQoU0M1MjBfUElPUEZTMTVfMCwgIDB4MDAwZik7CS8qIHNldCB0aGUgR1BJTyBwaW4gZnVuY3Rpb24gMTUtMCByZWcgKi8KCQl3cml0ZV9tbWNyX3dvcmQoU0M1MjBfUElPRElSMzFfMTYsIDB4MDAwZik7CS8qIHNldCB0aGUgR1BJTyBkaXJlY3Rpb24gMzEtMTYgcmVnICovCgkJd3JpdGVfbW1jcl93b3JkKFNDNTIwX1BJT0RJUjE1XzAsICAweDFmZjApOwkvKiBzZXQgdGhlIEdQSU8gZGlyZWN0aW9uIDE1LTAgcmVnICovCgkJd3JpdGVfbW1jcl9ieXRlKFNDNTIwX0NTUEZTLCAweGMwKTsJCS8qIHNldCB0aGUgQ1MgcGluIGZ1bmN0aW9uIHJlZyAqLwoJCXdyaXRlX21tY3JfYnl0ZShTQzUyMF9DTEtTRUwsIDB4NzApOwoKCQl3cml0ZV9tbWNyX3dvcmQoU0M1MjBfUElPQ0xSMzFfMTYsIDB4MDAwMyk7ICAgICAvKiByZXNldCBTU0kgY2hpcC1zZWxlY3RzICovCgkJd3JpdGVfbW1jcl93b3JkKFNDNTIwX1BJT1NFVDMxXzE2LCAweDAwMGMpOwoKCX0gZWxzZSB7CgkJLyogc2V0IHVwIHRoZSBHUCBJTyBwaW5zIChmb3IgdGhlIEh5Z2xvIGJvYXJkKSAqLwoJCXdyaXRlX21tY3Jfd29yZChTQzUyMF9QSU9QRlMzMV8xNiwgMHhmZmMwKTsJLyogc2V0IHRoZSBHUElPIHBpbiBmdW5jdGlvbiAzMS0xNiByZWcgKi8KCQl3cml0ZV9tbWNyX3dvcmQoU0M1MjBfUElPUEZTMTVfMCwgMHgxZTdmKTsJLyogc2V0IHRoZSBHUElPIHBpbiBmdW5jdGlvbiAxNS0wIHJlZyAqLwoJCXdyaXRlX21tY3Jfd29yZChTQzUyMF9QSU9ESVIzMV8xNiwgMHgwMDNmKTsJLyogc2V0IHRoZSBHUElPIGRpcmVjdGlvbiAzMS0xNiByZWcgKi8KCQl3cml0ZV9tbWNyX3dvcmQoU0M1MjBfUElPRElSMTVfMCwgMHhlMTgwKTsJLyogc2V0IHRoZSBHUElPIGRpcmVjdGlvbiAxNS0wIHJlZyAqLwoJCXdyaXRlX21tY3JfYnl0ZShTQzUyMF9DU1BGUywgMHgwMCk7CQkvKiBzZXQgdGhlIENTIHBpbiBmdW5jdGlvbiByZWcgKi8KCQl3cml0ZV9tbWNyX2J5dGUoU0M1MjBfQ0xLU0VMLCAweDcwKTsKCgkJd3JpdGVfbW1jcl93b3JkKFNDNTIwX1BJT0NMUjE1XzAsIDB4MDE4MCk7ICAgICAgLyogcmVzZXQgU1NJIGNoaXAtc2VsZWN0cyAqLwoJfQoKCXdyaXRlX21tY3JfYnl0ZShTQzUyMF9HUENTUlQsIDEpOyAgIC8qIHNldCB0aGUgR1AgQ1Mgb2Zmc2V0ICovCgl3cml0ZV9tbWNyX2J5dGUoU0M1MjBfR1BDU1BXLCAzKTsgICAvKiBzZXQgdGhlIEdQIENTIHB1bHNlIHdpZHRoICovCgl3cml0ZV9tbWNyX2J5dGUoU0M1MjBfR1BDU09GRiwgMSk7ICAvKiBzZXQgdGhlIEdQIENTIG9mZnNldCAqLwoJd3JpdGVfbW1jcl9ieXRlKFNDNTIwX0dQUkRXLCAzKTsgICAgLyogc2V0IHRoZSBSRCBwdWxzZSB3aWR0aCAqLwoJd3JpdGVfbW1jcl9ieXRlKFNDNTIwX0dQUkRPRkYsIDEpOyAgLyogc2V0IHRoZSBHUCBSRCBvZmZzZXQgKi8KCXdyaXRlX21tY3JfYnl0ZShTQzUyMF9HUFdSVywgMyk7ICAgIC8qIHNldCB0aGUgR1AgV1IgcHVsc2Ugd2lkdGggKi8KCXdyaXRlX21tY3JfYnl0ZShTQzUyMF9HUFdST0ZGLCAxKTsgIC8qIHNldCB0aGUgR1AgV1Igb2Zmc2V0ICovCgoJd3JpdGVfbW1jcl93b3JkKFNDNTIwX0JPT1RDU0NUTCwgMHgwNDA3KTsJCS8qIHNldCB1cCB0aW1pbmcgb2YgQk9PVENTICovCgoJLyogYWRqdXN0IHRoZSBtZW1vcnkgbWFwOgoJICogYnkgZGVmYXVsdCB0aGUgZmlyc3QgMjU2TUIgKDB4MDAwMDAwMDAgLSAweDBmZmZmZmZmKSBpcyBtYXBwZWQgdG8gU0RSQU0KCSAqIGFuZCAyNTZNQiB0byAxRy0xMjhrICAoMHgxMDAwMDAwIC0gMHgzN2ZmZmZmZikgaXMgbWFwcGVkIHRvIFBDSSBtbWlvCgkgKiB3ZSBuZWVkIHRvIG1hcCAxRy0xMjhrIC0gMUcgKDB4MzgwMDAwMDAgLSAweDNmZmZmZmZmKSB0byBDUzEgKi8KCgoJLyogYm9vdGNzICovCgl3cml0ZV9tbWNyX2xvbmcoU0M1MjBfUEFSMTIsIDB4OGJmZmU4MDApOwoKCS8qIElERTAgPSBHUENTNiAxZjAtMWY3ICovCgl3cml0ZV9tbWNyX2xvbmcoU0M1MjBfUEFSMywgIDB4MzgwODAxZjApOwoKCS8qIElERTEgPSBHUENTNyAzZjYgKi8KCXdyaXRlX21tY3JfbG9uZyhTQzUyMF9QQVI0LCAgMHgzYzAwMDNmNik7CgoJYXNtICgid2JpbnZkXG4iKTsgLyogRmx1c2ggY2FjaGUsIHJlcS4gYWZ0ZXIgc2V0dGluZyB0aGUgdW5jaGFjaGVkIGF0dHJpYnV0ZSBvbmEgUEFSICovCgoJd3JpdGVfbW1jcl9ieXRlKFNDNTIwX0FERERFQ0NUTCwgcmVhZF9tbWNyX2J5dGUoU0M1MjBfQUREREVDQ1RMKSAmIH4oVUFSVDJfRElTfFVBUlQxX0RJUykpOwoKfQoKCi8qIHBhciB1c2FnZToKICogUEFSMCAgIChsZWdhY3lfdmlkZW8pCiAqIFBBUjEgICAoUENJIFJPTSBtYXBwaW5nKQogKiBQQVIyCiAqIFBBUjMgICBJREUKICogUEFSNCAgIElERQogKiBQQVI1ICAgKGxlZ2FjeV92aWRlbykKICogUEFSNgogKiBQQVI3ICAgKGxlZ2FjeV92aWRlbykKICogUEFSOCAgIChsZWdhY3lfdmlkZW8pCiAqIFBBUjkgICAobGVnYWN5X3ZpZGVvKQogKiBQQVIxMAogKiBQQVIxMSAgKElTQVJPTSkKICogUEFSMTIgIEJPT1RDUwogKiBQQVIxMwogKiBQQVIxNAogKiBQQVIxNQogKi8KCi8qCiAqIFRoaXMgZnVuY3Rpb24gc2hvdWxkIG1hcCBhIGNodW5rIG9mIHNpemUgYnl0ZXMKICogb2YgdGhlIHN5c3RlbSBhZGRyZXNzIHNwYWNlIHRvIHRoZSBJU0EgYnVzCiAqCiAqIFRoZSBmdW5jdGlvbiB3aWxsIHJldHVybiB0aGUgbWVtb3J5IGFkZHJlc3MKICogYXMgc2VlbiBieSB0aGUgaG9zdCAod2hpY2ggbWF5IHZlcnkgd2lsbCBiZSB0aGUKICogc2FtZSBhcyB0aGUgYnVzIGFkZHJlc3MpCiAqLwp1MzIgaXNhX21hcF9yb20odTMyIGJ1c19hZGRyLCBpbnQgc2l6ZSkKewoJdTMyIHBhcjsKCglwcmludGYoImlzYV9tYXBfcm9tIGFza2VkIHRvIG1hcCAlZCBieXRlcyBhdCAleFxuIiwKCSAgICAgICBzaXplLCBidXNfYWRkcik7CgoJcGFyID0gc2l6ZTsKCWlmIChwYXIgPCAweDgwMDAwKSB7CgkJcGFyID0gMHg4MDAwMDsKCX0KCXBhciA+Pj0gMTI7CglwYXItLTsKCXBhciY9MHg3ZjsKCXBhciA8PD0gMTg7CglwYXIgfD0gKGJ1c19hZGRyPj4xMik7CglwYXIgfD0gMHg1MDAwMDAwMDsKCglwcmludGYgKCJzZXR0aW5nIFBBUjExIHRvICV4XG4iLCBwYXIpOwoKCS8qIE1hcCByb20gMHgxMDAwMCB3aXRoIFBBUjEgKi8KCXdyaXRlX21tY3JfbG9uZyhTQzUyMF9QQVIxMSwgIHBhcik7CgoJcmV0dXJuIGJ1c19hZGRyOwp9CgovKgogKiB0aGlzIGZ1bmN0aW9uIHJlbW92ZWQgYW55IG1hcHBpbmcgY3JlYXRlZAogKiB3aXRoIHBjaV9nZXRfcm9tX3dpbmRvdygpCiAqLwp2b2lkIGlzYV91bm1hcF9yb20odTMyIGFkZHIpCnsKCXByaW50ZigiaXNhX3VubWFwX3JvbSBhc2tlZCB0byB1bm1hcCAleCIsIGFkZHIpOwoJaWYgKChhZGRyPj4xMikgPT0gKHJlYWRfbW1jcl9sb25nKFNDNTIwX1BBUjExKSYweDNmZmZmKSkgewoJCXdyaXRlX21tY3JfbG9uZyhTQzUyMF9QQVIxMSwgMCk7CgkJcHJpbnRmKCIgZG9uZVxuIik7CgkJcmV0dXJuOwoJfQoJcHJpbnRmKCIgbm90IG91cnNcbiIpOwp9CgojaWZkZWYgQ09ORklHX1BDSQojZGVmaW5lIFBDSV9ST01fVEVNUF9TUEFDRSAweDEwMDAwCi8qCiAqIFRoaXMgZnVuY3Rpb24gc2hvdWxkIG1hcCBhIGNodW5rIG9mIHNpemUgYnl0ZXMKICogb2YgdGhlIHN5c3RlbSBhZGRyZXNzIHNwYWNlIHRvIHRoZSBQQ0kgYnVzLAogKiBzdWl0YWJsZSB0byBtYXAgUENJIFJPTVMgKGJ1cyBhZGRyZXNzIDwgMTZNKQogKiB0aGUgZnVuY3Rpb24gd2lsbCByZXR1cm4gdGhlIGhvc3QgbWVtb3J5IGFkZHJlc3MKICogd2hpY2ggc2hvdWxkIGJlIGNvbnZlcnRlZCBpbnRvIGEgYnVzIGFkZHJlc3MKICogYmVmb3JlIHVzZWQgdG8gY29uZmlndXJlIHRoZSBQQ0kgcm9tIGFkZHJlc3MKICogZGVjb2RlcgogKi8KdTMyIHBjaV9nZXRfcm9tX3dpbmRvdyhzdHJ1Y3QgcGNpX2NvbnRyb2xsZXIgKmhvc2UsIGludCBzaXplKQp7Cgl1MzIgcGFyOwoKCXBhciA9IHNpemU7CglpZiAocGFyIDwgMHg4MDAwMCkgewoJCXBhciA9IDB4ODAwMDA7Cgl9CglwYXIgPj49IDE2OwoJcGFyLS07CglwYXImPTB4N2ZmOwoJcGFyIDw8PSAxNDsKCXBhciB8PSAoUENJX1JPTV9URU1QX1NQQUNFPj4xNik7CglwYXIgfD0gMHg3MjAwMDAwMDsKCglwcmludGYgKCJzZXR0aW5nIFBBUjEgdG8gJXhcbiIsIHBhcik7CgoJLyogTWFwIHJvbSAweDEwMDAwIHdpdGggUEFSMSAqLwoJd3JpdGVfbW1jcl9sb25nKFNDNTIwX1BBUjEsICBwYXIpOwoKCXJldHVybiBQQ0lfUk9NX1RFTVBfU1BBQ0U7Cn0KCi8qCiAqIHRoaXMgZnVuY3Rpb24gcmVtb3ZlZCBhbnkgbWFwcGluZyBjcmVhdGVkCiAqIHdpdGggcGNpX2dldF9yb21fd2luZG93KCkKICovCnZvaWQgcGNpX3JlbW92ZV9yb21fd2luZG93KHN0cnVjdCBwY2lfY29udHJvbGxlciAqaG9zZSwgdTMyIGFkZHIpCnsKCXByaW50ZigicGNpX3JlbW92ZV9yb21fd2luZG93OiAleCIsIGFkZHIpOwoJaWYgKGFkZHIgPT0gUENJX1JPTV9URU1QX1NQQUNFKSB7CgkJd3JpdGVfbW1jcl9sb25nKFNDNTIwX1BBUjEsIDApOwoJCXByaW50ZigiIGRvbmVcbiIpOwoJCXJldHVybjsKCX0KCXByaW50ZigiIG5vdCBvdXJzXG4iKTsKCn0KCi8qCiAqIFRoaXMgZnVuY3Rpb24gaXMgY2FsbGVkIGluIG9yZGVyIHRvIHByb3ZpZGUgYWNjZXMgdG8gdGhlCiAqIGxlZ2FjeSB2aWRlbyBJL08gcG9ydHMgb24gdGhlIFBDSSBidXMuCiAqIEFmdGVyIHRoaXMgZnVuY3Rpb24gYWNjZXNzZXMgdG8gSS9PIHBvcnRzIDB4M2IwLTB4M2JiIGFuZAogKiAweDNjMC0weDNkZiBzaHVsZCByZXN1bHQgaW4gdHJhbnNhY3Rpb25zIG9uIHRoZSBQQ0kgYnVzLgogKgogKi8KaW50IHBjaV9lbmFibGVfbGVnYWN5X3ZpZGVvX3BvcnRzKHN0cnVjdCBwY2lfY29udHJvbGxlciAqaG9zZSkKewoJLyogTWFwIHZpZGVvIG1lbW9yeSB0byAweGEwMDAwKi8KCXdyaXRlX21tY3JfbG9uZyhTQzUyMF9QQVIwLCAgMHg3MjAwNDAwYSk7CgoJLyogZm9yd2FyZCBhbGwgSS9PIGFjY2Vzc2VzIHRvIFBDSSAqLwoJd3JpdGVfbW1jcl9ieXRlKFNDNTIwX0FERERFQ0NUTCwKCQkJcmVhZF9tbWNyX2J5dGUoU0M1MjBfQUREREVDQ1RMKSB8IElPX0hPTEVfREVTVF9QQ0kpOwoKCgkvKiBzbyB3ZSBtYXAgYXdheSBhbGwgaW8gcG9ydHMgdG8gcGNpIChvbmx5IHdheSB0byBhY2Nlc3MgcGNpIGlvCgkgKiBiZWxvdyAweDQwMC4gQnV0IHRoZW4gd2UgaGF2ZSB0byBtYXAgYmFjayB0aGUgcG9ydGlvbnMgdGhhdCB3ZSBkb250CgkgKiB1c2Ugc28gdGhhdCB0aGUgZ2VuZXJhdGUgY3ljbGVzIG9uIHRoZSBHUElPIGJ1cyB3aGVyZSB0aGUgc2lvIGFuZAoJICogSVNBIHNsb3RzIGFyZSBjb25uZWN0ZWQsIHRoaXMgcmVxdXJlIHRoZSB1c2Ugb2Ygc2V2ZXJhbCBQQVIgcmVnaXN0ZXJzCgkgKi8KCgkvKiBicmluZyAweDEwMCAtIDB4MmY3IGJhY2sgdG8gSVNBIHVzaW5nIFBBUjUgKi8KCXdyaXRlX21tY3JfbG9uZyhTQzUyMF9QQVI1LCAweDMxZjcwMTAwKTsKCgkvKiBjb20yIHVzZSAyZjgtMmZmICovCgoJLyogYnJpbmcgMHgzMDAgLSAweDNhZiBiYWNrIHRvIElTQSB1c2luZyBQQVI3ICovCgl3cml0ZV9tbWNyX2xvbmcoU0M1MjBfUEFSNywgMHgzMGFmMDMwMCk7CgoJLyogdmdhIHVzZSAzYjAtM2JiICovCgoJLyogYnJpbmcgMHgzYmMgLSAweDNiZiBiYWNrIHRvIElTQSB1c2luZyBQQVI4ICovCgl3cml0ZV9tbWNyX2xvbmcoU0M1MjBfUEFSOCwgMHgzMDAzMDNiYyk7CgoJLyogdmdhIHVzZSAzYzAtM2RmICovCgoJLyogYnJpbmcgMHgzZTAgLSAweDNmNyBiYWNrIHRvIElTQSB1c2luZyBQQVI5ICovCgl3cml0ZV9tbWNyX2xvbmcoU0M1MjBfUEFSOSwgMHgzMDE3MDNlMCk7CgoJLyogY29tMSB1c2UgM2Y4LTNmZiAqLwoKCXJldHVybiAwOwp9CiNlbmRpZgoKLyoKICogTWlzY2VsYW5lb3VzIHBsYXRmb3JtIGRlcGVuZGVudCBpbml0aWFsaXNhdGlvbnMKICovCgppbnQgYm9hcmRfaW5pdCh2b2lkKQp7Cglpbml0X3NjNTIwKCk7CglidXNfaW5pdCgpOwoJaXJxX2luaXQoKTsKCgkvKiBtYXggZHJpdmUgY3VycmVudCBvbiBTRFJBTSAqLwoJd3JpdGVfbW1jcl93b3JkKFNDNTIwX0RTQ1RMLCAweDAxMDApOwoKCS8qIGVudGVyIGRlYnVnIG1vZGUgYWZ0ZXIgbmV4dCByZXNldCAob25seSBpZiBqdW1wZXIgaXMgYWxzbyBzZXQpICovCgl3cml0ZV9tbWNyX2J5dGUoU0M1MjBfUkVTQ0ZHLCAweDA4KTsKCS8qIGNvbmZpZ3VyZSB0aGUgc29mdHdhcmUgdGltZXIgdG8gMzMuMDAwTUh6ICovCgl3cml0ZV9tbWNyX2J5dGUoU0M1MjBfU1dUTVJDRkcsIDEpOwoJZ2QtPmJ1c19jbGsgPSAzMzAwMDAwMDsKCglyZXR1cm4gMDsKfQoKaW50IGRyYW1faW5pdCh2b2lkKQp7Cglpbml0X3NjNTIwX2RyYW0oKTsKCXJldHVybiAwOwp9Cgp2b2lkIHNob3dfYm9vdF9wcm9ncmVzcyhpbnQgdmFsKQp7CglpbnQgdmVyc2lvbiA9IHJlYWRfbW1jcl9ieXRlKFNDNTIwX1NZU0lORk8pOwoKCWlmICh2YWwgPCAtMzIpIHZhbCA9IC0xOyAgLyogbGV0IHRoaW5ncyBjb21wYXRpYmxlICovCglpZiAodmVyc2lvbiA9PSAwKSB7CgkJLyogUElPMzEtUElPMTYgRGF0YSAqLwoJCXdyaXRlX21tY3Jfd29yZChTQzUyMF9QSU9EQVRBMzFfMTYsCgkJCQkocmVhZF9tbWNyX3dvcmQoU0M1MjBfUElPREFUQTMxXzE2KSAmIDB4ZmZjMCl8ICgodmFsJjB4N2UpPj4xKSk7IC8qIDB4MWY4ID4+IDMgKi8KCgkJLyogUElPMC1QSU8xNSBEYXRhICovCgkJd3JpdGVfbW1jcl93b3JkKFNDNTIwX1BJT0RBVEExNV8wLAoJCQkJKHJlYWRfbW1jcl93b3JkKFNDNTIwX1BJT0RBVEExNV8wKSAmIDB4MWZmZil8ICgodmFsJjB4Nyk8PDEzKSk7Cgl9IGVsc2UgewoJCS8qIG5ld2VyIGJvYXJkcyB1c2UgUElPNC1QSU8xMiAqLwoJCS8qIFBJTzAtUElPMTUgRGF0YSAqLwojaWYgMAoJCXZhbCA9ICh2YWwgJiAweDAwNykgfCAoKHZhbCAmIDB4MDM4KSA8PCAzKSB8ICgodmFsICYgMHgxYzApID4+IDMpOwojZWxzZQoJCXZhbCA9ICh2YWwgJiAweDAwNykgfCAoKHZhbCAmIDB4MDdlKSA8PCAyKTsKI2VuZGlmCgkJd3JpdGVfbW1jcl93b3JkKFNDNTIwX1BJT0RBVEExNV8wLAoJCQkJKHJlYWRfbW1jcl93b3JkKFNDNTIwX1BJT0RBVEExNV8wKSAmIDB4ZTAwZikgfCAoKHZhbCYweDAxZmYpPDw0KSk7Cgl9Cn0KCgppbnQgbGFzdF9zdGFnZV9pbml0KHZvaWQpCnsKCglpbnQgdmVyc2lvbiA9IHJlYWRfbW1jcl9ieXRlKFNDNTIwX1NZU0lORk8pOwoKCXByaW50ZigiT21pY3JvbiBDZXRpIFNDNTIwIFNwdW5rIHJldmlzaW9uICV4XG4iLCB2ZXJzaW9uKTsKCiNpZiAwCglpZiAodmVyc2lvbikgewoJCWludCB4LCB5OwoKCQlwcmludGYoImVlcHJvbSBwcm9iZSAlZFxuIiwgc3BpX2VlcHJvbV9wcm9iZSgxKSk7CgoJCXNwaV9lZXByb21fcmVhZCgxLCAwLCAodTgqKSZ4LCAyKTsKCQlzcGlfZWVwcm9tX3JlYWQoMSwgMSwgKHU4KikmeSwgMik7CgkJcHJpbnRmKCJlZXByb20gYnl0ZXMgJTA0eCUwNHhcbiIsIHgsIHkpOwoJCXggXj0gMHhmZmZmOwoJCXkgXj0gMHhmZmZmOwoJCXNwaV9lZXByb21fd3JpdGUoMSwgMCwgKHU4KikmeCwgMik7CgkJc3BpX2VlcHJvbV93cml0ZSgxLCAxLCAodTgqKSZ5LCAyKTsKCgkJc3BpX2VlcHJvbV9yZWFkKDEsIDAsICh1OCopJngsIDIpOwoJCXNwaV9lZXByb21fcmVhZCgxLCAxLCAodTgqKSZ5LCAyKTsKCQlwcmludGYoImVlcHJvbSBieXRlcyAlMDR4JTA0eFxuIiwgeCwgeSk7CgoJfSBlbHNlIHsKCQlpbnQgeCwgeTsKCgkJcHJpbnRmKCJlZXByb20gcHJvYmUgJWRcbiIsIG13X2VlcHJvbV9wcm9iZSgxKSk7CgoJCW13X2VlcHJvbV9yZWFkKDEsIDAsICh1OCopJngsIDIpOwoJCW13X2VlcHJvbV9yZWFkKDEsIDEsICh1OCopJnksIDIpOwoJCXByaW50ZigiZWVwcm9tIGJ5dGVzICUwNHglMDR4XG4iLCB4LCB5KTsKCgkJeCBePSAweGZmZmY7CgkJeSBePSAweGZmZmY7CgkJbXdfZWVwcm9tX3dyaXRlKDEsIDAsICh1OCopJngsIDIpOwoJCW13X2VlcHJvbV93cml0ZSgxLCAxLCAodTgqKSZ5LCAyKTsKCgkJbXdfZWVwcm9tX3JlYWQoMSwgMCwgKHU4KikmeCwgMik7CgkJbXdfZWVwcm9tX3JlYWQoMSwgMSwgKHU4KikmeSwgMik7CgkJcHJpbnRmKCJlZXByb20gYnl0ZXMgJTA0eCUwNHhcbiIsIHgsIHkpOwoKCgl9CiNlbmRpZgoKCWRzMTcyMl9wcm9iZSgyKTsKCglyZXR1cm4gMDsKfQoKdm9pZCBzc2lfY2hpcF9zZWxlY3QoaW50IGRldikKewoJaW50IHZlcnNpb24gPSByZWFkX21tY3JfYnl0ZShTQzUyMF9TWVNJTkZPKTsKCglpZiAodmVyc2lvbikgewoJCS8qIFNwdW5rIGJvYXJkOiBFRVBST00gYW5kIENBTiBhcmUgYWN0b3ZlLWxvdywgVEVNUCBhbmQgQVVYIGFyZSBhY3RpdmUgaGlnaCAqLwoJCXN3aXRjaCAoZGV2KSB7CgkJY2FzZSAxOiAvKiBFRVBST00gKi8KCQkJd3JpdGVfbW1jcl93b3JkKFNDNTIwX1BJT0NMUjMxXzE2LCAweDAwMDQpOwoJCQlicmVhazsKCgkJY2FzZSAyOiAvKiBUZW1wIFByb2JlICovCgkJCXdyaXRlX21tY3Jfd29yZChTQzUyMF9QSU9TRVQzMV8xNiwgMHgwMDAyKTsKCQkJYnJlYWs7CgoJCWNhc2UgMzogLyogQ0FOICovCgkJCXdyaXRlX21tY3Jfd29yZChTQzUyMF9QSU9DTFIzMV8xNiwgMHgwMDA4KTsKCQkJYnJlYWs7CgoJCWNhc2UgNDogLyogQVVYICovCgkJCXdyaXRlX21tY3Jfd29yZChTQzUyMF9QSU9TRVQzMV8xNiwgMHgwMDAxKTsKCQkJYnJlYWs7CgoJCWNhc2UgMDoKCQkJd3JpdGVfbW1jcl93b3JkKFNDNTIwX1BJT0NMUjMxXzE2LCAweDAwMDMpOwoJCQl3cml0ZV9tbWNyX3dvcmQoU0M1MjBfUElPU0VUMzFfMTYsIDB4MDAwYyk7CgkJCWJyZWFrOwoKCQlkZWZhdWx0OgoJCQlwcmludGYoIklsbGVnYWwgU1NJIGRldmljZSByZXF1ZXN0ZWQ6ICVkXG4iLCBkZXYpOwoJCX0KCX0gZWxzZSB7CgoJCS8qIEdsb2JveCBib2FyZDogQm90aCBFRVBST00gYW5kIFRFTVAgYXJlIGFjdGl2ZS1oaWdoICovCgoJCXN3aXRjaCAoZGV2KSB7CgkJY2FzZSAxOiAvKiBFRVBST00gKi8KCQkJd3JpdGVfbW1jcl93b3JkKFNDNTIwX1BJT1NFVDE1XzAsIDB4MDEwMCk7CgkJCWJyZWFrOwoKCQljYXNlIDI6IC8qIFRlbXAgUHJvYmUgKi8KCQkJd3JpdGVfbW1jcl93b3JkKFNDNTIwX1BJT1NFVDE1XzAsIDB4MDA4MCk7CgkJCWJyZWFrOwoKCQljYXNlIDA6CgkJCXdyaXRlX21tY3Jfd29yZChTQzUyMF9QSU9DTFIxNV8wLCAweDAxODApOwoJCQlicmVhazsKCgkJZGVmYXVsdDoKCQkJcHJpbnRmKCJJbGxlZ2FsIFNTSSBkZXZpY2UgcmVxdWVzdGVkOiAlZFxuIiwgZGV2KTsKCQl9Cgl9Cn0KCgp2b2lkIHNwaV9pbml0X2Yodm9pZCkKewoJcmVhZF9tbWNyX2J5dGUoU0M1MjBfU1lTSU5GTykgPwoJCXNwaV9lZXByb21fcHJvYmUoMSkgOgoJbXdfZWVwcm9tX3Byb2JlKDEpOwoKfQoKc3NpemVfdCBzcGlfcmVhZCh1Y2hhciAqYWRkciwgaW50IGFsZW4sIHVjaGFyICpidWZmZXIsIGludCBsZW4pCnsKCWludCBvZmZzZXQ7CglpbnQgaTsKCglvZmZzZXQgPSAwOwoJZm9yIChpPTA7aTxhbGVuO2krKykgewoJCW9mZnNldCA8PD0gODsKCQlvZmZzZXQgfD0gYWRkcltpXTsKCX0KCglyZXR1cm4JcmVhZF9tbWNyX2J5dGUoU0M1MjBfU1lTSU5GTykgPwoJCXNwaV9lZXByb21fcmVhZCgxLCBvZmZzZXQsIGJ1ZmZlciwgbGVuKSA6Cgltd19lZXByb21fcmVhZCgxLCBvZmZzZXQsIGJ1ZmZlciwgbGVuKTsKfQoKc3NpemVfdCBzcGlfd3JpdGUodWNoYXIgKmFkZHIsIGludCBhbGVuLCB1Y2hhciAqYnVmZmVyLCBpbnQgbGVuKQp7CglpbnQgb2Zmc2V0OwoJaW50IGk7CgoJb2Zmc2V0ID0gMDsKCWZvciAoaT0wO2k8YWxlbjtpKyspIHsKCQlvZmZzZXQgPDw9IDg7CgkJb2Zmc2V0IHw9IGFkZHJbaV07Cgl9CgoJcmV0dXJuCXJlYWRfbW1jcl9ieXRlKFNDNTIwX1NZU0lORk8pID8KCQlzcGlfZWVwcm9tX3dyaXRlKDEsIG9mZnNldCwgYnVmZmVyLCBsZW4pIDoKCW13X2VlcHJvbV93cml0ZSgxLCBvZmZzZXQsIGJ1ZmZlciwgbGVuKTsKfQoKaW50IGJvYXJkX2V0aF9pbml0KGJkX3QgKmJpcykKewoJcmV0dXJuIHBjaV9ldGhfaW5pdChiaXMpOwp9Cg==