LyoKICoKICogKEMpIENvcHlyaWdodCAyMDAyCiAqIERhbmllbCBFbmdzdHL2bSwgT21pY3JvbiBDZXRpIEFCIDxkYW5pZWxAb21pY3Jvbi5zZT4uCiAqCiAqIFNlZSBmaWxlIENSRURJVFMgZm9yIGxpc3Qgb2YgcGVvcGxlIHdobyBjb250cmlidXRlZCB0byB0aGlzCiAqIHByb2plY3QuCiAqCiAqIFRoaXMgcHJvZ3JhbSBpcyBmcmVlIHNvZnR3YXJlOyB5b3UgY2FuIHJlZGlzdHJpYnV0ZSBpdCBhbmQvb3IKICogbW9kaWZ5IGl0IHVuZGVyIHRoZSB0ZXJtcyBvZiB0aGUgR05VIEdlbmVyYWwgUHVibGljIExpY2Vuc2UgYXMKICogcHVibGlzaGVkIGJ5IHRoZSBGcmVlIFNvZnR3YXJlIEZvdW5kYXRpb247IGVpdGhlciB2ZXJzaW9uIDIgb2YKICogdGhlIExpY2Vuc2UsIG9yIChhdCB5b3VyIG9wdGlvbikgYW55IGxhdGVyIHZlcnNpb24uCiAqCiAqIFRoaXMgcHJvZ3JhbSBpcyBkaXN0cmlidXRlZCBpbiB0aGUgaG9wZSB0aGF0IGl0IHdpbGwgYmUgdXNlZnVsLAogKiBidXQgV0lUSE9VVCBBTlkgV0FSUkFOVFk7IHdpdGhvdXQgZXZlbiB0aGUgaW1wbGllZCB3YXJyYW50eSBvZgogKiBNRVJDSEFOVEFCSUxJVFkgb3IgRklUTkVTUyBGT1IgQSBQQVJUSUNVTEFSIFBVUlBPU0UuICBTZWUgdGhlCiAqIEdOVSBHZW5lcmFsIFB1YmxpYyBMaWNlbnNlIGZvciBtb3JlIGRldGFpbHMuCiAqCiAqIFlvdSBzaG91bGQgaGF2ZSByZWNlaXZlZCBhIGNvcHkgb2YgdGhlIEdOVSBHZW5lcmFsIFB1YmxpYyBMaWNlbnNlCiAqIGFsb25nIHdpdGggdGhpcyBwcm9ncmFtOyBpZiBub3QsIHdyaXRlIHRvIHRoZSBGcmVlIFNvZnR3YXJlCiAqIEZvdW5kYXRpb24sIEluYy4sIDU5IFRlbXBsZSBQbGFjZSwgU3VpdGUgMzMwLCBCb3N0b24sCiAqIE1BIDAyMTExLTEzMDcgVVNBCiAqLwoKI2luY2x1ZGUgPGNvbW1vbi5oPgojaW5jbHVkZSA8cGNpLmg+CiNpbmNsdWRlIDxzc2kuaD4KI2luY2x1ZGUgPGFzbS9pby5oPgojaW5jbHVkZSA8YXNtL3BjaS5oPgojaW5jbHVkZSA8YXNtL2ljL3NjNTIwLmg+CgpERUNMQVJFX0dMT0JBTF9EQVRBX1BUUjsKCi8qCiAqIFRoZW9yeToKICogV2UgZmlyc3Qgc2V0IHVwIGFsbCBJUlFzIHRvIGJlIG5vbi1wY2ksIGVkZ2UgdHJpZ2dlcmVkLAogKiB3aGVuIHdlIGxhdGVyIGVudW1lcmF0ZSB0aGUgcGNpIGJ1cyBhbmQgcGNpX3NjNTIwX2ZpeHVwX2lycSgpIGdldHMKICogY2FsbGVkIHdlIHJlYWxsb2NhdGUgaXJxcyB0byB0aGUgcGNpIGJ1cyB3aXRoIHNjNTIwX3BjaV9zZXRfaXJxKCkKICogYXMgbmVlZGVkLiBXaGUgY2hvb3NlIHRoZSBpcnFzIHRvIGdyYW0gZnJvbSBhIGNvbmZpZ3VyYWJsZSBsaXN0CiAqIGluc2lkZSBwY2lfc2M1MjBfZml4dXBfaXJxKCkgKElmIHRoaXMgbGlzdCBjb250YWlucyBzdHVwaWQgaXJxJ3MKICogc3VjaCBhcyAwIHRobmdhcyB3aWxsIG5vdCB3b3JrKQogKi8KCnN0YXRpYyB2b2lkIGlycV9pbml0KHZvaWQpCnsKCS8qIGRpc2FibGUgZ2xvYmFsIGludGVycnVwdCBtb2RlICovCgl3cml0ZV9tbWNyX2J5dGUoU0M1MjBfUElDSUNSLCAweDQwKTsKCgkvKiBzZXQgYWxsIGlycXMgdG8gZWRnZSAqLwoJd3JpdGVfbW1jcl9ieXRlKFNDNTIwX01QSUNNT0RFLCAweDAwKTsKCXdyaXRlX21tY3JfYnl0ZShTQzUyMF9TTDFQSUNNT0RFLCAweDAwKTsKCXdyaXRlX21tY3JfYnl0ZShTQzUyMF9TTDJQSUNNT0RFLCAweDAwKTsKCgkvKiBhY3RpdmUgbG93IHBvbGFyaXR5IG9uIFBJQyBpbnRlcnJ1cHQgcGlucywKCSAqICBhY3RpdmUgaGlnaCBwb2xhcml0eSBvbiBhbGwgb3RoZXIgaXJxIHBpbnMgKi8KCXdyaXRlX21tY3Jfd29yZChTQzUyMF9JTlRQSU5QT0wsIDB4MDAwMCk7CgoJLyogc2V0IGlycSBudW1iZXIgbWFwcGluZyAqLwoJd3JpdGVfbW1jcl9ieXRlKFNDNTIwX0dQVE1SME1BUCwgU0M1MjBfSVJRX0RJU0FCTEVEKTsgICAvKiBkaXNhYmxlIEdQIHRpbWVyIDAgSU5UICovCgl3cml0ZV9tbWNyX2J5dGUoU0M1MjBfR1BUTVIxTUFQLCBTQzUyMF9JUlFfRElTQUJMRUQpOyAgIC8qIGRpc2FibGUgR1AgdGltZXIgMSBJTlQgKi8KCXdyaXRlX21tY3JfYnl0ZShTQzUyMF9HUFRNUjJNQVAsIFNDNTIwX0lSUV9ESVNBQkxFRCk7ICAgLyogZGlzYWJsZSBHUCB0aW1lciAyIElOVCAqLwoJd3JpdGVfbW1jcl9ieXRlKFNDNTIwX1BJVDBNQVAsIFNDNTIwX0lSUTApOyAgICAgICAgICAgICAvKiBTZXQgUElUIHRpbWVyIDAgSU5UIHRvIElSUTAgKi8KCXdyaXRlX21tY3JfYnl0ZShTQzUyMF9QSVQxTUFQLCBTQzUyMF9JUlFfRElTQUJMRUQpOyAgICAgLyogZGlzYWJsZSBQSVQgdGltZXIgMSBJTlQgKi8KCXdyaXRlX21tY3JfYnl0ZShTQzUyMF9QSVQyTUFQLCBTQzUyMF9JUlFfRElTQUJMRUQpOyAgICAgLyogZGlzYWJsZSBQSVQgdGltZXIgMiBJTlQgKi8KCXdyaXRlX21tY3JfYnl0ZShTQzUyMF9QQ0lJTlRBTUFQLCBTQzUyMF9JUlFfRElTQUJMRUQpOyAgLyogZGlzYWJsZSBQQ0kgSU5UIEEgKi8KCXdyaXRlX21tY3JfYnl0ZShTQzUyMF9QQ0lJTlRCTUFQLCBTQzUyMF9JUlFfRElTQUJMRUQpOyAgLyogZGlzYWJsZSBQQ0kgSU5UIEIgKi8KCXdyaXRlX21tY3JfYnl0ZShTQzUyMF9QQ0lJTlRDTUFQLCBTQzUyMF9JUlFfRElTQUJMRUQpOyAgLyogZGlzYWJsZSBQQ0kgSU5UIEMgKi8KCXdyaXRlX21tY3JfYnl0ZShTQzUyMF9QQ0lJTlRETUFQLCBTQzUyMF9JUlFfRElTQUJMRUQpOyAgLyogZGlzYWJsZSBQQ0kgSU5UIEQgKi8KCXdyaXRlX21tY3JfYnl0ZShTQzUyMF9ETUFCQ0lOVE1BUCwgU0M1MjBfSVJRX0RJU0FCTEVEKTsgLyogZGlzYWJsZSBETUEgSU5UICovCgl3cml0ZV9tbWNyX2J5dGUoU0M1MjBfU1NJTUFQLCBTQzUyMF9JUlE2KTsgICAgICAgICAgICAgIC8qIFNldCBTeW5jaHJvbml1cyBzZXJpYWwgSU5UIHRvIElSUTYqLwoJd3JpdGVfbW1jcl9ieXRlKFNDNTIwX1dEVE1BUCwgU0M1MjBfSVJRX0RJU0FCTEVEKTsgICAgICAvKiBkaXNhYmxlIFdhdGNoZG9nIElOVCAqLwoJd3JpdGVfbW1jcl9ieXRlKFNDNTIwX1JUQ01BUCwgU0M1MjBfSVJROCk7ICAgICAgICAgICAgICAvKiBTZXQgUlRDIGludCB0byA4ICovCgl3cml0ZV9tbWNyX2J5dGUoU0M1MjBfV1BWTUFQLCBTQzUyMF9JUlFfRElTQUJMRUQpOyAgICAgIC8qIGRpc2FibGUgd3JpdGUgcHJvdGVjdCBJTlQgKi8KCXdyaXRlX21tY3JfYnl0ZShTQzUyMF9JQ0VNQVAsIFNDNTIwX0lSUTEpOyAgICAgICAgICAgICAgLyogU2V0IElDRSBEZWJ1ZyBTZXJpZWxwb3J0IElOVCB0byBJUlExICovCgl3cml0ZV9tbWNyX2J5dGUoU0M1MjBfRkVSUk1BUCxTQzUyMF9JUlExMyk7ICAgICAgICAgICAgIC8qIFNldCBGUCBlcnJvciBJTlQgdG8gSVJRMTMgKi8KCgl3cml0ZV9tbWNyX2J5dGUoU0M1MjBfVUFSVDFNQVAsIFNDNTIwX0lSUTQpOyAgICAgICAgICAgIC8qIFNldCBpbnRlcm5hbCBVQVJUMiBJTlQgdG8gSVJRNCAqLwoJd3JpdGVfbW1jcl9ieXRlKFNDNTIwX1VBUlQyTUFQLCBTQzUyMF9JUlEzKTsgICAgICAgICAgICAvKiBTZXQgaW50ZXJuYWwgVUFSVDIgSU5UIHRvIElSUTMgKi8KCgl3cml0ZV9tbWNyX2J5dGUoU0M1MjBfR1AwSU1BUCwgU0M1MjBfSVJRNyk7ICAgICAgICAgICAgIC8qIFNldCBHUElSUTAgKFBDLUNhcmQgQVVYIElSUSkgdG8gSVJRNyAqLwoJd3JpdGVfbW1jcl9ieXRlKFNDNTIwX0dQMUlNQVAsIFNDNTIwX0lSUTE0KTsgICAgICAgICAgICAvKiBTZXQgR1BJUlExIChDRiBJUlEpIHRvIElSUTE0ICovCgl3cml0ZV9tbWNyX2J5dGUoU0M1MjBfR1AzSU1BUCwgU0M1MjBfSVJRNSk7ICAgICAgICAgICAgIC8qIFNldCBHUElSUTMgKCBDQU4gSVJRICkgdGkgSVJRNSAqLwoJd3JpdGVfbW1jcl9ieXRlKFNDNTIwX0dQNElNQVAsIFNDNTIwX0lSUV9ESVNBQkxFRCk7ICAgICAvKiBkaXNiYWxlIEdJUlE0ICggSVJSIElSUSApICovCgl3cml0ZV9tbWNyX2J5dGUoU0M1MjBfR1A1SU1BUCwgU0M1MjBfSVJRX0RJU0FCTEVEKTsgICAgIC8qIGRpc2FibGUgR1BJUlE1ICovCgl3cml0ZV9tbWNyX2J5dGUoU0M1MjBfR1A2SU1BUCwgU0M1MjBfSVJRX0RJU0FCTEVEKTsgICAgIC8qIGRpc2FibGUgR1BJUlE2ICovCgl3cml0ZV9tbWNyX2J5dGUoU0M1MjBfR1A3SU1BUCwgU0M1MjBfSVJRX0RJU0FCTEVEKTsgICAgIC8qIGRpc2FibGUgR1BJUlE3ICovCgl3cml0ZV9tbWNyX2J5dGUoU0M1MjBfR1A4SU1BUCwgU0M1MjBfSVJRX0RJU0FCTEVEKTsgICAgIC8qIGRpc2FibGUgR1BJUlE4ICovCgl3cml0ZV9tbWNyX2J5dGUoU0M1MjBfR1A5SU1BUCwgU0M1MjBfSVJRX0RJU0FCTEVEKTsgICAgIC8qIGRpc2FibGUgR1BJUlE5ICovCgl3cml0ZV9tbWNyX2J5dGUoU0M1MjBfR1AySU1BUCwgU0M1MjBfSVJRX0RJU0FCTEVEKTsgICAgIC8qIGRpc2FibGUgR1BJUlEyICovCgl3cml0ZV9tbWNyX2J5dGUoU0M1MjBfR1AxMElNQVAsU0M1MjBfSVJRX0RJU0FCTEVEKTsgICAgIC8qIGRpc2FibGUgR1BJUlExMCAqLwoKCXdyaXRlX21tY3Jfd29yZChTQzUyMF9QQ0lIT1NUTUFQLCAweDExZik7ICAgICAgICAgICAgICAgLyogTWFwIFBDSSBob3N0YnJpZGdlIElOVCB0byBOTUkgKi8KCXdyaXRlX21tY3Jfd29yZChTQzUyMF9FQ0NNQVAsIDB4MTAwKTsgICAgICAgICAgICAgICAgICAgLyogTWFwIFNEUkFNIEVDQyBmYWlsdXJlIElOVCB0byBOTUkgKi8KCn0KCgovKiBQQ0kgc3R1ZmYgKi8Kc3RhdGljIHZvaWQgcGNpX3NjNTIwX3NwdW5rX2ZpeHVwX2lycShzdHJ1Y3QgcGNpX2NvbnRyb2xsZXIgKmhvc2UsIHBjaV9kZXZfdCBkZXYpCnsKCWludCB2ZXJzaW9uID0gcmVhZF9tbWNyX2J5dGUoU0M1MjBfU1lTSU5GTyk7CgoJLyogYSBjb25maWd1cmFibGUgbGlzdHMgb2YgaXJxcyB0byBzdGVhbAoJICogd2hlbiB3ZSBuZWVkIG9uZSAoYSBib2FyZCB3aXRoIG1vcmUgcGNpIGludGVycnVwdCBwaW5zCgkgKiB3b3VsZCB1c2UgYSBsYXJnZXIgdGFibGUgKi8KCXN0YXRpYyBpbnQgaXJxX2xpc3RbXSA9IHsKCQlDRkdfRklSU1RfUENJX0lSUSwKCQlDRkdfU0VDT05EX1BDSV9JUlEsCgkJQ0ZHX1RISVJEX1BDSV9JUlEsCgkJQ0ZHX0ZPUlRIX1BDSV9JUlEKCX07CglzdGF0aWMgaW50IG5leHRfaXJxX2luZGV4PTA7CgoJY2hhciB0bXBfcGluOwoJaW50IHBpbjsKCglwY2lfaG9zZV9yZWFkX2NvbmZpZ19ieXRlKGhvc2UsIGRldiwgUENJX0lOVEVSUlVQVF9QSU4sICZ0bXBfcGluKTsKCXBpbiA9IHRtcF9waW47CgoJcGluLT0xOyAvKiBwY2kgY29uZmlnIHNwYWNlIHVzZSAxLWJhc2VkIG51bWJlcmluZyAqLwoJaWYgKC0xID09IHBpbikgewoJCXJldHVybjsgLyogZGV2aWNlIHVzZSBubyBpcnEgKi8KCX0KCgoJLyogbWFwIGRldmljZSBudW1iZXIgKyAgcGluIHRvIGEgcGluIG9uIHRoZSBzYzUyMCAqLwoJc3dpdGNoIChQQ0lfREVWKGRldikpIHsKCWNhc2UgNjogIC8qIEVUSDAgKi8KCQlwaW4rPVNDNTIwX1BDSV9JTlRBOwoJCWJyZWFrOwoKCWNhc2UgNzogIC8qIEVUSDEgKi8KCQlwaW4rPVNDNTIwX1BDSV9JTlRCOwoJCWJyZWFrOwoKCWNhc2UgODogIC8qIENyeXB0byAqLwoJCXBpbis9U0M1MjBfUENJX0lOVEM7CgkJYnJlYWs7CgoJY2FzZSA5OiAvKiBQTUMgc2xvdCAqLwoJCXBpbis9U0M1MjBfUENJX0lOVEQ7CgkJYnJlYWs7CgoJY2FzZSAxMDogLyogUEMtQ2FyZCAqLwoKCQlpZiAodmVyc2lvbiA8IDEwKSB7CgkJCXBpbis9U0M1MjBfUENJX0lOVEQ7CgkJfSBlbHNlIHsKCQkJcGluKz1TQzUyMF9QQ0lfSU5UQzsKCQl9CgkJYnJlYWs7CgoJZGVmYXVsdDoKCQlyZXR1cm47Cgl9CgoJcGluJj0zOyAvKiB3cmFwIGFyb3VuZCAqLwoKCWlmIChzYzUyMF9wY2lfaW50c1twaW5dID09IC0xKSB7CgkJLyogcmUtcm91dGUgb25lIGludGVycnVwdCBmb3IgdXMgKi8KCQlpZiAobmV4dF9pcnFfaW5kZXggPiAzKSB7CgkJCXJldHVybjsKCQl9CgkJaWYgKHBjaV9zYzUyMF9zZXRfaXJxKHBpbiwgaXJxX2xpc3RbbmV4dF9pcnFfaW5kZXhdKSkgewoJCQlyZXR1cm47CgkJfQoJCW5leHRfaXJxX2luZGV4Kys7Cgl9CgoKCWlmICgtMSAhPSBzYzUyMF9wY2lfaW50c1twaW5dKSB7CgkJcGNpX2hvc2Vfd3JpdGVfY29uZmlnX2J5dGUoaG9zZSwgZGV2LCBQQ0lfSU5URVJSVVBUX0xJTkUsCgkJCQkJICAgc2M1MjBfcGNpX2ludHNbcGluXSk7Cgl9CiNpZiAwCglwcmludGYoImZpeHVwX2lycTogZGV2aWNlICVkIHBpbiAlYyBpcnEgJWRcbiIsCgkgICAgICAgUENJX0RFVihkZXYpLCAnQScgKyBwaW4sIHNjNTIwX3BjaV9pbnRzW3Bpbl0pOwojZW5kaWYKfQoKCnN0YXRpYyB2b2lkIHBjaV9zYzUyMF9zcHVua19jb25maWd1cmVfY2FyZGJ1cyhzdHJ1Y3QgcGNpX2NvbnRyb2xsZXIgKmhvc2UsCgkJCQkJICAgICAgcGNpX2Rldl90IGRldiwgc3RydWN0IHBjaV9jb25maWdfdGFibGUgKnRlKQp7Cgl1MzIgaW9fYmFzZTsKCXUzMiB0ZW1wOwoKCXBjaWF1dG9fY29uZmlnX2RldmljZShob3NlLCBkZXYpOwoKCXBjaV9ob3NlX3dyaXRlX2NvbmZpZ193b3JkKGhvc2UsIGRldiwgUENJX0NPTU1BTkQsIDB4MDcpOyAgLyogZW5hYmxlIGRldmljZSAqLwoJcGNpX2hvc2Vfd3JpdGVfY29uZmlnX2J5dGUoaG9zZSwgZGV2LCAweDBjLCAweDEwKTsgICAgICAgICAvKiBjYWNoZWxpbmUgc2l6ZSAqLwoJcGNpX2hvc2Vfd3JpdGVfY29uZmlnX2J5dGUoaG9zZSwgZGV2LCAweDBkLCAweDQwKTsgICAgICAgICAvKiBsYXRlbmN5IHRpbWVyICovCglwY2lfaG9zZV93cml0ZV9jb25maWdfYnl0ZShob3NlLCBkZXYsIDB4MWIsIDB4NDApOyAgICAgICAgIC8qIGNhcmRidXMgbGF0ZW5jeSB0aW1lciAqLwoJcGNpX2hvc2Vfd3JpdGVfY29uZmlnX3dvcmQoaG9zZSwgZGV2LCBQQ0lfQlJJREdFX0NPTlRST0wsIDB4MDA0MCk7ICAvKiByZXNldCBjYXJkYnVzICovCglwY2lfaG9zZV93cml0ZV9jb25maWdfd29yZChob3NlLCBkZXYsIFBDSV9CUklER0VfQ09OVFJPTCwgMHgwMDgwKTsgIC8qIHJvdXRlIGludGVycnVwdHMgdGhvdWdoIEV4Q0EgKi8KCXBjaV9ob3NlX3dyaXRlX2NvbmZpZ193b3JkKGhvc2UsIGRldiwgIDB4NDQsIDB4M2UwKTsgLyogbWFwIGxlZ2FjeSBJL08gcG9ydCB0byAweDNlMCAqLwoKCXBjaV9ob3NlX3JlYWRfY29uZmlnX2R3b3JkKGhvc2UsIGRldiwgIDB4ODAsICZ0ZW1wKTsgLyogU3lzdGVtIGNvbnRyb2wgKi8KCXBjaV9ob3NlX3dyaXRlX2NvbmZpZ19kd29yZChob3NlLCBkZXYsICAweDgwLCB0ZW1wIHwgMHg2MCk7IC8qIFN5c3RlbSBjb250cm9sOiBkaXNhYmxlIGNsb2NrcnVuICovCgkvKiByb3V0ZSBNRjAgdG8gfklOVCBhbmQgTUYzIHRvIElSUTcKCSAqIHJlc2VydmUgYWxsIG90aGVycyAqLwoJcGNpX2hvc2Vfd3JpdGVfY29uZmlnX2R3b3JkKGhvc2UsIGRldiwgMHg4YywgMHgwMDAwNzAwMik7CglwY2lfaG9zZV93cml0ZV9jb25maWdfYnl0ZShob3NlLCBkZXYsIDB4OTEsIDB4MDApOyAgICAvKiBjYXJkIGNvbnRyb2wgKi8KCXBjaV9ob3NlX3dyaXRlX2NvbmZpZ19ieXRlKGhvc2UsIGRldiwgMHg5MiwgMHg2Mik7ICAgIC8qIGRldmljZSBjb250cm9sICovCgoJaWYgKHRlLT5kZXZpY2UgIT0gMHhhYzU2KSB7CgkJcGNpX2hvc2Vfd3JpdGVfY29uZmlnX2J5dGUoaG9zZSwgZGV2LCAweDkzLCAweDIxKTsgICAgLyogYXN5bmMgaW50ZXJydXB0IGVuYWJsZSAqLwoJCXBjaV9ob3NlX3dyaXRlX2NvbmZpZ193b3JkKGhvc2UsIGRldiwgMHhhOCwgMHgwMDAwKTsgIC8qIHJlc2V0IEdQSU8gKi8KCQlwY2lfaG9zZV93cml0ZV9jb25maWdfd29yZChob3NlLCBkZXYsIDB4YWMsIDB4MDAwMCk7ICAvKiByZXNldCBHUElPICovCgkJcGNpX2hvc2Vfd3JpdGVfY29uZmlnX3dvcmQoaG9zZSwgZGV2LCAweGFhLCAweDAwMDApOyAgLyogcmVzZXQgR1BJTyAqLwoJCXBjaV9ob3NlX3dyaXRlX2NvbmZpZ193b3JkKGhvc2UsIGRldiwgMHhhZSwgMHgwMDAwKTsgIC8qIHJlc2V0IEdQSU8gKi8KCX0gZWxzZSB7CgkJcGNpX2hvc2Vfd3JpdGVfY29uZmlnX2J5dGUoaG9zZSwgZGV2LCAweDkzLCAweDIwKTsgICAgLyogICovCgl9CglwY2lfaG9zZV93cml0ZV9jb25maWdfd29yZChob3NlLCBkZXYsIDB4YTQsIDB4ODAwMCk7ICAvKiByZXNldCBwb3dlciBtYW5hZ2VtZW50ICovCgoKCXBjaV9ob3NlX3JlYWRfY29uZmlnX2R3b3JkKGhvc2UsIGRldiwgUENJX0JBU0VfQUREUkVTU18wLCAmaW9fYmFzZSk7Cglpb19iYXNlICY9IH4weGZMOwoKCXdyaXRlYigweDA3LCBpb19iYXNlKzB4ODAzKTsgLyogcm91dGUgQ1NDIGlycSB0aG91Z2ggRXhDQSBhbmQgZW5hYmxlIElSUTcgKi8KCXdyaXRlbCgwLCBpb19iYXNlKzB4MTApOyAgICAgLyogQ0xLUlVOIGRlZmF1bHQgKi8KCXdyaXRlbCgwLCBpb19iYXNlKzB4MjApOyAgICAgLyogQ0xLUlVOIGRlZmF1bHQgKi8KCn0KCgpzdGF0aWMgc3RydWN0IHBjaV9jb25maWdfdGFibGUgcGNpX3NjNTIwX3NwdW5rX2NvbmZpZ190YWJsZVtdID0gewoJeyAweDEwNGMsIDB4YWM1MCwgUENJX0FOWV9JRCwgMCwgMHgwYSwgMCwgcGNpX3NjNTIwX3NwdW5rX2NvbmZpZ3VyZV9jYXJkYnVzLCB7IDAsIDAsIDB9IH0sCgl7IDB4MTA0YywgMHhhYzU2LCBQQ0lfQU5ZX0lELCAwLCAweDBhLCAwLCBwY2lfc2M1MjBfc3B1bmtfY29uZmlndXJlX2NhcmRidXMsIHsgMCwgMCwgMH0gfSwKCXsgMCwgMCwgMCwgMCwgMCwgMCwgTlVMTCwgezAsMCwwfX0KfTsKCnN0YXRpYyBzdHJ1Y3QgcGNpX2NvbnRyb2xsZXIgc2M1MjBfc3B1bmtfaG9zZSA9IHsKCWZpeHVwX2lycTogcGNpX3NjNTIwX3NwdW5rX2ZpeHVwX2lycSwKCWNvbmZpZ190YWJsZTogcGNpX3NjNTIwX3NwdW5rX2NvbmZpZ190YWJsZSwKCWZpcnN0X2J1c25vOiAweDAwLAoJbGFzdF9idXNubzogMHhmZiwKfTsKCnZvaWQgcGNpX2luaXRfYm9hcmQodm9pZCkKewoJcGNpX3NjNTIwX2luaXQoJnNjNTIwX3NwdW5rX2hvc2UpOwp9CgoKLyogc2V0IHVwIHRoZSBJU0EgYnVzIHRpbWluZyBhbmQgc3lzdGVtIGFkZHJlc3MgbWFwcGluZ3MgKi8Kc3RhdGljIHZvaWQgYnVzX2luaXQodm9pZCkKewoJLyogdmVyc2lvbnMKCSAqIDAgICBIeWdsbyB2ZXJzaW9ucyAwLjk1IGFuZCAwLjk2IChsYXJnZSBiYW9yZHMpCgkgKiA/PyAgSHlnbG8gdmVyc2lvbiAwLjk3IChzbWFsbCBib2FyZCkKCSAqIDEwICBTcHVuayBib2FyZAoJICovCglpbnQgdmVyc2lvbiA9IHJlYWRfbW1jcl9ieXRlKFNDNTIwX1NZU0lORk8pOwoKCWlmICh2ZXJzaW9uKSB7CgkJLyogc2V0IHVwIHRoZSBHUCBJTyBwaW5zIChmb3IgdGhlIFNwdW5rIGJvYXJkKSAqLwoJCXdyaXRlX21tY3Jfd29yZChTQzUyMF9QSU9QRlMzMV8xNiwgMHhmZmYwKTsJLyogc2V0IHRoZSBHUElPIHBpbiBmdW5jdGlvbiAzMS0xNiByZWcgKi8KCQl3cml0ZV9tbWNyX3dvcmQoU0M1MjBfUElPUEZTMTVfMCwgIDB4MDAwZik7CS8qIHNldCB0aGUgR1BJTyBwaW4gZnVuY3Rpb24gMTUtMCByZWcgKi8KCQl3cml0ZV9tbWNyX3dvcmQoU0M1MjBfUElPRElSMzFfMTYsIDB4MDAwZik7CS8qIHNldCB0aGUgR1BJTyBkaXJlY3Rpb24gMzEtMTYgcmVnICovCgkJd3JpdGVfbW1jcl93b3JkKFNDNTIwX1BJT0RJUjE1XzAsICAweDFmZjApOwkvKiBzZXQgdGhlIEdQSU8gZGlyZWN0aW9uIDE1LTAgcmVnICovCgkJd3JpdGVfbW1jcl9ieXRlKFNDNTIwX0NTUEZTLCAweGMwKTsJCS8qIHNldCB0aGUgQ1MgcGluIGZ1bmN0aW9uIHJlZyAqLwoJCXdyaXRlX21tY3JfYnl0ZShTQzUyMF9DTEtTRUwsIDB4NzApOwoKCQl3cml0ZV9tbWNyX3dvcmQoU0M1MjBfUElPQ0xSMzFfMTYsIDB4MDAwMyk7ICAgICAvKiByZXNldCBTU0kgY2hpcC1zZWxlY3RzICovCgkJd3JpdGVfbW1jcl93b3JkKFNDNTIwX1BJT1NFVDMxXzE2LCAweDAwMGMpOwoKCX0gZWxzZSB7CgkJLyogc2V0IHVwIHRoZSBHUCBJTyBwaW5zIChmb3IgdGhlIEh5Z2xvIGJvYXJkKSAqLwoJCXdyaXRlX21tY3Jfd29yZChTQzUyMF9QSU9QRlMzMV8xNiwgMHhmZmMwKTsJLyogc2V0IHRoZSBHUElPIHBpbiBmdW5jdGlvbiAzMS0xNiByZWcgKi8KCQl3cml0ZV9tbWNyX3dvcmQoU0M1MjBfUElPUEZTMTVfMCwgMHgxZTdmKTsJLyogc2V0IHRoZSBHUElPIHBpbiBmdW5jdGlvbiAxNS0wIHJlZyAqLwoJCXdyaXRlX21tY3Jfd29yZChTQzUyMF9QSU9ESVIzMV8xNiwgMHgwMDNmKTsJLyogc2V0IHRoZSBHUElPIGRpcmVjdGlvbiAzMS0xNiByZWcgKi8KCQl3cml0ZV9tbWNyX3dvcmQoU0M1MjBfUElPRElSMTVfMCwgMHhlMTgwKTsJLyogc2V0IHRoZSBHUElPIGRpcmVjdGlvbiAxNS0wIHJlZyAqLwoJCXdyaXRlX21tY3JfYnl0ZShTQzUyMF9DU1BGUywgMHgwMCk7CQkvKiBzZXQgdGhlIENTIHBpbiBmdW5jdGlvbiByZWcgKi8KCQl3cml0ZV9tbWNyX2J5dGUoU0M1MjBfQ0xLU0VMLCAweDcwKTsKCgkJd3JpdGVfbW1jcl93b3JkKFNDNTIwX1BJT0NMUjE1XzAsIDB4MDE4MCk7ICAgICAgLyogcmVzZXQgU1NJIGNoaXAtc2VsZWN0cyAqLwoJfQoKCXdyaXRlX21tY3JfYnl0ZShTQzUyMF9HUENTUlQsIDEpOyAgIC8qIHNldCB0aGUgR1AgQ1Mgb2Zmc2V0ICovCgl3cml0ZV9tbWNyX2J5dGUoU0M1MjBfR1BDU1BXLCAzKTsgICAvKiBzZXQgdGhlIEdQIENTIHB1bHNlIHdpZHRoICovCgl3cml0ZV9tbWNyX2J5dGUoU0M1MjBfR1BDU09GRiwgMSk7ICAvKiBzZXQgdGhlIEdQIENTIG9mZnNldCAqLwoJd3JpdGVfbW1jcl9ieXRlKFNDNTIwX0dQUkRXLCAzKTsgICAgLyogc2V0IHRoZSBSRCBwdWxzZSB3aWR0aCAqLwoJd3JpdGVfbW1jcl9ieXRlKFNDNTIwX0dQUkRPRkYsIDEpOyAgLyogc2V0IHRoZSBHUCBSRCBvZmZzZXQgKi8KCXdyaXRlX21tY3JfYnl0ZShTQzUyMF9HUFdSVywgMyk7ICAgIC8qIHNldCB0aGUgR1AgV1IgcHVsc2Ugd2lkdGggKi8KCXdyaXRlX21tY3JfYnl0ZShTQzUyMF9HUFdST0ZGLCAxKTsgIC8qIHNldCB0aGUgR1AgV1Igb2Zmc2V0ICovCgoJd3JpdGVfbW1jcl93b3JkKFNDNTIwX0JPT1RDU0NUTCwgMHgwNDA3KTsJCS8qIHNldCB1cCB0aW1pbmcgb2YgQk9PVENTICovCgoJLyogYWRqdXN0IHRoZSBtZW1vcnkgbWFwOgoJICogYnkgZGVmYXVsdCB0aGUgZmlyc3QgMjU2TUIgKDB4MDAwMDAwMDAgLSAweDBmZmZmZmZmKSBpcyBtYXBwZWQgdG8gU0RSQU0KCSAqIGFuZCAyNTZNQiB0byAxRy0xMjhrICAoMHgxMDAwMDAwIC0gMHgzN2ZmZmZmZikgaXMgbWFwcGVkIHRvIFBDSSBtbWlvCgkgKiB3ZSBuZWVkIHRvIG1hcCAxRy0xMjhrIC0gMUcgKDB4MzgwMDAwMDAgLSAweDNmZmZmZmZmKSB0byBDUzEgKi8KCgoJLyogYm9vdGNzICovCgl3cml0ZV9tbWNyX2xvbmcoU0M1MjBfUEFSMTIsIDB4OGJmZmU4MDApOwoKCS8qIElERTAgPSBHUENTNiAxZjAtMWY3ICovCgl3cml0ZV9tbWNyX2xvbmcoU0M1MjBfUEFSMywgIDB4MzgwODAxZjApOwoKCS8qIElERTEgPSBHUENTNyAzZjYgKi8KCXdyaXRlX21tY3JfbG9uZyhTQzUyMF9QQVI0LCAgMHgzYzAwMDNmNik7CgoJYXNtICgid2JpbnZkXG4iKTsgLyogRmx1c2ggY2FjaGUsIHJlcS4gYWZ0ZXIgc2V0dGluZyB0aGUgdW5jaGFjaGVkIGF0dHJpYnV0ZSBvbmEgUEFSICovCgoJd3JpdGVfbW1jcl9ieXRlKFNDNTIwX0FERERFQ0NUTCwgcmVhZF9tbWNyX2J5dGUoU0M1MjBfQUREREVDQ1RMKSAmIH4oVUFSVDJfRElTfFVBUlQxX0RJUykpOwoKfQoKCi8qIHBhciB1c2FnZToKICogUEFSMCAgIChsZWdhY3lfdmlkZW8pCiAqIFBBUjEgICAoUENJIFJPTSBtYXBwaW5nKQogKiBQQVIyCiAqIFBBUjMgICBJREUKICogUEFSNCAgIElERQogKiBQQVI1ICAgKGxlZ2FjeV92aWRlbykKICogUEFSNgogKiBQQVI3ICAgKGxlZ2FjeV92aWRlbykKICogUEFSOCAgIChsZWdhY3lfdmlkZW8pCiAqIFBBUjkgICAobGVnYWN5X3ZpZGVvKQogKiBQQVIxMAogKiBQQVIxMSAgKElTQVJPTSkKICogUEFSMTIgIEJPT1RDUwogKiBQQVIxMwogKiBQQVIxNAogKiBQQVIxNQogKi8KCi8qCiAqIFRoaXMgZnVuY3Rpb24gc2hvdWxkIG1hcCBhIGNodW5rIG9mIHNpemUgYnl0ZXMKICogb2YgdGhlIHN5c3RlbSBhZGRyZXNzIHNwYWNlIHRvIHRoZSBJU0EgYnVzCiAqCiAqIFRoZSBmdW5jdGlvbiB3aWxsIHJldHVybiB0aGUgbWVtb3J5IGFkZHJlc3MKICogYXMgc2VlbiBieSB0aGUgaG9zdCAod2hpY2ggbWF5IHZlcnkgd2lsbCBiZSB0aGUKICogc2FtZSBhcyB0aGUgYnVzIGFkZHJlc3MpCiAqLwp1MzIgaXNhX21hcF9yb20odTMyIGJ1c19hZGRyLCBpbnQgc2l6ZSkKewoJdTMyIHBhcjsKCglwcmludGYoImlzYV9tYXBfcm9tIGFza2VkIHRvIG1hcCAlZCBieXRlcyBhdCAleFxuIiwKCSAgICAgICBzaXplLCBidXNfYWRkcik7CgoJcGFyID0gc2l6ZTsKCWlmIChwYXIgPCAweDgwMDAwKSB7CgkJcGFyID0gMHg4MDAwMDsKCX0KCXBhciA+Pj0gMTI7CglwYXItLTsKCXBhciY9MHg3ZjsKCXBhciA8PD0gMTg7CglwYXIgfD0gKGJ1c19hZGRyPj4xMik7CglwYXIgfD0gMHg1MDAwMDAwMDsKCglwcmludGYgKCJzZXR0aW5nIFBBUjExIHRvICV4XG4iLCBwYXIpOwoKCS8qIE1hcCByb20gMHgxMDAwMCB3aXRoIFBBUjEgKi8KCXdyaXRlX21tY3JfbG9uZyhTQzUyMF9QQVIxMSwgIHBhcik7CgoJcmV0dXJuIGJ1c19hZGRyOwp9CgovKgogKiB0aGlzIGZ1bmN0aW9uIHJlbW92ZWQgYW55IG1hcHBpbmcgY3JlYXRlZAogKiB3aXRoIHBjaV9nZXRfcm9tX3dpbmRvdygpCiAqLwp2b2lkIGlzYV91bm1hcF9yb20odTMyIGFkZHIpCnsKCXByaW50ZigiaXNhX3VubWFwX3JvbSBhc2tlZCB0byB1bm1hcCAleCIsIGFkZHIpOwoJaWYgKChhZGRyPj4xMikgPT0gKHJlYWRfbW1jcl9sb25nKFNDNTIwX1BBUjExKSYweDNmZmZmKSkgewoJCXdyaXRlX21tY3JfbG9uZyhTQzUyMF9QQVIxMSwgMCk7CgkJcHJpbnRmKCIgZG9uZVxuIik7CgkJcmV0dXJuOwoJfQoJcHJpbnRmKCIgbm90IG91cnNcbiIpOwp9CgojaWZkZWYgQ09ORklHX1BDSQojZGVmaW5lIFBDSV9ST01fVEVNUF9TUEFDRSAweDEwMDAwCi8qCiAqIFRoaXMgZnVuY3Rpb24gc2hvdWxkIG1hcCBhIGNodW5rIG9mIHNpemUgYnl0ZXMKICogb2YgdGhlIHN5c3RlbSBhZGRyZXNzIHNwYWNlIHRvIHRoZSBQQ0kgYnVzLAogKiBzdWl0YWJsZSB0byBtYXAgUENJIFJPTVMgKGJ1cyBhZGRyZXNzIDwgMTZNKQogKiB0aGUgZnVuY3Rpb24gd2lsbCByZXR1cm4gdGhlIGhvc3QgbWVtb3J5IGFkZHJlc3MKICogd2hpY2ggc2hvdWxkIGJlIGNvbnZlcnRlZCBpbnRvIGEgYnVzIGFkZHJlc3MKICogYmVmb3JlIHVzZWQgdG8gY29uZmlndXJlIHRoZSBQQ0kgcm9tIGFkZHJlc3MKICogZGVjb2RlcgogKi8KdTMyIHBjaV9nZXRfcm9tX3dpbmRvdyhzdHJ1Y3QgcGNpX2NvbnRyb2xsZXIgKmhvc2UsIGludCBzaXplKQp7Cgl1MzIgcGFyOwoKCXBhciA9IHNpemU7CglpZiAocGFyIDwgMHg4MDAwMCkgewoJCXBhciA9IDB4ODAwMDA7Cgl9CglwYXIgPj49IDE2OwoJcGFyLS07CglwYXImPTB4N2ZmOwoJcGFyIDw8PSAxNDsKCXBhciB8PSAoUENJX1JPTV9URU1QX1NQQUNFPj4xNik7CglwYXIgfD0gMHg3MjAwMDAwMDsKCglwcmludGYgKCJzZXR0aW5nIFBBUjEgdG8gJXhcbiIsIHBhcik7CgoJLyogTWFwIHJvbSAweDEwMDAwIHdpdGggUEFSMSAqLwoJd3JpdGVfbW1jcl9sb25nKFNDNTIwX1BBUjEsICBwYXIpOwoKCXJldHVybiBQQ0lfUk9NX1RFTVBfU1BBQ0U7Cn0KCi8qCiAqIHRoaXMgZnVuY3Rpb24gcmVtb3ZlZCBhbnkgbWFwcGluZyBjcmVhdGVkCiAqIHdpdGggcGNpX2dldF9yb21fd2luZG93KCkKICovCnZvaWQgcGNpX3JlbW92ZV9yb21fd2luZG93KHN0cnVjdCBwY2lfY29udHJvbGxlciAqaG9zZSwgdTMyIGFkZHIpCnsKCXByaW50ZigicGNpX3JlbW92ZV9yb21fd2luZG93OiAleCIsIGFkZHIpOwoJaWYgKGFkZHIgPT0gUENJX1JPTV9URU1QX1NQQUNFKSB7CgkJd3JpdGVfbW1jcl9sb25nKFNDNTIwX1BBUjEsIDApOwoJCXByaW50ZigiIGRvbmVcbiIpOwoJCXJldHVybjsKCX0KCXByaW50ZigiIG5vdCBvdXJzXG4iKTsKCn0KCi8qCiAqIFRoaXMgZnVuY3Rpb24gaXMgY2FsbGVkIGluIG9yZGVyIHRvIHByb3ZpZGUgYWNjZXMgdG8gdGhlCiAqIGxlZ2FjeSB2aWRlbyBJL08gcG9ydHMgb24gdGhlIFBDSSBidXMuCiAqIEFmdGVyIHRoaXMgZnVuY3Rpb24gYWNjZXNzZXMgdG8gSS9PIHBvcnRzIDB4M2IwLTB4M2JiIGFuZAogKiAweDNjMC0weDNkZiBzaHVsZCByZXN1bHQgaW4gdHJhbnNhY3Rpb25zIG9uIHRoZSBQQ0kgYnVzLgogKgogKi8KaW50IHBjaV9lbmFibGVfbGVnYWN5X3ZpZGVvX3BvcnRzKHN0cnVjdCBwY2lfY29udHJvbGxlciAqaG9zZSkKewoJLyogTWFwIHZpZGVvIG1lbW9yeSB0byAweGEwMDAwKi8KCXdyaXRlX21tY3JfbG9uZyhTQzUyMF9QQVIwLCAgMHg3MjAwNDAwYSk7CgoJLyogZm9yd2FyZCBhbGwgSS9PIGFjY2Vzc2VzIHRvIFBDSSAqLwoJd3JpdGVfbW1jcl9ieXRlKFNDNTIwX0FERERFQ0NUTCwKCQkJcmVhZF9tbWNyX2J5dGUoU0M1MjBfQUREREVDQ1RMKSB8IElPX0hPTEVfREVTVF9QQ0kpOwoKCgkvKiBzbyB3ZSBtYXAgYXdheSBhbGwgaW8gcG9ydHMgdG8gcGNpIChvbmx5IHdheSB0byBhY2Nlc3MgcGNpIGlvCgkgKiBiZWxvdyAweDQwMC4gQnV0IHRoZW4gd2UgaGF2ZSB0byBtYXAgYmFjayB0aGUgcG9ydGlvbnMgdGhhdCB3ZSBkb250CgkgKiB1c2Ugc28gdGhhdCB0aGUgZ2VuZXJhdGUgY3ljbGVzIG9uIHRoZSBHUElPIGJ1cyB3aGVyZSB0aGUgc2lvIGFuZAoJICogSVNBIHNsb3RzIGFyZSBjb25uZWN0ZWQsIHRoaXMgcmVxdXJlIHRoZSB1c2Ugb2Ygc2V2ZXJhbCBQQVIgcmVnaXN0ZXJzCgkgKi8KCgkvKiBicmluZyAweDEwMCAtIDB4MmY3IGJhY2sgdG8gSVNBIHVzaW5nIFBBUjUgKi8KCXdyaXRlX21tY3JfbG9uZyhTQzUyMF9QQVI1LCAweDMxZjcwMTAwKTsKCgkvKiBjb20yIHVzZSAyZjgtMmZmICovCgoJLyogYnJpbmcgMHgzMDAgLSAweDNhZiBiYWNrIHRvIElTQSB1c2luZyBQQVI3ICovCgl3cml0ZV9tbWNyX2xvbmcoU0M1MjBfUEFSNywgMHgzMGFmMDMwMCk7CgoJLyogdmdhIHVzZSAzYjAtM2JiICovCgoJLyogYnJpbmcgMHgzYmMgLSAweDNiZiBiYWNrIHRvIElTQSB1c2luZyBQQVI4ICovCgl3cml0ZV9tbWNyX2xvbmcoU0M1MjBfUEFSOCwgMHgzMDAzMDNiYyk7CgoJLyogdmdhIHVzZSAzYzAtM2RmICovCgoJLyogYnJpbmcgMHgzZTAgLSAweDNmNyBiYWNrIHRvIElTQSB1c2luZyBQQVI5ICovCgl3cml0ZV9tbWNyX2xvbmcoU0M1MjBfUEFSOSwgMHgzMDE3MDNlMCk7CgoJLyogY29tMSB1c2UgM2Y4LTNmZiAqLwoKCXJldHVybiAwOwp9CiNlbmRpZgoKLyoKICogTWlzY2VsYW5lb3VzIHBsYXRmb3JtIGRlcGVuZGVudCBpbml0aWFsaXNhdGlvbnMKICovCgppbnQgYm9hcmRfaW5pdCh2b2lkKQp7Cglpbml0X3NjNTIwKCk7CglidXNfaW5pdCgpOwoJaXJxX2luaXQoKTsKCgkvKiBtYXggZHJpdmUgY3VycmVudCBvbiBTRFJBTSAqLwoJd3JpdGVfbW1jcl93b3JkKFNDNTIwX0RTQ1RMLCAweDAxMDApOwoKCS8qIGVudGVyIGRlYnVnIG1vZGUgYWZ0ZXIgbmV4dCByZXNldCAob25seSBpZiBqdW1wZXIgaXMgYWxzbyBzZXQpICovCgl3cml0ZV9tbWNyX2J5dGUoU0M1MjBfUkVTQ0ZHLCAweDA4KTsKCS8qIGNvbmZpZ3VyZSB0aGUgc29mdHdhcmUgdGltZXIgdG8gMzMuMDAwTUh6ICovCgl3cml0ZV9tbWNyX2J5dGUoU0M1MjBfU1dUTVJDRkcsIDEpOwoJZ2QtPmJ1c19jbGsgPSAzMzAwMDAwMDsKCglyZXR1cm4gMDsKfQoKaW50IGRyYW1faW5pdCh2b2lkKQp7Cglpbml0X3NjNTIwX2RyYW0oKTsKCXJldHVybiAwOwp9Cgp2b2lkIHNob3dfYm9vdF9wcm9ncmVzcyhpbnQgdmFsKQp7CglpbnQgdmVyc2lvbiA9IHJlYWRfbW1jcl9ieXRlKFNDNTIwX1NZU0lORk8pOwoKCWlmICh2YWwgPCAtMzIpIHZhbCA9IC0xOyAgLyogbGV0IHRoaW5ncyBjb21wYXRpYmxlICovCglpZiAodmVyc2lvbiA9PSAwKSB7CgkJLyogUElPMzEtUElPMTYgRGF0YSAqLwoJCXdyaXRlX21tY3Jfd29yZChTQzUyMF9QSU9EQVRBMzFfMTYsCgkJCQkocmVhZF9tbWNyX3dvcmQoU0M1MjBfUElPREFUQTMxXzE2KSAmIDB4ZmZjMCl8ICgodmFsJjB4N2UpPj4xKSk7IC8qIDB4MWY4ID4+IDMgKi8KCgkJLyogUElPMC1QSU8xNSBEYXRhICovCgkJd3JpdGVfbW1jcl93b3JkKFNDNTIwX1BJT0RBVEExNV8wLAoJCQkJKHJlYWRfbW1jcl93b3JkKFNDNTIwX1BJT0RBVEExNV8wKSAmIDB4MWZmZil8ICgodmFsJjB4Nyk8PDEzKSk7Cgl9IGVsc2UgewoJCS8qIG5ld2VyIGJvYXJkcyB1c2UgUElPNC1QSU8xMiAqLwoJCS8qIFBJTzAtUElPMTUgRGF0YSAqLwojaWYgMAoJCXZhbCA9ICh2YWwgJiAweDAwNykgfCAoKHZhbCAmIDB4MDM4KSA8PCAzKSB8ICgodmFsICYgMHgxYzApID4+IDMpOwojZWxzZQoJCXZhbCA9ICh2YWwgJiAweDAwNykgfCAoKHZhbCAmIDB4MDdlKSA8PCAyKTsKI2VuZGlmCgkJd3JpdGVfbW1jcl93b3JkKFNDNTIwX1BJT0RBVEExNV8wLAoJCQkJKHJlYWRfbW1jcl93b3JkKFNDNTIwX1BJT0RBVEExNV8wKSAmIDB4ZTAwZikgfCAoKHZhbCYweDAxZmYpPDw0KSk7Cgl9Cn0KCgppbnQgbGFzdF9zdGFnZV9pbml0KHZvaWQpCnsKCglpbnQgdmVyc2lvbiA9IHJlYWRfbW1jcl9ieXRlKFNDNTIwX1NZU0lORk8pOwoKCXByaW50ZigiT21pY3JvbiBDZXRpIFNDNTIwIFNwdW5rIHJldmlzaW9uICV4XG4iLCB2ZXJzaW9uKTsKCiNpZiAwCglpZiAodmVyc2lvbikgewoJCWludCB4LCB5OwoKCQlwcmludGYoImVlcHJvbSBwcm9iZSAlZFxuIiwgc3BpX2VlcHJvbV9wcm9iZSgxKSk7CgoJCXNwaV9lZXByb21fcmVhZCgxLCAwLCAodTgqKSZ4LCAyKTsKCQlzcGlfZWVwcm9tX3JlYWQoMSwgMSwgKHU4KikmeSwgMik7CgkJcHJpbnRmKCJlZXByb20gYnl0ZXMgJTA0eCUwNHhcbiIsIHgsIHkpOwoJCXggXj0gMHhmZmZmOwoJCXkgXj0gMHhmZmZmOwoJCXNwaV9lZXByb21fd3JpdGUoMSwgMCwgKHU4KikmeCwgMik7CgkJc3BpX2VlcHJvbV93cml0ZSgxLCAxLCAodTgqKSZ5LCAyKTsKCgkJc3BpX2VlcHJvbV9yZWFkKDEsIDAsICh1OCopJngsIDIpOwoJCXNwaV9lZXByb21fcmVhZCgxLCAxLCAodTgqKSZ5LCAyKTsKCQlwcmludGYoImVlcHJvbSBieXRlcyAlMDR4JTA0eFxuIiwgeCwgeSk7CgoJfSBlbHNlIHsKCQlpbnQgeCwgeTsKCgkJcHJpbnRmKCJlZXByb20gcHJvYmUgJWRcbiIsIG13X2VlcHJvbV9wcm9iZSgxKSk7CgoJCW13X2VlcHJvbV9yZWFkKDEsIDAsICh1OCopJngsIDIpOwoJCW13X2VlcHJvbV9yZWFkKDEsIDEsICh1OCopJnksIDIpOwoJCXByaW50ZigiZWVwcm9tIGJ5dGVzICUwNHglMDR4XG4iLCB4LCB5KTsKCgkJeCBePSAweGZmZmY7CgkJeSBePSAweGZmZmY7CgkJbXdfZWVwcm9tX3dyaXRlKDEsIDAsICh1OCopJngsIDIpOwoJCW13X2VlcHJvbV93cml0ZSgxLCAxLCAodTgqKSZ5LCAyKTsKCgkJbXdfZWVwcm9tX3JlYWQoMSwgMCwgKHU4KikmeCwgMik7CgkJbXdfZWVwcm9tX3JlYWQoMSwgMSwgKHU4KikmeSwgMik7CgkJcHJpbnRmKCJlZXByb20gYnl0ZXMgJTA0eCUwNHhcbiIsIHgsIHkpOwoKCgl9CiNlbmRpZgoKCWRzMTcyMl9wcm9iZSgyKTsKCglyZXR1cm4gMDsKfQoKdm9pZCBzc2lfY2hpcF9zZWxlY3QoaW50IGRldikKewoJaW50IHZlcnNpb24gPSByZWFkX21tY3JfYnl0ZShTQzUyMF9TWVNJTkZPKTsKCglpZiAodmVyc2lvbikgewoJCS8qIFNwdW5rIGJvYXJkOiBFRVBST00gYW5kIENBTiBhcmUgYWN0b3ZlLWxvdywgVEVNUCBhbmQgQVVYIGFyZSBhY3RpdmUgaGlnaCAqLwoJCXN3aXRjaCAoZGV2KSB7CgkJY2FzZSAxOiAvKiBFRVBST00gKi8KCQkJd3JpdGVfbW1jcl93b3JkKFNDNTIwX1BJT0NMUjMxXzE2LCAweDAwMDQpOwoJCQlicmVhazsKCgkJY2FzZSAyOiAvKiBUZW1wIFByb2JlICovCgkJCXdyaXRlX21tY3Jfd29yZChTQzUyMF9QSU9TRVQzMV8xNiwgMHgwMDAyKTsKCQkJYnJlYWs7CgoJCWNhc2UgMzogLyogQ0FOICovCgkJCXdyaXRlX21tY3Jfd29yZChTQzUyMF9QSU9DTFIzMV8xNiwgMHgwMDA4KTsKCQkJYnJlYWs7CgoJCWNhc2UgNDogLyogQVVYICovCgkJCXdyaXRlX21tY3Jfd29yZChTQzUyMF9QSU9TRVQzMV8xNiwgMHgwMDAxKTsKCQkJYnJlYWs7CgoJCWNhc2UgMDoKCQkJd3JpdGVfbW1jcl93b3JkKFNDNTIwX1BJT0NMUjMxXzE2LCAweDAwMDMpOwoJCQl3cml0ZV9tbWNyX3dvcmQoU0M1MjBfUElPU0VUMzFfMTYsIDB4MDAwYyk7CgkJCWJyZWFrOwoKCQlkZWZhdWx0OgoJCQlwcmludGYoIklsbGVnYWwgU1NJIGRldmljZSByZXF1ZXN0ZWQ6ICVkXG4iLCBkZXYpOwoJCX0KCX0gZWxzZSB7CgoJCS8qIEdsb2JveCBib2FyZDogQm90aCBFRVBST00gYW5kIFRFTVAgYXJlIGFjdGl2ZS1oaWdoICovCgoJCXN3aXRjaCAoZGV2KSB7CgkJY2FzZSAxOiAvKiBFRVBST00gKi8KCQkJd3JpdGVfbW1jcl93b3JkKFNDNTIwX1BJT1NFVDE1XzAsIDB4MDEwMCk7CgkJCWJyZWFrOwoKCQljYXNlIDI6IC8qIFRlbXAgUHJvYmUgKi8KCQkJd3JpdGVfbW1jcl93b3JkKFNDNTIwX1BJT1NFVDE1XzAsIDB4MDA4MCk7CgkJCWJyZWFrOwoKCQljYXNlIDA6CgkJCXdyaXRlX21tY3Jfd29yZChTQzUyMF9QSU9DTFIxNV8wLCAweDAxODApOwoJCQlicmVhazsKCgkJZGVmYXVsdDoKCQkJcHJpbnRmKCJJbGxlZ2FsIFNTSSBkZXZpY2UgcmVxdWVzdGVkOiAlZFxuIiwgZGV2KTsKCQl9Cgl9Cn0KCgp2b2lkIHNwaV9pbml0X2Yodm9pZCkKewoJcmVhZF9tbWNyX2J5dGUoU0M1MjBfU1lTSU5GTykgPwoJCXNwaV9lZXByb21fcHJvYmUoMSkgOgoJbXdfZWVwcm9tX3Byb2JlKDEpOwoKfQoKc3NpemVfdCBzcGlfcmVhZCh1Y2hhciAqYWRkciwgaW50IGFsZW4sIHVjaGFyICpidWZmZXIsIGludCBsZW4pCnsKCWludCBvZmZzZXQ7CglpbnQgaTsKCglvZmZzZXQgPSAwOwoJZm9yIChpPTA7aTxhbGVuO2krKykgewoJCW9mZnNldCA8PD0gODsKCQlvZmZzZXQgfD0gYWRkcltpXTsKCX0KCglyZXR1cm4JcmVhZF9tbWNyX2J5dGUoU0M1MjBfU1lTSU5GTykgPwoJCXNwaV9lZXByb21fcmVhZCgxLCBvZmZzZXQsIGJ1ZmZlciwgbGVuKSA6Cgltd19lZXByb21fcmVhZCgxLCBvZmZzZXQsIGJ1ZmZlciwgbGVuKTsKfQoKc3NpemVfdCBzcGlfd3JpdGUodWNoYXIgKmFkZHIsIGludCBhbGVuLCB1Y2hhciAqYnVmZmVyLCBpbnQgbGVuKQp7CglpbnQgb2Zmc2V0OwoJaW50IGk7CgoJb2Zmc2V0ID0gMDsKCWZvciAoaT0wO2k8YWxlbjtpKyspIHsKCQlvZmZzZXQgPDw9IDg7CgkJb2Zmc2V0IHw9IGFkZHJbaV07Cgl9CgoJcmV0dXJuCXJlYWRfbW1jcl9ieXRlKFNDNTIwX1NZU0lORk8pID8KCQlzcGlfZWVwcm9tX3dyaXRlKDEsIG9mZnNldCwgYnVmZmVyLCBsZW4pIDoKCW13X2VlcHJvbV93cml0ZSgxLCBvZmZzZXQsIGJ1ZmZlciwgbGVuKTsKfQo=