LyoKICogT01BUDIgUmVtb3RlIEZyYW1lIEJ1ZmZlciBJbnRlcmZhY2Ugc3VwcG9ydAogKgogKiBDb3B5cmlnaHQgKEMpIDIwMDUgTm9raWEgQ29ycG9yYXRpb24KICogQXV0aG9yOiBKdWhhIFlyavZs5CA8anVoYS55cmpvbGFAbm9raWEuY29tPgogKgkgICBJbXJlIERlYWsgPGltcmUuZGVha0Bub2tpYS5jb20+CiAqCiAqIFRoaXMgcHJvZ3JhbSBpcyBmcmVlIHNvZnR3YXJlOyB5b3UgY2FuIHJlZGlzdHJpYnV0ZSBpdCBhbmQvb3IgbW9kaWZ5IGl0CiAqIHVuZGVyIHRoZSB0ZXJtcyBvZiB0aGUgR05VIEdlbmVyYWwgUHVibGljIExpY2Vuc2UgYXMgcHVibGlzaGVkIGJ5IHRoZQogKiBGcmVlIFNvZnR3YXJlIEZvdW5kYXRpb247IGVpdGhlciB2ZXJzaW9uIDIgb2YgdGhlIExpY2Vuc2UsIG9yIChhdCB5b3VyCiAqIG9wdGlvbikgYW55IGxhdGVyIHZlcnNpb24uCiAqCiAqIFRoaXMgcHJvZ3JhbSBpcyBkaXN0cmlidXRlZCBpbiB0aGUgaG9wZSB0aGF0IGl0IHdpbGwgYmUgdXNlZnVsLCBidXQKICogV0lUSE9VVCBBTlkgV0FSUkFOVFk7IHdpdGhvdXQgZXZlbiB0aGUgaW1wbGllZCB3YXJyYW50eSBvZgogKiBNRVJDSEFOVEFCSUxJVFkgb3IgRklUTkVTUyBGT1IgQSBQQVJUSUNVTEFSIFBVUlBPU0UuICBTZWUgdGhlIEdOVQogKiBHZW5lcmFsIFB1YmxpYyBMaWNlbnNlIGZvciBtb3JlIGRldGFpbHMuCiAqCiAqIFlvdSBzaG91bGQgaGF2ZSByZWNlaXZlZCBhIGNvcHkgb2YgdGhlIEdOVSBHZW5lcmFsIFB1YmxpYyBMaWNlbnNlIGFsb25nCiAqIHdpdGggdGhpcyBwcm9ncmFtOyBpZiBub3QsIHdyaXRlIHRvIHRoZSBGcmVlIFNvZnR3YXJlIEZvdW5kYXRpb24sIEluYy4sCiAqIDU5IFRlbXBsZSBQbGFjZSAtIFN1aXRlIDMzMCwgQm9zdG9uLCBNQSAgMDIxMTEtMTMwNywgVVNBLgogKi8KI2luY2x1ZGUgPGxpbnV4L21vZHVsZS5oPgojaW5jbHVkZSA8bGludXgvZGVsYXkuaD4KI2luY2x1ZGUgPGxpbnV4L2kyYy5oPgojaW5jbHVkZSA8bGludXgvZXJyLmg+CiNpbmNsdWRlIDxsaW51eC9pbnRlcnJ1cHQuaD4KI2luY2x1ZGUgPGxpbnV4L2Nsay5oPgojaW5jbHVkZSA8bGludXgvaW8uaD4KI2luY2x1ZGUgPGxpbnV4L3BsYXRmb3JtX2RldmljZS5oPgoKI2luY2x1ZGUgIm9tYXBmYi5oIgojaW5jbHVkZSAiZGlzcGMuaCIKCi8qIFRvIHdvcmsgYXJvdW5kIGFuIFJGQkkgdHJhbnNmZXIgcmF0ZSBsaW1pdGF0aW9uICovCiNkZWZpbmUgT01BUF9SRkJJX1JBVEVfTElNSVQJMQoKI2RlZmluZSBSRkJJX0JBU0UJCTB4NDgwNTA4MDAKI2RlZmluZSBSRkJJX1JFVklTSU9OCQkweDAwMDAKI2RlZmluZSBSRkJJX1NZU0NPTkZJRwkJMHgwMDEwCiNkZWZpbmUgUkZCSV9TWVNTVEFUVVMJCTB4MDAxNAojZGVmaW5lIFJGQklfQ09OVFJPTAkJMHgwMDQwCiNkZWZpbmUgUkZCSV9QSVhFTF9DTlQJCTB4MDA0NAojZGVmaW5lIFJGQklfTElORV9OVU1CRVIJMHgwMDQ4CiNkZWZpbmUgUkZCSV9DTUQJCTB4MDA0YwojZGVmaW5lIFJGQklfUEFSQU0JCTB4MDA1MAojZGVmaW5lIFJGQklfREFUQQkJMHgwMDU0CiNkZWZpbmUgUkZCSV9SRUFECQkweDAwNTgKI2RlZmluZSBSRkJJX1NUQVRVUwkJMHgwMDVjCiNkZWZpbmUgUkZCSV9DT05GSUcwCQkweDAwNjAKI2RlZmluZSBSRkJJX09OT0ZGX1RJTUUwCTB4MDA2NAojZGVmaW5lIFJGQklfQ1lDTEVfVElNRTAJMHgwMDY4CiNkZWZpbmUgUkZCSV9EQVRBX0NZQ0xFMV8wCTB4MDA2YwojZGVmaW5lIFJGQklfREFUQV9DWUNMRTJfMAkweDAwNzAKI2RlZmluZSBSRkJJX0RBVEFfQ1lDTEUzXzAJMHgwMDc0CiNkZWZpbmUgUkZCSV9WU1lOQ19XSURUSAkweDAwOTAKI2RlZmluZSBSRkJJX0hTWU5DX1dJRFRICTB4MDA5NAoKI2RlZmluZSBESVNQQ19CQVNFCQkweDQ4MDUwNDAwCiNkZWZpbmUgRElTUENfQ09OVFJPTAkJMHgwMDQwCiNkZWZpbmUgRElTUENfSVJRX0ZSQU1FTUFTSyAgICAgMHgwMDAxCgpzdGF0aWMgc3RydWN0IHsKCXZvaWQgX19pb21lbQkqYmFzZTsKCXZvaWQJCSgqbGNkY19jYWxsYmFjaykodm9pZCAqZGF0YSk7Cgl2b2lkCQkqbGNkY19jYWxsYmFja19kYXRhOwoJdW5zaWduZWQgbG9uZwlsNF9raHo7CglpbnQJCWJpdHNfcGVyX2N5Y2xlOwoJc3RydWN0IG9tYXBmYl9kZXZpY2UgKmZiZGV2OwoJc3RydWN0IGNsawkqZHNzX2ljazsKCXN0cnVjdCBjbGsJKmRzczFfZmNrOwoJdW5zaWduZWQJdGVhcnN5bmNfcGluX2NudDsKCXVuc2lnbmVkCXRlYXJzeW5jX21vZGU7Cn0gcmZiaTsKCnN0YXRpYyBpbmxpbmUgdm9pZCByZmJpX3dyaXRlX3JlZyhpbnQgaWR4LCB1MzIgdmFsKQp7CglfX3Jhd193cml0ZWwodmFsLCByZmJpLmJhc2UgKyBpZHgpOwp9CgpzdGF0aWMgaW5saW5lIHUzMiByZmJpX3JlYWRfcmVnKGludCBpZHgpCnsKCXJldHVybiBfX3Jhd19yZWFkbChyZmJpLmJhc2UgKyBpZHgpOwp9CgpzdGF0aWMgaW50IHJmYmlfZ2V0X2Nsb2Nrcyh2b2lkKQp7CglyZmJpLmRzc19pY2sgPSBjbGtfZ2V0KCZyZmJpLmZiZGV2LT5kc3NkZXYtPmRldiwgImljayIpOwoJaWYgKElTX0VSUihyZmJpLmRzc19pY2spKSB7CgkJZGV2X2VycihyZmJpLmZiZGV2LT5kZXYsICJjYW4ndCBnZXQgaWNrXG4iKTsKCQlyZXR1cm4gUFRSX0VSUihyZmJpLmRzc19pY2spOwoJfQoKCXJmYmkuZHNzMV9mY2sgPSBjbGtfZ2V0KCZyZmJpLmZiZGV2LT5kc3NkZXYtPmRldiwgImRzczFfZmNrIik7CglpZiAoSVNfRVJSKHJmYmkuZHNzMV9mY2spKSB7CgkJZGV2X2VycihyZmJpLmZiZGV2LT5kZXYsICJjYW4ndCBnZXQgZHNzMV9mY2tcbiIpOwoJCWNsa19wdXQocmZiaS5kc3NfaWNrKTsKCQlyZXR1cm4gUFRSX0VSUihyZmJpLmRzczFfZmNrKTsKCX0KCglyZXR1cm4gMDsKfQoKc3RhdGljIHZvaWQgcmZiaV9wdXRfY2xvY2tzKHZvaWQpCnsKCWNsa19wdXQocmZiaS5kc3MxX2Zjayk7CgljbGtfcHV0KHJmYmkuZHNzX2ljayk7Cn0KCnN0YXRpYyB2b2lkIHJmYmlfZW5hYmxlX2Nsb2NrcyhpbnQgZW5hYmxlKQp7CglpZiAoZW5hYmxlKSB7CgkJY2xrX2VuYWJsZShyZmJpLmRzc19pY2spOwoJCWNsa19lbmFibGUocmZiaS5kc3MxX2Zjayk7Cgl9IGVsc2UgewoJCWNsa19kaXNhYmxlKHJmYmkuZHNzMV9mY2spOwoJCWNsa19kaXNhYmxlKHJmYmkuZHNzX2ljayk7Cgl9Cn0KCgojaWZkZWYgVkVSQk9TRQpzdGF0aWMgdm9pZCByZmJpX3ByaW50X3RpbWluZ3Modm9pZCkKewoJdTMyIGw7Cgl1MzIgdGltZTsKCglsID0gcmZiaV9yZWFkX3JlZyhSRkJJX0NPTkZJRzApOwoJdGltZSA9IDEwMDAwMDAwMDAgLyByZmJpLmw0X2toejsKCWlmIChsICYgKDEgPDwgNCkpCgkJdGltZSAqPSAyOwoKCWRldl9kYmcocmZiaS5mYmRldi0+ZGV2LCAiVGljayB0aW1lICV1IHBzXG4iLCB0aW1lKTsKCWwgPSByZmJpX3JlYWRfcmVnKFJGQklfT05PRkZfVElNRTApOwoJZGV2X2RiZyhyZmJpLmZiZGV2LT5kZXYsCgkJIkNTT05USU1FICVkLCBDU09GRlRJTUUgJWQsIFdFT05USU1FICVkLCBXRU9GRlRJTUUgJWQsICIKCQkiUkVPTlRJTUUgJWQsIFJFT0ZGVElNRSAlZFxuIiwKCQlsICYgMHgwZiwgKGwgPj4gNCkgJiAweDNmLCAobCA+PiAxMCkgJiAweDBmLCAobCA+PiAxNCkgJiAweDNmLAoJCShsID4+IDIwKSAmIDB4MGYsIChsID4+IDI0KSAmIDB4M2YpOwoKCWwgPSByZmJpX3JlYWRfcmVnKFJGQklfQ1lDTEVfVElNRTApOwoJZGV2X2RiZyhyZmJpLmZiZGV2LT5kZXYsCgkJIldFQ1lDTEVUSU1FICVkLCBSRUNZQ0xFVElNRSAlZCwgQ1NQVUxTRVdJRFRIICVkLCAiCgkJIkFDQ0VTU1RJTUUgJWRcbiIsCgkJKGwgJiAweDNmKSwgKGwgPj4gNikgJiAweDNmLCAobCA+PiAxMikgJiAweDNmLAoJCShsID4+IDIyKSAmIDB4M2YpOwp9CiNlbHNlCnN0YXRpYyB2b2lkIHJmYmlfcHJpbnRfdGltaW5ncyh2b2lkKSB7fQojZW5kaWYKCnN0YXRpYyB2b2lkIHJmYmlfc2V0X3RpbWluZ3MoY29uc3Qgc3RydWN0IGV4dGlmX3RpbWluZ3MgKnQpCnsKCXUzMiBsOwoKCUJVR19PTighdC0+Y29udmVydGVkKTsKCglyZmJpX2VuYWJsZV9jbG9ja3MoMSk7CglyZmJpX3dyaXRlX3JlZyhSRkJJX09OT0ZGX1RJTUUwLCB0LT50aW1bMF0pOwoJcmZiaV93cml0ZV9yZWcoUkZCSV9DWUNMRV9USU1FMCwgdC0+dGltWzFdKTsKCglsID0gcmZiaV9yZWFkX3JlZyhSRkJJX0NPTkZJRzApOwoJbCAmPSB+KDEgPDwgNCk7CglsIHw9ICh0LT50aW1bMl0gPyAxIDogMCkgPDwgNDsKCXJmYmlfd3JpdGVfcmVnKFJGQklfQ09ORklHMCwgbCk7CgoJcmZiaV9wcmludF90aW1pbmdzKCk7CglyZmJpX2VuYWJsZV9jbG9ja3MoMCk7Cn0KCnN0YXRpYyB2b2lkIHJmYmlfZ2V0X2Nsa19pbmZvKHUzMiAqY2xrX3BlcmlvZCwgdTMyICptYXhfY2xrX2RpdikKewoJKmNsa19wZXJpb2QgPSAxMDAwMDAwMDAwIC8gcmZiaS5sNF9raHo7CgkqbWF4X2Nsa19kaXYgPSAyOwp9CgpzdGF0aWMgaW50IHBzX3RvX3JmYmlfdGlja3MoaW50IHRpbWUsIGludCBkaXYpCnsKCXVuc2lnbmVkIGxvbmcgdGlja19wczsKCWludCByZXQ7CgoJLyogQ2FsY3VsYXRlIGluIHBpY29zZWNzIHRvIHlpZWxkIG1vcmUgZXhhY3QgcmVzdWx0cyAqLwoJdGlja19wcyA9IDEwMDAwMDAwMDAgLyAocmZiaS5sNF9raHopICogZGl2OwoKCXJldCA9ICh0aW1lICsgdGlja19wcyAtIDEpIC8gdGlja19wczsKCglyZXR1cm4gcmV0Owp9CgojaWZkZWYgT01BUF9SRkJJX1JBVEVfTElNSVQKc3RhdGljIHVuc2lnbmVkIGxvbmcgcmZiaV9nZXRfbWF4X3R4X3JhdGUodm9pZCkKewoJdW5zaWduZWQgbG9uZwlsNF9yYXRlLCBkc3MxX3JhdGU7CglpbnQJCW1pbl9sNF90aWNrcyA9IDA7CglpbnQJCWk7CgoJLyogQWNjb3JkaW5nIHRvIFRJIHRoaXMgY2FuJ3QgYmUgY2FsY3VsYXRlZCBzbyBtYWtlIHRoZQoJICogYWRqdXN0bWVudHMgZm9yIGEgY291cGxlIG9mIGtub3duIGZyZXF1ZW5jaWVzIGFuZCB3YXJuIGZvcgoJICogb3RoZXJzLgoJICovCglzdGF0aWMgY29uc3Qgc3RydWN0IHsKCQl1bnNpZ25lZCBsb25nIGw0X2NsazsJCS8qIEhaICovCgkJdW5zaWduZWQgbG9uZyBkc3MxX2NsazsJCS8qIEhaICovCgkJdW5zaWduZWQgbG9uZyBtaW5fbDRfdGlja3M7Cgl9IGZ0YWJbXSA9IHsKCQl7IDU1LAkxMzIsCTcsIH0sCQkvKiA3Ljg2IE1QaXgvcyAqLwoJCXsgMTEwLAkxMTAsCTEyLCB9LAkJLyogOS4xNiBNUGl4L3MgKi8KCQl7IDExMCwJMTMyLAkxMCwgfSwJCS8qIDExICAgTXBpeC9zICovCgkJeyAxMjAsCTEyMCwJMTAsIH0sCQkvKiAxMiAgIE1waXgvcyAqLwoJCXsgMTMzLAkxMzMsCTEwLCB9LAkJLyogMTMuMyBNcGl4L3MgKi8KCX07CgoJbDRfcmF0ZSA9IHJmYmkubDRfa2h6IC8gMTAwMDsKCWRzczFfcmF0ZSA9IGNsa19nZXRfcmF0ZShyZmJpLmRzczFfZmNrKSAvIDEwMDAwMDA7CgoJZm9yIChpID0gMDsgaSA8IEFSUkFZX1NJWkUoZnRhYik7IGkrKykgewoJCS8qIFVzZSBhIHdpbmRvdyBpbnN0ZWFkIG9mIGFuIGV4YWN0IG1hdGNoLCB0byBhY2NvdW50CgkJICogZm9yIGRpZmZlcmVudCBEUExMIG11bHRpcGxpZXIgLyBkaXZpZGVyIHBhaXJzLgoJCSAqLwoJCWlmIChhYnMoZnRhYltpXS5sNF9jbGsgLSBsNF9yYXRlKSA8IDMgJiYKCQkgICAgYWJzKGZ0YWJbaV0uZHNzMV9jbGsgLSBkc3MxX3JhdGUpIDwgMykgewoJCQltaW5fbDRfdGlja3MgPSBmdGFiW2ldLm1pbl9sNF90aWNrczsKCQkJYnJlYWs7CgkJfQoJfQoJaWYgKGkgPT0gQVJSQVlfU0laRShmdGFiKSkgewoJCS8qIENhbid0IGJlIHN1cmUsIHJldHVybiBhbnl3YXkgdGhlIG1heGltdW0gbm90CgkJICogcmF0ZS1saW1pdGVkLiBUaGlzIG1pZ2h0IGNhdXNlIGEgcHJvYmxlbSBvbmx5IGZvciB0aGUKCQkgKiB0ZWFyaW5nIHN5bmNocm9uaXNhdGlvbi4KCQkgKi8KCQlkZXZfZXJyKHJmYmkuZmJkZXYtPmRldiwKCQkJImNhbid0IGRldGVybWluZSBtYXhpbXVtIFJGQkkgdHJhbnNmZXIgcmF0ZVxuIik7CgkJcmV0dXJuIHJmYmkubDRfa2h6ICogMTAwMDsKCX0KCXJldHVybiByZmJpLmw0X2toeiAqIDEwMDAgLyBtaW5fbDRfdGlja3M7Cn0KI2Vsc2UKc3RhdGljIGludCByZmJpX2dldF9tYXhfdHhfcmF0ZSh2b2lkKQp7CglyZXR1cm4gcmZiaS5sNF9raHogKiAxMDAwOwp9CiNlbmRpZgoKCnN0YXRpYyBpbnQgcmZiaV9jb252ZXJ0X3RpbWluZ3Moc3RydWN0IGV4dGlmX3RpbWluZ3MgKnQpCnsKCXUzMiBsOwoJaW50IHJlb24sIHJlb2ZmLCB3ZW9uLCB3ZW9mZiwgY3NvbiwgY3NvZmYsIGNzX3B1bHNlOwoJaW50IGFjdGltLCByZWN5Yywgd2VjeWM7CglpbnQgZGl2ID0gdC0+Y2xrX2RpdjsKCglpZiAoZGl2IDw9IDAgfHwgZGl2ID4gMikKCQlyZXR1cm4gLTE7CgoJLyogTWFrZSBzdXJlIHRoYXQgYWZ0ZXIgY29udmVyc2lvbiBpdCBzdGlsbCBob2xkcyB0aGF0OgoJICogd2VvZmYgPiB3ZW9uLCByZW9mZiA+IHJlb24sIHJlY3ljID49IHJlb2ZmLCB3ZWN5YyA+PSB3ZW9mZiwKCSAqIGNzb2ZmID4gY3NvbiwgY3NvZmYgPj0gbWF4KHdlb2ZmLCByZW9mZiksIGFjdGltID4gcmVvbgoJICovCgl3ZW9uID0gcHNfdG9fcmZiaV90aWNrcyh0LT53ZV9vbl90aW1lLCBkaXYpOwoJd2VvZmYgPSBwc190b19yZmJpX3RpY2tzKHQtPndlX29mZl90aW1lLCBkaXYpOwoJaWYgKHdlb2ZmIDw9IHdlb24pCgkJd2VvZmYgPSB3ZW9uICsgMTsKCWlmICh3ZW9uID4gMHgwZikKCQlyZXR1cm4gLTE7CglpZiAod2VvZmYgPiAweDNmKQoJCXJldHVybiAtMTsKCglyZW9uID0gcHNfdG9fcmZiaV90aWNrcyh0LT5yZV9vbl90aW1lLCBkaXYpOwoJcmVvZmYgPSBwc190b19yZmJpX3RpY2tzKHQtPnJlX29mZl90aW1lLCBkaXYpOwoJaWYgKHJlb2ZmIDw9IHJlb24pCgkJcmVvZmYgPSByZW9uICsgMTsKCWlmIChyZW9uID4gMHgwZikKCQlyZXR1cm4gLTE7CglpZiAocmVvZmYgPiAweDNmKQoJCXJldHVybiAtMTsKCgljc29uID0gcHNfdG9fcmZiaV90aWNrcyh0LT5jc19vbl90aW1lLCBkaXYpOwoJY3NvZmYgPSBwc190b19yZmJpX3RpY2tzKHQtPmNzX29mZl90aW1lLCBkaXYpOwoJaWYgKGNzb2ZmIDw9IGNzb24pCgkJY3NvZmYgPSBjc29uICsgMTsKCWlmIChjc29mZiA8IG1heCh3ZW9mZiwgcmVvZmYpKQoJCWNzb2ZmID0gbWF4KHdlb2ZmLCByZW9mZik7CglpZiAoY3NvbiA+IDB4MGYpCgkJcmV0dXJuIC0xOwoJaWYgKGNzb2ZmID4gMHgzZikKCQlyZXR1cm4gLTE7CgoJbCA9ICBjc29uOwoJbCB8PSBjc29mZiA8PCA0OwoJbCB8PSB3ZW9uICA8PCAxMDsKCWwgfD0gd2VvZmYgPDwgMTQ7CglsIHw9IHJlb24gIDw8IDIwOwoJbCB8PSByZW9mZiA8PCAyNDsKCgl0LT50aW1bMF0gPSBsOwoKCWFjdGltID0gcHNfdG9fcmZiaV90aWNrcyh0LT5hY2Nlc3NfdGltZSwgZGl2KTsKCWlmIChhY3RpbSA8PSByZW9uKQoJCWFjdGltID0gcmVvbiArIDE7CglpZiAoYWN0aW0gPiAweDNmKQoJCXJldHVybiAtMTsKCgl3ZWN5YyA9IHBzX3RvX3JmYmlfdGlja3ModC0+d2VfY3ljbGVfdGltZSwgZGl2KTsKCWlmICh3ZWN5YyA8IHdlb2ZmKQoJCXdlY3ljID0gd2VvZmY7CglpZiAod2VjeWMgPiAweDNmKQoJCXJldHVybiAtMTsKCglyZWN5YyA9IHBzX3RvX3JmYmlfdGlja3ModC0+cmVfY3ljbGVfdGltZSwgZGl2KTsKCWlmIChyZWN5YyA8IHJlb2ZmKQoJCXJlY3ljID0gcmVvZmY7CglpZiAocmVjeWMgPiAweDNmKQoJCXJldHVybiAtMTsKCgljc19wdWxzZSA9IHBzX3RvX3JmYmlfdGlja3ModC0+Y3NfcHVsc2Vfd2lkdGgsIGRpdik7CglpZiAoY3NfcHVsc2UgPiAweDNmKQoJCXJldHVybiAtMTsKCglsID0gIHdlY3ljOwoJbCB8PSByZWN5YyAgICA8PCA2OwoJbCB8PSBjc19wdWxzZSA8PCAxMjsKCWwgfD0gYWN0aW0gICAgPDwgMjI7CgoJdC0+dGltWzFdID0gbDsKCgl0LT50aW1bMl0gPSBkaXYgLSAxOwoKCXQtPmNvbnZlcnRlZCA9IDE7CgoJcmV0dXJuIDA7Cn0KCnN0YXRpYyBpbnQgcmZiaV9zZXR1cF90ZWFyc3luYyh1bnNpZ25lZCBwaW5fY250LAoJCQkgICAgICAgdW5zaWduZWQgaHNfcHVsc2VfdGltZSwgdW5zaWduZWQgdnNfcHVsc2VfdGltZSwKCQkJICAgICAgIGludCBoc19wb2xfaW52LCBpbnQgdnNfcG9sX2ludiwgaW50IGV4dGlmX2RpdikKewoJaW50IGhzLCB2czsKCWludCBtaW47Cgl1MzIgbDsKCglpZiAocGluX2NudCAhPSAxICYmIHBpbl9jbnQgIT0gMikKCQlyZXR1cm4gLUVJTlZBTDsKCglocyA9IHBzX3RvX3JmYmlfdGlja3MoaHNfcHVsc2VfdGltZSwgMSk7Cgl2cyA9IHBzX3RvX3JmYmlfdGlja3ModnNfcHVsc2VfdGltZSwgMSk7CglpZiAoaHMgPCAyKQoJCXJldHVybiAtRURPTTsKCWlmIChwaW5fY250ID09IDIpCgkJbWluID0gMjsKCWVsc2UKCQltaW4gPSA0OwoJaWYgKHZzIDwgbWluKQoJCXJldHVybiAtRURPTTsKCWlmICh2cyA9PSBocykKCQlyZXR1cm4gLUVJTlZBTDsKCXJmYmkudGVhcnN5bmNfcGluX2NudCA9IHBpbl9jbnQ7CglkZXZfZGJnKHJmYmkuZmJkZXYtPmRldiwKCQkic2V0dXBfdGVhcnN5bmM6IHBpbnMgJWQgaHMgJWQgdnMgJWQgaHNfaW52ICVkIHZzX2ludiAlZFxuIiwKCQlwaW5fY250LCBocywgdnMsIGhzX3BvbF9pbnYsIHZzX3BvbF9pbnYpOwoKCXJmYmlfZW5hYmxlX2Nsb2NrcygxKTsKCXJmYmlfd3JpdGVfcmVnKFJGQklfSFNZTkNfV0lEVEgsIGhzKTsKCXJmYmlfd3JpdGVfcmVnKFJGQklfVlNZTkNfV0lEVEgsIHZzKTsKCglsID0gcmZiaV9yZWFkX3JlZyhSRkJJX0NPTkZJRzApOwoJaWYgKGhzX3BvbF9pbnYpCgkJbCAmPSB+KDEgPDwgMjEpOwoJZWxzZQoJCWwgfD0gMSA8PCAyMTsKCWlmICh2c19wb2xfaW52KQoJCWwgJj0gfigxIDw8IDIwKTsKCWVsc2UKCQlsIHw9IDEgPDwgMjA7CglyZmJpX2VuYWJsZV9jbG9ja3MoMCk7CgoJcmV0dXJuIDA7Cn0KCnN0YXRpYyBpbnQgcmZiaV9lbmFibGVfdGVhcnN5bmMoaW50IGVuYWJsZSwgdW5zaWduZWQgbGluZSkKewoJdTMyIGw7CgoJZGV2X2RiZyhyZmJpLmZiZGV2LT5kZXYsICJ0ZWFyc3luYyAlZCBsaW5lICVkIG1vZGUgJWRcbiIsCgkJZW5hYmxlLCBsaW5lLCByZmJpLnRlYXJzeW5jX21vZGUpOwoJaWYgKGxpbmUgPiAoMSA8PCAxMSkgLSAxKQoJCXJldHVybiAtRUlOVkFMOwoKCXJmYmlfZW5hYmxlX2Nsb2NrcygxKTsKCWwgPSByZmJpX3JlYWRfcmVnKFJGQklfQ09ORklHMCk7CglsICY9IH4oMHgzIDw8IDIpOwoJaWYgKGVuYWJsZSkgewoJCXJmYmkudGVhcnN5bmNfbW9kZSA9IHJmYmkudGVhcnN5bmNfcGluX2NudDsKCQlsIHw9IHJmYmkudGVhcnN5bmNfbW9kZSA8PCAyOwoJfSBlbHNlCgkJcmZiaS50ZWFyc3luY19tb2RlID0gMDsKCXJmYmlfd3JpdGVfcmVnKFJGQklfQ09ORklHMCwgbCk7CglyZmJpX3dyaXRlX3JlZyhSRkJJX0xJTkVfTlVNQkVSLCBsaW5lKTsKCXJmYmlfZW5hYmxlX2Nsb2NrcygwKTsKCglyZXR1cm4gMDsKfQoKc3RhdGljIHZvaWQgcmZiaV93cml0ZV9jb21tYW5kKGNvbnN0IHZvaWQgKmJ1ZiwgdW5zaWduZWQgaW50IGxlbikKewoJcmZiaV9lbmFibGVfY2xvY2tzKDEpOwoJaWYgKHJmYmkuYml0c19wZXJfY3ljbGUgPT0gMTYpIHsKCQljb25zdCB1MTYgKncgPSBidWY7CgkJQlVHX09OKGxlbiAmIDEpOwoJCWZvciAoOyBsZW47IGxlbiAtPSAyKQoJCQlyZmJpX3dyaXRlX3JlZyhSRkJJX0NNRCwgKncrKyk7Cgl9IGVsc2UgewoJCWNvbnN0IHU4ICpiID0gYnVmOwoJCUJVR19PTihyZmJpLmJpdHNfcGVyX2N5Y2xlICE9IDgpOwoJCWZvciAoOyBsZW47IGxlbi0tKQoJCQlyZmJpX3dyaXRlX3JlZyhSRkJJX0NNRCwgKmIrKyk7Cgl9CglyZmJpX2VuYWJsZV9jbG9ja3MoMCk7Cn0KCnN0YXRpYyB2b2lkIHJmYmlfcmVhZF9kYXRhKHZvaWQgKmJ1ZiwgdW5zaWduZWQgaW50IGxlbikKewoJcmZiaV9lbmFibGVfY2xvY2tzKDEpOwoJaWYgKHJmYmkuYml0c19wZXJfY3ljbGUgPT0gMTYpIHsKCQl1MTYgKncgPSBidWY7CgkJQlVHX09OKGxlbiAmIH4xKTsKCQlmb3IgKDsgbGVuOyBsZW4gLT0gMikgewoJCQlyZmJpX3dyaXRlX3JlZyhSRkJJX1JFQUQsIDApOwoJCQkqdysrID0gcmZiaV9yZWFkX3JlZyhSRkJJX1JFQUQpOwoJCX0KCX0gZWxzZSB7CgkJdTggKmIgPSBidWY7CgkJQlVHX09OKHJmYmkuYml0c19wZXJfY3ljbGUgIT0gOCk7CgkJZm9yICg7IGxlbjsgbGVuLS0pIHsKCQkJcmZiaV93cml0ZV9yZWcoUkZCSV9SRUFELCAwKTsKCQkJKmIrKyA9IHJmYmlfcmVhZF9yZWcoUkZCSV9SRUFEKTsKCQl9Cgl9CglyZmJpX2VuYWJsZV9jbG9ja3MoMCk7Cn0KCnN0YXRpYyB2b2lkIHJmYmlfd3JpdGVfZGF0YShjb25zdCB2b2lkICpidWYsIHVuc2lnbmVkIGludCBsZW4pCnsKCXJmYmlfZW5hYmxlX2Nsb2NrcygxKTsKCWlmIChyZmJpLmJpdHNfcGVyX2N5Y2xlID09IDE2KSB7CgkJY29uc3QgdTE2ICp3ID0gYnVmOwoJCUJVR19PTihsZW4gJiAxKTsKCQlmb3IgKDsgbGVuOyBsZW4gLT0gMikKCQkJcmZiaV93cml0ZV9yZWcoUkZCSV9QQVJBTSwgKncrKyk7Cgl9IGVsc2UgewoJCWNvbnN0IHU4ICpiID0gYnVmOwoJCUJVR19PTihyZmJpLmJpdHNfcGVyX2N5Y2xlICE9IDgpOwoJCWZvciAoOyBsZW47IGxlbi0tKQoJCQlyZmJpX3dyaXRlX3JlZyhSRkJJX1BBUkFNLCAqYisrKTsKCX0KCXJmYmlfZW5hYmxlX2Nsb2NrcygwKTsKfQoKc3RhdGljIHZvaWQgcmZiaV90cmFuc2Zlcl9hcmVhKGludCB3aWR0aCwgaW50IGhlaWdodCwKCQkJCXZvaWQgKGNhbGxiYWNrKSh2b2lkICogZGF0YSksIHZvaWQgKmRhdGEpCnsKCXUzMiB3OwoKCUJVR19PTihjYWxsYmFjayA9PSBOVUxMKTsKCglyZmJpX2VuYWJsZV9jbG9ja3MoMSk7CglvbWFwX2Rpc3BjX3NldF9sY2Rfc2l6ZSh3aWR0aCwgaGVpZ2h0KTsKCglyZmJpLmxjZGNfY2FsbGJhY2sgPSBjYWxsYmFjazsKCXJmYmkubGNkY19jYWxsYmFja19kYXRhID0gZGF0YTsKCglyZmJpX3dyaXRlX3JlZyhSRkJJX1BJWEVMX0NOVCwgd2lkdGggKiBoZWlnaHQpOwoKCXcgPSByZmJpX3JlYWRfcmVnKFJGQklfQ09OVFJPTCk7Cgl3IHw9IDE7CQkJCS8qIGVuYWJsZSAqLwoJaWYgKCFyZmJpLnRlYXJzeW5jX21vZGUpCgkJdyB8PSAxIDw8IDQ7CQkvKiBpbnRlcm5hbCB0cmlnZ2VyLCByZXNldCBieSBIVyAqLwoJcmZiaV93cml0ZV9yZWcoUkZCSV9DT05UUk9MLCB3KTsKCglvbWFwX2Rpc3BjX2VuYWJsZV9sY2Rfb3V0KDEpOwp9CgpzdGF0aWMgaW5saW5lIHZvaWQgX3N0b3BfdHJhbnNmZXIodm9pZCkKewoJdTMyIHc7CgoJdyA9IHJmYmlfcmVhZF9yZWcoUkZCSV9DT05UUk9MKTsKCXJmYmlfd3JpdGVfcmVnKFJGQklfQ09OVFJPTCwgdyAmIH4oMSA8PCAwKSk7CglyZmJpX2VuYWJsZV9jbG9ja3MoMCk7Cn0KCnN0YXRpYyB2b2lkIHJmYmlfZG1hX2NhbGxiYWNrKHZvaWQgKmRhdGEpCnsKCV9zdG9wX3RyYW5zZmVyKCk7CglyZmJpLmxjZGNfY2FsbGJhY2socmZiaS5sY2RjX2NhbGxiYWNrX2RhdGEpOwp9CgpzdGF0aWMgdm9pZCByZmJpX3NldF9iaXRzX3Blcl9jeWNsZShpbnQgYnBjKQp7Cgl1MzIgbDsKCglyZmJpX2VuYWJsZV9jbG9ja3MoMSk7CglsID0gcmZiaV9yZWFkX3JlZyhSRkJJX0NPTkZJRzApOwoJbCAmPSB+KDB4MDMgPDwgMCk7CgoJc3dpdGNoIChicGMpIHsKCWNhc2UgODoKCQlicmVhazsKCWNhc2UgMTY6CgkJbCB8PSAzOwoJCWJyZWFrOwoJZGVmYXVsdDoKCQlCVUcoKTsKCX0KCXJmYmlfd3JpdGVfcmVnKFJGQklfQ09ORklHMCwgbCk7CglyZmJpLmJpdHNfcGVyX2N5Y2xlID0gYnBjOwoJcmZiaV9lbmFibGVfY2xvY2tzKDApOwp9CgpzdGF0aWMgaW50IHJmYmlfaW5pdChzdHJ1Y3Qgb21hcGZiX2RldmljZSAqZmJkZXYpCnsKCXUzMiBsOwoJaW50IHI7CgoJcmZiaS5mYmRldiA9IGZiZGV2OwoJcmZiaS5iYXNlID0gaW9yZW1hcChSRkJJX0JBU0UsIFNaXzFLKTsKCWlmICghcmZiaS5iYXNlKSB7CgkJZGV2X2VycihmYmRldi0+ZGV2LCAiY2FuJ3QgaW9yZW1hcCBSRkJJXG4iKTsKCQlyZXR1cm4gLUVOT01FTTsKCX0KCglpZiAoKHIgPSByZmJpX2dldF9jbG9ja3MoKSkgPCAwKQoJCXJldHVybiByOwoJcmZiaV9lbmFibGVfY2xvY2tzKDEpOwoKCXJmYmkubDRfa2h6ID0gY2xrX2dldF9yYXRlKHJmYmkuZHNzX2ljaykgLyAxMDAwOwoKCS8qIFJlc2V0ICovCglyZmJpX3dyaXRlX3JlZyhSRkJJX1NZU0NPTkZJRywgMSA8PCAxKTsKCXdoaWxlICghKHJmYmlfcmVhZF9yZWcoUkZCSV9TWVNTVEFUVVMpICYgKDEgPDwgMCkpKTsKCglsID0gcmZiaV9yZWFkX3JlZyhSRkJJX1NZU0NPTkZJRyk7CgkvKiBFbmFibGUgYXV0b2lkbGUgYW5kIHNtYXJ0LWlkbGUgKi8KCWwgfD0gKDEgPDwgMCkgfCAoMiA8PCAzKTsKCXJmYmlfd3JpdGVfcmVnKFJGQklfU1lTQ09ORklHLCBsKTsKCgkvKiAxNi1iaXQgaW50ZXJmYWNlLCBJVEUgdHJpZ2dlciBtb2RlLCAxNi1iaXQgZGF0YSAqLwoJbCA9ICgweDAzIDw8IDApIHwgKDB4MDAgPDwgMikgfCAoMHgwMSA8PCA1KSB8ICgweDAyIDw8IDcpOwoJbCB8PSAoMCA8PCA5KSB8ICgxIDw8IDIwKSB8ICgxIDw8IDIxKTsKCXJmYmlfd3JpdGVfcmVnKFJGQklfQ09ORklHMCwgbCk7CgoJcmZiaV93cml0ZV9yZWcoUkZCSV9EQVRBX0NZQ0xFMV8wLCAweDAwMDAwMDEwKTsKCglsID0gcmZiaV9yZWFkX3JlZyhSRkJJX0NPTlRST0wpOwoJLyogU2VsZWN0IENTMCwgY2xlYXIgYnlwYXNzIG1vZGUgKi8KCWwgPSAoMHgwMSA8PCAyKTsKCXJmYmlfd3JpdGVfcmVnKFJGQklfQ09OVFJPTCwgbCk7CgoJciA9IG9tYXBfZGlzcGNfcmVxdWVzdF9pcnEoRElTUENfSVJRX0ZSQU1FTUFTSywgcmZiaV9kbWFfY2FsbGJhY2ssCgkJCQkgICBOVUxMKTsKCWlmIChyIDwgMCkgewoJCWRldl9lcnIoZmJkZXYtPmRldiwgImNhbid0IGdldCBESVNQQyBpcnFcbiIpOwoJCXJmYmlfZW5hYmxlX2Nsb2NrcygwKTsKCQlyZXR1cm4gcjsKCX0KCglsID0gcmZiaV9yZWFkX3JlZyhSRkJJX1JFVklTSU9OKTsKCXByX2luZm8oIm9tYXBmYjogUkZCSSB2ZXJzaW9uICVkLiVkIGluaXRpYWxpemVkXG4iLAoJCShsID4+IDQpICYgMHgwZiwgbCAmIDB4MGYpOwoKCXJmYmlfZW5hYmxlX2Nsb2NrcygwKTsKCglyZXR1cm4gMDsKfQoKc3RhdGljIHZvaWQgcmZiaV9jbGVhbnVwKHZvaWQpCnsKCW9tYXBfZGlzcGNfZnJlZV9pcnEoRElTUENfSVJRX0ZSQU1FTUFTSywgcmZiaV9kbWFfY2FsbGJhY2ssIE5VTEwpOwoJcmZiaV9wdXRfY2xvY2tzKCk7Cglpb3VubWFwKHJmYmkuYmFzZSk7Cn0KCmNvbnN0IHN0cnVjdCBsY2RfY3RybF9leHRpZiBvbWFwMl9leHRfaWYgPSB7CgkuaW5pdAkJCT0gcmZiaV9pbml0LAoJLmNsZWFudXAJCT0gcmZiaV9jbGVhbnVwLAoJLmdldF9jbGtfaW5mbwkJPSByZmJpX2dldF9jbGtfaW5mbywKCS5nZXRfbWF4X3R4X3JhdGUJPSByZmJpX2dldF9tYXhfdHhfcmF0ZSwKCS5zZXRfYml0c19wZXJfY3ljbGUJPSByZmJpX3NldF9iaXRzX3Blcl9jeWNsZSwKCS5jb252ZXJ0X3RpbWluZ3MJPSByZmJpX2NvbnZlcnRfdGltaW5ncywKCS5zZXRfdGltaW5ncwkJPSByZmJpX3NldF90aW1pbmdzLAoJLndyaXRlX2NvbW1hbmQJCT0gcmZiaV93cml0ZV9jb21tYW5kLAoJLnJlYWRfZGF0YQkJPSByZmJpX3JlYWRfZGF0YSwKCS53cml0ZV9kYXRhCQk9IHJmYmlfd3JpdGVfZGF0YSwKCS50cmFuc2Zlcl9hcmVhCQk9IHJmYmlfdHJhbnNmZXJfYXJlYSwKCS5zZXR1cF90ZWFyc3luYwkJPSByZmJpX3NldHVwX3RlYXJzeW5jLAoJLmVuYWJsZV90ZWFyc3luYwk9IHJmYmlfZW5hYmxlX3RlYXJzeW5jLAoKCS5tYXhfdHJhbnNtaXRfc2l6ZQk9ICh1MzIpIH4wLAp9OwoK