LyoKICogQ29weXJpZ2h0IChDKSBFeGNpdG8gRWxla3Ryb25payBpIFNr5W5lIEFCLCBBbGwgcmlnaHRzIHJlc2VydmVkLgogKiBBdXRob3I6IFRvciBLcmlsbCA8dG9yQGV4Y2l0by5jb20+CiAqCiAqIFRoaXMgcHJvZ3JhbSBpcyBmcmVlIHNvZnR3YXJlOyB5b3UgY2FuIHJlZGlzdHJpYnV0ZSBpdCBhbmQvb3IKICogbW9kaWZ5IGl0IHVuZGVyIHRoZSB0ZXJtcyBvZiB0aGUgR05VIEdlbmVyYWwgUHVibGljIExpY2Vuc2UgYXMKICogcHVibGlzaGVkIGJ5IHRoZSBGcmVlIFNvZnR3YXJlIEZvdW5kYXRpb247IGVpdGhlciB2ZXJzaW9uIDIgb2YKICogdGhlIExpY2Vuc2UsIG9yIChhdCB5b3VyIG9wdGlvbikgYW55IGxhdGVyIHZlcnNpb24uCiAqCiAqIFRoaXMgcHJvZ3JhbSBpcyBkaXN0cmlidXRlZCBpbiB0aGUgaG9wZSB0aGF0IGl0IHdpbGwgYmUgdXNlZnVsLAogKiBidXQgV0lUSE9VVCBBTlkgV0FSUkFOVFk7IHdpdGhvdXQgZXZlbiB0aGUgaW1wbGllZCB3YXJyYW50eSBvZgogKiBNRVJDSEFOVEFCSUxJVFkgb3IgRklUTkVTUyBGT1IgQSBQQVJUSUNVTEFSIFBVUlBPU0UuICBTZWUgdGhlCiAqIEdOVSBHZW5lcmFsIFB1YmxpYyBMaWNlbnNlIGZvciBtb3JlIGRldGFpbHMuCiAqCiAqIFlvdSBzaG91bGQgaGF2ZSByZWNlaXZlZCBhIGNvcHkgb2YgdGhlIEdOVSBHZW5lcmFsIFB1YmxpYyBMaWNlbnNlCiAqIGFsb25nIHdpdGggdGhpcyBwcm9ncmFtOyBpZiBub3QsIHdyaXRlIHRvIHRoZSBGcmVlIFNvZnR3YXJlCiAqIEZvdW5kYXRpb24sIEluYy4sIDU5IFRlbXBsZSBQbGFjZSwgU3VpdGUgMzMwLCBCb3N0b24sCiAqIE1BIDAyMTExLTEzMDcgVVNBCiAqCiAqIFRoaXMgaXMgYSBkcml2ZXIgZm9yIFNpbGljb24gSW1hZ2Ugc2lsMzExNCBzYXRhIGNoaXAgbW9kZWxsZWQgb24KICogdGhlIGF0YV9waWl4IGRyaXZlcgogKi8KCiNpbmNsdWRlIDxjb21tb24uaD4KI2luY2x1ZGUgPHBjaS5oPgojaW5jbHVkZSA8Y29tbWFuZC5oPgojaW5jbHVkZSA8Y29uZmlnLmg+CiNpbmNsdWRlIDxhc20vYnl0ZW9yZGVyLmg+CiNpbmNsdWRlIDxhc20vaW8uaD4KI2luY2x1ZGUgPGlkZS5oPgojaW5jbHVkZSA8bGliYXRhLmg+CiNpbmNsdWRlICJzYXRhX3NpbDMxMTQuaCIKCi8qIENvbnZlcnQgc2VjdG9yc2l6ZSB0byB3b3Jkc2l6ZSAqLwojZGVmaW5lIEFUQV9TRUNUT1JfV09SRFMgKEFUQV9TRUNUX1NJWkUvMikKCi8qIEZvcndhcmRzICovCnU4IHNpbDMxMTRfc3Bpbl91cCAoaW50IG51bSk7CnU4IHNpbDMxMTRfc3Bpbl9kb3duIChpbnQgbnVtKTsKc3RhdGljIGludCBzYXRhX2J1c19zb2Z0cmVzZXQgKGludCBudW0pOwpzdGF0aWMgdm9pZCBzYXRhX2lkZW50aWZ5IChpbnQgbnVtLCBpbnQgZGV2KTsKc3RhdGljIHU4IGNoZWNrX3Bvd2VyX21vZGUgKGludCBudW0pOwpzdGF0aWMgdm9pZCBzYXRhX3BvcnQgKHN0cnVjdCBzYXRhX2lvcG9ydHMgKmlvcG9ydCk7CnN0YXRpYyB2b2lkIHNldF9GZWF0dXJlX2NtZCAoaW50IG51bSwgaW50IGRldik7CnN0YXRpYyB1OCBzYXRhX2J1c3lfd2FpdCAoc3RydWN0IHNhdGFfaW9wb3J0cyAqaW9hZGRyLCBpbnQgYml0cywKCQkJICB1bnNpZ25lZCBpbnQgbWF4LCB1OCB1c2VhbHRzdGF0dXMpOwpzdGF0aWMgdTggc2F0YV9jaGtfc3RhdHVzIChzdHJ1Y3Qgc2F0YV9pb3BvcnRzICppb2FkZHIsIHU4IHVzZWFsdHN0YXR1cyk7CnN0YXRpYyB2b2lkIG1zbGVlcCAoaW50IGNvdW50KTsKCnN0YXRpYyB1MzIgaW9iYXNlWzZdID0geyAwLCAwLCAwLCAwLCAwLCAwfTsJLyogUENJIEJBUiByZWdpc3RlcnMgZm9yIGRldmljZSAqLwpleHRlcm4gYmxvY2tfZGV2X2Rlc2NfdCBzYXRhX2Rldl9kZXNjW0NGR19TQVRBX01BWF9ERVZJQ0VdOwoKc3RhdGljIHN0cnVjdCBzYXRhX3BvcnQgcG9ydFtDRkdfU0FUQV9NQVhfREVWSUNFXTsKCnN0YXRpYyB2b2lkIG91dHB1dF9kYXRhIChzdHJ1Y3Qgc2F0YV9pb3BvcnRzICppb2FkZHIsIHUxNiAqIHNlY3RfYnVmLCBpbnQgd29yZHMpCnsKCXdoaWxlICh3b3Jkcy0tKSB7CgkJX19yYXdfd3JpdGV3ICgqc2VjdF9idWYrKywgKHZvaWQgKilpb2FkZHItPmRhdGFfYWRkcik7Cgl9Cn0KCnN0YXRpYyBpbnQgaW5wdXRfZGF0YSAoc3RydWN0IHNhdGFfaW9wb3J0cyAqaW9hZGRyLCB1MTYgKiBzZWN0X2J1ZiwgaW50IHdvcmRzKQp7Cgl3aGlsZSAod29yZHMtLSkgewoJCSpzZWN0X2J1ZisrID0gX19yYXdfcmVhZHcgKCh2b2lkICopaW9hZGRyLT5kYXRhX2FkZHIpOwoJfQoJcmV0dXJuIDA7Cn0KCnN0YXRpYyBpbnQgc2F0YV9idXNfc29mdHJlc2V0IChpbnQgbnVtKQp7Cgl1OCBzdGF0dXMgPSAwOwoKCXBvcnRbbnVtXS5kZXZfbWFzayA9IDE7CgoJcG9ydFtudW1dLmN0bF9yZWcgPSAweDA4OwkvKkRlZmF1bHQgdmFsdWUgb2YgY29udHJvbCByZWcgKi8KCXdyaXRlYiAocG9ydFtudW1dLmN0bF9yZWcsIHBvcnRbbnVtXS5pb2FkZHIuY3RsX2FkZHIpOwoJdWRlbGF5ICgxMCk7Cgl3cml0ZWIgKHBvcnRbbnVtXS5jdGxfcmVnIHwgQVRBX1NSU1QsIHBvcnRbbnVtXS5pb2FkZHIuY3RsX2FkZHIpOwoJdWRlbGF5ICgxMCk7Cgl3cml0ZWIgKHBvcnRbbnVtXS5jdGxfcmVnLCBwb3J0W251bV0uaW9hZGRyLmN0bF9hZGRyKTsKCgkvKiBzcGVjIG1hbmRhdGVzICI+PSAybXMiIGJlZm9yZSBjaGVja2luZyBzdGF0dXMuCgkgKiBXZSB3YWl0IDE1MG1zLCBiZWNhdXNlIHRoYXQgd2FzIHRoZSBtYWdpYyBkZWxheSB1c2VkIGZvcgoJICogQVRBUEkgZGV2aWNlcyBpbiBIYWxlIExhbmRpcydzIEFUQURSVlIsIGZvciB0aGUgcGVyaW9kIG9mIHRpbWUKCSAqIGJldHdlZW4gd2hlbiB0aGUgQVRBIGNvbW1hbmQgcmVnaXN0ZXIgaXMgd3JpdHRlbiwgYW5kIHRoZW4KCSAqIHN0YXR1cyBpcyBjaGVja2VkLiAgQmVjYXVzZSB3YWl0aW5nIGZvciAiYSB3aGlsZSIgYmVmb3JlCgkgKiBjaGVja2luZyBzdGF0dXMgaXMgZmluZSwgcG9zdCBTUlNULCB3ZSBwZXJmb3JtIHRoaXMgbWFnaWMKCSAqIGRlbGF5IGhlcmUgYXMgd2VsbC4KCSAqLwoJbXNsZWVwICgxNTApOwoJc3RhdHVzID0gc2F0YV9idXN5X3dhaXQgKCZwb3J0W251bV0uaW9hZGRyLCBBVEFfQlVTWSwgMzAwLCAwKTsKCXdoaWxlICgoc3RhdHVzICYgQVRBX0JVU1kpKSB7CgkJbXNsZWVwICgxMDApOwoJCXN0YXR1cyA9IHNhdGFfYnVzeV93YWl0ICgmcG9ydFtudW1dLmlvYWRkciwgQVRBX0JVU1ksIDMsIDApOwoJfQoKCWlmIChzdGF0dXMgJiBBVEFfQlVTWSkgewoJCXByaW50ZiAoImF0YSV1IGlzIHNsb3cgdG8gcmVzcG9uZCxwbHogYmUgcGF0aWVudFxuIiwgcG9ydCk7Cgl9CgoJd2hpbGUgKChzdGF0dXMgJiBBVEFfQlVTWSkpIHsKCQltc2xlZXAgKDEwMCk7CgkJc3RhdHVzID0gc2F0YV9jaGtfc3RhdHVzICgmcG9ydFtudW1dLmlvYWRkciwgMCk7Cgl9CgoJaWYgKHN0YXR1cyAmIEFUQV9CVVNZKSB7CgkJcHJpbnRmICgiYXRhJXUgZmFpbGVkIHRvIHJlc3BvbmQgOiAiLCBwb3J0KTsKCQlwcmludGYgKCJidXMgcmVzZXQgZmFpbGVkXG4iKTsKCQlwb3J0W251bV0uZGV2X21hc2sgPSAwOwoJCXJldHVybiAxOwoJfQoJcmV0dXJuIDA7Cn0KCnN0YXRpYyB2b2lkIHNhdGFfaWRlbnRpZnkgKGludCBudW0sIGludCBkZXYpCnsKCXU4IGNtZCA9IDAsIHN0YXR1cyA9IDAsIGRldm5vID0gbnVtOwoJdTE2IGlvYnVmW0FUQV9TRUNUT1JfV09SRFNdOwoJdTY0IG5fc2VjdG9ycyA9IDA7CgoJbWVtc2V0IChpb2J1ZiwgMCwgc2l6ZW9mIChpb2J1ZikpOwoKCWlmICghKHBvcnRbbnVtXS5kZXZfbWFzayAmIDB4MDEpKSB7CgkJcHJpbnRmICgiZGV2JWQgaXMgbm90IHByZXNlbnQgb24gcG9ydCMlZFxuIiwgZGV2LCBudW0pOwoJCXJldHVybjsKCX0KCglkZWJ1ZyAoInBvcnQ9JWQgZGV2PSVkXG4iLCBudW0sIGRldik7CgoJc3RhdHVzID0gMDsKCWNtZCA9IEFUQV9DTURfSURfQVRBOwkvKkRldmljZSBJZGVudGlmeSBDb21tYW5kICovCgl3cml0ZWIgKGNtZCwgcG9ydFtudW1dLmlvYWRkci5jb21tYW5kX2FkZHIpOwoJcmVhZGIgKHBvcnRbbnVtXS5pb2FkZHIuYWx0c3RhdHVzX2FkZHIpOwoJdWRlbGF5ICgxMCk7CgoJc3RhdHVzID0gc2F0YV9idXN5X3dhaXQgKCZwb3J0W251bV0uaW9hZGRyLCBBVEFfQlVTWSwgMTAwMCwgMCk7CglpZiAoc3RhdHVzICYgQVRBX0VSUikgewoJCXByaW50ZiAoIlxuZGV2aWNlIG5vdCByZXNwb25kaW5nXG4iKTsKCQlwb3J0W251bV0uZGV2X21hc2sgJj0gfjB4MDE7CgkJcmV0dXJuOwoJfQoKCWlucHV0X2RhdGEgKCZwb3J0W251bV0uaW9hZGRyLCBpb2J1ZiwgQVRBX1NFQ1RPUl9XT1JEUyk7CgoJYXRhX3N3YXBfYnVmX2xlMTYgKGlvYnVmLCBBVEFfU0VDVE9SX1dPUkRTKTsKCglkZWJ1ZyAoIlNwZWNpZmljIGNvbmZpZzogJXhcbiIsIGlvYnVmWzJdKTsKCgkvKiB3ZSByZXF1aXJlIExCQSBhbmQgRE1BIHN1cHBvcnQgKGJpdHMgOCAmIDkgb2Ygd29yZCA0OSkgKi8KCWlmICghYXRhX2lkX2hhc19kbWEgKGlvYnVmKSB8fCAhYXRhX2lkX2hhc19sYmEgKGlvYnVmKSkgewoJCWRlYnVnICgiYXRhJXU6IG5vIGRtYS9sYmFcbiIsIG51bSk7Cgl9CiNpZmRlZiBERUJVRwoJYXRhX2R1bXBfaWQgKGlvYnVmKTsKI2VuZGlmCgluX3NlY3RvcnMgPSBhdGFfaWRfbl9zZWN0b3JzIChpb2J1Zik7CgoJaWYgKG5fc2VjdG9ycyA9PSAwKSB7CgkJcG9ydFtudW1dLmRldl9tYXNrICY9IH4weDAxOwoJCXJldHVybjsKCX0KCWF0YV9pZF9jX3N0cmluZyAoaW9idWYsICh1bnNpZ25lZCBjaGFyICopc2F0YV9kZXZfZGVzY1tkZXZub10ucmV2aXNpb24sCgkJCSBBVEFfSURfRldfUkVWLCBzaXplb2YgKHNhdGFfZGV2X2Rlc2NbZGV2bm9dLnJldmlzaW9uKSk7CglhdGFfaWRfY19zdHJpbmcgKGlvYnVmLCAodW5zaWduZWQgY2hhciAqKXNhdGFfZGV2X2Rlc2NbZGV2bm9dLnZlbmRvciwKCQkJIEFUQV9JRF9QUk9ELCBzaXplb2YgKHNhdGFfZGV2X2Rlc2NbZGV2bm9dLnZlbmRvcikpOwoJYXRhX2lkX2Nfc3RyaW5nIChpb2J1ZiwgKHVuc2lnbmVkIGNoYXIgKilzYXRhX2Rldl9kZXNjW2Rldm5vXS5wcm9kdWN0LAoJCQkgQVRBX0lEX1NFUk5PLCBzaXplb2YgKHNhdGFfZGV2X2Rlc2NbZGV2bm9dLnByb2R1Y3QpKTsKCgkvKiBUT0RPIC0gYXRtIHdlIGFzdW1lIGhhcmRkaXNrIGllIG5vdCByZW1vdmFibGUgKi8KCXNhdGFfZGV2X2Rlc2NbZGV2bm9dLnJlbW92YWJsZSA9IDA7CgoJc2F0YV9kZXZfZGVzY1tkZXZub10ubGJhID0gKHUzMikgbl9zZWN0b3JzOwoJZGVidWcgKCJsYmE9MHgleFxuIiwgc2F0YV9kZXZfZGVzY1tkZXZub10ubGJhKTsKCiNpZmRlZiBDT05GSUdfTEJBNDgKCWlmIChpb2J1Zls4M10gJiAoMSA8PCAxMCkpIHsKCQlzYXRhX2Rldl9kZXNjW2Rldm5vXS5sYmE0OCA9IDE7Cgl9IGVsc2UgewoJCXNhdGFfZGV2X2Rlc2NbZGV2bm9dLmxiYTQ4ID0gMDsKCX0KI2VuZGlmCgoJLyogYXNzdW1pbmcgSEQgKi8KCXNhdGFfZGV2X2Rlc2NbZGV2bm9dLnR5cGUgPSBERVZfVFlQRV9IQVJERElTSzsKCXNhdGFfZGV2X2Rlc2NbZGV2bm9dLmJsa3N6ID0gQVRBX1NFQ1RfU0laRTsKCXNhdGFfZGV2X2Rlc2NbZGV2bm9dLmx1biA9IDA7CS8qIGp1c3QgdG8gZmlsbCBzb21ldGhpbmcgaW4uLi4gKi8KfQoKc3RhdGljIHZvaWQgc2V0X0ZlYXR1cmVfY21kIChpbnQgbnVtLCBpbnQgZGV2KQp7Cgl1OCBzdGF0dXMgPSAwOwoKCWlmICghKHBvcnRbbnVtXS5kZXZfbWFzayAmIDB4MDEpKSB7CgkJZGVidWcgKCJkZXYlZCBpcyBub3QgcHJlc2VudCBvbiBwb3J0IyVkXG4iLCBkZXYsIG51bSk7CgkJcmV0dXJuOwoJfQoKCXdyaXRlYiAoU0VURkVBVFVSRVNfWEZFUiwgcG9ydFtudW1dLmlvYWRkci5mZWF0dXJlX2FkZHIpOwoJd3JpdGViIChYRkVSX1BJT180LCBwb3J0W251bV0uaW9hZGRyLm5zZWN0X2FkZHIpOwoJd3JpdGViICgwLCBwb3J0W251bV0uaW9hZGRyLmxiYWxfYWRkcik7Cgl3cml0ZWIgKDAsIHBvcnRbbnVtXS5pb2FkZHIubGJhbV9hZGRyKTsKCXdyaXRlYiAoMCwgcG9ydFtudW1dLmlvYWRkci5sYmFoX2FkZHIpOwoKCXdyaXRlYiAoQVRBX0RFVklDRV9PQlMsIHBvcnRbbnVtXS5pb2FkZHIuZGV2aWNlX2FkZHIpOwoJd3JpdGViIChBVEFfQ01EX1NFVF9GRUFUVVJFUywgcG9ydFtudW1dLmlvYWRkci5jb21tYW5kX2FkZHIpOwoKCXVkZWxheSAoNTApOwoJbXNsZWVwICgxNTApOwoKCXN0YXR1cyA9IHNhdGFfYnVzeV93YWl0ICgmcG9ydFtudW1dLmlvYWRkciwgQVRBX0JVU1ksIDUwMDAsIDApOwoJaWYgKChzdGF0dXMgJiAoQVRBX0JVU1kgfCBBVEFfRVJSKSkpIHsKCQlwcmludGYgKCJFcnJvciAgOiBzdGF0dXMgMHglMDJ4XG4iLCBzdGF0dXMpOwoJCXBvcnRbbnVtXS5kZXZfbWFzayAmPSB+MHgwMTsKCX0KfQoKdTggc2lsMzExNF9zcGluX2Rvd24gKGludCBudW0pCnsKCXU4IHN0YXR1cyA9IDA7CgoJZGVidWcgKCJTcGluIGRvd24gZGlza1xuIik7CgoJaWYgKCEocG9ydFtudW1dLmRldl9tYXNrICYgMHgwMSkpIHsKCQlkZWJ1ZyAoIkRldmljZSBhdGElZCBpcyBub3QgcHJlc2VudFxuIiwgbnVtKTsKCQlyZXR1cm4gMTsKCX0KCglpZiAoKHN0YXR1cyA9IGNoZWNrX3Bvd2VyX21vZGUgKG51bSkpID09IDB4MDApIHsKCQlkZWJ1ZyAoIkFscmVhZHkgaW4gc3RhbmRieVxuIik7CgkJcmV0dXJuIDA7Cgl9CgoJaWYgKHN0YXR1cyA9PSAweDAxKSB7CgkJcHJpbnRmICgiRmFpbGVkIHRvIGNoZWNrIHBvd2VyIG1vZGUgb24gYXRhJWRcbiIsIG51bSk7CgkJcmV0dXJuIDE7Cgl9CgoJaWYgKCEoKHN0YXR1cyA9IHNhdGFfY2hrX3N0YXR1cyAoJnBvcnRbbnVtXS5pb2FkZHIsIDApKSAmIEFUQV9EUkRZKSkgewoJCXByaW50ZiAoIkRldmljZSBhdGElZCBub3QgcmVhZHlcbiIsIG51bSk7CgkJcmV0dXJuIDE7Cgl9CgoJd3JpdGViICgweDAwLCBwb3J0W251bV0uaW9hZGRyLmZlYXR1cmVfYWRkcik7CgoJd3JpdGViICgweDAwLCBwb3J0W251bV0uaW9hZGRyLm5zZWN0X2FkZHIpOwoJd3JpdGViICgweDAwLCBwb3J0W251bV0uaW9hZGRyLmxiYWxfYWRkcik7Cgl3cml0ZWIgKDB4MDAsIHBvcnRbbnVtXS5pb2FkZHIubGJhbV9hZGRyKTsKCXdyaXRlYiAoMHgwMCwgcG9ydFtudW1dLmlvYWRkci5sYmFoX2FkZHIpOwoKCXdyaXRlYiAoQVRBX0RFVklDRV9PQlMsIHBvcnRbbnVtXS5pb2FkZHIuZGV2aWNlX2FkZHIpOwoJd3JpdGViIChBVEFfQ01EX1NUQU5EQlksIHBvcnRbbnVtXS5pb2FkZHIuY29tbWFuZF9hZGRyKTsKCglzdGF0dXMgPSBzYXRhX2J1c3lfd2FpdCAoJnBvcnRbbnVtXS5pb2FkZHIsIEFUQV9CVVNZLCAzMDAwMCwgMCk7CglpZiAoKHN0YXR1cyAmIChBVEFfQlVTWSB8IEFUQV9FUlIpKSkgewoJCXByaW50ZiAoIkVycm9yIHdhaXRpbmcgZm9yIGRpc2sgc3BpbiBkb3duOiBzdGF0dXMgMHglMDJ4XG4iLAoJCQlzdGF0dXMpOwoJCXBvcnRbbnVtXS5kZXZfbWFzayAmPSB+MHgwMTsKCQlyZXR1cm4gMTsKCX0KCXJldHVybiAwOwp9Cgp1OCBzaWwzMTE0X3NwaW5fdXAgKGludCBudW0pCnsKCXU4IHN0YXR1cyA9IDA7CgoJZGVidWcgKCJTcGluIHVwIGRpc2tcbiIpOwoKCWlmICghKHBvcnRbbnVtXS5kZXZfbWFzayAmIDB4MDEpKSB7CgkJZGVidWcgKCJEZXZpY2UgYXRhJWQgaXMgbm90IHByZXNlbnRcbiIsIG51bSk7CgkJcmV0dXJuIDE7Cgl9CgoJaWYgKChzdGF0dXMgPSBjaGVja19wb3dlcl9tb2RlIChudW0pKSAhPSAweDAwKSB7CgkJaWYgKHN0YXR1cyA9PSAweDAxKSB7CgkJCXByaW50ZiAoIkZhaWxlZCB0byBjaGVjayBwb3dlciBtb2RlIG9uIGF0YSVkXG4iLCBudW0pOwoJCQlyZXR1cm4gMTsKCQl9IGVsc2UgewoJCQkvKiBzaG91bGQgYmUgdXAgYW5kIHJ1bm5pbmcgYWxyZWFkeSAqLwoJCQlyZXR1cm4gMDsKCQl9Cgl9CgoJaWYgKCEoKHN0YXR1cyA9IHNhdGFfY2hrX3N0YXR1cyAoJnBvcnRbbnVtXS5pb2FkZHIsIDApKSAmIEFUQV9EUkRZKSkgewoJCXByaW50ZiAoIkRldmljZSBhdGElZCBub3QgcmVhZHlcbiIsIG51bSk7CgkJcmV0dXJuIDE7Cgl9CgoJZGVidWcgKCJTdGF1dHVzIG9mIGRldmljZSBjaGVjazogJWRcbiIsIHN0YXR1cyk7CgoJd3JpdGViICgweDAwLCBwb3J0W251bV0uaW9hZGRyLmZlYXR1cmVfYWRkcik7CgoJd3JpdGViICgweDAwLCBwb3J0W251bV0uaW9hZGRyLm5zZWN0X2FkZHIpOwoJd3JpdGViICgweDAwLCBwb3J0W251bV0uaW9hZGRyLmxiYWxfYWRkcik7Cgl3cml0ZWIgKDB4MDAsIHBvcnRbbnVtXS5pb2FkZHIubGJhbV9hZGRyKTsKCXdyaXRlYiAoMHgwMCwgcG9ydFtudW1dLmlvYWRkci5sYmFoX2FkZHIpOwoKCXdyaXRlYiAoQVRBX0RFVklDRV9PQlMsIHBvcnRbbnVtXS5pb2FkZHIuZGV2aWNlX2FkZHIpOwoJd3JpdGViIChBVEFfQ01EX0lETEUsIHBvcnRbbnVtXS5pb2FkZHIuY29tbWFuZF9hZGRyKTsKCglzdGF0dXMgPSBzYXRhX2J1c3lfd2FpdCAoJnBvcnRbbnVtXS5pb2FkZHIsIEFUQV9CVVNZLCAzMDAwMCwgMCk7CglpZiAoKHN0YXR1cyAmIChBVEFfQlVTWSB8IEFUQV9FUlIpKSkgewoJCXByaW50ZiAoIkVycm9yIHdhaXRpbmcgZm9yIGRpc2sgc3BpbiB1cDogc3RhdHVzIDB4JTAyeFxuIiwKCQkJc3RhdHVzKTsKCQlwb3J0W251bV0uZGV2X21hc2sgJj0gfjB4MDE7CgkJcmV0dXJuIDE7Cgl9CgoJLyogV2FpdCBmb3IgZGlzayB0byBlbnRlciBBY3RpdmUgc3RhdGUgKi8KCWRvIHsKCQltc2xlZXAgKDEwKTsKCQlzdGF0dXMgPSBjaGVja19wb3dlcl9tb2RlIChudW0pOwoJfSB3aGlsZSAoKHN0YXR1cyA9PSAweDAwKSB8fCAoc3RhdHVzID09IDB4ODApKTsKCglpZiAoc3RhdHVzID09IDB4MDEpIHsKCQlwcmludGYgKCJGYWxpZWQgd2FpdGluZyBmb3IgZGlzayB0byBzcGluIHVwXG4iKTsKCQlyZXR1cm4gMTsKCX0KCglyZXR1cm4gMDsKfQoKLyogUmV0dXJuIHZhbHVlIGlzIG5vdCB0aGUgdXN1YWwgaGVyZQogKiAweDAwIC0gRGV2aWNlIHN0YW5kIGJ5CiAqIDB4MDEgLSBPcGVyYXRpb24gZmFpbGVkCiAqIDB4ODAgLSBEZXZpY2UgaWRsZQogKiAweGZmIC0gRGV2aWNlIGFjdGl2ZQoqLwpzdGF0aWMgdTggY2hlY2tfcG93ZXJfbW9kZSAoaW50IG51bSkKewoJdTggc3RhdHVzID0gMDsKCXU4IHJlcyA9IDA7CglpZiAoIShwb3J0W251bV0uZGV2X21hc2sgJiAweDAxKSkgewoJCWRlYnVnICgiRGV2aWNlIGF0YSVkIGlzIG5vdCBwcmVzZW50XG4iLCBudW0pOwoJCXJldHVybiAxOwoJfQoKCWlmICghKHNhdGFfY2hrX3N0YXR1cyAoJnBvcnRbbnVtXS5pb2FkZHIsIDApICYgQVRBX0RSRFkpKSB7CgkJcHJpbnRmICgiRGV2aWNlIGF0YSVkIG5vdCByZWFkeVxuIiwgbnVtKTsKCQlyZXR1cm4gMTsKCX0KCgl3cml0ZWIgKDAsIHBvcnRbbnVtXS5pb2FkZHIuZmVhdHVyZV9hZGRyKTsKCXdyaXRlYiAoMCwgcG9ydFtudW1dLmlvYWRkci5uc2VjdF9hZGRyKTsKCXdyaXRlYiAoMCwgcG9ydFtudW1dLmlvYWRkci5sYmFsX2FkZHIpOwoJd3JpdGViICgwLCBwb3J0W251bV0uaW9hZGRyLmxiYW1fYWRkcik7Cgl3cml0ZWIgKDAsIHBvcnRbbnVtXS5pb2FkZHIubGJhaF9hZGRyKTsKCgl3cml0ZWIgKEFUQV9ERVZJQ0VfT0JTLCBwb3J0W251bV0uaW9hZGRyLmRldmljZV9hZGRyKTsKCXdyaXRlYiAoQVRBX0NNRF9DSEtfUE9XRVIsIHBvcnRbbnVtXS5pb2FkZHIuY29tbWFuZF9hZGRyKTsKCglzdGF0dXMgPSBzYXRhX2J1c3lfd2FpdCAoJnBvcnRbbnVtXS5pb2FkZHIsIEFUQV9CVVNZLCA1MDAwLCAwKTsKCWlmICgoc3RhdHVzICYgKEFUQV9CVVNZIHwgQVRBX0VSUikpKSB7CgkJcHJpbnRmCgkJICAgICgiRXJyb3Igd2FpdGluZyBmb3IgY2hlY2sgcG93ZXIgbW9kZSBjb21wbGV0ZSAgOiBzdGF0dXMgMHglMDJ4XG4iLAoJCSAgICAgc3RhdHVzKTsKCQlwb3J0W251bV0uZGV2X21hc2sgJj0gfjB4MDE7CgkJcmV0dXJuIDE7Cgl9CglyZXMgPSByZWFkYiAocG9ydFtudW1dLmlvYWRkci5uc2VjdF9hZGRyKTsKCWRlYnVnICgiQ2hlY2sgcG93ZXJtb2RlOiAlZFxuIiwgcmVzKTsKCXJldHVybiByZXM7Cgp9CgpzdGF0aWMgdm9pZCBzYXRhX3BvcnQgKHN0cnVjdCBzYXRhX2lvcG9ydHMgKmlvcG9ydCkKewoJaW9wb3J0LT5kYXRhX2FkZHIgPSBpb3BvcnQtPmNtZF9hZGRyICsgQVRBX1JFR19EQVRBOwoJaW9wb3J0LT5lcnJvcl9hZGRyID0gaW9wb3J0LT5jbWRfYWRkciArIEFUQV9SRUdfRVJSOwoJaW9wb3J0LT5mZWF0dXJlX2FkZHIgPSBpb3BvcnQtPmNtZF9hZGRyICsgQVRBX1JFR19GRUFUVVJFOwoJaW9wb3J0LT5uc2VjdF9hZGRyID0gaW9wb3J0LT5jbWRfYWRkciArIEFUQV9SRUdfTlNFQ1Q7Cglpb3BvcnQtPmxiYWxfYWRkciA9IGlvcG9ydC0+Y21kX2FkZHIgKyBBVEFfUkVHX0xCQUw7Cglpb3BvcnQtPmxiYW1fYWRkciA9IGlvcG9ydC0+Y21kX2FkZHIgKyBBVEFfUkVHX0xCQU07Cglpb3BvcnQtPmxiYWhfYWRkciA9IGlvcG9ydC0+Y21kX2FkZHIgKyBBVEFfUkVHX0xCQUg7Cglpb3BvcnQtPmRldmljZV9hZGRyID0gaW9wb3J0LT5jbWRfYWRkciArIEFUQV9SRUdfREVWSUNFOwoJaW9wb3J0LT5zdGF0dXNfYWRkciA9IGlvcG9ydC0+Y21kX2FkZHIgKyBBVEFfUkVHX1NUQVRVUzsKCWlvcG9ydC0+Y29tbWFuZF9hZGRyID0gaW9wb3J0LT5jbWRfYWRkciArIEFUQV9SRUdfQ01EOwp9CgpzdGF0aWMgdTggd2FpdF9mb3JfaXJxIChpbnQgbnVtLCB1bnNpZ25lZCBpbnQgbWF4KQp7CgoJdTMyIHBvcnQgPSBpb2Jhc2VbNV07Cglzd2l0Y2ggKG51bSkgewoJY2FzZSAwOgoJCXBvcnQgKz0gVk5EX1RGX0NOU1RfQ0gwOwoJCWJyZWFrOwoJY2FzZSAxOgoJCXBvcnQgKz0gVk5EX1RGX0NOU1RfQ0gxOwoJCWJyZWFrOwoJY2FzZSAyOgoJCXBvcnQgKz0gVk5EX1RGX0NOU1RfQ0gyOwoJCWJyZWFrOwoJY2FzZSAzOgoJCXBvcnQgKz0gVk5EX1RGX0NOU1RfQ0gzOwoJCWJyZWFrOwoJZGVmYXVsdDoKCQlyZXR1cm4gMTsKCX0KCglkbyB7CgkJaWYgKHJlYWRsIChwb3J0KSAmIFZORF9URl9DTlNUX0lOVFNUKSB7CgkJCWJyZWFrOwoJCX0KCQl1ZGVsYXkgKDEwMDApOwoJCW1heC0tOwoJfSB3aGlsZSAoKG1heCA+IDApKTsKCglyZXR1cm4gKG1heCA9PSAwKTsKfQoKc3RhdGljIHU4IHNhdGFfYnVzeV93YWl0IChzdHJ1Y3Qgc2F0YV9pb3BvcnRzICppb2FkZHIsIGludCBiaXRzLAoJCQkgIHVuc2lnbmVkIGludCBtYXgsIHU4IHVzZWFsdHN0YXR1cykKewoJdTggc3RhdHVzOwoKCWRvIHsKCQlpZiAoISgoc3RhdHVzID0gc2F0YV9jaGtfc3RhdHVzIChpb2FkZHIsIHVzZWFsdHN0YXR1cykpICYgYml0cykpIHsKCQkJYnJlYWs7CgkJfQoJCXVkZWxheSAoMTAwMCk7CgkJbWF4LS07Cgl9IHdoaWxlICgoc3RhdHVzICYgYml0cykgJiYgKG1heCA+IDApKTsKCglyZXR1cm4gc3RhdHVzOwp9CgpzdGF0aWMgdTggc2F0YV9jaGtfc3RhdHVzIChzdHJ1Y3Qgc2F0YV9pb3BvcnRzICppb2FkZHIsIHU4IHVzZWFsdHN0YXR1cykKewoJaWYgKCF1c2VhbHRzdGF0dXMpIHsKCQlyZXR1cm4gcmVhZGIgKGlvYWRkci0+c3RhdHVzX2FkZHIpOwoJfSBlbHNlIHsKCQlyZXR1cm4gcmVhZGIgKGlvYWRkci0+YWx0c3RhdHVzX2FkZHIpOwoJfQp9CgpzdGF0aWMgdm9pZCBtc2xlZXAgKGludCBjb3VudCkKewoJaW50IGk7CgoJZm9yIChpID0gMDsgaSA8IGNvdW50OyBpKyspCgkJdWRlbGF5ICgxMDAwKTsKfQoKLyogUmVhZCB1cCB0byAyNTUgc2VjdG9ycwogKgogKiBSZXR1cm5zIHNlY3RvcnMgcmVhZAoqLwpzdGF0aWMgdTggZG9fb25lX3JlYWQgKGludCBkZXZpY2UsIHVsb25nIGJsb2NrLCB1OCBibGtjbnQsIHUxNiAqIGJ1ZmYsCgkJICAgICAgIHVjaGFyIGxiYTQ4KQp7CgoJdTggc3IgPSAwOwoJdTggc3RhdHVzOwoJdTY0IGJsa25yID0gKHU2NCkgYmxvY2s7CgoJaWYgKCEoc2F0YV9jaGtfc3RhdHVzICgmcG9ydFtkZXZpY2VdLmlvYWRkciwgMCkgJiBBVEFfRFJEWSkpIHsKCQlwcmludGYgKCJEZXZpY2UgYXRhJWQgbm90IHJlYWR5XG4iLCBkZXZpY2UpOwoJCXJldHVybiAwOwoJfQoKCS8qIFNldCB1cCB0cmFuc2ZlciAqLwojaWZkZWYgQ09ORklHX0xCQTQ4CglpZiAobGJhNDgpIHsKCQkvKiB3cml0ZSBoaWdoIGJpdHMgKi8KCQl3cml0ZWIgKDAsIHBvcnRbZGV2aWNlXS5pb2FkZHIubnNlY3RfYWRkcik7CgkJd3JpdGViICgoYmxrbnIgPj4gMjQpICYgMHhGRiwgcG9ydFtkZXZpY2VdLmlvYWRkci5sYmFsX2FkZHIpOwoJCXdyaXRlYiAoKGJsa25yID4+IDMyKSAmIDB4RkYsIHBvcnRbZGV2aWNlXS5pb2FkZHIubGJhbV9hZGRyKTsKCQl3cml0ZWIgKChibGtuciA+PiA0MCkgJiAweEZGLCBwb3J0W2RldmljZV0uaW9hZGRyLmxiYWhfYWRkcik7Cgl9CiNlbmRpZgoJd3JpdGViIChibGtjbnQsIHBvcnRbZGV2aWNlXS5pb2FkZHIubnNlY3RfYWRkcik7Cgl3cml0ZWIgKCgoYmxrbnIpID4+IDApICYgMHhGRiwgcG9ydFtkZXZpY2VdLmlvYWRkci5sYmFsX2FkZHIpOwoJd3JpdGViICgoYmxrbnIgPj4gOCkgJiAweEZGLCBwb3J0W2RldmljZV0uaW9hZGRyLmxiYW1fYWRkcik7Cgl3cml0ZWIgKChibGtuciA+PiAxNikgJiAweEZGLCBwb3J0W2RldmljZV0uaW9hZGRyLmxiYWhfYWRkcik7CgojaWZkZWYgQ09ORklHX0xCQTQ4CglpZiAobGJhNDgpIHsKCQl3cml0ZWIgKEFUQV9MQkEsIHBvcnRbZGV2aWNlXS5pb2FkZHIuZGV2aWNlX2FkZHIpOwoJCXdyaXRlYiAoQVRBX0NNRF9QSU9fUkVBRF9FWFQsIHBvcnRbZGV2aWNlXS5pb2FkZHIuY29tbWFuZF9hZGRyKTsKCX0gZWxzZQojZW5kaWYKCXsKCQl3cml0ZWIgKEFUQV9MQkEgfCAoKGJsa25yID4+IDI0KSAmIDB4RiksCgkJCXBvcnRbZGV2aWNlXS5pb2FkZHIuZGV2aWNlX2FkZHIpOwoJCXdyaXRlYiAoQVRBX0NNRF9QSU9fUkVBRCwgcG9ydFtkZXZpY2VdLmlvYWRkci5jb21tYW5kX2FkZHIpOwoJfQoKCXN0YXR1cyA9IHNhdGFfYnVzeV93YWl0ICgmcG9ydFtkZXZpY2VdLmlvYWRkciwgQVRBX0JVU1ksIDEwMDAwLCAxKTsKCglpZiAoc3RhdHVzICYgQVRBX0JVU1kpIHsKCQl1OCBlcnIgPSAwOwoKCQlwcmludGYgKCJEZXZpY2UgJWQgbm90IHJlc3BvbmRpbmcgc3RhdHVzICVkXG4iLCBkZXZpY2UsIHN0YXR1cyk7CgkJZXJyID0gcmVhZGIgKHBvcnRbZGV2aWNlXS5pb2FkZHIuZXJyb3JfYWRkcik7CgkJcHJpbnRmICgiRXJyb3IgcmVnID0gMHgleFxuIiwgZXJyKTsKCgkJcmV0dXJuIChzcik7Cgl9Cgl3aGlsZSAoYmxrY250LS0pIHsKCgkJaWYgKHdhaXRfZm9yX2lycSAoZGV2aWNlLCA1MDApKSB7CgkJCXByaW50ZiAoImF0YSV1IGlycSBmYWlsZWRcbiIsIGRldmljZSk7CgkJCXJldHVybiBzcjsKCQl9CgoJCXN0YXR1cyA9IHNhdGFfY2hrX3N0YXR1cyAoJnBvcnRbZGV2aWNlXS5pb2FkZHIsIDApOwoJCWlmIChzdGF0dXMgJiBBVEFfRVJSKSB7CgkJCXByaW50ZiAoImF0YSV1IGVycm9yICVkXG4iLCBkZXZpY2UsCgkJCQlyZWFkYiAocG9ydFtkZXZpY2VdLmlvYWRkci5lcnJvcl9hZGRyKSk7CgkJCXJldHVybiBzcjsKCQl9CgkJLyogUmVhZCBvbmUgc2VjdG9yICovCgkJaW5wdXRfZGF0YSAoJnBvcnRbZGV2aWNlXS5pb2FkZHIsIGJ1ZmYsIEFUQV9TRUNUT1JfV09SRFMpOwoJCWJ1ZmYgKz0gQVRBX1NFQ1RPUl9XT1JEUzsKCQlzcisrOwoKCX0KCXJldHVybiBzcjsKfQoKdWxvbmcgc2F0YV9yZWFkIChpbnQgZGV2aWNlLCB1bG9uZyBibG9jaywgbGJhaW50X3QgYmxrY250LCB2b2lkICpidWZmKQp7Cgl1bG9uZyBuID0gMCwgc3JlYWQ7Cgl1MTYgKmJ1ZmZlciA9ICh1MTYgKikgYnVmZjsKCXU4IHN0YXR1cyA9IDA7Cgl1NjQgYmxrbnIgPSAodTY0KSBibG9jazsKCXVuc2lnbmVkIGNoYXIgbGJhNDggPSAwOwoKI2lmZGVmIENPTkZJR19MQkE0OAoJaWYgKGJsa25yID4gMHhmZmZmZmZmKSB7CgkJaWYgKCFzYXRhX2Rldl9kZXNjW2RldmljZV0ubGJhNDgpIHsKCQkJcHJpbnRmICgiRHJpdmUgZG9lc24ndCBzdXBwb3J0IDQ4LWJpdCBhZGRyZXNzaW5nXG4iKTsKCQkJcmV0dXJuIDA7CgkJfQoJCS8qIG1vcmUgdGhhbiAyOCBiaXRzIHVzZWQsIHVzZSA0OGJpdCBtb2RlICovCgkJbGJhNDggPSAxOwoJfQojZW5kaWYKCgl3aGlsZSAoYmxrY250ID4gMCkgewoKCQlpZiAoYmxrY250ID4gMjU1KSB7CgkJCXNyZWFkID0gMjU1OwoJCX0gZWxzZSB7CgkJCXNyZWFkID0gYmxrY250OwoJCX0KCgkJc3RhdHVzID0gZG9fb25lX3JlYWQgKGRldmljZSwgYmxrbnIsIHNyZWFkLCBidWZmZXIsIGxiYTQ4KTsKCQlpZiAoc3RhdHVzICE9IHNyZWFkKSB7CgkJCXByaW50ZiAoIlJlYWQgZmFpbGVkXG4iKTsKCQkJcmV0dXJuIG47CgkJfQoKCQlibGtjbnQgLT0gc3JlYWQ7CgkJYmxrbnIgKz0gc3JlYWQ7CgkJbiArPSBzcmVhZDsKCQlidWZmZXIgKz0gc3JlYWQgKiBBVEFfU0VDVE9SX1dPUkRTOwoJfQoJcmV0dXJuIG47Cn0KCnVsb25nIHNhdGFfd3JpdGUgKGludCBkZXZpY2UsIHVsb25nIGJsb2NrLCBsYmFpbnRfdCBibGtjbnQsIGNvbnN0IHZvaWQgKmJ1ZmYpCnsKCXVsb25nIG4gPSAwOwoJdTE2ICpidWZmZXIgPSAodTE2ICopIGJ1ZmY7Cgl1bnNpZ25lZCBjaGFyIHN0YXR1cyA9IDAsIG51bSA9IDA7Cgl1NjQgYmxrbnIgPSAodTY0KSBibG9jazsKI2lmZGVmIENPTkZJR19MQkE0OAoJdW5zaWduZWQgY2hhciBsYmE0OCA9IDA7CgoJaWYgKGJsa25yID4gMHhmZmZmZmZmKSB7CgkJaWYgKCFzYXRhX2Rldl9kZXNjW2RldmljZV0ubGJhNDgpIHsKCQkJcHJpbnRmICgiRHJpdmUgZG9lc24ndCBzdXBwb3J0IDQ4LWJpdCBhZGRyZXNzaW5nXG4iKTsKCQkJcmV0dXJuIDA7CgkJfQoJCS8qIG1vcmUgdGhhbiAyOCBiaXRzIHVzZWQsIHVzZSA0OGJpdCBtb2RlICovCgkJbGJhNDggPSAxOwoJfQojZW5kaWYKCS8qUG9ydCBOdW1iZXIgKi8KCW51bSA9IGRldmljZTsKCgl3aGlsZSAoYmxrY250LS0gPiAwKSB7CgkJc3RhdHVzID0gc2F0YV9idXN5X3dhaXQgKCZwb3J0W251bV0uaW9hZGRyLCBBVEFfQlVTWSwgNTAwLCAwKTsKCQlpZiAoc3RhdHVzICYgQVRBX0JVU1kpIHsKCQkJcHJpbnRmICgiYXRhJXUgZmFpbGVkIHRvIHJlc3BvbmRcbiIsIHBvcnRbbnVtXS5wb3J0X25vKTsKCQkJcmV0dXJuIG47CgkJfQojaWZkZWYgQ09ORklHX0xCQTQ4CgkJaWYgKGxiYTQ4KSB7CgkJCS8qIHdyaXRlIGhpZ2ggYml0cyAqLwoJCQl3cml0ZWIgKDAsIHBvcnRbbnVtXS5pb2FkZHIubnNlY3RfYWRkcik7CgkJCXdyaXRlYiAoKGJsa25yID4+IDI0KSAmIDB4RkYsCgkJCQlwb3J0W251bV0uaW9hZGRyLmxiYWxfYWRkcik7CgkJCXdyaXRlYiAoKGJsa25yID4+IDMyKSAmIDB4RkYsCgkJCQlwb3J0W251bV0uaW9hZGRyLmxiYW1fYWRkcik7CgkJCXdyaXRlYiAoKGJsa25yID4+IDQwKSAmIDB4RkYsCgkJCQlwb3J0W251bV0uaW9hZGRyLmxiYWhfYWRkcik7CgkJfQojZW5kaWYKCQl3cml0ZWIgKDEsIHBvcnRbbnVtXS5pb2FkZHIubnNlY3RfYWRkcik7CgkJd3JpdGViICgoYmxrbnIgPj4gMCkgJiAweEZGLCBwb3J0W251bV0uaW9hZGRyLmxiYWxfYWRkcik7CgkJd3JpdGViICgoYmxrbnIgPj4gOCkgJiAweEZGLCBwb3J0W251bV0uaW9hZGRyLmxiYW1fYWRkcik7CgkJd3JpdGViICgoYmxrbnIgPj4gMTYpICYgMHhGRiwgcG9ydFtudW1dLmlvYWRkci5sYmFoX2FkZHIpOwojaWZkZWYgQ09ORklHX0xCQTQ4CgkJaWYgKGxiYTQ4KSB7CgkJCXdyaXRlYiAoQVRBX0xCQSwgcG9ydFtudW1dLmlvYWRkci5kZXZpY2VfYWRkcik7CgkJCXdyaXRlYiAoQVRBX0NNRF9QSU9fV1JJVEVfRVhULCBwb3J0W251bV0uaW9hZGRyLmNvbW1hbmRfYWRkcik7CgkJfSBlbHNlCiNlbmRpZgoJCXsKCQkJd3JpdGViIChBVEFfTEJBIHwgKChibGtuciA+PiAyNCkgJiAweEYpLAoJCQkJcG9ydFtudW1dLmlvYWRkci5kZXZpY2VfYWRkcik7CgkJCXdyaXRlYiAoQVRBX0NNRF9QSU9fV1JJVEUsIHBvcnRbbnVtXS5pb2FkZHIuY29tbWFuZF9hZGRyKTsKCQl9CgoJCW1zbGVlcCAoNTApOwoJCS8qbWF5IHRha2UgdXAgdG8gNCBzZWMgKi8KCQlzdGF0dXMgPSBzYXRhX2J1c3lfd2FpdCAoJnBvcnRbbnVtXS5pb2FkZHIsIEFUQV9CVVNZLCA0MDAwLCAwKTsKCQlpZiAoKHN0YXR1cyAmIChBVEFfRFJRIHwgQVRBX0JVU1kgfCBBVEFfRVJSKSkgIT0gQVRBX0RSUSkgewoJCQlwcmludGYgKCJFcnJvciBubyBEUlEgZGV2ICVkIGJsayAlbGQ6IHN0cyAweCUwMnhcbiIsCgkJCQlkZXZpY2UsICh1bG9uZykgYmxrbnIsIHN0YXR1cyk7CgkJCXJldHVybiAobik7CgkJfQoKCQlvdXRwdXRfZGF0YSAoJnBvcnRbbnVtXS5pb2FkZHIsIGJ1ZmZlciwgQVRBX1NFQ1RPUl9XT1JEUyk7CgkJcmVhZGIgKHBvcnRbbnVtXS5pb2FkZHIuYWx0c3RhdHVzX2FkZHIpOwoJCXVkZWxheSAoNTApOwoKCQkrK247CgkJKytibGtucjsKCQlidWZmZXIgKz0gQVRBX1NFQ1RPUl9XT1JEUzsKCX0KCXJldHVybiBuOwp9CgovKiBEcml2ZXIgaW1wbGVtZW50YXRpb24gKi8Kc3RhdGljIHU4IHNpbF9nZXRfZGV2aWNlX2NhY2hlX2xpbmUgKHBjaV9kZXZfdCBwZGV2KQp7Cgl1OCBjYWNoZV9saW5lID0gMDsKCXBjaV9yZWFkX2NvbmZpZ19ieXRlIChwZGV2LCBQQ0lfQ0FDSEVfTElORV9TSVpFLCAmY2FjaGVfbGluZSk7CglyZXR1cm4gY2FjaGVfbGluZTsKfQoKaW50IGluaXRfc2F0YSAoaW50IGRldikKewoJc3RhdGljIHU4IGluaXRfZG9uZSA9IDA7CglzdGF0aWMgaW50IHJlcyA9IDE7CglwY2lfZGV2X3QgZGV2bm87Cgl1OCBjbHMgPSAwOwoJdTE2IGNtZCA9IDA7Cgl1MzIgc2NvbmYgPSAwOwoKCWlmIChpbml0X2RvbmUpIHsKCQlyZXR1cm4gcmVzOwoJfQoKCWluaXRfZG9uZSA9IDE7CgoJaWYgKChkZXZubyA9IHBjaV9maW5kX2RldmljZSAoU0lMX1ZFTkRfSUQsIFNJTDMxMTRfREVWSUNFX0lELCAwKSkgPT0gLTEpIHsKCQlyZXMgPSAxOwoJCXJldHVybiByZXM7Cgl9CgoJLyogUmVhZCBvdXQgYWxsIEJBUnMsIGV2ZW4gdGhvdWdoIHdlIG9ubHkgdXNlIE1NSU8gZnJvbSBCQVI1ICovCglwY2lfcmVhZF9jb25maWdfZHdvcmQgKGRldm5vLCBQQ0lfQkFTRV9BRERSRVNTXzAsICZpb2Jhc2VbMF0pOwoJcGNpX3JlYWRfY29uZmlnX2R3b3JkIChkZXZubywgUENJX0JBU0VfQUREUkVTU18xLCAmaW9iYXNlWzFdKTsKCXBjaV9yZWFkX2NvbmZpZ19kd29yZCAoZGV2bm8sIFBDSV9CQVNFX0FERFJFU1NfMiwgJmlvYmFzZVsyXSk7CglwY2lfcmVhZF9jb25maWdfZHdvcmQgKGRldm5vLCBQQ0lfQkFTRV9BRERSRVNTXzMsICZpb2Jhc2VbM10pOwoJcGNpX3JlYWRfY29uZmlnX2R3b3JkIChkZXZubywgUENJX0JBU0VfQUREUkVTU180LCAmaW9iYXNlWzRdKTsKCXBjaV9yZWFkX2NvbmZpZ19kd29yZCAoZGV2bm8sIFBDSV9CQVNFX0FERFJFU1NfNSwgJmlvYmFzZVs1XSk7CgoJaWYgKChpb2Jhc2VbMF0gPT0gMHhGRkZGRkZGRikgfHwgKGlvYmFzZVsxXSA9PSAweEZGRkZGRkZGKSB8fAoJICAgIChpb2Jhc2VbMl0gPT0gMHhGRkZGRkZGRikgfHwgKGlvYmFzZVszXSA9PSAweEZGRkZGRkZGKSB8fAoJICAgIChpb2Jhc2VbNF0gPT0gMHhGRkZGRkZGRikgfHwgKGlvYmFzZVs1XSA9PSAweEZGRkZGRkZGKSkgewoJCXByaW50ZiAoIkVycm9yIG5vIGJhc2UgYWRkciBmb3IgU0FUQSBjb250cm9sbGVyXG4iKTsKCQlyZXMgPSAxOwoJCXJldHVybiByZXM7Cgl9CgoJLyogbWFzayBvZmYgdW51c2VkIGJpdHMgKi8KCWlvYmFzZVswXSAmPSAweGZmZmZmZmZjOwoJaW9iYXNlWzFdICY9IDB4ZmZmZmZmZjg7Cglpb2Jhc2VbMl0gJj0gMHhmZmZmZmZmYzsKCWlvYmFzZVszXSAmPSAweGZmZmZmZmY4OwoJaW9iYXNlWzRdICY9IDB4ZmZmZmZmZjA7Cglpb2Jhc2VbNV0gJj0gMHhmZmZmZmMwMDsKCgkvKiBmcm9tIHNhdGFfc2lsIGluIExpbnV4IGtlcm5lbCAqLwoJY2xzID0gc2lsX2dldF9kZXZpY2VfY2FjaGVfbGluZSAoZGV2bm8pOwoJaWYgKGNscykgewoJCWNscyA+Pj0gMzsKCQljbHMrKzsJCS8qIGNscyA9IChsaW5lX3NpemUvOCkrMSAqLwoJCXdyaXRlbCAoY2xzIDw8IDggfCBjbHMsIGlvYmFzZVs1XSArIFZORF9GSUZPQ0ZHX0NIMCk7CgkJd3JpdGVsIChjbHMgPDwgOCB8IGNscywgaW9iYXNlWzVdICsgVk5EX0ZJRk9DRkdfQ0gxKTsKCQl3cml0ZWwgKGNscyA8PCA4IHwgY2xzLCBpb2Jhc2VbNV0gKyBWTkRfRklGT0NGR19DSDIpOwoJCXdyaXRlbCAoY2xzIDw8IDggfCBjbHMsIGlvYmFzZVs1XSArIFZORF9GSUZPQ0ZHX0NIMyk7Cgl9IGVsc2UgewoJCXByaW50ZiAoIkNhY2hlIGxpbmUgbm90IHNldC4gRHJpdmVyIG1heSBub3QgZnVuY3Rpb25cbiIpOwoJfQoKCS8qIEVuYWJsZSBvcGVyYXRpb24gKi8KCXBjaV9yZWFkX2NvbmZpZ193b3JkIChkZXZubywgUENJX0NPTU1BTkQsICZjbWQpOwoJY21kIHw9IFBDSV9DT01NQU5EX01BU1RFUiB8IFBDSV9DT01NQU5EX0lPIHwgUENJX0NPTU1BTkRfTUVNT1JZOwoJcGNpX3dyaXRlX2NvbmZpZ193b3JkIChkZXZubywgUENJX0NPTU1BTkQsIGNtZCk7CgoJLyogRGlzYWJsZSBpbnRlcnJ1cHQgdXNhZ2UgKi8KCXBjaV9yZWFkX2NvbmZpZ19kd29yZCAoZGV2bm8sIFZORF9TWVNDT05GU1RBVCwgJnNjb25mKTsKCXNjb25mIHw9IChWTkRfU1lTQ09ORlNUQVRfQ0hOXzBfSU5UQkxPQ0sgfCBWTkRfU1lTQ09ORlNUQVRfQ0hOXzFfSU5UQkxPQ0spOwoJcGNpX3dyaXRlX2NvbmZpZ19kd29yZCAoZGV2bm8sIFZORF9TWVNDT05GU1RBVCwgc2NvbmYpOwoKCXJlcyA9IDA7CglyZXR1cm4gcmVzOwp9CgovKiBDaGVjayBpZiBkZXZpY2UgaXMgY29ubmVjdGVkIHRvIHBvcnQgKi8KaW50IHNhdGFfYnVzX3Byb2JlIChpbnQgcG9ydG5vKQp7Cgl1MzIgcG9ydCA9IGlvYmFzZVs1XTsKCXUzMiB2YWw7Cglzd2l0Y2ggKHBvcnRubykgewoJY2FzZSAwOgoJCXBvcnQgKz0gVk5EX1NTVEFUVVNfQ0gwOwoJCWJyZWFrOwoJY2FzZSAxOgoJCXBvcnQgKz0gVk5EX1NTVEFUVVNfQ0gxOwoJCWJyZWFrOwoJY2FzZSAyOgoJCXBvcnQgKz0gVk5EX1NTVEFUVVNfQ0gyOwoJCWJyZWFrOwoJY2FzZSAzOgoJCXBvcnQgKz0gVk5EX1NTVEFUVVNfQ0gzOwoJCWJyZWFrOwoJZGVmYXVsdDoKCQlyZXR1cm4gMDsKCX0KCXZhbCA9IHJlYWRsIChwb3J0KTsKCWlmICgodmFsICYgU0FUQV9ERVRfUFJFUykgPT0gU0FUQV9ERVRfUFJFUykgewoJCXJldHVybiAxOwoJfSBlbHNlIHsKCQlyZXR1cm4gMDsKCX0KfQoKaW50IHNhdGFfcGh5X3Jlc2V0IChpbnQgcG9ydG5vKQp7Cgl1MzIgcG9ydCA9IGlvYmFzZVs1XTsKCXUzMiB2YWw7Cglzd2l0Y2ggKHBvcnRubykgewoJY2FzZSAwOgoJCXBvcnQgKz0gVk5EX1NDT05UUk9MX0NIMDsKCQlicmVhazsKCWNhc2UgMToKCQlwb3J0ICs9IFZORF9TQ09OVFJPTF9DSDE7CgkJYnJlYWs7CgljYXNlIDI6CgkJcG9ydCArPSBWTkRfU0NPTlRST0xfQ0gyOwoJCWJyZWFrOwoJY2FzZSAzOgoJCXBvcnQgKz0gVk5EX1NDT05UUk9MX0NIMzsKCQlicmVhazsKCWRlZmF1bHQ6CgkJcmV0dXJuIDA7Cgl9Cgl2YWwgPSByZWFkbCAocG9ydCk7Cgl3cml0ZWwgKHZhbCB8IFNBVEFfU0NfREVUX1JTVCwgcG9ydCk7Cgltc2xlZXAgKDE1MCk7Cgl3cml0ZWwgKHZhbCAmIH5TQVRBX1NDX0RFVF9SU1QsIHBvcnQpOwoJcmV0dXJuIDA7Cn0KCmludCBzY2FuX3NhdGEgKGludCBkZXYpCnsKCS8qIEEgYml0IGJyYWluIGRlYWQsIGJ1dCB0aGUgY29kZSBoYXMgYSBsZWdhY3kgKi8KCXN3aXRjaCAoZGV2KSB7CgljYXNlIDA6CgkJcG9ydFswXS5wb3J0X25vID0gMDsKCQlwb3J0WzBdLmlvYWRkci5jbWRfYWRkciA9IGlvYmFzZVs1XSArIFZORF9URjBfQ0gwOwoJCXBvcnRbMF0uaW9hZGRyLmFsdHN0YXR1c19hZGRyID0gcG9ydFswXS5pb2FkZHIuY3RsX2FkZHIgPQoJCSAgICAoaW9iYXNlWzVdICsgVk5EX1RGMl9DSDApIHwgQVRBX1BDSV9DVExfT0ZTOwoJCXBvcnRbMF0uaW9hZGRyLmJtZG1hX2FkZHIgPSBpb2Jhc2VbNV0gKyBWTkRfQk1ETUFfQ0gwOwoJCWJyZWFrOwoJY2FzZSAxOgoJCXBvcnRbMV0ucG9ydF9ubyA9IDA7CgkJcG9ydFsxXS5pb2FkZHIuY21kX2FkZHIgPSBpb2Jhc2VbNV0gKyBWTkRfVEYwX0NIMTsKCQlwb3J0WzFdLmlvYWRkci5hbHRzdGF0dXNfYWRkciA9IHBvcnRbMV0uaW9hZGRyLmN0bF9hZGRyID0KCQkgICAgKGlvYmFzZVs1XSArIFZORF9URjJfQ0gxKSB8IEFUQV9QQ0lfQ1RMX09GUzsKCQlwb3J0WzFdLmlvYWRkci5ibWRtYV9hZGRyID0gaW9iYXNlWzVdICsgVk5EX0JNRE1BX0NIMTsKCQlicmVhazsKCWNhc2UgMjoKCQlwb3J0WzJdLnBvcnRfbm8gPSAwOwoJCXBvcnRbMl0uaW9hZGRyLmNtZF9hZGRyID0gaW9iYXNlWzVdICsgVk5EX1RGMF9DSDI7CgkJcG9ydFsyXS5pb2FkZHIuYWx0c3RhdHVzX2FkZHIgPSBwb3J0WzJdLmlvYWRkci5jdGxfYWRkciA9CgkJICAgIChpb2Jhc2VbNV0gKyBWTkRfVEYyX0NIMikgfCBBVEFfUENJX0NUTF9PRlM7CgkJcG9ydFsyXS5pb2FkZHIuYm1kbWFfYWRkciA9IGlvYmFzZVs1XSArIFZORF9CTURNQV9DSDI7CgkJYnJlYWs7CgljYXNlIDM6CgkJcG9ydFszXS5wb3J0X25vID0gMDsKCQlwb3J0WzNdLmlvYWRkci5jbWRfYWRkciA9IGlvYmFzZVs1XSArIFZORF9URjBfQ0gzOwoJCXBvcnRbM10uaW9hZGRyLmFsdHN0YXR1c19hZGRyID0gcG9ydFszXS5pb2FkZHIuY3RsX2FkZHIgPQoJCSAgICAoaW9iYXNlWzVdICsgVk5EX1RGMl9DSDMpIHwgQVRBX1BDSV9DVExfT0ZTOwoJCXBvcnRbM10uaW9hZGRyLmJtZG1hX2FkZHIgPSBpb2Jhc2VbNV0gKyBWTkRfQk1ETUFfQ0gzOwoJCWJyZWFrOwoJZGVmYXVsdDoKCQlwcmludGYgKCJUcmllZCB0byBzY2FuIHVua25vd24gcG9ydDogYXRhJWRcbiIsIGRldik7CgkJcmV0dXJuIDE7Cgl9CgoJLyogSW5pdGlhbGl6ZSBvdGhlciByZWdpc3RlcnMgKi8KCXNhdGFfcG9ydCAoJnBvcnRbZGV2XS5pb2FkZHIpOwoKCS8qIENoZWNrIGZvciBhdHRhY2hlZCBkZXZpY2UgKi8KCWlmICghc2F0YV9idXNfcHJvYmUgKGRldikpIHsKCQlwb3J0W2Rldl0ucG9ydF9zdGF0ZSA9IDA7CgkJZGVidWcgKCJTQVRBIyVkIHBvcnQgaXMgbm90IHByZXNlbnRcbiIsIGRldik7Cgl9IGVsc2UgewoJCWRlYnVnICgiU0FUQSMlZCBwb3J0IGlzIHByZXNlbnRcbiIsIGRldik7CgkJaWYgKHNhdGFfYnVzX3NvZnRyZXNldCAoZGV2KSkgewoJCQkvKiBzb2Z0IHJlc2V0IGZhaWxlZCwgdHJ5IGEgaGFyZCBvbmUgKi8KCQkJc2F0YV9waHlfcmVzZXQgKGRldik7CgkJCWlmIChzYXRhX2J1c19zb2Z0cmVzZXQgKGRldikpIHsKCQkJCXBvcnRbZGV2XS5wb3J0X3N0YXRlID0gMDsKCQkJfSBlbHNlIHsKCQkJCXBvcnRbZGV2XS5wb3J0X3N0YXRlID0gMTsKCQkJfQoJCX0gZWxzZSB7CgkJCXBvcnRbZGV2XS5wb3J0X3N0YXRlID0gMTsKCQl9Cgl9CglpZiAocG9ydFtkZXZdLnBvcnRfc3RhdGUgPT0gMSkgewoJCS8qIFByb2JlIGRldmljZSBhbmQgc2V0IHhmZXIgbW9kZSAqLwoJCXNhdGFfaWRlbnRpZnkgKGRldiwgMCk7CgkJc2V0X0ZlYXR1cmVfY21kIChkZXYsIDApOwoJfQoKCXJldHVybiAwOwp9Cg==