LyoKICogKEMpIENvcHlyaWdodCAyMDAyCiAqIERhbmllbCBFbmdzdHL2bSwgT21pY3JvbiBDZXRpIEFCLCBkYW5pZWxAb21pY3Jvbi5zZQogKgogKiBTZWUgZmlsZSBDUkVESVRTIGZvciBsaXN0IG9mIHBlb3BsZSB3aG8gY29udHJpYnV0ZWQgdG8gdGhpcwogKiBwcm9qZWN0LgogKgogKiBUaGlzIHByb2dyYW0gaXMgZnJlZSBzb2Z0d2FyZTsgeW91IGNhbiByZWRpc3RyaWJ1dGUgaXQgYW5kL29yCiAqIG1vZGlmeSBpdCB1bmRlciB0aGUgdGVybXMgb2YgdGhlIEdOVSBHZW5lcmFsIFB1YmxpYyBMaWNlbnNlIGFzCiAqIHB1Ymxpc2hlZCBieSB0aGUgRnJlZSBTb2Z0d2FyZSBGb3VuZGF0aW9uOyBlaXRoZXIgdmVyc2lvbiAyIG9mCiAqIHRoZSBMaWNlbnNlLCBvciAoYXQgeW91ciBvcHRpb24pIGFueSBsYXRlciB2ZXJzaW9uLgogKgogKiBUaGlzIHByb2dyYW0gaXMgZGlzdHJpYnV0ZWQgaW4gdGhlIGhvcGUgdGhhdCBpdCB3aWxsIGJlIHVzZWZ1bCwKICogYnV0IFdJVEhPVVQgQU5ZIFdBUlJBTlRZOyB3aXRob3V0IGV2ZW4gdGhlIGltcGxpZWQgd2FycmFudHkgb2YKICogTUVSQ0hBTlRBQklMSVRZIG9yIEZJVE5FU1MgRk9SIEEgUEFSVElDVUxBUiBQVVJQT1NFLiAgU2VlIHRoZQogKiBHTlUgR2VuZXJhbCBQdWJsaWMgTGljZW5zZSBmb3IgbW9yZSBkZXRhaWxzLgogKgogKiBZb3Ugc2hvdWxkIGhhdmUgcmVjZWl2ZWQgYSBjb3B5IG9mIHRoZSBHTlUgR2VuZXJhbCBQdWJsaWMgTGljZW5zZQogKiBhbG9uZyB3aXRoIHRoaXMgcHJvZ3JhbTsgaWYgbm90LCB3cml0ZSB0byB0aGUgRnJlZSBTb2Z0d2FyZQogKiBGb3VuZGF0aW9uLCBJbmMuLCA1OSBUZW1wbGUgUGxhY2UsIFN1aXRlIDMzMCwgQm9zdG9uLAogKiBNQSAwMjExMS0xMzA3IFVTQQogKi8KCiNpbmNsdWRlIDxjb21tb24uaD4KI2luY2x1ZGUgPHBjaS5oPgojaW5jbHVkZSA8bWFsbG9jLmg+CiNpbmNsdWRlIDxhc20vcHRyYWNlLmg+CiNpbmNsdWRlIDxhc20vcmVhbG1vZGUuaD4KI2luY2x1ZGUgPGFzbS9pby5oPgojaW5jbHVkZSA8YXNtL3BjaS5oPgoKI3VuZGVmIFBDSV9CSU9TX0RFQlVHCiN1bmRlZiBWR0FfQklPU19ERUJVRwoKI2lmZGVmCVZHQV9CSU9TX0RFQlVHCiNkZWZpbmUJUFJJTlRGKGZtdCxhcmdzLi4uKQlwcmludGYgKGZtdCAsIyNhcmdzKQojZWxzZQojZGVmaW5lIFBSSU5URihmbXQsYXJncy4uLikKI2VuZGlmCgojaWZkZWYgQ09ORklHX1BDSQoKI2lmZGVmIFBDSV9CSU9TX0RFQlVHCiNkZWZpbmUgUkVMT0NfMTYoc2VnLCBvZmYpICoodTMyKikoc2VnIDw8IDQgfCAodTMyKSZvZmYpCmV4dGVybiB1MzIgbnVtX3BjaV9iaW9zX3ByZXNlbnQ7CmV4dGVybiB1MzIgbnVtX3BjaV9iaW9zX2ZpbmRfZGV2aWNlOwpleHRlcm4gdTMyIG51bV9wY2lfYmlvc19maW5kX2NsYXNzOwpleHRlcm4gdTMyIG51bV9wY2lfYmlvc19nZW5lcmF0ZV9zcGVjaWFsX2N5Y2xlOwpleHRlcm4gdTMyIG51bV9wY2lfYmlvc19yZWFkX2NmZ19ieXRlOwpleHRlcm4gdTMyIG51bV9wY2lfYmlvc19yZWFkX2NmZ193b3JkOwpleHRlcm4gdTMyIG51bV9wY2lfYmlvc19yZWFkX2NmZ19kd29yZDsKZXh0ZXJuIHUzMiBudW1fcGNpX2Jpb3Nfd3JpdGVfY2ZnX2J5dGU7CmV4dGVybiB1MzIgbnVtX3BjaV9iaW9zX3dyaXRlX2NmZ193b3JkOwpleHRlcm4gdTMyIG51bV9wY2lfYmlvc193cml0ZV9jZmdfZHdvcmQ7CmV4dGVybiB1MzIgbnVtX3BjaV9iaW9zX2dldF9pcnFfcm91dGluZzsKZXh0ZXJuIHUzMiBudW1fcGNpX2Jpb3Nfc2V0X2lycTsKZXh0ZXJuIHUzMiBudW1fcGNpX2Jpb3NfdW5rbm93bl9mdW5jdGlvbjsKCnZvaWQgcHJpbnRfYmlvc19iaW9zX3N0YXQodm9pZCkKewoJcHJpbnRmKCIxNiBiaXQgZnVuY3Rpb25zOlxuIik7CglwcmludGYoInBjaV9iaW9zX3ByZXNlbnQ6ICAgICAgICAgICAgICAgICVkXG4iLCBSRUxPQ18xNigweGYwMDAsIG51bV9wY2lfYmlvc19wcmVzZW50KSk7CglwcmludGYoInBjaV9iaW9zX2ZpbmRfZGV2aWNlOiAgICAgICAgICAgICVkXG4iLCBSRUxPQ18xNigweGYwMDAsIG51bV9wY2lfYmlvc19maW5kX2RldmljZSkpOwoJcHJpbnRmKCJwY2lfYmlvc19maW5kX2NsYXNzOiAgICAgICAgICAgICAlZFxuIiwgUkVMT0NfMTYoMHhmMDAwLCBudW1fcGNpX2Jpb3NfZmluZF9jbGFzcykpOwoJcHJpbnRmKCJwY2lfYmlvc19nZW5lcmF0ZV9zcGVjaWFsX2N5Y2xlOiAlZFxuIiwgUkVMT0NfMTYoMHhmMDAwLCBudW1fcGNpX2Jpb3NfZ2VuZXJhdGVfc3BlY2lhbF9jeWNsZSkpOwoJcHJpbnRmKCJwY2lfYmlvc19yZWFkX2NmZ19ieXRlOiAgICAgICAgICAlZFxuIiwgUkVMT0NfMTYoMHhmMDAwLCBudW1fcGNpX2Jpb3NfcmVhZF9jZmdfYnl0ZSkpOwoJcHJpbnRmKCJwY2lfYmlvc19yZWFkX2NmZ193b3JkOiAgICAgICAgICAlZFxuIiwgUkVMT0NfMTYoMHhmMDAwLCBudW1fcGNpX2Jpb3NfcmVhZF9jZmdfd29yZCkpOwoJcHJpbnRmKCJwY2lfYmlvc19yZWFkX2NmZ19kd29yZDogICAgICAgICAlZFxuIiwgUkVMT0NfMTYoMHhmMDAwLCBudW1fcGNpX2Jpb3NfcmVhZF9jZmdfZHdvcmQpKTsKCXByaW50ZigicGNpX2Jpb3Nfd3JpdGVfY2ZnX2J5dGU6ICAgICAgICAgJWRcbiIsIFJFTE9DXzE2KDB4ZjAwMCwgbnVtX3BjaV9iaW9zX3dyaXRlX2NmZ19ieXRlKSk7CglwcmludGYoInBjaV9iaW9zX3dyaXRlX2NmZ193b3JkOiAgICAgICAgICVkXG4iLCBSRUxPQ18xNigweGYwMDAsIG51bV9wY2lfYmlvc193cml0ZV9jZmdfd29yZCkpOwoJcHJpbnRmKCJwY2lfYmlvc193cml0ZV9jZmdfZHdvcmQ6ICAgICAgICAlZFxuIiwgUkVMT0NfMTYoMHhmMDAwLCBudW1fcGNpX2Jpb3Nfd3JpdGVfY2ZnX2R3b3JkKSk7CglwcmludGYoInBjaV9iaW9zX2dldF9pcnFfcm91dGluZzogICAgICAgICVkXG4iLCBSRUxPQ18xNigweGYwMDAsIG51bV9wY2lfYmlvc19nZXRfaXJxX3JvdXRpbmcpKTsKCXByaW50ZigicGNpX2Jpb3Nfc2V0X2lycTogICAgICAgICAgICAgICAgJWRcbiIsIFJFTE9DXzE2KDB4ZjAwMCwgbnVtX3BjaV9iaW9zX3NldF9pcnEpKTsKCXByaW50ZigicGNpX2Jpb3NfdW5rbm93bl9mdW5jdGlvbjogICAgICAgJWRcbiIsIFJFTE9DXzE2KDB4ZjAwMCwgbnVtX3BjaV9iaW9zX3Vua25vd25fZnVuY3Rpb24pKTsKCn0KI2VuZGlmCgojZGVmaW5lIFBDSV9DTEFTU19WSURFTyAgICAgICAgICAgICAzCiNkZWZpbmUgUENJX0NMQVNTX1ZJREVPX1NURCAgICAgICAgIDAKI2RlZmluZSBQQ0lfQ0xBU1NfVklERU9fUFJPR19JRl9WR0EgMAoKCnN0YXRpYyB1MzIgcHJvYmVfcGNpX3ZpZGVvKHZvaWQpCnsKCXBjaV9kZXZfdCBkZXZidXNmbjsKCglpZiAoKGRldmJ1c2ZuID0gcGNpX2ZpbmRfY2xhc3MoUENJX0NMQVNTX1ZJREVPLAoJCQkJICAgICAgIFBDSV9DTEFTU19WSURFT19TVEQsCgkJCQkgICAgICAgUENJX0NMQVNTX1ZJREVPX1BST0dfSUZfVkdBLCAwKSkgIT0gLTEpIHsKCQl1MzIgb2xkOwoJCXUzMiBhZGRyOwoKCQkvKiBQQ0kgdmlkZW8gZGV2aWNlIGRldGVjdGVkICovCgkJcHJpbnRmKCJGb3VuZCBQQ0kgVkdBIGRldmljZSBhdCAlMDJ4LiUwMnguJXhcbiIsCgkJICAgICAgIFBDSV9CVVMoZGV2YnVzZm4pLCBQQ0lfREVWKGRldmJ1c2ZuKSwgUENJX0ZVTkMoZGV2YnVzZm4pKTsKCgkJLyogRW5hYmxlIEkvTyBkZWNvZGluZyBhcyB3ZWxsLCBQQ0kgdml1ZGVvIGJvYXJkcwoJCSAqIHN1cHBvcnQgSS9PIGFjY2Vzc2VzLCBidXQgdGhleSBwcm92aWRlIG5vCgkJICogYmFyIHJlZ2lzdGVyIGZvciB0aGlzIHNpbmNlIHRoZSBwb3J0cyBhcmUgZml4ZWQuCgkJICovCgkJcGNpX3dyaXRlX2NvbmZpZ193b3JkKGRldmJ1c2ZuLCBQQ0lfQ09NTUFORCwgUENJX0NPTU1BTkRfTUVNT1JZIHwgUENJX0NPTU1BTkRfSU8gfCBQQ0lfQ09NTUFORF9NQVNURVIpOwoKCQkvKiBUZXN0IHRoZSBST00gZGVjb2RlciwgZG8gdGhlIGRldmljZSBzdXBwb3J0IGEgcm9tPyAqLwoJCXBjaV9yZWFkX2NvbmZpZ19kd29yZChkZXZidXNmbiwgUENJX1JPTV9BRERSRVNTLCAmb2xkKTsKCQlwY2lfd3JpdGVfY29uZmlnX2R3b3JkKGRldmJ1c2ZuLCBQQ0lfUk9NX0FERFJFU1MsIFBDSV9ST01fQUREUkVTU19NQVNLKTsKCQlwY2lfcmVhZF9jb25maWdfZHdvcmQoZGV2YnVzZm4sIFBDSV9ST01fQUREUkVTUywgJmFkZHIpOwoJCXBjaV93cml0ZV9jb25maWdfZHdvcmQoZGV2YnVzZm4sIFBDSV9ST01fQUREUkVTUywgb2xkKTsKCgkJaWYgKCFhZGRyKSB7CgkJCXByaW50ZigiUENJIFZHQSBoYXZlIG5vIFJPTT9cbiIpOwoJCQlyZXR1cm4gMDsKCQl9CgoJCS8qIGRldmljZSBoYXZlIGEgcm9tICovCgkJaWYgKHBjaV9zaGFkb3dfcm9tKGRldmJ1c2ZuLCAodm9pZCopMHhjMDAwMCkpIHsKCQkJcHJpbnRmKCJTaGFkb3dpbmcgb2YgUENJIFZHQSBCSU9TIGZhaWxlZFxuIik7CgkJCXJldHVybiAwOwoJCX0KCgkJLyogTm93IGVuYWJsZSBsYWdhY3kgVkdBIHBvcnQgYWNjZXNzICovCgkJaWYgKHBjaV9lbmFibGVfbGVnYWN5X3ZpZGVvX3BvcnRzKHBjaV9idXNfdG9faG9zZShQQ0lfQlVTKGRldmJ1c2ZuKSkpKSB7CgkJCXByaW50ZigiUENJIFZHQSBlbmFibGUgZmFpbGVkXG4iKTsKCQkJcmV0dXJuIDA7CgkJfQoKCgkJLyogcmV0dXJuIHRoZSBwY2kgZGV2aWNlIGluZm8sIHRoYXQgd2UnbGwgbmVlZCBsYXRlciAqLwoJCXJldHVybiBQQ0lfQlVTKGRldmJ1c2ZuKSA8PCA4IHwKCQkJUENJX0RFVihkZXZidXNmbikgPDwgMyB8IChQQ0lfRlVOQyhkZXZidXNmbikmNyk7Cgl9CgoJcmV0dXJuIDA7Cn0KCgojZW5kaWYKCiNpZmRlZiBDT05GSUdfVklERU8KCnN0YXRpYyBpbnQgcHJvYmVfaXNhX3ZpZGVvKHZvaWQpCnsKCXUzMiBwdHI7CgljaGFyICpidWY7CgoJaWYgKDAgPT0gKHB0ciA9IGlzYV9tYXBfcm9tKDB4YzAwMDAsIDB4ODAwMCkpKSB7CgkJcmV0dXJuIC0xOwoJfQoJaWYgKE5VTEwgPT0gKGJ1Zj1tYWxsb2MoMHg4MDAwKSkpIHsKCQlpc2FfdW5tYXBfcm9tKHB0cik7CgkJcmV0dXJuIC0xOwoJfQoJaWYgKHJlYWR3KHB0cikgIT0gMHhhYTU1KSB7CgkJZnJlZShidWYpOwoJCWlzYV91bm1hcF9yb20ocHRyKTsKCQlyZXR1cm4gLTE7Cgl9CgoJLyogc2hhZG93IHRoZSByb20gKi8KCW1lbWNweShidWYsICh2b2lkKilwdHIsIDB4ODAwMCk7Cglpc2FfdW5tYXBfcm9tKHB0cik7CgltZW1jcHkoKHZvaWQqKTB4YzAwMDAsIGJ1ZiwgMHg4MDAwKTsKCglmcmVlKGJ1Zik7CgoJcmV0dXJuIDA7Cn0KCmludCB2aWRlb19iaW9zX2luaXQodm9pZCkKewoJc3RydWN0IHB0X3JlZ3MgcmVnczsKCgkvKiBjbGVhciB0aGUgdmlkZW8gYmlvcyBhcmVhIGluIGNhc2Ugd2Ugd2FybWJvb3RlZCAqLwoJbWVtc2V0KCh2b2lkKikweGMwMDAwLCAwLCAweDgwMDApOwoJbWVtc2V0KCZyZWdzLCAwLCBzaXplb2Yoc3RydWN0IHB0X3JlZ3MpKTsKCglpZiAocHJvYmVfaXNhX3ZpZGVvKCkpIHsKCQkvKiBObyBJU0EgYm9hcmQgZm91bmQsIHRyeSB0aGUgUENJIGJ1cyAqLwoJCXJlZ3MuZWF4ID0gcHJvYmVfcGNpX3ZpZGVvKCk7Cgl9CgoJLyogRGlkIHdlIHN1Y2NlZWQgaW4gbWFwcGluZyBhbnkgdmlkZW8gYmlvcyAqLwoJaWYgKHJlYWR3KDB4YzAwMDApID09IDB4YWE1NSkgewoJICAgICAgICBpbnQgc2l6ZTsKCQlpbnQgaTsKCQl1OCBzdW07CgoJCVBSSU5URigiRm91bmQgdmlkZW8gYmlvcyBzaWduYXR1cmVcbiIpOwoJCXNpemUgPSA1MTIqcmVhZGIoMHhjMDAwMik7CgkJUFJJTlRGKCJzaXplICVkXG4iLCBzaXplKTsKCQlzdW09MDsKCQlmb3IgKGk9MDtpPHNpemU7aSsrKSB7CgkJCXN1bSArPSByZWFkYigweGMwMDAwICsgaSk7CgkJfQoJCVBSSU5URigiQ2hlY2tzdW0gaXMgJXNPS1xuIixzdW0/Ik5PVCAiOiIiKTsKCQlpZiAoc3VtKSB7CgkJCXJldHVybiAxOwoJCX0KCgkJLyogc29tZSB2aWRlbyBiaW9zZXMgKEFUSSBNYWNoNjQpIHNlZW0gdG8gdGhpbmsgdGhhdAoJCSAqIHRoZSBvcmlnaW5hbCBpbnQgMTAgaGFuZGxlciBpcyBhbHdheXMgYXQKCQkgKiAweGYwMDA6MHhmMDY1ICwgcGxhY2UgYW4gaXJldCBpbnN0cnVjdGlvbiB0aGVyZQoJCSAqLwoJCXdyaXRlYigweGNmLCAweGZmMDY1KTsKCgkJcmVncy5lc3AgPSAweDgwMDA7CgkJcmVncy54c3MgPSAweDIwMDA7CgkJZW50ZXJfcmVhbG1vZGUoMHhjMDAwLCAzLCAmcmVncywgJnJlZ3MpOwoJCVBSSU5URigiSU5UIDB4MTAgdmVjdG9yIGFmdGVyOiAgJTA0eDolMDR4XG4iLAoJCSAgICAgICByZWFkdygweDQyKSwgcmVhZHcoMHg0MCkpOwoJCVBSSU5URigiQklPUyByZXR1cm5lZCAlc2NhcnJ5XG4iLCByZWdzLmVmbGFncyAmIDE/IiI6Ik5PVCAiKTsKI2lmZGVmIFBDSV9CSU9TX0RFQlVHCgkJcHJpbnRfYmlvc19iaW9zX3N0YXQoKTsKI2VuZGlmCgkJcmV0dXJuIChyZWdzLmVmbGFncyAmIDEpOwoKCX0KCglyZXR1cm4gMTsKCn0KI2VuZGlmCg==