LyoKICogQ29weXJpZ2h0IChDKSBFeGNpdG8gRWxla3Ryb25payBpIFNr5W5lIEFCLCBBbGwgcmlnaHRzIHJlc2VydmVkLgogKiBBdXRob3I6IFRvciBLcmlsbCA8dG9yQGV4Y2l0by5jb20+CiAqCiAqIFRoaXMgcHJvZ3JhbSBpcyBmcmVlIHNvZnR3YXJlOyB5b3UgY2FuIHJlZGlzdHJpYnV0ZSBpdCBhbmQvb3IKICogbW9kaWZ5IGl0IHVuZGVyIHRoZSB0ZXJtcyBvZiB0aGUgR05VIEdlbmVyYWwgUHVibGljIExpY2Vuc2UgYXMKICogcHVibGlzaGVkIGJ5IHRoZSBGcmVlIFNvZnR3YXJlIEZvdW5kYXRpb247IGVpdGhlciB2ZXJzaW9uIDIgb2YKICogdGhlIExpY2Vuc2UsIG9yIChhdCB5b3VyIG9wdGlvbikgYW55IGxhdGVyIHZlcnNpb24uCiAqCiAqIFRoaXMgcHJvZ3JhbSBpcyBkaXN0cmlidXRlZCBpbiB0aGUgaG9wZSB0aGF0IGl0IHdpbGwgYmUgdXNlZnVsLAogKiBidXQgV0lUSE9VVCBBTlkgV0FSUkFOVFk7IHdpdGhvdXQgZXZlbiB0aGUgaW1wbGllZCB3YXJyYW50eSBvZgogKiBNRVJDSEFOVEFCSUxJVFkgb3IgRklUTkVTUyBGT1IgQSBQQVJUSUNVTEFSIFBVUlBPU0UuICBTZWUgdGhlCiAqIEdOVSBHZW5lcmFsIFB1YmxpYyBMaWNlbnNlIGZvciBtb3JlIGRldGFpbHMuCiAqCiAqIFlvdSBzaG91bGQgaGF2ZSByZWNlaXZlZCBhIGNvcHkgb2YgdGhlIEdOVSBHZW5lcmFsIFB1YmxpYyBMaWNlbnNlCiAqIGFsb25nIHdpdGggdGhpcyBwcm9ncmFtOyBpZiBub3QsIHdyaXRlIHRvIHRoZSBGcmVlIFNvZnR3YXJlCiAqIEZvdW5kYXRpb24sIEluYy4sIDU5IFRlbXBsZSBQbGFjZSwgU3VpdGUgMzMwLCBCb3N0b24sCiAqIE1BIDAyMTExLTEzMDcgVVNBCiAqCiAqIFRoaXMgaXMgYSBkcml2ZXIgZm9yIFNpbGljb24gSW1hZ2Ugc2lsMzExNCBzYXRhIGNoaXAgbW9kZWxsZWQgb24KICogdGhlIGF0YV9waWl4IGRyaXZlcgogKi8KCiNpbmNsdWRlIDxjb21tb24uaD4KI2luY2x1ZGUgPHBjaS5oPgojaW5jbHVkZSA8Y29tbWFuZC5oPgojaW5jbHVkZSA8Y29uZmlnLmg+CiNpbmNsdWRlIDxhc20vYnl0ZW9yZGVyLmg+CiNpbmNsdWRlIDxhc20vaW8uaD4KI2luY2x1ZGUgPGlkZS5oPgojaW5jbHVkZSA8bGliYXRhLmg+CiNpbmNsdWRlICJzYXRhX3NpbDMxMTQuaCIKCi8qIENvbnZlcnQgc2VjdG9yc2l6ZSB0byB3b3Jkc2l6ZSAqLwojZGVmaW5lIEFUQV9TRUNUT1JfV09SRFMgKEFUQV9TRUNUX1NJWkUvMikKCi8qIEZvcndhcmRzICovCnU4IHNpbDMxMTRfc3Bpbl91cCAoaW50IG51bSk7CnU4IHNpbDMxMTRfc3Bpbl9kb3duIChpbnQgbnVtKTsKc3RhdGljIGludCBzYXRhX2J1c19zb2Z0cmVzZXQgKGludCBudW0pOwpzdGF0aWMgdm9pZCBzYXRhX2lkZW50aWZ5IChpbnQgbnVtLCBpbnQgZGV2KTsKc3RhdGljIHU4IGNoZWNrX3Bvd2VyX21vZGUgKGludCBudW0pOwpzdGF0aWMgdm9pZCBzYXRhX3BvcnQgKHN0cnVjdCBzYXRhX2lvcG9ydHMgKmlvcG9ydCk7CnN0YXRpYyB2b2lkIHNldF9GZWF0dXJlX2NtZCAoaW50IG51bSwgaW50IGRldik7CnN0YXRpYyB1OCBzYXRhX2J1c3lfd2FpdCAoc3RydWN0IHNhdGFfaW9wb3J0cyAqaW9hZGRyLCBpbnQgYml0cywKCQkJICB1bnNpZ25lZCBpbnQgbWF4LCB1OCB1c2VhbHRzdGF0dXMpOwpzdGF0aWMgdTggc2F0YV9jaGtfc3RhdHVzIChzdHJ1Y3Qgc2F0YV9pb3BvcnRzICppb2FkZHIsIHU4IHVzZWFsdHN0YXR1cyk7CnN0YXRpYyB2b2lkIG1zbGVlcCAoaW50IGNvdW50KTsKCnN0YXRpYyB1MzIgaW9iYXNlWzZdID0geyAwLCAwLCAwLCAwLCAwLCAwfTsJLyogUENJIEJBUiByZWdpc3RlcnMgZm9yIGRldmljZSAqLwpleHRlcm4gYmxvY2tfZGV2X2Rlc2NfdCBzYXRhX2Rldl9kZXNjW0NPTkZJR19TWVNfU0FUQV9NQVhfREVWSUNFXTsKCnN0YXRpYyBzdHJ1Y3Qgc2F0YV9wb3J0IHBvcnRbQ09ORklHX1NZU19TQVRBX01BWF9ERVZJQ0VdOwoKc3RhdGljIHZvaWQgb3V0cHV0X2RhdGEgKHN0cnVjdCBzYXRhX2lvcG9ydHMgKmlvYWRkciwgdTE2ICogc2VjdF9idWYsIGludCB3b3JkcykKewoJd2hpbGUgKHdvcmRzLS0pIHsKCQlfX3Jhd193cml0ZXcgKCpzZWN0X2J1ZisrLCAodm9pZCAqKWlvYWRkci0+ZGF0YV9hZGRyKTsKCX0KfQoKc3RhdGljIGludCBpbnB1dF9kYXRhIChzdHJ1Y3Qgc2F0YV9pb3BvcnRzICppb2FkZHIsIHUxNiAqIHNlY3RfYnVmLCBpbnQgd29yZHMpCnsKCXdoaWxlICh3b3Jkcy0tKSB7CgkJKnNlY3RfYnVmKysgPSBfX3Jhd19yZWFkdyAoKHZvaWQgKilpb2FkZHItPmRhdGFfYWRkcik7Cgl9CglyZXR1cm4gMDsKfQoKc3RhdGljIGludCBzYXRhX2J1c19zb2Z0cmVzZXQgKGludCBudW0pCnsKCXU4IHN0YXR1cyA9IDA7CgoJcG9ydFtudW1dLmRldl9tYXNrID0gMTsKCglwb3J0W251bV0uY3RsX3JlZyA9IDB4MDg7CS8qRGVmYXVsdCB2YWx1ZSBvZiBjb250cm9sIHJlZyAqLwoJd3JpdGViIChwb3J0W251bV0uY3RsX3JlZywgcG9ydFtudW1dLmlvYWRkci5jdGxfYWRkcik7Cgl1ZGVsYXkgKDEwKTsKCXdyaXRlYiAocG9ydFtudW1dLmN0bF9yZWcgfCBBVEFfU1JTVCwgcG9ydFtudW1dLmlvYWRkci5jdGxfYWRkcik7Cgl1ZGVsYXkgKDEwKTsKCXdyaXRlYiAocG9ydFtudW1dLmN0bF9yZWcsIHBvcnRbbnVtXS5pb2FkZHIuY3RsX2FkZHIpOwoKCS8qIHNwZWMgbWFuZGF0ZXMgIj49IDJtcyIgYmVmb3JlIGNoZWNraW5nIHN0YXR1cy4KCSAqIFdlIHdhaXQgMTUwbXMsIGJlY2F1c2UgdGhhdCB3YXMgdGhlIG1hZ2ljIGRlbGF5IHVzZWQgZm9yCgkgKiBBVEFQSSBkZXZpY2VzIGluIEhhbGUgTGFuZGlzJ3MgQVRBRFJWUiwgZm9yIHRoZSBwZXJpb2Qgb2YgdGltZQoJICogYmV0d2VlbiB3aGVuIHRoZSBBVEEgY29tbWFuZCByZWdpc3RlciBpcyB3cml0dGVuLCBhbmQgdGhlbgoJICogc3RhdHVzIGlzIGNoZWNrZWQuICBCZWNhdXNlIHdhaXRpbmcgZm9yICJhIHdoaWxlIiBiZWZvcmUKCSAqIGNoZWNraW5nIHN0YXR1cyBpcyBmaW5lLCBwb3N0IFNSU1QsIHdlIHBlcmZvcm0gdGhpcyBtYWdpYwoJICogZGVsYXkgaGVyZSBhcyB3ZWxsLgoJICovCgltc2xlZXAgKDE1MCk7CglzdGF0dXMgPSBzYXRhX2J1c3lfd2FpdCAoJnBvcnRbbnVtXS5pb2FkZHIsIEFUQV9CVVNZLCAzMDAsIDApOwoJd2hpbGUgKChzdGF0dXMgJiBBVEFfQlVTWSkpIHsKCQltc2xlZXAgKDEwMCk7CgkJc3RhdHVzID0gc2F0YV9idXN5X3dhaXQgKCZwb3J0W251bV0uaW9hZGRyLCBBVEFfQlVTWSwgMywgMCk7Cgl9CgoJaWYgKHN0YXR1cyAmIEFUQV9CVVNZKSB7CgkJcHJpbnRmICgiYXRhJXUgaXMgc2xvdyB0byByZXNwb25kLHBseiBiZSBwYXRpZW50XG4iLCBwb3J0KTsKCX0KCgl3aGlsZSAoKHN0YXR1cyAmIEFUQV9CVVNZKSkgewoJCW1zbGVlcCAoMTAwKTsKCQlzdGF0dXMgPSBzYXRhX2Noa19zdGF0dXMgKCZwb3J0W251bV0uaW9hZGRyLCAwKTsKCX0KCglpZiAoc3RhdHVzICYgQVRBX0JVU1kpIHsKCQlwcmludGYgKCJhdGEldSBmYWlsZWQgdG8gcmVzcG9uZCA6ICIsIHBvcnQpOwoJCXByaW50ZiAoImJ1cyByZXNldCBmYWlsZWRcbiIpOwoJCXBvcnRbbnVtXS5kZXZfbWFzayA9IDA7CgkJcmV0dXJuIDE7Cgl9CglyZXR1cm4gMDsKfQoKc3RhdGljIHZvaWQgc2F0YV9pZGVudGlmeSAoaW50IG51bSwgaW50IGRldikKewoJdTggY21kID0gMCwgc3RhdHVzID0gMCwgZGV2bm8gPSBudW07Cgl1MTYgaW9idWZbQVRBX1NFQ1RPUl9XT1JEU107Cgl1NjQgbl9zZWN0b3JzID0gMDsKCgltZW1zZXQgKGlvYnVmLCAwLCBzaXplb2YgKGlvYnVmKSk7CgoJaWYgKCEocG9ydFtudW1dLmRldl9tYXNrICYgMHgwMSkpIHsKCQlwcmludGYgKCJkZXYlZCBpcyBub3QgcHJlc2VudCBvbiBwb3J0IyVkXG4iLCBkZXYsIG51bSk7CgkJcmV0dXJuOwoJfQoKCWRlYnVnICgicG9ydD0lZCBkZXY9JWRcbiIsIG51bSwgZGV2KTsKCglzdGF0dXMgPSAwOwoJY21kID0gQVRBX0NNRF9JRF9BVEE7CS8qRGV2aWNlIElkZW50aWZ5IENvbW1hbmQgKi8KCXdyaXRlYiAoY21kLCBwb3J0W251bV0uaW9hZGRyLmNvbW1hbmRfYWRkcik7CglyZWFkYiAocG9ydFtudW1dLmlvYWRkci5hbHRzdGF0dXNfYWRkcik7Cgl1ZGVsYXkgKDEwKTsKCglzdGF0dXMgPSBzYXRhX2J1c3lfd2FpdCAoJnBvcnRbbnVtXS5pb2FkZHIsIEFUQV9CVVNZLCAxMDAwLCAwKTsKCWlmIChzdGF0dXMgJiBBVEFfRVJSKSB7CgkJcHJpbnRmICgiXG5kZXZpY2Ugbm90IHJlc3BvbmRpbmdcbiIpOwoJCXBvcnRbbnVtXS5kZXZfbWFzayAmPSB+MHgwMTsKCQlyZXR1cm47Cgl9CgoJaW5wdXRfZGF0YSAoJnBvcnRbbnVtXS5pb2FkZHIsIGlvYnVmLCBBVEFfU0VDVE9SX1dPUkRTKTsKCglhdGFfc3dhcF9idWZfbGUxNiAoaW9idWYsIEFUQV9TRUNUT1JfV09SRFMpOwoKCWRlYnVnICgiU3BlY2lmaWMgY29uZmlnOiAleFxuIiwgaW9idWZbMl0pOwoKCS8qIHdlIHJlcXVpcmUgTEJBIGFuZCBETUEgc3VwcG9ydCAoYml0cyA4ICYgOSBvZiB3b3JkIDQ5KSAqLwoJaWYgKCFhdGFfaWRfaGFzX2RtYSAoaW9idWYpIHx8ICFhdGFfaWRfaGFzX2xiYSAoaW9idWYpKSB7CgkJZGVidWcgKCJhdGEldTogbm8gZG1hL2xiYVxuIiwgbnVtKTsKCX0KI2lmZGVmIERFQlVHCglhdGFfZHVtcF9pZCAoaW9idWYpOwojZW5kaWYKCW5fc2VjdG9ycyA9IGF0YV9pZF9uX3NlY3RvcnMgKGlvYnVmKTsKCglpZiAobl9zZWN0b3JzID09IDApIHsKCQlwb3J0W251bV0uZGV2X21hc2sgJj0gfjB4MDE7CgkJcmV0dXJuOwoJfQoJYXRhX2lkX2Nfc3RyaW5nIChpb2J1ZiwgKHVuc2lnbmVkIGNoYXIgKilzYXRhX2Rldl9kZXNjW2Rldm5vXS5yZXZpc2lvbiwKCQkJIEFUQV9JRF9GV19SRVYsIHNpemVvZiAoc2F0YV9kZXZfZGVzY1tkZXZub10ucmV2aXNpb24pKTsKCWF0YV9pZF9jX3N0cmluZyAoaW9idWYsICh1bnNpZ25lZCBjaGFyICopc2F0YV9kZXZfZGVzY1tkZXZub10udmVuZG9yLAoJCQkgQVRBX0lEX1BST0QsIHNpemVvZiAoc2F0YV9kZXZfZGVzY1tkZXZub10udmVuZG9yKSk7CglhdGFfaWRfY19zdHJpbmcgKGlvYnVmLCAodW5zaWduZWQgY2hhciAqKXNhdGFfZGV2X2Rlc2NbZGV2bm9dLnByb2R1Y3QsCgkJCSBBVEFfSURfU0VSTk8sIHNpemVvZiAoc2F0YV9kZXZfZGVzY1tkZXZub10ucHJvZHVjdCkpOwoKCS8qIFRPRE8gLSBhdG0gd2UgYXN1bWUgaGFyZGRpc2sgaWUgbm90IHJlbW92YWJsZSAqLwoJc2F0YV9kZXZfZGVzY1tkZXZub10ucmVtb3ZhYmxlID0gMDsKCglzYXRhX2Rldl9kZXNjW2Rldm5vXS5sYmEgPSAodTMyKSBuX3NlY3RvcnM7CglkZWJ1ZyAoImxiYT0weCV4XG4iLCBzYXRhX2Rldl9kZXNjW2Rldm5vXS5sYmEpOwoKI2lmZGVmIENPTkZJR19MQkE0OAoJaWYgKGlvYnVmWzgzXSAmICgxIDw8IDEwKSkgewoJCXNhdGFfZGV2X2Rlc2NbZGV2bm9dLmxiYTQ4ID0gMTsKCX0gZWxzZSB7CgkJc2F0YV9kZXZfZGVzY1tkZXZub10ubGJhNDggPSAwOwoJfQojZW5kaWYKCgkvKiBhc3N1bWluZyBIRCAqLwoJc2F0YV9kZXZfZGVzY1tkZXZub10udHlwZSA9IERFVl9UWVBFX0hBUkRESVNLOwoJc2F0YV9kZXZfZGVzY1tkZXZub10uYmxrc3ogPSBBVEFfU0VDVF9TSVpFOwoJc2F0YV9kZXZfZGVzY1tkZXZub10ubHVuID0gMDsJLyoganVzdCB0byBmaWxsIHNvbWV0aGluZyBpbi4uLiAqLwp9CgpzdGF0aWMgdm9pZCBzZXRfRmVhdHVyZV9jbWQgKGludCBudW0sIGludCBkZXYpCnsKCXU4IHN0YXR1cyA9IDA7CgoJaWYgKCEocG9ydFtudW1dLmRldl9tYXNrICYgMHgwMSkpIHsKCQlkZWJ1ZyAoImRldiVkIGlzIG5vdCBwcmVzZW50IG9uIHBvcnQjJWRcbiIsIGRldiwgbnVtKTsKCQlyZXR1cm47Cgl9CgoJd3JpdGViIChTRVRGRUFUVVJFU19YRkVSLCBwb3J0W251bV0uaW9hZGRyLmZlYXR1cmVfYWRkcik7Cgl3cml0ZWIgKFhGRVJfUElPXzQsIHBvcnRbbnVtXS5pb2FkZHIubnNlY3RfYWRkcik7Cgl3cml0ZWIgKDAsIHBvcnRbbnVtXS5pb2FkZHIubGJhbF9hZGRyKTsKCXdyaXRlYiAoMCwgcG9ydFtudW1dLmlvYWRkci5sYmFtX2FkZHIpOwoJd3JpdGViICgwLCBwb3J0W251bV0uaW9hZGRyLmxiYWhfYWRkcik7CgoJd3JpdGViIChBVEFfREVWSUNFX09CUywgcG9ydFtudW1dLmlvYWRkci5kZXZpY2VfYWRkcik7Cgl3cml0ZWIgKEFUQV9DTURfU0VUX0ZFQVRVUkVTLCBwb3J0W251bV0uaW9hZGRyLmNvbW1hbmRfYWRkcik7CgoJdWRlbGF5ICg1MCk7Cgltc2xlZXAgKDE1MCk7CgoJc3RhdHVzID0gc2F0YV9idXN5X3dhaXQgKCZwb3J0W251bV0uaW9hZGRyLCBBVEFfQlVTWSwgNTAwMCwgMCk7CglpZiAoKHN0YXR1cyAmIChBVEFfQlVTWSB8IEFUQV9FUlIpKSkgewoJCXByaW50ZiAoIkVycm9yICA6IHN0YXR1cyAweCUwMnhcbiIsIHN0YXR1cyk7CgkJcG9ydFtudW1dLmRldl9tYXNrICY9IH4weDAxOwoJfQp9Cgp1OCBzaWwzMTE0X3NwaW5fZG93biAoaW50IG51bSkKewoJdTggc3RhdHVzID0gMDsKCglkZWJ1ZyAoIlNwaW4gZG93biBkaXNrXG4iKTsKCglpZiAoIShwb3J0W251bV0uZGV2X21hc2sgJiAweDAxKSkgewoJCWRlYnVnICgiRGV2aWNlIGF0YSVkIGlzIG5vdCBwcmVzZW50XG4iLCBudW0pOwoJCXJldHVybiAxOwoJfQoKCWlmICgoc3RhdHVzID0gY2hlY2tfcG93ZXJfbW9kZSAobnVtKSkgPT0gMHgwMCkgewoJCWRlYnVnICgiQWxyZWFkeSBpbiBzdGFuZGJ5XG4iKTsKCQlyZXR1cm4gMDsKCX0KCglpZiAoc3RhdHVzID09IDB4MDEpIHsKCQlwcmludGYgKCJGYWlsZWQgdG8gY2hlY2sgcG93ZXIgbW9kZSBvbiBhdGElZFxuIiwgbnVtKTsKCQlyZXR1cm4gMTsKCX0KCglpZiAoISgoc3RhdHVzID0gc2F0YV9jaGtfc3RhdHVzICgmcG9ydFtudW1dLmlvYWRkciwgMCkpICYgQVRBX0RSRFkpKSB7CgkJcHJpbnRmICgiRGV2aWNlIGF0YSVkIG5vdCByZWFkeVxuIiwgbnVtKTsKCQlyZXR1cm4gMTsKCX0KCgl3cml0ZWIgKDB4MDAsIHBvcnRbbnVtXS5pb2FkZHIuZmVhdHVyZV9hZGRyKTsKCgl3cml0ZWIgKDB4MDAsIHBvcnRbbnVtXS5pb2FkZHIubnNlY3RfYWRkcik7Cgl3cml0ZWIgKDB4MDAsIHBvcnRbbnVtXS5pb2FkZHIubGJhbF9hZGRyKTsKCXdyaXRlYiAoMHgwMCwgcG9ydFtudW1dLmlvYWRkci5sYmFtX2FkZHIpOwoJd3JpdGViICgweDAwLCBwb3J0W251bV0uaW9hZGRyLmxiYWhfYWRkcik7CgoJd3JpdGViIChBVEFfREVWSUNFX09CUywgcG9ydFtudW1dLmlvYWRkci5kZXZpY2VfYWRkcik7Cgl3cml0ZWIgKEFUQV9DTURfU1RBTkRCWSwgcG9ydFtudW1dLmlvYWRkci5jb21tYW5kX2FkZHIpOwoKCXN0YXR1cyA9IHNhdGFfYnVzeV93YWl0ICgmcG9ydFtudW1dLmlvYWRkciwgQVRBX0JVU1ksIDMwMDAwLCAwKTsKCWlmICgoc3RhdHVzICYgKEFUQV9CVVNZIHwgQVRBX0VSUikpKSB7CgkJcHJpbnRmICgiRXJyb3Igd2FpdGluZyBmb3IgZGlzayBzcGluIGRvd246IHN0YXR1cyAweCUwMnhcbiIsCgkJCXN0YXR1cyk7CgkJcG9ydFtudW1dLmRldl9tYXNrICY9IH4weDAxOwoJCXJldHVybiAxOwoJfQoJcmV0dXJuIDA7Cn0KCnU4IHNpbDMxMTRfc3Bpbl91cCAoaW50IG51bSkKewoJdTggc3RhdHVzID0gMDsKCglkZWJ1ZyAoIlNwaW4gdXAgZGlza1xuIik7CgoJaWYgKCEocG9ydFtudW1dLmRldl9tYXNrICYgMHgwMSkpIHsKCQlkZWJ1ZyAoIkRldmljZSBhdGElZCBpcyBub3QgcHJlc2VudFxuIiwgbnVtKTsKCQlyZXR1cm4gMTsKCX0KCglpZiAoKHN0YXR1cyA9IGNoZWNrX3Bvd2VyX21vZGUgKG51bSkpICE9IDB4MDApIHsKCQlpZiAoc3RhdHVzID09IDB4MDEpIHsKCQkJcHJpbnRmICgiRmFpbGVkIHRvIGNoZWNrIHBvd2VyIG1vZGUgb24gYXRhJWRcbiIsIG51bSk7CgkJCXJldHVybiAxOwoJCX0gZWxzZSB7CgkJCS8qIHNob3VsZCBiZSB1cCBhbmQgcnVubmluZyBhbHJlYWR5ICovCgkJCXJldHVybiAwOwoJCX0KCX0KCglpZiAoISgoc3RhdHVzID0gc2F0YV9jaGtfc3RhdHVzICgmcG9ydFtudW1dLmlvYWRkciwgMCkpICYgQVRBX0RSRFkpKSB7CgkJcHJpbnRmICgiRGV2aWNlIGF0YSVkIG5vdCByZWFkeVxuIiwgbnVtKTsKCQlyZXR1cm4gMTsKCX0KCglkZWJ1ZyAoIlN0YXV0dXMgb2YgZGV2aWNlIGNoZWNrOiAlZFxuIiwgc3RhdHVzKTsKCgl3cml0ZWIgKDB4MDAsIHBvcnRbbnVtXS5pb2FkZHIuZmVhdHVyZV9hZGRyKTsKCgl3cml0ZWIgKDB4MDAsIHBvcnRbbnVtXS5pb2FkZHIubnNlY3RfYWRkcik7Cgl3cml0ZWIgKDB4MDAsIHBvcnRbbnVtXS5pb2FkZHIubGJhbF9hZGRyKTsKCXdyaXRlYiAoMHgwMCwgcG9ydFtudW1dLmlvYWRkci5sYmFtX2FkZHIpOwoJd3JpdGViICgweDAwLCBwb3J0W251bV0uaW9hZGRyLmxiYWhfYWRkcik7CgoJd3JpdGViIChBVEFfREVWSUNFX09CUywgcG9ydFtudW1dLmlvYWRkci5kZXZpY2VfYWRkcik7Cgl3cml0ZWIgKEFUQV9DTURfSURMRSwgcG9ydFtudW1dLmlvYWRkci5jb21tYW5kX2FkZHIpOwoKCXN0YXR1cyA9IHNhdGFfYnVzeV93YWl0ICgmcG9ydFtudW1dLmlvYWRkciwgQVRBX0JVU1ksIDMwMDAwLCAwKTsKCWlmICgoc3RhdHVzICYgKEFUQV9CVVNZIHwgQVRBX0VSUikpKSB7CgkJcHJpbnRmICgiRXJyb3Igd2FpdGluZyBmb3IgZGlzayBzcGluIHVwOiBzdGF0dXMgMHglMDJ4XG4iLAoJCQlzdGF0dXMpOwoJCXBvcnRbbnVtXS5kZXZfbWFzayAmPSB+MHgwMTsKCQlyZXR1cm4gMTsKCX0KCgkvKiBXYWl0IGZvciBkaXNrIHRvIGVudGVyIEFjdGl2ZSBzdGF0ZSAqLwoJZG8gewoJCW1zbGVlcCAoMTApOwoJCXN0YXR1cyA9IGNoZWNrX3Bvd2VyX21vZGUgKG51bSk7Cgl9IHdoaWxlICgoc3RhdHVzID09IDB4MDApIHx8IChzdGF0dXMgPT0gMHg4MCkpOwoKCWlmIChzdGF0dXMgPT0gMHgwMSkgewoJCXByaW50ZiAoIkZhbGllZCB3YWl0aW5nIGZvciBkaXNrIHRvIHNwaW4gdXBcbiIpOwoJCXJldHVybiAxOwoJfQoKCXJldHVybiAwOwp9CgovKiBSZXR1cm4gdmFsdWUgaXMgbm90IHRoZSB1c3VhbCBoZXJlCiAqIDB4MDAgLSBEZXZpY2Ugc3RhbmQgYnkKICogMHgwMSAtIE9wZXJhdGlvbiBmYWlsZWQKICogMHg4MCAtIERldmljZSBpZGxlCiAqIDB4ZmYgLSBEZXZpY2UgYWN0aXZlCiovCnN0YXRpYyB1OCBjaGVja19wb3dlcl9tb2RlIChpbnQgbnVtKQp7Cgl1OCBzdGF0dXMgPSAwOwoJdTggcmVzID0gMDsKCWlmICghKHBvcnRbbnVtXS5kZXZfbWFzayAmIDB4MDEpKSB7CgkJZGVidWcgKCJEZXZpY2UgYXRhJWQgaXMgbm90IHByZXNlbnRcbiIsIG51bSk7CgkJcmV0dXJuIDE7Cgl9CgoJaWYgKCEoc2F0YV9jaGtfc3RhdHVzICgmcG9ydFtudW1dLmlvYWRkciwgMCkgJiBBVEFfRFJEWSkpIHsKCQlwcmludGYgKCJEZXZpY2UgYXRhJWQgbm90IHJlYWR5XG4iLCBudW0pOwoJCXJldHVybiAxOwoJfQoKCXdyaXRlYiAoMCwgcG9ydFtudW1dLmlvYWRkci5mZWF0dXJlX2FkZHIpOwoJd3JpdGViICgwLCBwb3J0W251bV0uaW9hZGRyLm5zZWN0X2FkZHIpOwoJd3JpdGViICgwLCBwb3J0W251bV0uaW9hZGRyLmxiYWxfYWRkcik7Cgl3cml0ZWIgKDAsIHBvcnRbbnVtXS5pb2FkZHIubGJhbV9hZGRyKTsKCXdyaXRlYiAoMCwgcG9ydFtudW1dLmlvYWRkci5sYmFoX2FkZHIpOwoKCXdyaXRlYiAoQVRBX0RFVklDRV9PQlMsIHBvcnRbbnVtXS5pb2FkZHIuZGV2aWNlX2FkZHIpOwoJd3JpdGViIChBVEFfQ01EX0NIS19QT1dFUiwgcG9ydFtudW1dLmlvYWRkci5jb21tYW5kX2FkZHIpOwoKCXN0YXR1cyA9IHNhdGFfYnVzeV93YWl0ICgmcG9ydFtudW1dLmlvYWRkciwgQVRBX0JVU1ksIDUwMDAsIDApOwoJaWYgKChzdGF0dXMgJiAoQVRBX0JVU1kgfCBBVEFfRVJSKSkpIHsKCQlwcmludGYKCQkgICAgKCJFcnJvciB3YWl0aW5nIGZvciBjaGVjayBwb3dlciBtb2RlIGNvbXBsZXRlICA6IHN0YXR1cyAweCUwMnhcbiIsCgkJICAgICBzdGF0dXMpOwoJCXBvcnRbbnVtXS5kZXZfbWFzayAmPSB+MHgwMTsKCQlyZXR1cm4gMTsKCX0KCXJlcyA9IHJlYWRiIChwb3J0W251bV0uaW9hZGRyLm5zZWN0X2FkZHIpOwoJZGVidWcgKCJDaGVjayBwb3dlcm1vZGU6ICVkXG4iLCByZXMpOwoJcmV0dXJuIHJlczsKCn0KCnN0YXRpYyB2b2lkIHNhdGFfcG9ydCAoc3RydWN0IHNhdGFfaW9wb3J0cyAqaW9wb3J0KQp7Cglpb3BvcnQtPmRhdGFfYWRkciA9IGlvcG9ydC0+Y21kX2FkZHIgKyBBVEFfUkVHX0RBVEE7Cglpb3BvcnQtPmVycm9yX2FkZHIgPSBpb3BvcnQtPmNtZF9hZGRyICsgQVRBX1JFR19FUlI7Cglpb3BvcnQtPmZlYXR1cmVfYWRkciA9IGlvcG9ydC0+Y21kX2FkZHIgKyBBVEFfUkVHX0ZFQVRVUkU7Cglpb3BvcnQtPm5zZWN0X2FkZHIgPSBpb3BvcnQtPmNtZF9hZGRyICsgQVRBX1JFR19OU0VDVDsKCWlvcG9ydC0+bGJhbF9hZGRyID0gaW9wb3J0LT5jbWRfYWRkciArIEFUQV9SRUdfTEJBTDsKCWlvcG9ydC0+bGJhbV9hZGRyID0gaW9wb3J0LT5jbWRfYWRkciArIEFUQV9SRUdfTEJBTTsKCWlvcG9ydC0+bGJhaF9hZGRyID0gaW9wb3J0LT5jbWRfYWRkciArIEFUQV9SRUdfTEJBSDsKCWlvcG9ydC0+ZGV2aWNlX2FkZHIgPSBpb3BvcnQtPmNtZF9hZGRyICsgQVRBX1JFR19ERVZJQ0U7Cglpb3BvcnQtPnN0YXR1c19hZGRyID0gaW9wb3J0LT5jbWRfYWRkciArIEFUQV9SRUdfU1RBVFVTOwoJaW9wb3J0LT5jb21tYW5kX2FkZHIgPSBpb3BvcnQtPmNtZF9hZGRyICsgQVRBX1JFR19DTUQ7Cn0KCnN0YXRpYyB1OCB3YWl0X2Zvcl9pcnEgKGludCBudW0sIHVuc2lnbmVkIGludCBtYXgpCnsKCgl1MzIgcG9ydCA9IGlvYmFzZVs1XTsKCXN3aXRjaCAobnVtKSB7CgljYXNlIDA6CgkJcG9ydCArPSBWTkRfVEZfQ05TVF9DSDA7CgkJYnJlYWs7CgljYXNlIDE6CgkJcG9ydCArPSBWTkRfVEZfQ05TVF9DSDE7CgkJYnJlYWs7CgljYXNlIDI6CgkJcG9ydCArPSBWTkRfVEZfQ05TVF9DSDI7CgkJYnJlYWs7CgljYXNlIDM6CgkJcG9ydCArPSBWTkRfVEZfQ05TVF9DSDM7CgkJYnJlYWs7CglkZWZhdWx0OgoJCXJldHVybiAxOwoJfQoKCWRvIHsKCQlpZiAocmVhZGwgKHBvcnQpICYgVk5EX1RGX0NOU1RfSU5UU1QpIHsKCQkJYnJlYWs7CgkJfQoJCXVkZWxheSAoMTAwMCk7CgkJbWF4LS07Cgl9IHdoaWxlICgobWF4ID4gMCkpOwoKCXJldHVybiAobWF4ID09IDApOwp9CgpzdGF0aWMgdTggc2F0YV9idXN5X3dhaXQgKHN0cnVjdCBzYXRhX2lvcG9ydHMgKmlvYWRkciwgaW50IGJpdHMsCgkJCSAgdW5zaWduZWQgaW50IG1heCwgdTggdXNlYWx0c3RhdHVzKQp7Cgl1OCBzdGF0dXM7CgoJZG8gewoJCWlmICghKChzdGF0dXMgPSBzYXRhX2Noa19zdGF0dXMgKGlvYWRkciwgdXNlYWx0c3RhdHVzKSkgJiBiaXRzKSkgewoJCQlicmVhazsKCQl9CgkJdWRlbGF5ICgxMDAwKTsKCQltYXgtLTsKCX0gd2hpbGUgKChzdGF0dXMgJiBiaXRzKSAmJiAobWF4ID4gMCkpOwoKCXJldHVybiBzdGF0dXM7Cn0KCnN0YXRpYyB1OCBzYXRhX2Noa19zdGF0dXMgKHN0cnVjdCBzYXRhX2lvcG9ydHMgKmlvYWRkciwgdTggdXNlYWx0c3RhdHVzKQp7CglpZiAoIXVzZWFsdHN0YXR1cykgewoJCXJldHVybiByZWFkYiAoaW9hZGRyLT5zdGF0dXNfYWRkcik7Cgl9IGVsc2UgewoJCXJldHVybiByZWFkYiAoaW9hZGRyLT5hbHRzdGF0dXNfYWRkcik7Cgl9Cn0KCnN0YXRpYyB2b2lkIG1zbGVlcCAoaW50IGNvdW50KQp7CglpbnQgaTsKCglmb3IgKGkgPSAwOyBpIDwgY291bnQ7IGkrKykKCQl1ZGVsYXkgKDEwMDApOwp9CgovKiBSZWFkIHVwIHRvIDI1NSBzZWN0b3JzCiAqCiAqIFJldHVybnMgc2VjdG9ycyByZWFkCiovCnN0YXRpYyB1OCBkb19vbmVfcmVhZCAoaW50IGRldmljZSwgdWxvbmcgYmxvY2ssIHU4IGJsa2NudCwgdTE2ICogYnVmZiwKCQkgICAgICAgdWNoYXIgbGJhNDgpCnsKCgl1OCBzciA9IDA7Cgl1OCBzdGF0dXM7Cgl1NjQgYmxrbnIgPSAodTY0KSBibG9jazsKCglpZiAoIShzYXRhX2Noa19zdGF0dXMgKCZwb3J0W2RldmljZV0uaW9hZGRyLCAwKSAmIEFUQV9EUkRZKSkgewoJCXByaW50ZiAoIkRldmljZSBhdGElZCBub3QgcmVhZHlcbiIsIGRldmljZSk7CgkJcmV0dXJuIDA7Cgl9CgoJLyogU2V0IHVwIHRyYW5zZmVyICovCiNpZmRlZiBDT05GSUdfTEJBNDgKCWlmIChsYmE0OCkgewoJCS8qIHdyaXRlIGhpZ2ggYml0cyAqLwoJCXdyaXRlYiAoMCwgcG9ydFtkZXZpY2VdLmlvYWRkci5uc2VjdF9hZGRyKTsKCQl3cml0ZWIgKChibGtuciA+PiAyNCkgJiAweEZGLCBwb3J0W2RldmljZV0uaW9hZGRyLmxiYWxfYWRkcik7CgkJd3JpdGViICgoYmxrbnIgPj4gMzIpICYgMHhGRiwgcG9ydFtkZXZpY2VdLmlvYWRkci5sYmFtX2FkZHIpOwoJCXdyaXRlYiAoKGJsa25yID4+IDQwKSAmIDB4RkYsIHBvcnRbZGV2aWNlXS5pb2FkZHIubGJhaF9hZGRyKTsKCX0KI2VuZGlmCgl3cml0ZWIgKGJsa2NudCwgcG9ydFtkZXZpY2VdLmlvYWRkci5uc2VjdF9hZGRyKTsKCXdyaXRlYiAoKChibGtucikgPj4gMCkgJiAweEZGLCBwb3J0W2RldmljZV0uaW9hZGRyLmxiYWxfYWRkcik7Cgl3cml0ZWIgKChibGtuciA+PiA4KSAmIDB4RkYsIHBvcnRbZGV2aWNlXS5pb2FkZHIubGJhbV9hZGRyKTsKCXdyaXRlYiAoKGJsa25yID4+IDE2KSAmIDB4RkYsIHBvcnRbZGV2aWNlXS5pb2FkZHIubGJhaF9hZGRyKTsKCiNpZmRlZiBDT05GSUdfTEJBNDgKCWlmIChsYmE0OCkgewoJCXdyaXRlYiAoQVRBX0xCQSwgcG9ydFtkZXZpY2VdLmlvYWRkci5kZXZpY2VfYWRkcik7CgkJd3JpdGViIChBVEFfQ01EX1BJT19SRUFEX0VYVCwgcG9ydFtkZXZpY2VdLmlvYWRkci5jb21tYW5kX2FkZHIpOwoJfSBlbHNlCiNlbmRpZgoJewoJCXdyaXRlYiAoQVRBX0xCQSB8ICgoYmxrbnIgPj4gMjQpICYgMHhGKSwKCQkJcG9ydFtkZXZpY2VdLmlvYWRkci5kZXZpY2VfYWRkcik7CgkJd3JpdGViIChBVEFfQ01EX1BJT19SRUFELCBwb3J0W2RldmljZV0uaW9hZGRyLmNvbW1hbmRfYWRkcik7Cgl9CgoJc3RhdHVzID0gc2F0YV9idXN5X3dhaXQgKCZwb3J0W2RldmljZV0uaW9hZGRyLCBBVEFfQlVTWSwgMTAwMDAsIDEpOwoKCWlmIChzdGF0dXMgJiBBVEFfQlVTWSkgewoJCXU4IGVyciA9IDA7CgoJCXByaW50ZiAoIkRldmljZSAlZCBub3QgcmVzcG9uZGluZyBzdGF0dXMgJWRcbiIsIGRldmljZSwgc3RhdHVzKTsKCQllcnIgPSByZWFkYiAocG9ydFtkZXZpY2VdLmlvYWRkci5lcnJvcl9hZGRyKTsKCQlwcmludGYgKCJFcnJvciByZWcgPSAweCV4XG4iLCBlcnIpOwoKCQlyZXR1cm4gKHNyKTsKCX0KCXdoaWxlIChibGtjbnQtLSkgewoKCQlpZiAod2FpdF9mb3JfaXJxIChkZXZpY2UsIDUwMCkpIHsKCQkJcHJpbnRmICgiYXRhJXUgaXJxIGZhaWxlZFxuIiwgZGV2aWNlKTsKCQkJcmV0dXJuIHNyOwoJCX0KCgkJc3RhdHVzID0gc2F0YV9jaGtfc3RhdHVzICgmcG9ydFtkZXZpY2VdLmlvYWRkciwgMCk7CgkJaWYgKHN0YXR1cyAmIEFUQV9FUlIpIHsKCQkJcHJpbnRmICgiYXRhJXUgZXJyb3IgJWRcbiIsIGRldmljZSwKCQkJCXJlYWRiIChwb3J0W2RldmljZV0uaW9hZGRyLmVycm9yX2FkZHIpKTsKCQkJcmV0dXJuIHNyOwoJCX0KCQkvKiBSZWFkIG9uZSBzZWN0b3IgKi8KCQlpbnB1dF9kYXRhICgmcG9ydFtkZXZpY2VdLmlvYWRkciwgYnVmZiwgQVRBX1NFQ1RPUl9XT1JEUyk7CgkJYnVmZiArPSBBVEFfU0VDVE9SX1dPUkRTOwoJCXNyKys7CgoJfQoJcmV0dXJuIHNyOwp9Cgp1bG9uZyBzYXRhX3JlYWQgKGludCBkZXZpY2UsIHVsb25nIGJsb2NrLCBsYmFpbnRfdCBibGtjbnQsIHZvaWQgKmJ1ZmYpCnsKCXVsb25nIG4gPSAwLCBzcmVhZDsKCXUxNiAqYnVmZmVyID0gKHUxNiAqKSBidWZmOwoJdTggc3RhdHVzID0gMDsKCXU2NCBibGtuciA9ICh1NjQpIGJsb2NrOwoJdW5zaWduZWQgY2hhciBsYmE0OCA9IDA7CgojaWZkZWYgQ09ORklHX0xCQTQ4CglpZiAoYmxrbnIgPiAweGZmZmZmZmYpIHsKCQlpZiAoIXNhdGFfZGV2X2Rlc2NbZGV2aWNlXS5sYmE0OCkgewoJCQlwcmludGYgKCJEcml2ZSBkb2Vzbid0IHN1cHBvcnQgNDgtYml0IGFkZHJlc3NpbmdcbiIpOwoJCQlyZXR1cm4gMDsKCQl9CgkJLyogbW9yZSB0aGFuIDI4IGJpdHMgdXNlZCwgdXNlIDQ4Yml0IG1vZGUgKi8KCQlsYmE0OCA9IDE7Cgl9CiNlbmRpZgoKCXdoaWxlIChibGtjbnQgPiAwKSB7CgoJCWlmIChibGtjbnQgPiAyNTUpIHsKCQkJc3JlYWQgPSAyNTU7CgkJfSBlbHNlIHsKCQkJc3JlYWQgPSBibGtjbnQ7CgkJfQoKCQlzdGF0dXMgPSBkb19vbmVfcmVhZCAoZGV2aWNlLCBibGtuciwgc3JlYWQsIGJ1ZmZlciwgbGJhNDgpOwoJCWlmIChzdGF0dXMgIT0gc3JlYWQpIHsKCQkJcHJpbnRmICgiUmVhZCBmYWlsZWRcbiIpOwoJCQlyZXR1cm4gbjsKCQl9CgoJCWJsa2NudCAtPSBzcmVhZDsKCQlibGtuciArPSBzcmVhZDsKCQluICs9IHNyZWFkOwoJCWJ1ZmZlciArPSBzcmVhZCAqIEFUQV9TRUNUT1JfV09SRFM7Cgl9CglyZXR1cm4gbjsKfQoKdWxvbmcgc2F0YV93cml0ZSAoaW50IGRldmljZSwgdWxvbmcgYmxvY2ssIGxiYWludF90IGJsa2NudCwgY29uc3Qgdm9pZCAqYnVmZikKewoJdWxvbmcgbiA9IDA7Cgl1MTYgKmJ1ZmZlciA9ICh1MTYgKikgYnVmZjsKCXVuc2lnbmVkIGNoYXIgc3RhdHVzID0gMCwgbnVtID0gMDsKCXU2NCBibGtuciA9ICh1NjQpIGJsb2NrOwojaWZkZWYgQ09ORklHX0xCQTQ4Cgl1bnNpZ25lZCBjaGFyIGxiYTQ4ID0gMDsKCglpZiAoYmxrbnIgPiAweGZmZmZmZmYpIHsKCQlpZiAoIXNhdGFfZGV2X2Rlc2NbZGV2aWNlXS5sYmE0OCkgewoJCQlwcmludGYgKCJEcml2ZSBkb2Vzbid0IHN1cHBvcnQgNDgtYml0IGFkZHJlc3NpbmdcbiIpOwoJCQlyZXR1cm4gMDsKCQl9CgkJLyogbW9yZSB0aGFuIDI4IGJpdHMgdXNlZCwgdXNlIDQ4Yml0IG1vZGUgKi8KCQlsYmE0OCA9IDE7Cgl9CiNlbmRpZgoJLypQb3J0IE51bWJlciAqLwoJbnVtID0gZGV2aWNlOwoKCXdoaWxlIChibGtjbnQtLSA+IDApIHsKCQlzdGF0dXMgPSBzYXRhX2J1c3lfd2FpdCAoJnBvcnRbbnVtXS5pb2FkZHIsIEFUQV9CVVNZLCA1MDAsIDApOwoJCWlmIChzdGF0dXMgJiBBVEFfQlVTWSkgewoJCQlwcmludGYgKCJhdGEldSBmYWlsZWQgdG8gcmVzcG9uZFxuIiwgcG9ydFtudW1dLnBvcnRfbm8pOwoJCQlyZXR1cm4gbjsKCQl9CiNpZmRlZiBDT05GSUdfTEJBNDgKCQlpZiAobGJhNDgpIHsKCQkJLyogd3JpdGUgaGlnaCBiaXRzICovCgkJCXdyaXRlYiAoMCwgcG9ydFtudW1dLmlvYWRkci5uc2VjdF9hZGRyKTsKCQkJd3JpdGViICgoYmxrbnIgPj4gMjQpICYgMHhGRiwKCQkJCXBvcnRbbnVtXS5pb2FkZHIubGJhbF9hZGRyKTsKCQkJd3JpdGViICgoYmxrbnIgPj4gMzIpICYgMHhGRiwKCQkJCXBvcnRbbnVtXS5pb2FkZHIubGJhbV9hZGRyKTsKCQkJd3JpdGViICgoYmxrbnIgPj4gNDApICYgMHhGRiwKCQkJCXBvcnRbbnVtXS5pb2FkZHIubGJhaF9hZGRyKTsKCQl9CiNlbmRpZgoJCXdyaXRlYiAoMSwgcG9ydFtudW1dLmlvYWRkci5uc2VjdF9hZGRyKTsKCQl3cml0ZWIgKChibGtuciA+PiAwKSAmIDB4RkYsIHBvcnRbbnVtXS5pb2FkZHIubGJhbF9hZGRyKTsKCQl3cml0ZWIgKChibGtuciA+PiA4KSAmIDB4RkYsIHBvcnRbbnVtXS5pb2FkZHIubGJhbV9hZGRyKTsKCQl3cml0ZWIgKChibGtuciA+PiAxNikgJiAweEZGLCBwb3J0W251bV0uaW9hZGRyLmxiYWhfYWRkcik7CiNpZmRlZiBDT05GSUdfTEJBNDgKCQlpZiAobGJhNDgpIHsKCQkJd3JpdGViIChBVEFfTEJBLCBwb3J0W251bV0uaW9hZGRyLmRldmljZV9hZGRyKTsKCQkJd3JpdGViIChBVEFfQ01EX1BJT19XUklURV9FWFQsIHBvcnRbbnVtXS5pb2FkZHIuY29tbWFuZF9hZGRyKTsKCQl9IGVsc2UKI2VuZGlmCgkJewoJCQl3cml0ZWIgKEFUQV9MQkEgfCAoKGJsa25yID4+IDI0KSAmIDB4RiksCgkJCQlwb3J0W251bV0uaW9hZGRyLmRldmljZV9hZGRyKTsKCQkJd3JpdGViIChBVEFfQ01EX1BJT19XUklURSwgcG9ydFtudW1dLmlvYWRkci5jb21tYW5kX2FkZHIpOwoJCX0KCgkJbXNsZWVwICg1MCk7CgkJLyptYXkgdGFrZSB1cCB0byA0IHNlYyAqLwoJCXN0YXR1cyA9IHNhdGFfYnVzeV93YWl0ICgmcG9ydFtudW1dLmlvYWRkciwgQVRBX0JVU1ksIDQwMDAsIDApOwoJCWlmICgoc3RhdHVzICYgKEFUQV9EUlEgfCBBVEFfQlVTWSB8IEFUQV9FUlIpKSAhPSBBVEFfRFJRKSB7CgkJCXByaW50ZiAoIkVycm9yIG5vIERSUSBkZXYgJWQgYmxrICVsZDogc3RzIDB4JTAyeFxuIiwKCQkJCWRldmljZSwgKHVsb25nKSBibGtuciwgc3RhdHVzKTsKCQkJcmV0dXJuIChuKTsKCQl9CgoJCW91dHB1dF9kYXRhICgmcG9ydFtudW1dLmlvYWRkciwgYnVmZmVyLCBBVEFfU0VDVE9SX1dPUkRTKTsKCQlyZWFkYiAocG9ydFtudW1dLmlvYWRkci5hbHRzdGF0dXNfYWRkcik7CgkJdWRlbGF5ICg1MCk7CgoJCSsrbjsKCQkrK2Jsa25yOwoJCWJ1ZmZlciArPSBBVEFfU0VDVE9SX1dPUkRTOwoJfQoJcmV0dXJuIG47Cn0KCi8qIERyaXZlciBpbXBsZW1lbnRhdGlvbiAqLwpzdGF0aWMgdTggc2lsX2dldF9kZXZpY2VfY2FjaGVfbGluZSAocGNpX2Rldl90IHBkZXYpCnsKCXU4IGNhY2hlX2xpbmUgPSAwOwoJcGNpX3JlYWRfY29uZmlnX2J5dGUgKHBkZXYsIFBDSV9DQUNIRV9MSU5FX1NJWkUsICZjYWNoZV9saW5lKTsKCXJldHVybiBjYWNoZV9saW5lOwp9CgppbnQgaW5pdF9zYXRhIChpbnQgZGV2KQp7CglzdGF0aWMgdTggaW5pdF9kb25lID0gMDsKCXN0YXRpYyBpbnQgcmVzID0gMTsKCXBjaV9kZXZfdCBkZXZubzsKCXU4IGNscyA9IDA7Cgl1MTYgY21kID0gMDsKCXUzMiBzY29uZiA9IDA7CgoJaWYgKGluaXRfZG9uZSkgewoJCXJldHVybiByZXM7Cgl9CgoJaW5pdF9kb25lID0gMTsKCglpZiAoKGRldm5vID0gcGNpX2ZpbmRfZGV2aWNlIChTSUxfVkVORF9JRCwgU0lMMzExNF9ERVZJQ0VfSUQsIDApKSA9PSAtMSkgewoJCXJlcyA9IDE7CgkJcmV0dXJuIHJlczsKCX0KCgkvKiBSZWFkIG91dCBhbGwgQkFScywgZXZlbiB0aG91Z2ggd2Ugb25seSB1c2UgTU1JTyBmcm9tIEJBUjUgKi8KCXBjaV9yZWFkX2NvbmZpZ19kd29yZCAoZGV2bm8sIFBDSV9CQVNFX0FERFJFU1NfMCwgJmlvYmFzZVswXSk7CglwY2lfcmVhZF9jb25maWdfZHdvcmQgKGRldm5vLCBQQ0lfQkFTRV9BRERSRVNTXzEsICZpb2Jhc2VbMV0pOwoJcGNpX3JlYWRfY29uZmlnX2R3b3JkIChkZXZubywgUENJX0JBU0VfQUREUkVTU18yLCAmaW9iYXNlWzJdKTsKCXBjaV9yZWFkX2NvbmZpZ19kd29yZCAoZGV2bm8sIFBDSV9CQVNFX0FERFJFU1NfMywgJmlvYmFzZVszXSk7CglwY2lfcmVhZF9jb25maWdfZHdvcmQgKGRldm5vLCBQQ0lfQkFTRV9BRERSRVNTXzQsICZpb2Jhc2VbNF0pOwoJcGNpX3JlYWRfY29uZmlnX2R3b3JkIChkZXZubywgUENJX0JBU0VfQUREUkVTU181LCAmaW9iYXNlWzVdKTsKCglpZiAoKGlvYmFzZVswXSA9PSAweEZGRkZGRkZGKSB8fCAoaW9iYXNlWzFdID09IDB4RkZGRkZGRkYpIHx8CgkgICAgKGlvYmFzZVsyXSA9PSAweEZGRkZGRkZGKSB8fCAoaW9iYXNlWzNdID09IDB4RkZGRkZGRkYpIHx8CgkgICAgKGlvYmFzZVs0XSA9PSAweEZGRkZGRkZGKSB8fCAoaW9iYXNlWzVdID09IDB4RkZGRkZGRkYpKSB7CgkJcHJpbnRmICgiRXJyb3Igbm8gYmFzZSBhZGRyIGZvciBTQVRBIGNvbnRyb2xsZXJcbiIpOwoJCXJlcyA9IDE7CgkJcmV0dXJuIHJlczsKCX0KCgkvKiBtYXNrIG9mZiB1bnVzZWQgYml0cyAqLwoJaW9iYXNlWzBdICY9IDB4ZmZmZmZmZmM7Cglpb2Jhc2VbMV0gJj0gMHhmZmZmZmZmODsKCWlvYmFzZVsyXSAmPSAweGZmZmZmZmZjOwoJaW9iYXNlWzNdICY9IDB4ZmZmZmZmZjg7Cglpb2Jhc2VbNF0gJj0gMHhmZmZmZmZmMDsKCWlvYmFzZVs1XSAmPSAweGZmZmZmYzAwOwoKCS8qIGZyb20gc2F0YV9zaWwgaW4gTGludXgga2VybmVsICovCgljbHMgPSBzaWxfZ2V0X2RldmljZV9jYWNoZV9saW5lIChkZXZubyk7CglpZiAoY2xzKSB7CgkJY2xzID4+PSAzOwoJCWNscysrOwkJLyogY2xzID0gKGxpbmVfc2l6ZS84KSsxICovCgkJd3JpdGVsIChjbHMgPDwgOCB8IGNscywgaW9iYXNlWzVdICsgVk5EX0ZJRk9DRkdfQ0gwKTsKCQl3cml0ZWwgKGNscyA8PCA4IHwgY2xzLCBpb2Jhc2VbNV0gKyBWTkRfRklGT0NGR19DSDEpOwoJCXdyaXRlbCAoY2xzIDw8IDggfCBjbHMsIGlvYmFzZVs1XSArIFZORF9GSUZPQ0ZHX0NIMik7CgkJd3JpdGVsIChjbHMgPDwgOCB8IGNscywgaW9iYXNlWzVdICsgVk5EX0ZJRk9DRkdfQ0gzKTsKCX0gZWxzZSB7CgkJcHJpbnRmICgiQ2FjaGUgbGluZSBub3Qgc2V0LiBEcml2ZXIgbWF5IG5vdCBmdW5jdGlvblxuIik7Cgl9CgoJLyogRW5hYmxlIG9wZXJhdGlvbiAqLwoJcGNpX3JlYWRfY29uZmlnX3dvcmQgKGRldm5vLCBQQ0lfQ09NTUFORCwgJmNtZCk7CgljbWQgfD0gUENJX0NPTU1BTkRfTUFTVEVSIHwgUENJX0NPTU1BTkRfSU8gfCBQQ0lfQ09NTUFORF9NRU1PUlk7CglwY2lfd3JpdGVfY29uZmlnX3dvcmQgKGRldm5vLCBQQ0lfQ09NTUFORCwgY21kKTsKCgkvKiBEaXNhYmxlIGludGVycnVwdCB1c2FnZSAqLwoJcGNpX3JlYWRfY29uZmlnX2R3b3JkIChkZXZubywgVk5EX1NZU0NPTkZTVEFULCAmc2NvbmYpOwoJc2NvbmYgfD0gKFZORF9TWVNDT05GU1RBVF9DSE5fMF9JTlRCTE9DSyB8IFZORF9TWVNDT05GU1RBVF9DSE5fMV9JTlRCTE9DSyk7CglwY2lfd3JpdGVfY29uZmlnX2R3b3JkIChkZXZubywgVk5EX1NZU0NPTkZTVEFULCBzY29uZik7CgoJcmVzID0gMDsKCXJldHVybiByZXM7Cn0KCi8qIENoZWNrIGlmIGRldmljZSBpcyBjb25uZWN0ZWQgdG8gcG9ydCAqLwppbnQgc2F0YV9idXNfcHJvYmUgKGludCBwb3J0bm8pCnsKCXUzMiBwb3J0ID0gaW9iYXNlWzVdOwoJdTMyIHZhbDsKCXN3aXRjaCAocG9ydG5vKSB7CgljYXNlIDA6CgkJcG9ydCArPSBWTkRfU1NUQVRVU19DSDA7CgkJYnJlYWs7CgljYXNlIDE6CgkJcG9ydCArPSBWTkRfU1NUQVRVU19DSDE7CgkJYnJlYWs7CgljYXNlIDI6CgkJcG9ydCArPSBWTkRfU1NUQVRVU19DSDI7CgkJYnJlYWs7CgljYXNlIDM6CgkJcG9ydCArPSBWTkRfU1NUQVRVU19DSDM7CgkJYnJlYWs7CglkZWZhdWx0OgoJCXJldHVybiAwOwoJfQoJdmFsID0gcmVhZGwgKHBvcnQpOwoJaWYgKCh2YWwgJiBTQVRBX0RFVF9QUkVTKSA9PSBTQVRBX0RFVF9QUkVTKSB7CgkJcmV0dXJuIDE7Cgl9IGVsc2UgewoJCXJldHVybiAwOwoJfQp9CgppbnQgc2F0YV9waHlfcmVzZXQgKGludCBwb3J0bm8pCnsKCXUzMiBwb3J0ID0gaW9iYXNlWzVdOwoJdTMyIHZhbDsKCXN3aXRjaCAocG9ydG5vKSB7CgljYXNlIDA6CgkJcG9ydCArPSBWTkRfU0NPTlRST0xfQ0gwOwoJCWJyZWFrOwoJY2FzZSAxOgoJCXBvcnQgKz0gVk5EX1NDT05UUk9MX0NIMTsKCQlicmVhazsKCWNhc2UgMjoKCQlwb3J0ICs9IFZORF9TQ09OVFJPTF9DSDI7CgkJYnJlYWs7CgljYXNlIDM6CgkJcG9ydCArPSBWTkRfU0NPTlRST0xfQ0gzOwoJCWJyZWFrOwoJZGVmYXVsdDoKCQlyZXR1cm4gMDsKCX0KCXZhbCA9IHJlYWRsIChwb3J0KTsKCXdyaXRlbCAodmFsIHwgU0FUQV9TQ19ERVRfUlNULCBwb3J0KTsKCW1zbGVlcCAoMTUwKTsKCXdyaXRlbCAodmFsICYgflNBVEFfU0NfREVUX1JTVCwgcG9ydCk7CglyZXR1cm4gMDsKfQoKaW50IHNjYW5fc2F0YSAoaW50IGRldikKewoJLyogQSBiaXQgYnJhaW4gZGVhZCwgYnV0IHRoZSBjb2RlIGhhcyBhIGxlZ2FjeSAqLwoJc3dpdGNoIChkZXYpIHsKCWNhc2UgMDoKCQlwb3J0WzBdLnBvcnRfbm8gPSAwOwoJCXBvcnRbMF0uaW9hZGRyLmNtZF9hZGRyID0gaW9iYXNlWzVdICsgVk5EX1RGMF9DSDA7CgkJcG9ydFswXS5pb2FkZHIuYWx0c3RhdHVzX2FkZHIgPSBwb3J0WzBdLmlvYWRkci5jdGxfYWRkciA9CgkJICAgIChpb2Jhc2VbNV0gKyBWTkRfVEYyX0NIMCkgfCBBVEFfUENJX0NUTF9PRlM7CgkJcG9ydFswXS5pb2FkZHIuYm1kbWFfYWRkciA9IGlvYmFzZVs1XSArIFZORF9CTURNQV9DSDA7CgkJYnJlYWs7CgljYXNlIDE6CgkJcG9ydFsxXS5wb3J0X25vID0gMDsKCQlwb3J0WzFdLmlvYWRkci5jbWRfYWRkciA9IGlvYmFzZVs1XSArIFZORF9URjBfQ0gxOwoJCXBvcnRbMV0uaW9hZGRyLmFsdHN0YXR1c19hZGRyID0gcG9ydFsxXS5pb2FkZHIuY3RsX2FkZHIgPQoJCSAgICAoaW9iYXNlWzVdICsgVk5EX1RGMl9DSDEpIHwgQVRBX1BDSV9DVExfT0ZTOwoJCXBvcnRbMV0uaW9hZGRyLmJtZG1hX2FkZHIgPSBpb2Jhc2VbNV0gKyBWTkRfQk1ETUFfQ0gxOwoJCWJyZWFrOwoJY2FzZSAyOgoJCXBvcnRbMl0ucG9ydF9ubyA9IDA7CgkJcG9ydFsyXS5pb2FkZHIuY21kX2FkZHIgPSBpb2Jhc2VbNV0gKyBWTkRfVEYwX0NIMjsKCQlwb3J0WzJdLmlvYWRkci5hbHRzdGF0dXNfYWRkciA9IHBvcnRbMl0uaW9hZGRyLmN0bF9hZGRyID0KCQkgICAgKGlvYmFzZVs1XSArIFZORF9URjJfQ0gyKSB8IEFUQV9QQ0lfQ1RMX09GUzsKCQlwb3J0WzJdLmlvYWRkci5ibWRtYV9hZGRyID0gaW9iYXNlWzVdICsgVk5EX0JNRE1BX0NIMjsKCQlicmVhazsKCWNhc2UgMzoKCQlwb3J0WzNdLnBvcnRfbm8gPSAwOwoJCXBvcnRbM10uaW9hZGRyLmNtZF9hZGRyID0gaW9iYXNlWzVdICsgVk5EX1RGMF9DSDM7CgkJcG9ydFszXS5pb2FkZHIuYWx0c3RhdHVzX2FkZHIgPSBwb3J0WzNdLmlvYWRkci5jdGxfYWRkciA9CgkJICAgIChpb2Jhc2VbNV0gKyBWTkRfVEYyX0NIMykgfCBBVEFfUENJX0NUTF9PRlM7CgkJcG9ydFszXS5pb2FkZHIuYm1kbWFfYWRkciA9IGlvYmFzZVs1XSArIFZORF9CTURNQV9DSDM7CgkJYnJlYWs7CglkZWZhdWx0OgoJCXByaW50ZiAoIlRyaWVkIHRvIHNjYW4gdW5rbm93biBwb3J0OiBhdGElZFxuIiwgZGV2KTsKCQlyZXR1cm4gMTsKCX0KCgkvKiBJbml0aWFsaXplIG90aGVyIHJlZ2lzdGVycyAqLwoJc2F0YV9wb3J0ICgmcG9ydFtkZXZdLmlvYWRkcik7CgoJLyogQ2hlY2sgZm9yIGF0dGFjaGVkIGRldmljZSAqLwoJaWYgKCFzYXRhX2J1c19wcm9iZSAoZGV2KSkgewoJCXBvcnRbZGV2XS5wb3J0X3N0YXRlID0gMDsKCQlkZWJ1ZyAoIlNBVEEjJWQgcG9ydCBpcyBub3QgcHJlc2VudFxuIiwgZGV2KTsKCX0gZWxzZSB7CgkJZGVidWcgKCJTQVRBIyVkIHBvcnQgaXMgcHJlc2VudFxuIiwgZGV2KTsKCQlpZiAoc2F0YV9idXNfc29mdHJlc2V0IChkZXYpKSB7CgkJCS8qIHNvZnQgcmVzZXQgZmFpbGVkLCB0cnkgYSBoYXJkIG9uZSAqLwoJCQlzYXRhX3BoeV9yZXNldCAoZGV2KTsKCQkJaWYgKHNhdGFfYnVzX3NvZnRyZXNldCAoZGV2KSkgewoJCQkJcG9ydFtkZXZdLnBvcnRfc3RhdGUgPSAwOwoJCQl9IGVsc2UgewoJCQkJcG9ydFtkZXZdLnBvcnRfc3RhdGUgPSAxOwoJCQl9CgkJfSBlbHNlIHsKCQkJcG9ydFtkZXZdLnBvcnRfc3RhdGUgPSAxOwoJCX0KCX0KCWlmIChwb3J0W2Rldl0ucG9ydF9zdGF0ZSA9PSAxKSB7CgkJLyogUHJvYmUgZGV2aWNlIGFuZCBzZXQgeGZlciBtb2RlICovCgkJc2F0YV9pZGVudGlmeSAoZGV2LCAwKTsKCQlzZXRfRmVhdHVyZV9jbWQgKGRldiwgMCk7Cgl9CgoJcmV0dXJuIDA7Cn0K