LyoKICogKEMpIENvcHlyaWdodCAyMDA4CiAqIEdyYWVtZSBSdXNzLCBncmFlbWUucnVzc0BnbWFpbC5jb20uCiAqCiAqIChDKSBDb3B5cmlnaHQgMjAwMgogKiBEYW5pZWwgRW5nc3Ry9m0sIE9taWNyb24gQ2V0aSBBQiA8ZGFuaWVsQG9taWNyb24uc2U+LgogKgogKiBTZWUgZmlsZSBDUkVESVRTIGZvciBsaXN0IG9mIHBlb3BsZSB3aG8gY29udHJpYnV0ZWQgdG8gdGhpcwogKiBwcm9qZWN0LgogKgogKiBUaGlzIHByb2dyYW0gaXMgZnJlZSBzb2Z0d2FyZTsgeW91IGNhbiByZWRpc3RyaWJ1dGUgaXQgYW5kL29yCiAqIG1vZGlmeSBpdCB1bmRlciB0aGUgdGVybXMgb2YgdGhlIEdOVSBHZW5lcmFsIFB1YmxpYyBMaWNlbnNlIGFzCiAqIHB1Ymxpc2hlZCBieSB0aGUgRnJlZSBTb2Z0d2FyZSBGb3VuZGF0aW9uOyBlaXRoZXIgdmVyc2lvbiAyIG9mCiAqIHRoZSBMaWNlbnNlLCBvciAoYXQgeW91ciBvcHRpb24pIGFueSBsYXRlciB2ZXJzaW9uLgogKgogKiBUaGlzIHByb2dyYW0gaXMgZGlzdHJpYnV0ZWQgaW4gdGhlIGhvcGUgdGhhdCBpdCB3aWxsIGJlIHVzZWZ1bCwKICogYnV0IFdJVEhPVVQgQU5ZIFdBUlJBTlRZOyB3aXRob3V0IGV2ZW4gdGhlIGltcGxpZWQgd2FycmFudHkgb2YKICogTUVSQ0hBTlRBQklMSVRZIG9yIEZJVE5FU1MgRk9SIEEgUEFSVElDVUxBUiBQVVJQT1NFLgkgU2VlIHRoZQogKiBHTlUgR2VuZXJhbCBQdWJsaWMgTGljZW5zZSBmb3IgbW9yZSBkZXRhaWxzLgogKgogKiBZb3Ugc2hvdWxkIGhhdmUgcmVjZWl2ZWQgYSBjb3B5IG9mIHRoZSBHTlUgR2VuZXJhbCBQdWJsaWMgTGljZW5zZQogKiBhbG9uZyB3aXRoIHRoaXMgcHJvZ3JhbTsgaWYgbm90LCB3cml0ZSB0byB0aGUgRnJlZSBTb2Z0d2FyZQogKiBGb3VuZGF0aW9uLCBJbmMuLCA1OSBUZW1wbGUgUGxhY2UsIFN1aXRlIDMzMCwgQm9zdG9uLAogKiBNQSAwMjExMS0xMzA3IFVTQQogKi8KI2luY2x1ZGUgPGNvbW1vbi5oPgojaW5jbHVkZSA8cGNpLmg+CiNpbmNsdWRlIDxhc20vcGNpLmg+CiNpbmNsdWRlIDxhc20vaWMvcGNpLmg+CgpzdGF0aWMgdm9pZCBwY2lfZW5ldF9maXh1cF9pcnEoc3RydWN0IHBjaV9jb250cm9sbGVyICpob3NlLCBwY2lfZGV2X3QgZGV2KQp7CgkvKiBhIGNvbmZpZ3VyYWJsZSBsaXN0cyBvZiBJUlFzIHRvIHN0ZWFsIHdoZW4gd2UgbmVlZCBvbmUgKi8KCXN0YXRpYyBpbnQgaXJxX2xpc3RbXSA9IHsKCQlDT05GSUdfU1lTX0ZJUlNUX1BDSV9JUlEsCgkJQ09ORklHX1NZU19TRUNPTkRfUENJX0lSUSwKCQlDT05GSUdfU1lTX1RISVJEX1BDSV9JUlEsCgkJQ09ORklHX1NZU19GT1JUSF9QQ0lfSVJRCgl9OwoJc3RhdGljIGludCBuZXh0X2lycV9pbmRleD0wOwoKCXVjaGFyIHRtcF9waW47CglpbnQgcGluOwoKCXBjaV9ob3NlX3JlYWRfY29uZmlnX2J5dGUoaG9zZSwgZGV2LCBQQ0lfSU5URVJSVVBUX1BJTiwgJnRtcF9waW4pOwoJcGluID0gdG1wX3BpbjsKCglwaW4gLT0gMTsgLyogUENJIGNvbmZpZyBzcGFjZSB1c2UgMS1iYXNlZCBudW1iZXJpbmcgKi8KCWlmIChwaW4gPT0gLTEpIHsKCQlyZXR1cm47IC8qIGRldmljZSB1c2Ugbm8gaXJxICovCgl9CgoJLyogbWFwIGRldmljZSBudW1iZXIgKyAgcGluIHRvIGEgcGluIG9uIHRoZSBzYzUyMCAqLwoJc3dpdGNoIChQQ0lfREVWKGRldikpIHsKCWNhc2UgMTI6CS8qIEZpcnN0IEV0aGVybmV0IENoaXAgKi8KCQlwaW4gKz0gU0M1MjBfUENJX0lOVEE7CgkJYnJlYWs7CgoJY2FzZSAxMzoJLyogU2Vjb25kIEV0aGVybmV0IENoaXAgKi8KCQlwaW4gKz0gU0M1MjBfUENJX0lOVEI7CgkJYnJlYWs7CgoJZGVmYXVsdDoKCQlyZXR1cm47Cgl9CgoJcGluICY9IDM7IC8qIHdyYXAgYXJvdW5kICovCgoJaWYgKHNjNTIwX3BjaV9pbnRzW3Bpbl0gPT0gLTEpIHsKCQkvKiByZS1yb3V0ZSBvbmUgaW50ZXJydXB0IGZvciB1cyAqLwoJCWlmIChuZXh0X2lycV9pbmRleCA+IDMpIHsKCQkJcmV0dXJuOwoJCX0KCQlpZiAocGNpX3NjNTIwX3NldF9pcnEocGluLCBpcnFfbGlzdFtuZXh0X2lycV9pbmRleF0pKSB7CgkJCXJldHVybjsKCQl9CgkJbmV4dF9pcnFfaW5kZXgrKzsKCX0KCglpZiAoLTEgIT0gc2M1MjBfcGNpX2ludHNbcGluXSkgewoJcGNpX2hvc2Vfd3JpdGVfY29uZmlnX2J5dGUoaG9zZSwgZGV2LCBQQ0lfSU5URVJSVVBUX0xJTkUsCgkJCQkJICAgc2M1MjBfcGNpX2ludHNbcGluXSk7Cgl9CglwcmludGYoImZpeHVwX2lycTogZGV2aWNlICVkIHBpbiAlYyBpcnEgJWRcbiIsCgkgICAgICAgUENJX0RFVihkZXYpLCAnQScgKyBwaW4sIHNjNTIwX3BjaV9pbnRzW3Bpbl0pOwp9CgpzdGF0aWMgc3RydWN0IHBjaV9jb250cm9sbGVyIGVuZXRfaG9zZSA9IHsKCWZpeHVwX2lycTogcGNpX2VuZXRfZml4dXBfaXJxLAp9OwoKdm9pZCBwY2lfaW5pdF9ib2FyZCh2b2lkKQp7CglwY2lfc2M1MjBfaW5pdCgmZW5ldF9ob3NlKTsKfQoKaW50IHBjaV9zZXRfcmVnaW9ucyhzdHJ1Y3QgcGNpX2NvbnRyb2xsZXIgKmhvc2UpCnsKCS8qIFN5c3RlbSBtZW1vcnkgc3BhY2UgKi8KCXBjaV9zZXRfcmVnaW9uKGhvc2UtPnJlZ2lvbnMgKyAwLAoJCSAgICAgICBTQzUyMF9QQ0lfTUVNT1JZX0JVUywKCQkgICAgICAgU0M1MjBfUENJX01FTU9SWV9QSFlTLAoJCSAgICAgICBTQzUyMF9QQ0lfTUVNT1JZX1NJWkUsCgkJICAgICAgIFBDSV9SRUdJT05fTUVNIHwgUENJX1JFR0lPTl9TWVNfTUVNT1JZKTsKCgkvKiBJU0EvUENJIG1lbW9yeSBzcGFjZSAqLwoJcGNpX3NldF9yZWdpb24oaG9zZS0+cmVnaW9ucyArIDEsCgkJICAgICAgIFNDNTIwX0lTQV9NRU1fQlVTLAoJCSAgICAgICBTQzUyMF9JU0FfTUVNX1BIWVMsCgkJICAgICAgIFNDNTIwX0lTQV9NRU1fU0laRSwKCQkgICAgICAgUENJX1JFR0lPTl9NRU0pOwoKCS8qIFBDSSBJL08gc3BhY2UgKi8KCXBjaV9zZXRfcmVnaW9uKGhvc2UtPnJlZ2lvbnMgKyAyLAoJCSAgICAgICBTQzUyMF9QQ0lfSU9fQlVTLAoJCSAgICAgICBTQzUyMF9QQ0lfSU9fUEhZUywKCQkgICAgICAgU0M1MjBfUENJX0lPX1NJWkUsCgkJICAgICAgIFBDSV9SRUdJT05fSU8pOwoKCS8qIElTQS9QQ0kgSS9PIHNwYWNlICovCglwY2lfc2V0X3JlZ2lvbihob3NlLT5yZWdpb25zICsgMywKCQkgICAgICAgU0M1MjBfSVNBX0lPX0JVUywKCQkgICAgICAgU0M1MjBfSVNBX0lPX1BIWVMsCgkJICAgICAgIFNDNTIwX0lTQV9JT19TSVpFLAoJCSAgICAgICBQQ0lfUkVHSU9OX0lPKTsKCglyZXR1cm4gNDsKfQo=