LyogCiAqIEVtYWdpYyBFTUkgMnw2IHVzYiBhdWRpbyBpbnRlcmZhY2UgZmlybXdhcmUgbG9hZGVyLgogKiBDb3B5cmlnaHQgKEMpIDIwMDIKICogCVRhcGlvIExheHN0cvZtICh0YXBpby5sYXhzdHJvbUBpcHRpbWUuZmkpCiAqCiAqIFRoaXMgcHJvZ3JhbSBpcyBmcmVlIHNvZnR3YXJlOyB5b3UgY2FuIHJlZGlzdHJpYnV0ZSBpdCBhbmQvb3IgbW9kaWZ5CiAqIGl0IHVuZGVyIHRoZSB0ZXJtcyBvZiB0aGUgR05VIEdlbmVyYWwgUHVibGljIExpY2Vuc2UsIGFzIHB1Ymxpc2hlZCBieQogKiB0aGUgRnJlZSBTb2Z0d2FyZSBGb3VuZGF0aW9uLCB2ZXJzaW9uIDIuCiAqIAogKiBlbWkyNi5jLHYgMS4xMyAyMDAyLzAzLzA4IDEzOjEwOjI2IHRhcGlvIEV4cAogKi8KI2luY2x1ZGUgPGxpbnV4L2tlcm5lbC5oPgojaW5jbHVkZSA8bGludXgvZXJybm8uaD4KI2luY2x1ZGUgPGxpbnV4L3NsYWIuaD4KI2luY2x1ZGUgPGxpbnV4L21vZHVsZS5oPgojaW5jbHVkZSA8bGludXgvaW5pdC5oPgojaW5jbHVkZSA8bGludXgvdXNiLmg+CgojZGVmaW5lIE1BWF9JTlRFTF9IRVhfUkVDT1JEX0xFTkdUSCAxNgp0eXBlZGVmIHN0cnVjdCBfSU5URUxfSEVYX1JFQ09SRAp7CglfX3UzMglsZW5ndGg7CglfX3UzMglhZGRyZXNzOwoJX191MzIJdHlwZTsKCV9fdTgJZGF0YVtNQVhfSU5URUxfSEVYX1JFQ09SRF9MRU5HVEhdOwp9IElOVEVMX0hFWF9SRUNPUkQsICpQSU5URUxfSEVYX1JFQ09SRDsKCi8qIGluY2x1ZGUgZmlybXdhcmUgKHZhcmlhYmxlcykgKi8KI2luY2x1ZGUgImVtaTI2X2Z3LmgiCgojZGVmaW5lIEVNSTI2X1ZFTkRPUl9JRCAJCTB4MDg2YSAgLyogRW1hZ2ljIFNvZnQtdW5kIEhhcmR3YXJlIEdtQkggKi8KI2RlZmluZSBFTUkyNl9QUk9EVUNUX0lECQkweDAxMDAJLyogRU1JIDJ8NiB3aXRob3V0IGZpcm13YXJlICovCgojZGVmaW5lIEFOQ0hPUl9MT0FEX0lOVEVSTkFMCTB4QTAJLyogVmVuZG9yIHNwZWNpZmljIHJlcXVlc3QgY29kZSBmb3IgQW5jaG9yIFVwbG9hZC9Eb3dubG9hZCAoVGhpcyBvbmUgaXMgaW1wbGVtZW50ZWQgaW4gdGhlIGNvcmUpICovCiNkZWZpbmUgQU5DSE9SX0xPQURfRVhURVJOQUwJMHhBMwkvKiBUaGlzIGNvbW1hbmQgaXMgbm90IGltcGxlbWVudGVkIGluIHRoZSBjb3JlLiBSZXF1aXJlcyBmaXJtd2FyZSAqLwojZGVmaW5lIEFOQ0hPUl9MT0FEX0ZQR0EJMHhBNQkvKiBUaGlzIGNvbW1hbmQgaXMgbm90IGltcGxlbWVudGVkIGluIHRoZSBjb3JlLiBSZXF1aXJlcyBmaXJtd2FyZS4gRW1hZ2ljIGV4dGVuc2lvbiAqLwojZGVmaW5lIE1BWF9JTlRFUk5BTF9BRERSRVNTCTB4MUIzRgkvKiBUaGlzIGlzIHRoZSBoaWdoZXN0IGludGVybmFsIFJBTSBhZGRyZXNzIGZvciB0aGUgQU4yMTMxUSAqLwojZGVmaW5lIENQVUNTX1JFRwkJMHg3RjkyICAvKiBFWi1VU0IgQ29udHJvbCBhbmQgU3RhdHVzIFJlZ2lzdGVyLiAgQml0IDAgY29udHJvbHMgODA1MSByZXNldCAqLyAKI2RlZmluZSBJTlRFUk5BTF9SQU0oYWRkcmVzcykgICAoYWRkcmVzcyA8PSBNQVhfSU5URVJOQUxfQUREUkVTUykKCnN0YXRpYyBpbnQgZW1pMjZfd3JpdGVtZW1vcnkoIHN0cnVjdCB1c2JfZGV2aWNlICpkZXYsIGludCBhZGRyZXNzLCB1bnNpZ25lZCBjaGFyICpkYXRhLCBpbnQgbGVuZ3RoLCBfX3U4IGJSZXF1ZXN0KTsKc3RhdGljIGludCBlbWkyNl9zZXRfcmVzZXQoc3RydWN0IHVzYl9kZXZpY2UgKmRldiwgdW5zaWduZWQgY2hhciByZXNldF9iaXQpOwpzdGF0aWMgaW50IGVtaTI2X2xvYWRfZmlybXdhcmUgKHN0cnVjdCB1c2JfZGV2aWNlICpkZXYpOwpzdGF0aWMgdm9pZCAqZW1pMjZfcHJvYmUoc3RydWN0IHVzYl9kZXZpY2UgKmRldiwgdW5zaWduZWQgaW50IGlmX251bSwgY29uc3Qgc3RydWN0IHVzYl9kZXZpY2VfaWQgKmlkKTsKc3RhdGljIHZvaWQgZW1pMjZfZGlzY29ubmVjdChzdHJ1Y3QgdXNiX2RldmljZSAqZGV2LCB2b2lkICpkcnZfY29udGV4dCk7CnN0YXRpYyBpbnQgX19pbml0IGVtaTI2X2luaXQgKHZvaWQpOwpzdGF0aWMgdm9pZCBfX2V4aXQgZW1pMjZfZXhpdCAodm9pZCk7CgoKLyogdGhhbmtzIHRvIGRyaXZlcnMvdXNiL3NlcmlhbC9rZXlzcGFuX3BkYS5jIGNvZGUgKi8Kc3RhdGljIGludCBlbWkyNl93cml0ZW1lbW9yeSAoc3RydWN0IHVzYl9kZXZpY2UgKmRldiwgaW50IGFkZHJlc3MsIHVuc2lnbmVkIGNoYXIgKmRhdGEsIGludCBsZW5ndGgsIF9fdTggcmVxdWVzdCkKewoJaW50IHJlc3VsdDsKCXVuc2lnbmVkIGNoYXIgKmJ1ZmZlciA9ICBrbWFsbG9jIChsZW5ndGgsIEdGUF9LRVJORUwpOwoKCWlmICghYnVmZmVyKSB7CgkJcHJpbnRrKEtFUk5fRVJSICJlbWkyNjoga21hbGxvYyglZCkgZmFpbGVkLiIsIGxlbmd0aCk7CgkJcmV0dXJuIC1FTk9NRU07Cgl9CgltZW1jcHkgKGJ1ZmZlciwgZGF0YSwgbGVuZ3RoKTsKCS8qIE5vdGU6IHVzYl9jb250cm9sX21zZyByZXR1cm5zIG5lZ2F0aXZlIHZhbHVlIG9uIGVycm9yIG9yIGxlbmd0aCBvZiB0aGUKCSAqIAkJIGRhdGEgdGhhdCB3YXMgd3JpdHRlbiEgKi8KCXJlc3VsdCA9IHVzYl9jb250cm9sX21zZyAoZGV2LCB1c2Jfc25kY3RybHBpcGUoZGV2LCAwKSwgcmVxdWVzdCwgMHg0MCwgYWRkcmVzcywgMCwgYnVmZmVyLCBsZW5ndGgsIDMwMCk7CglrZnJlZSAoYnVmZmVyKTsKCXJldHVybiByZXN1bHQ7Cn0KCi8qIHRoYW5rcyB0byBkcml2ZXJzL3VzYi9zZXJpYWwva2V5c3Bhbl9wZGEuYyBjb2RlICovCnN0YXRpYyBpbnQgZW1pMjZfc2V0X3Jlc2V0IChzdHJ1Y3QgdXNiX2RldmljZSAqZGV2LCB1bnNpZ25lZCBjaGFyIHJlc2V0X2JpdCkKewoJaW50IHJlc3BvbnNlOwoJcHJpbnRrKEtFUk5fSU5GTyAiJXMgLSAlZCIsIF9fRlVOQ1RJT05fXywgcmVzZXRfYml0KTsKCS8qIHByaW50ayhLRVJOX0RFQlVHICIlcyAtICVkIiwgX19GVU5DVElPTl9fLCByZXNldF9iaXQpOyAqLwoJcmVzcG9uc2UgPSBlbWkyNl93cml0ZW1lbW9yeSAoZGV2LCBDUFVDU19SRUcsICZyZXNldF9iaXQsIDEsIDB4YTApOwoJaWYgKHJlc3BvbnNlIDwgMCkgewoJCXByaW50ayhLRVJOX0VSUiAiZW1pMjY6IHNldF9yZXNldCAoJWQpIGZhaWxlZCIsIHJlc2V0X2JpdCk7Cgl9CglyZXR1cm4gcmVzcG9uc2U7Cn0KCnN0YXRpYyBpbnQgZW1pMjZfbG9hZF9maXJtd2FyZSAoc3RydWN0IHVzYl9kZXZpY2UgKmRldikKewoJaW50IGVycjsKCWludCBpOwoJaW50IHBvcyA9IDA7CS8qIFBvc2l0aW9uIGluIGhleCByZWNvcmQgKi8KCV9fdTMyIGFkZHI7CS8qIEFkZHJlc3MgdG8gd3JpdGUgKi8KCV9fdTggYnVmWzEwMjNdOwoKCS8qIEFzc2VydCByZXNldCAoc3RvcCB0aGUgQ1BVIGluIHRoZSBFTUkpICovCgllcnIgPSBlbWkyNl9zZXRfcmVzZXQoZGV2LDEpOwoJaWYgKGVyciA8IDApIHsKCQlwcmludGsoS0VSTl9FUlIgIiVzIC0gZXJyb3IgbG9hZGluZyBmaXJtd2FyZTogZXJyb3IgPSAlZCIsIF9fRlVOQ1RJT05fXywgZXJyKTsKCQlyZXR1cm4gZXJyOwoJfQoKCS8qIDEuIFdlIG5lZWQgdG8gcHV0IHRoZSBsb2FkZXIgZm9yIHRoZSBGUEdBIGludG8gdGhlIEVaLVVTQiAqLwoJZm9yIChpPTA7IGdfTG9hZGVyW2ldLnR5cGUgPT0gMDsgaSsrKSB7CgkJZXJyID0gZW1pMjZfd3JpdGVtZW1vcnkoZGV2LCBnX0xvYWRlcltpXS5hZGRyZXNzLCBnX0xvYWRlcltpXS5kYXRhLCBnX0xvYWRlcltpXS5sZW5ndGgsIEFOQ0hPUl9MT0FEX0lOVEVSTkFMKTsKCQlpZiAoZXJyIDwgMCkgewoJCQlwcmludGsoS0VSTl9FUlIgIiVzIC0gZXJyb3IgbG9hZGluZyBmaXJtd2FyZTogZXJyb3IgPSAlZCIsIF9fRlVOQ1RJT05fXywgZXJyKTsKCQkJcmV0dXJuIGVycjsKCQl9Cgl9CgoJLyogRGUtYXNzZXJ0IHJlc2V0IChsZXQgdGhlIENQVSBydW4pICovCgllcnIgPSBlbWkyNl9zZXRfcmVzZXQoZGV2LDApOwoKCS8qIDIuIFdlIHVwbG9hZCB0aGUgRlBHQSBmaXJtd2FyZSBpbnRvIHRoZSBFTUkKCSAqIE5vdGU6IGNvbGxlY3QgdXAgdG8gMTAyMyAoeWVzISkgYnl0ZXMgYW5kIHNlbmQgdGhlbSB3aXRoCgkgKiBhIHNpbmdsZSByZXF1ZXN0LiBUaGlzIGlzIF9tdWNoXyBmYXN0ZXIhICovCglkbyB7CgkJaSA9IDA7CgkJYWRkciA9IGdfYml0c3RyZWFtW3Bvc10uYWRkcmVzczsKCgkJLyogaW50ZWwgaGV4IHJlY29yZHMgYXJlIHRlcm1pbmF0ZWQgd2l0aCB0eXBlIDAgZWxlbWVudCAqLwoJCXdoaWxlICgoZ19iaXRzdHJlYW1bcG9zXS50eXBlID09IDApICYmIChpICsgZ19iaXRzdHJlYW1bcG9zXS5sZW5ndGggPCBzaXplb2YoYnVmKSkpIHsKCQkJbWVtY3B5KGJ1ZiArIGksIGdfYml0c3RyZWFtW3Bvc10uZGF0YSwgZ19iaXRzdHJlYW1bcG9zXS5sZW5ndGgpOwoJCQlpICs9IGdfYml0c3RyZWFtW3Bvc10ubGVuZ3RoOwoJCQlwb3MrKzsKCQl9CgkJZXJyID0gZW1pMjZfd3JpdGVtZW1vcnkoZGV2LCBhZGRyLCBidWYsIGksIEFOQ0hPUl9MT0FEX0ZQR0EpOwoJCWlmIChlcnIgPCAwKSB7CgkJCXByaW50ayhLRVJOX0VSUiAiJXMgLSBlcnJvciBsb2FkaW5nIGZpcm13YXJlOiBlcnJvciA9ICVkIiwgX19GVU5DVElPTl9fLCBlcnIpOwoJCQlyZXR1cm4gZXJyOwoJCX0KCX0gd2hpbGUgKGkgPiAwKTsKCgkvKiBBc3NlcnQgcmVzZXQgKHN0b3AgdGhlIENQVSBpbiB0aGUgRU1JKSAqLwoJZXJyID0gZW1pMjZfc2V0X3Jlc2V0KGRldiwxKTsKCWlmIChlcnIgPCAwKSB7CgkJcHJpbnRrKEtFUk5fRVJSICIlcyAtIGVycm9yIGxvYWRpbmcgZmlybXdhcmU6IGVycm9yID0gJWQiLCBfX0ZVTkNUSU9OX18sIGVycik7CgkJcmV0dXJuIGVycjsKCX0KCgkvKiAzLiBXZSBuZWVkIHRvIHB1dCB0aGUgbG9hZGVyIGZvciB0aGUgZmlybXdhcmUgaW50byB0aGUgRVotVVNCIChhZ2Fpbi4uLikgKi8KCWZvciAoaT0wOyBnX0xvYWRlcltpXS50eXBlID09IDA7IGkrKykgewoJCWVyciA9IGVtaTI2X3dyaXRlbWVtb3J5KGRldiwgZ19Mb2FkZXJbaV0uYWRkcmVzcywgZ19Mb2FkZXJbaV0uZGF0YSwgZ19Mb2FkZXJbaV0ubGVuZ3RoLCBBTkNIT1JfTE9BRF9JTlRFUk5BTCk7CgkJaWYgKGVyciA8IDApIHsKCQkJcHJpbnRrKEtFUk5fRVJSICIlcyAtIGVycm9yIGxvYWRpbmcgZmlybXdhcmU6IGVycm9yID0gJWQiLCBfX0ZVTkNUSU9OX18sIGVycik7CgkJCXJldHVybiBlcnI7CgkJfQoJfQoKCS8qIERlLWFzc2VydCByZXNldCAobGV0IHRoZSBDUFUgcnVuKSAqLwoJZXJyID0gZW1pMjZfc2V0X3Jlc2V0KGRldiwwKTsKCWlmIChlcnIgPCAwKSB7CgkJcHJpbnRrKEtFUk5fRVJSICIlcyAtIGVycm9yIGxvYWRpbmcgZmlybXdhcmU6IGVycm9yID0gJWQiLCBfX0ZVTkNUSU9OX18sIGVycik7CgkJcmV0dXJuIGVycjsKCX0KCgkvKiA0LiBXZSBwdXQgdGhlIHBhcnQgb2YgdGhlIGZpcm13YXJlIHRoYXQgbGllcyBpbiB0aGUgZXh0ZXJuYWwgUkFNIGludG8gdGhlIEVaLVVTQiAqLwoJZm9yIChpPTA7IGdfRmlybXdhcmVbaV0udHlwZSA9PSAwOyBpKyspIHsKCQlpZiAoIUlOVEVSTkFMX1JBTShnX0Zpcm13YXJlW2ldLmFkZHJlc3MpKSB7CgkJCWVyciA9IGVtaTI2X3dyaXRlbWVtb3J5KGRldiwgZ19GaXJtd2FyZVtpXS5hZGRyZXNzLCBnX0Zpcm13YXJlW2ldLmRhdGEsIGdfRmlybXdhcmVbaV0ubGVuZ3RoLCBBTkNIT1JfTE9BRF9FWFRFUk5BTCk7CgkJCWlmIChlcnIgPCAwKSB7CgkJCQlwcmludGsoS0VSTl9FUlIgIiVzIC0gZXJyb3IgbG9hZGluZyBmaXJtd2FyZTogZXJyb3IgPSAlZCIsIF9fRlVOQ1RJT05fXywgZXJyKTsKCQkJCXJldHVybiBlcnI7CgkJCX0KCQl9Cgl9CgkKCS8qIEFzc2VydCByZXNldCAoc3RvcCB0aGUgQ1BVIGluIHRoZSBFTUkpICovCgllcnIgPSBlbWkyNl9zZXRfcmVzZXQoZGV2LDEpOwoJaWYgKGVyciA8IDApIHsKCQlwcmludGsoS0VSTl9FUlIgIiVzIC0gZXJyb3IgbG9hZGluZyBmaXJtd2FyZTogZXJyb3IgPSAlZCIsIF9fRlVOQ1RJT05fXywgZXJyKTsKCQlyZXR1cm4gZXJyOwoJfQoKCWZvciAoaT0wOyBnX0Zpcm13YXJlW2ldLnR5cGUgPT0gMDsgaSsrKSB7CgkJaWYgKElOVEVSTkFMX1JBTShnX0Zpcm13YXJlW2ldLmFkZHJlc3MpKSB7CgkJCWVyciA9IGVtaTI2X3dyaXRlbWVtb3J5KGRldiwgZ19GaXJtd2FyZVtpXS5hZGRyZXNzLCBnX0Zpcm13YXJlW2ldLmRhdGEsIGdfRmlybXdhcmVbaV0ubGVuZ3RoLCBBTkNIT1JfTE9BRF9JTlRFUk5BTCk7CgkJCWlmIChlcnIgPCAwKSB7CgkJCQlwcmludGsoS0VSTl9FUlIgIiVzIC0gZXJyb3IgbG9hZGluZyBmaXJtd2FyZTogZXJyb3IgPSAlZCIsIF9fRlVOQ1RJT05fXywgZXJyKTsKCQkJCXJldHVybiBlcnI7CgkJCX0KCQl9Cgl9CgoJLyogRGUtYXNzZXJ0IHJlc2V0IChsZXQgdGhlIENQVSBydW4pICovCgllcnIgPSBlbWkyNl9zZXRfcmVzZXQoZGV2LDApOwoJaWYgKGVyciA8IDApIHsKCQlwcmludGsoS0VSTl9FUlIgIiVzIC0gZXJyb3IgbG9hZGluZyBmaXJtd2FyZTogZXJyb3IgPSAlZCIsIF9fRlVOQ1RJT05fXywgZXJyKTsKCQlyZXR1cm4gZXJyOwoJfQoKCS8qIHJldHVybiAxIHRvIGZhaWwgdGhlIGRyaXZlciBpbmlhbGl6YXRpb24KCSAqIGFuZCBnaXZlIHJlYWwgZHJpdmVyIGNoYW5nZSB0byBsb2FkICovCglyZXR1cm4gMTsKfQoKc3RhdGljIF9fZGV2aW5pdGRhdGEgc3RydWN0IHVzYl9kZXZpY2VfaWQgaWRfdGFibGUgW10gPSB7Cgl7IFVTQl9ERVZJQ0UoRU1JMjZfVkVORE9SX0lELCBFTUkyNl9QUk9EVUNUX0lEKSB9LAoJeyB9ICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgLyogVGVybWluYXRpbmcgZW50cnkgKi8KfTsKCk1PRFVMRV9ERVZJQ0VfVEFCTEUgKHVzYiwgaWRfdGFibGUpOwoKc3RhdGljIHZvaWQgKiBlbWkyNl9wcm9iZShzdHJ1Y3QgdXNiX2RldmljZSAqZGV2LCB1bnNpZ25lZCBpbnQgaWZfbnVtLCBjb25zdCBzdHJ1Y3QgdXNiX2RldmljZV9pZCAqaWQpCnsKCXByaW50ayhLRVJOX0lORk8gIiVzIHN0YXJ0IiwgX19GVU5DVElPTl9fKTsgCgkKCWlmKChkZXYtPmRlc2NyaXB0b3IuaWRWZW5kb3IgPT0gRU1JMjZfVkVORE9SX0lEKSAmJiAoZGV2LT5kZXNjcmlwdG9yLmlkUHJvZHVjdCA9PSBFTUkyNl9QUk9EVUNUX0lEKSkgewoJCWVtaTI2X2xvYWRfZmlybXdhcmUoZGV2KTsKCX0KCQoJLyogZG8gbm90IHJldHVybiB0aGUgZHJpdmVyIGNvbnRleHQsIGxldCByZWFsIGF1ZGlvIGRyaXZlciBkbyB0aGF0ICovCglyZXR1cm4gMDsKfQoKc3RhdGljIHZvaWQgZW1pMjZfZGlzY29ubmVjdChzdHJ1Y3QgdXNiX2RldmljZSAqZGV2LCB2b2lkICpkcnZfY29udGV4dCkKewp9CgpzdHJ1Y3QgdXNiX2RyaXZlciBlbWkyNl9kcml2ZXIgPSB7Cm5hbWU6CQkJImVtaTI2IC0gZmlybXdhcmUgbG9hZGVyIiwKcHJvYmU6CQkJZW1pMjZfcHJvYmUsCmRpc2Nvbm5lY3Q6CQllbWkyNl9kaXNjb25uZWN0LAppZF90YWJsZToJCU5VTEwsCn07CgpzdGF0aWMgaW50IF9faW5pdCBlbWkyNl9pbml0ICh2b2lkKQp7Cgl1c2JfcmVnaXN0ZXIgKCZlbWkyNl9kcml2ZXIpOwoJcmV0dXJuIDA7Cn0KCnN0YXRpYyB2b2lkIF9fZXhpdCBlbWkyNl9leGl0ICh2b2lkKQp7Cgl1c2JfZGVyZWdpc3RlciAoJmVtaTI2X2RyaXZlcik7Cn0KCm1vZHVsZV9pbml0KGVtaTI2X2luaXQpOwptb2R1bGVfZXhpdChlbWkyNl9leGl0KTsKCk1PRFVMRV9BVVRIT1IoInRhcGlvIGxheHN0cvZtIik7Ck1PRFVMRV9ERVNDUklQVElPTigiRW1hZ2ljIEVNSSAyfDYgZmlybXdhcmUgbG9hZGVyLiIpOwpNT0RVTEVfTElDRU5TRSgiR1BMIik7CgovKiB2aTphaTpzeW50YXg9Yzpzdz04OnRzPTg6dHc9ODAKICovCg==