LyoKICogIEZvcmNlIGZlZWRiYWNrIHN1cHBvcnQgZm9yIFBhbnRoZXJMb3JkL0dyZWVuQXNpYSBiYXNlZCBkZXZpY2VzCiAqCiAqICBUaGUgZGV2aWNlcyBhcmUgZGlzdHJpYnV0ZWQgdW5kZXIgdmFyaW91cyBuYW1lcyBhbmQgdGhlIHNhbWUgVVNCIGRldmljZSBJRAogKiAgY2FuIGJlIHVzZWQgaW4gYm90aCBhZGFwdGVycyBhbmQgYWN0dWFsIGdhbWUgY29udHJvbGxlcnMuCiAqCiAqICAwODEwOjAwMDEgIlR3aW4gVVNCIEpveXN0aWNrIgogKiAgIC0gdGVzdGVkIHdpdGggUGFudGhlckxvcmQgVVNCL1BTMiAyaW4xIEFkYXB0ZXIKICogICAtIGNvbnRhaW5zIHR3byByZXBvcnRzLCBvbmUgZm9yIGVhY2ggcG9ydCAoSElEX1FVSVJLX01VTFRJX0lOUFVUKQogKgogKiAgMGU4ZjowMDAzICJHcmVlbkFzaWEgSW5jLiAgICBVU0IgSm95c3RpY2sgICAgICIKICogICAtIHRlc3RlZCB3aXRoIEv2bmlnIEdhbWluZyBnYW1lcGFkCiAqCiAqICAwZThmOjAwMDMgIkdBU0lBIFVTQiBHYW1lcGFkIgogKiAgIC0gYW5vdGhlciB2ZXJzaW9uIG9mIHRoZSBL9m5pZyBnYW1lcGFkCiAqCiAqICBDb3B5cmlnaHQgKGMpIDIwMDcsIDIwMDkgQW5zc2kgSGFubnVsYSA8YW5zc2kuaGFubnVsYUBnbWFpbC5jb20+CiAqLwoKLyoKICogVGhpcyBwcm9ncmFtIGlzIGZyZWUgc29mdHdhcmU7IHlvdSBjYW4gcmVkaXN0cmlidXRlIGl0IGFuZC9vciBtb2RpZnkKICogaXQgdW5kZXIgdGhlIHRlcm1zIG9mIHRoZSBHTlUgR2VuZXJhbCBQdWJsaWMgTGljZW5zZSBhcyBwdWJsaXNoZWQgYnkKICogdGhlIEZyZWUgU29mdHdhcmUgRm91bmRhdGlvbjsgZWl0aGVyIHZlcnNpb24gMiBvZiB0aGUgTGljZW5zZSwgb3IKICogKGF0IHlvdXIgb3B0aW9uKSBhbnkgbGF0ZXIgdmVyc2lvbi4KICoKICogVGhpcyBwcm9ncmFtIGlzIGRpc3RyaWJ1dGVkIGluIHRoZSBob3BlIHRoYXQgaXQgd2lsbCBiZSB1c2VmdWwsCiAqIGJ1dCBXSVRIT1VUIEFOWSBXQVJSQU5UWTsgd2l0aG91dCBldmVuIHRoZSBpbXBsaWVkIHdhcnJhbnR5IG9mCiAqIE1FUkNIQU5UQUJJTElUWSBvciBGSVRORVNTIEZPUiBBIFBBUlRJQ1VMQVIgUFVSUE9TRS4gIFNlZSB0aGUKICogR05VIEdlbmVyYWwgUHVibGljIExpY2Vuc2UgZm9yIG1vcmUgZGV0YWlscy4KICoKICogWW91IHNob3VsZCBoYXZlIHJlY2VpdmVkIGEgY29weSBvZiB0aGUgR05VIEdlbmVyYWwgUHVibGljIExpY2Vuc2UKICogYWxvbmcgd2l0aCB0aGlzIHByb2dyYW07IGlmIG5vdCwgd3JpdGUgdG8gdGhlIEZyZWUgU29mdHdhcmUKICogRm91bmRhdGlvbiwgSW5jLiwgNTkgVGVtcGxlIFBsYWNlLCBTdWl0ZSAzMzAsIEJvc3RvbiwgTUEgMDIxMTEtMTMwNyBVU0EKICovCgoKLyogI2RlZmluZSBERUJVRyAqLwoKI2RlZmluZSBkZWJ1Zyhmb3JtYXQsIGFyZy4uLikgcHJfZGVidWcoImhpZC1wbGZmOiAiIGZvcm1hdCAiXG4iICwgIyMgYXJnKQoKI2luY2x1ZGUgPGxpbnV4L2lucHV0Lmg+CiNpbmNsdWRlIDxsaW51eC9zbGFiLmg+CiNpbmNsdWRlIDxsaW51eC91c2IuaD4KI2luY2x1ZGUgPGxpbnV4L2hpZC5oPgoKI2luY2x1ZGUgImhpZC1pZHMuaCIKCiNpZmRlZiBDT05GSUdfUEFOVEhFUkxPUkRfRkYKI2luY2x1ZGUgInVzYmhpZC91c2JoaWQuaCIKCnN0cnVjdCBwbGZmX2RldmljZSB7CglzdHJ1Y3QgaGlkX3JlcG9ydCAqcmVwb3J0OwoJczMyICpzdHJvbmc7CglzMzIgKndlYWs7Cn07CgpzdGF0aWMgaW50IGhpZF9wbGZmX3BsYXkoc3RydWN0IGlucHV0X2RldiAqZGV2LCB2b2lkICpkYXRhLAoJCQkgc3RydWN0IGZmX2VmZmVjdCAqZWZmZWN0KQp7CglzdHJ1Y3QgaGlkX2RldmljZSAqaGlkID0gaW5wdXRfZ2V0X2RydmRhdGEoZGV2KTsKCXN0cnVjdCBwbGZmX2RldmljZSAqcGxmZiA9IGRhdGE7CglpbnQgbGVmdCwgcmlnaHQ7CgoJbGVmdCA9IGVmZmVjdC0+dS5ydW1ibGUuc3Ryb25nX21hZ25pdHVkZTsKCXJpZ2h0ID0gZWZmZWN0LT51LnJ1bWJsZS53ZWFrX21hZ25pdHVkZTsKCWRlYnVnKCJjYWxsZWQgd2l0aCAweCUwNHggMHglMDR4IiwgbGVmdCwgcmlnaHQpOwoKCWxlZnQgPSBsZWZ0ICogMHg3ZiAvIDB4ZmZmZjsKCXJpZ2h0ID0gcmlnaHQgKiAweDdmIC8gMHhmZmZmOwoKCSpwbGZmLT5zdHJvbmcgPSBsZWZ0OwoJKnBsZmYtPndlYWsgPSByaWdodDsKCWRlYnVnKCJydW5uaW5nIHdpdGggMHglMDJ4IDB4JTAyeCIsIGxlZnQsIHJpZ2h0KTsKCXVzYmhpZF9zdWJtaXRfcmVwb3J0KGhpZCwgcGxmZi0+cmVwb3J0LCBVU0JfRElSX09VVCk7CgoJcmV0dXJuIDA7Cn0KCnN0YXRpYyBpbnQgcGxmZl9pbml0KHN0cnVjdCBoaWRfZGV2aWNlICpoaWQpCnsKCXN0cnVjdCBwbGZmX2RldmljZSAqcGxmZjsKCXN0cnVjdCBoaWRfcmVwb3J0ICpyZXBvcnQ7CglzdHJ1Y3QgaGlkX2lucHV0ICpoaWRpbnB1dDsKCXN0cnVjdCBsaXN0X2hlYWQgKnJlcG9ydF9saXN0ID0KCQkJJmhpZC0+cmVwb3J0X2VudW1bSElEX09VVFBVVF9SRVBPUlRdLnJlcG9ydF9saXN0OwoJc3RydWN0IGxpc3RfaGVhZCAqcmVwb3J0X3B0ciA9IHJlcG9ydF9saXN0OwoJc3RydWN0IGlucHV0X2RldiAqZGV2OwoJaW50IGVycm9yOwoJczMyICpzdHJvbmc7CglzMzIgKndlYWs7CgoJLyogVGhlIGRldmljZSBjb250YWlucyBvbmUgb3V0cHV0IHJlcG9ydCBwZXIgcGh5c2ljYWwgZGV2aWNlLCBhbGwKCSAgIGNvbnRhaW5pbmcgMSBmaWVsZCwgd2hpY2ggY29udGFpbnMgNCBmZjAwLjAwMDIgdXNhZ2VzIGFuZCA0IDE2Yml0CgkgICBhYnNvbHV0ZSB2YWx1ZXMuCgoJICAgVGhlIGlucHV0IHJlcG9ydHMgYWxzbyBjb250YWluIGEgZmllbGQgd2hpY2ggY29udGFpbnMKCSAgIDggZmYwMC4wMDAxIHVzYWdlcyBhbmQgOCBib29sZWFuIHZhbHVlcy4gVGhlaXIgbWVhbmluZyBpcwoJICAgY3VycmVudGx5IHVua25vd24uCgkgICAKCSAgIEEgdmVyc2lvbiBvZiB0aGUgMGU4ZjowMDAzIGV4aXN0cyB0aGF0IGhhcyBhbGwgdGhlIHZhbHVlcyBpbgoJICAgc2VwYXJhdGUgZmllbGRzIGFuZCBtaXNzZXMgdGhlIGV4dHJhIGlucHV0IGZpZWxkLCB0aHVzIHJlc2VtYmxpbmcKCSAgIFplcm9wbHVzIChoaWQtenBmZikgZGV2aWNlcy4KCSovCgoJaWYgKGxpc3RfZW1wdHkocmVwb3J0X2xpc3QpKSB7CgkJaGlkX2VycihoaWQsICJubyBvdXRwdXQgcmVwb3J0cyBmb3VuZFxuIik7CgkJcmV0dXJuIC1FTk9ERVY7Cgl9CgoJbGlzdF9mb3JfZWFjaF9lbnRyeShoaWRpbnB1dCwgJmhpZC0+aW5wdXRzLCBsaXN0KSB7CgoJCXJlcG9ydF9wdHIgPSByZXBvcnRfcHRyLT5uZXh0OwoKCQlpZiAocmVwb3J0X3B0ciA9PSByZXBvcnRfbGlzdCkgewoJCQloaWRfZXJyKGhpZCwgInJlcXVpcmVkIG91dHB1dCByZXBvcnQgaXMgbWlzc2luZ1xuIik7CgkJCXJldHVybiAtRU5PREVWOwoJCX0KCgkJcmVwb3J0ID0gbGlzdF9lbnRyeShyZXBvcnRfcHRyLCBzdHJ1Y3QgaGlkX3JlcG9ydCwgbGlzdCk7CgkJaWYgKHJlcG9ydC0+bWF4ZmllbGQgPCAxKSB7CgkJCWhpZF9lcnIoaGlkLCAibm8gZmllbGRzIGluIHRoZSByZXBvcnRcbiIpOwoJCQlyZXR1cm4gLUVOT0RFVjsKCQl9CgoJCWlmIChyZXBvcnQtPmZpZWxkWzBdLT5yZXBvcnRfY291bnQgPj0gNCkgewoJCQlyZXBvcnQtPmZpZWxkWzBdLT52YWx1ZVswXSA9IDB4MDA7CgkJCXJlcG9ydC0+ZmllbGRbMF0tPnZhbHVlWzFdID0gMHgwMDsKCQkJc3Ryb25nID0gJnJlcG9ydC0+ZmllbGRbMF0tPnZhbHVlWzJdOwoJCQl3ZWFrID0gJnJlcG9ydC0+ZmllbGRbMF0tPnZhbHVlWzNdOwoJCQlkZWJ1ZygiZGV0ZWN0ZWQgc2luZ2xlLWZpZWxkIGRldmljZSIpOwoJCX0gZWxzZSBpZiAocmVwb3J0LT5tYXhmaWVsZCA+PSA0ICYmIHJlcG9ydC0+ZmllbGRbMF0tPm1heHVzYWdlID09IDEgJiYKCQkJCXJlcG9ydC0+ZmllbGRbMF0tPnVzYWdlWzBdLmhpZCA9PSAoSElEX1VQX0xFRCB8IDB4NDMpKSB7CgkJCXJlcG9ydC0+ZmllbGRbMF0tPnZhbHVlWzBdID0gMHgwMDsKCQkJcmVwb3J0LT5maWVsZFsxXS0+dmFsdWVbMF0gPSAweDAwOwoJCQlzdHJvbmcgPSAmcmVwb3J0LT5maWVsZFsyXS0+dmFsdWVbMF07CgkJCXdlYWsgPSAmcmVwb3J0LT5maWVsZFszXS0+dmFsdWVbMF07CgkJCWRlYnVnKCJkZXRlY3RlZCA0LWZpZWxkIGRldmljZSIpOwoJCX0gZWxzZSB7CgkJCWhpZF9lcnIoaGlkLCAibm90IGVub3VnaCBmaWVsZHMgb3IgdmFsdWVzXG4iKTsKCQkJcmV0dXJuIC1FTk9ERVY7CgkJfQoKCQlwbGZmID0ga3phbGxvYyhzaXplb2Yoc3RydWN0IHBsZmZfZGV2aWNlKSwgR0ZQX0tFUk5FTCk7CgkJaWYgKCFwbGZmKQoJCQlyZXR1cm4gLUVOT01FTTsKCgkJZGV2ID0gaGlkaW5wdXQtPmlucHV0OwoKCQlzZXRfYml0KEZGX1JVTUJMRSwgZGV2LT5mZmJpdCk7CgoJCWVycm9yID0gaW5wdXRfZmZfY3JlYXRlX21lbWxlc3MoZGV2LCBwbGZmLCBoaWRfcGxmZl9wbGF5KTsKCQlpZiAoZXJyb3IpIHsKCQkJa2ZyZWUocGxmZik7CgkJCXJldHVybiBlcnJvcjsKCQl9CgoJCXBsZmYtPnJlcG9ydCA9IHJlcG9ydDsKCQlwbGZmLT5zdHJvbmcgPSBzdHJvbmc7CgkJcGxmZi0+d2VhayA9IHdlYWs7CgoJCSpzdHJvbmcgPSAweDAwOwoJCSp3ZWFrID0gMHgwMDsKCQl1c2JoaWRfc3VibWl0X3JlcG9ydChoaWQsIHBsZmYtPnJlcG9ydCwgVVNCX0RJUl9PVVQpOwoJfQoKCWhpZF9pbmZvKGhpZCwgIkZvcmNlIGZlZWRiYWNrIGZvciBQYW50aGVyTG9yZC9HcmVlbkFzaWEgZGV2aWNlcyBieSBBbnNzaSBIYW5udWxhIDxhbnNzaS5oYW5udWxhQGdtYWlsLmNvbT5cbiIpOwoKCXJldHVybiAwOwp9CiNlbHNlCnN0YXRpYyBpbmxpbmUgaW50IHBsZmZfaW5pdChzdHJ1Y3QgaGlkX2RldmljZSAqaGlkKQp7CglyZXR1cm4gMDsKfQojZW5kaWYKCnN0YXRpYyBpbnQgcGxfcHJvYmUoc3RydWN0IGhpZF9kZXZpY2UgKmhkZXYsIGNvbnN0IHN0cnVjdCBoaWRfZGV2aWNlX2lkICppZCkKewoJaW50IHJldDsKCglpZiAoaWQtPmRyaXZlcl9kYXRhKQoJCWhkZXYtPnF1aXJrcyB8PSBISURfUVVJUktfTVVMVElfSU5QVVQ7CgoJcmV0ID0gaGlkX3BhcnNlKGhkZXYpOwoJaWYgKHJldCkgewoJCWhpZF9lcnIoaGRldiwgInBhcnNlIGZhaWxlZFxuIik7CgkJZ290byBlcnI7Cgl9CgoJcmV0ID0gaGlkX2h3X3N0YXJ0KGhkZXYsIEhJRF9DT05ORUNUX0RFRkFVTFQgJiB+SElEX0NPTk5FQ1RfRkYpOwoJaWYgKHJldCkgewoJCWhpZF9lcnIoaGRldiwgImh3IHN0YXJ0IGZhaWxlZFxuIik7CgkJZ290byBlcnI7Cgl9CgoJcGxmZl9pbml0KGhkZXYpOwoKCXJldHVybiAwOwplcnI6CglyZXR1cm4gcmV0Owp9CgpzdGF0aWMgY29uc3Qgc3RydWN0IGhpZF9kZXZpY2VfaWQgcGxfZGV2aWNlc1tdID0gewoJeyBISURfVVNCX0RFVklDRShVU0JfVkVORE9SX0lEX0dBTUVST04sIFVTQl9ERVZJQ0VfSURfR0FNRVJPTl9EVUFMX1BTWF9BREFQVE9SKSwKCQkuZHJpdmVyX2RhdGEgPSAxIH0sIC8qIFR3aW4gVVNCIEpveXN0aWNrICovCgl7IEhJRF9VU0JfREVWSUNFKFVTQl9WRU5ET1JfSURfR0FNRVJPTiwgVVNCX0RFVklDRV9JRF9HQU1FUk9OX0RVQUxfUENTX0FEQVBUT1IpLAoJCS5kcml2ZXJfZGF0YSA9IDEgfSwgLyogVHdpbiBVU0IgSm95c3RpY2sgKi8KCXsgSElEX1VTQl9ERVZJQ0UoVVNCX1ZFTkRPUl9JRF9HUkVFTkFTSUEsIDB4MDAwMyksIH0sCgl7IH0KfTsKTU9EVUxFX0RFVklDRV9UQUJMRShoaWQsIHBsX2RldmljZXMpOwoKc3RhdGljIHN0cnVjdCBoaWRfZHJpdmVyIHBsX2RyaXZlciA9IHsKCS5uYW1lID0gInBhbnRoZXJsb3JkIiwKCS5pZF90YWJsZSA9IHBsX2RldmljZXMsCgkucHJvYmUgPSBwbF9wcm9iZSwKfTsKCnN0YXRpYyBpbnQgX19pbml0IHBsX2luaXQodm9pZCkKewoJcmV0dXJuIGhpZF9yZWdpc3Rlcl9kcml2ZXIoJnBsX2RyaXZlcik7Cn0KCnN0YXRpYyB2b2lkIF9fZXhpdCBwbF9leGl0KHZvaWQpCnsKCWhpZF91bnJlZ2lzdGVyX2RyaXZlcigmcGxfZHJpdmVyKTsKfQoKbW9kdWxlX2luaXQocGxfaW5pdCk7Cm1vZHVsZV9leGl0KHBsX2V4aXQpOwpNT0RVTEVfTElDRU5TRSgiR1BMIik7Cg==