LyogCiAqIEVtYWdpYyBFTUkgMnw2IHVzYiBhdWRpbyBpbnRlcmZhY2UgZmlybXdhcmUgbG9hZGVyLgogKiBDb3B5cmlnaHQgKEMpIDIwMDIKICogCVRhcGlvIExheHN0cvZtICh0YXBpby5sYXhzdHJvbUBpcHRpbWUuZmkpCiAqCiAqIFRoaXMgcHJvZ3JhbSBpcyBmcmVlIHNvZnR3YXJlOyB5b3UgY2FuIHJlZGlzdHJpYnV0ZSBpdCBhbmQvb3IgbW9kaWZ5CiAqIGl0IHVuZGVyIHRoZSB0ZXJtcyBvZiB0aGUgR05VIEdlbmVyYWwgUHVibGljIExpY2Vuc2UsIGFzIHB1Ymxpc2hlZCBieQogKiB0aGUgRnJlZSBTb2Z0d2FyZSBGb3VuZGF0aW9uLCB2ZXJzaW9uIDIuCiAqIAogKiBlbWkyNi5jLHYgMS4xMyAyMDAyLzAzLzA4IDEzOjEwOjI2IHRhcGlvIEV4cAogKi8KI2luY2x1ZGUgPGxpbnV4L2tlcm5lbC5oPgojaW5jbHVkZSA8bGludXgvZXJybm8uaD4KI2luY2x1ZGUgPGxpbnV4L3NsYWIuaD4KI2luY2x1ZGUgPGxpbnV4L21vZHVsZS5oPgojaW5jbHVkZSA8bGludXgvaW5pdC5oPgojaW5jbHVkZSA8bGludXgvdXNiLmg+CgojZGVmaW5lIE1BWF9JTlRFTF9IRVhfUkVDT1JEX0xFTkdUSCAxNgp0eXBlZGVmIHN0cnVjdCBfSU5URUxfSEVYX1JFQ09SRAp7CglfX3UzMglsZW5ndGg7CglfX3UzMglhZGRyZXNzOwoJX191MzIJdHlwZTsKCV9fdTgJZGF0YVtNQVhfSU5URUxfSEVYX1JFQ09SRF9MRU5HVEhdOwp9IElOVEVMX0hFWF9SRUNPUkQsICpQSU5URUxfSEVYX1JFQ09SRDsKCi8qIGluY2x1ZGUgZmlybXdhcmUgKHZhcmlhYmxlcykgKi8KI2luY2x1ZGUgImVtaTI2X2Z3LmgiCgojZGVmaW5lIEVNSTI2X1ZFTkRPUl9JRCAJCTB4MDg2YSAgLyogRW1hZ2ljIFNvZnQtdW5kIEhhcmR3YXJlIEdtQkggKi8KI2RlZmluZSBFTUkyNl9QUk9EVUNUX0lECQkweDAxMDAJLyogRU1JIDJ8NiB3aXRob3V0IGZpcm13YXJlICovCgojZGVmaW5lIEFOQ0hPUl9MT0FEX0lOVEVSTkFMCTB4QTAJLyogVmVuZG9yIHNwZWNpZmljIHJlcXVlc3QgY29kZSBmb3IgQW5jaG9yIFVwbG9hZC9Eb3dubG9hZCAoVGhpcyBvbmUgaXMgaW1wbGVtZW50ZWQgaW4gdGhlIGNvcmUpICovCiNkZWZpbmUgQU5DSE9SX0xPQURfRVhURVJOQUwJMHhBMwkvKiBUaGlzIGNvbW1hbmQgaXMgbm90IGltcGxlbWVudGVkIGluIHRoZSBjb3JlLiBSZXF1aXJlcyBmaXJtd2FyZSAqLwojZGVmaW5lIEFOQ0hPUl9MT0FEX0ZQR0EJMHhBNQkvKiBUaGlzIGNvbW1hbmQgaXMgbm90IGltcGxlbWVudGVkIGluIHRoZSBjb3JlLiBSZXF1aXJlcyBmaXJtd2FyZS4gRW1hZ2ljIGV4dGVuc2lvbiAqLwojZGVmaW5lIE1BWF9JTlRFUk5BTF9BRERSRVNTCTB4MUIzRgkvKiBUaGlzIGlzIHRoZSBoaWdoZXN0IGludGVybmFsIFJBTSBhZGRyZXNzIGZvciB0aGUgQU4yMTMxUSAqLwojZGVmaW5lIENQVUNTX1JFRwkJMHg3RjkyICAvKiBFWi1VU0IgQ29udHJvbCBhbmQgU3RhdHVzIFJlZ2lzdGVyLiAgQml0IDAgY29udHJvbHMgODA1MSByZXNldCAqLyAKI2RlZmluZSBJTlRFUk5BTF9SQU0oYWRkcmVzcykgICAoYWRkcmVzcyA8PSBNQVhfSU5URVJOQUxfQUREUkVTUykKCnN0YXRpYyBpbnQgZW1pMjZfd3JpdGVtZW1vcnkoIHN0cnVjdCB1c2JfZGV2aWNlICpkZXYsIGludCBhZGRyZXNzLCB1bnNpZ25lZCBjaGFyICpkYXRhLCBpbnQgbGVuZ3RoLCBfX3U4IGJSZXF1ZXN0KTsKc3RhdGljIGludCBlbWkyNl9zZXRfcmVzZXQoc3RydWN0IHVzYl9kZXZpY2UgKmRldiwgdW5zaWduZWQgY2hhciByZXNldF9iaXQpOwpzdGF0aWMgaW50IGVtaTI2X2xvYWRfZmlybXdhcmUgKHN0cnVjdCB1c2JfZGV2aWNlICpkZXYpOwpzdGF0aWMgaW50IGVtaTI2X3Byb2JlKHN0cnVjdCB1c2JfaW50ZXJmYWNlICppbnRmLCBjb25zdCBzdHJ1Y3QgdXNiX2RldmljZV9pZCAqaWQpOwpzdGF0aWMgdm9pZCBlbWkyNl9kaXNjb25uZWN0KHN0cnVjdCB1c2JfaW50ZXJmYWNlICppbnRmKTsKc3RhdGljIGludCBfX2luaXQgZW1pMjZfaW5pdCAodm9pZCk7CnN0YXRpYyB2b2lkIF9fZXhpdCBlbWkyNl9leGl0ICh2b2lkKTsKCgovKiB0aGFua3MgdG8gZHJpdmVycy91c2Ivc2VyaWFsL2tleXNwYW5fcGRhLmMgY29kZSAqLwpzdGF0aWMgaW50IGVtaTI2X3dyaXRlbWVtb3J5IChzdHJ1Y3QgdXNiX2RldmljZSAqZGV2LCBpbnQgYWRkcmVzcywgdW5zaWduZWQgY2hhciAqZGF0YSwgaW50IGxlbmd0aCwgX191OCByZXF1ZXN0KQp7CglpbnQgcmVzdWx0OwoJdW5zaWduZWQgY2hhciAqYnVmZmVyID0gIGttYWxsb2MgKGxlbmd0aCwgR0ZQX0tFUk5FTCk7CgoJaWYgKCFidWZmZXIpIHsKCQllcnIoImVtaTI2OiBrbWFsbG9jKCVkKSBmYWlsZWQuIiwgbGVuZ3RoKTsKCQlyZXR1cm4gLUVOT01FTTsKCX0KCW1lbWNweSAoYnVmZmVyLCBkYXRhLCBsZW5ndGgpOwoJLyogTm90ZTogdXNiX2NvbnRyb2xfbXNnIHJldHVybnMgbmVnYXRpdmUgdmFsdWUgb24gZXJyb3Igb3IgbGVuZ3RoIG9mIHRoZQoJICogCQkgZGF0YSB0aGF0IHdhcyB3cml0dGVuISAqLwoJcmVzdWx0ID0gdXNiX2NvbnRyb2xfbXNnIChkZXYsIHVzYl9zbmRjdHJscGlwZShkZXYsIDApLCByZXF1ZXN0LCAweDQwLCBhZGRyZXNzLCAwLCBidWZmZXIsIGxlbmd0aCwgMzAwKTsKCWtmcmVlIChidWZmZXIpOwoJcmV0dXJuIHJlc3VsdDsKfQoKLyogdGhhbmtzIHRvIGRyaXZlcnMvdXNiL3NlcmlhbC9rZXlzcGFuX3BkYS5jIGNvZGUgKi8Kc3RhdGljIGludCBlbWkyNl9zZXRfcmVzZXQgKHN0cnVjdCB1c2JfZGV2aWNlICpkZXYsIHVuc2lnbmVkIGNoYXIgcmVzZXRfYml0KQp7CglpbnQgcmVzcG9uc2U7CglpbmZvKCIlcyAtICVkIiwgX19GVU5DVElPTl9fLCByZXNldF9iaXQpOwoJLyogcHJpbnRrKEtFUk5fREVCVUcgIiVzIC0gJWQiLCBfX0ZVTkNUSU9OX18sIHJlc2V0X2JpdCk7ICovCglyZXNwb25zZSA9IGVtaTI2X3dyaXRlbWVtb3J5IChkZXYsIENQVUNTX1JFRywgJnJlc2V0X2JpdCwgMSwgMHhhMCk7CglpZiAocmVzcG9uc2UgPCAwKSB7CgkJZXJyKCJlbWkyNjogc2V0X3Jlc2V0ICglZCkgZmFpbGVkIiwgcmVzZXRfYml0KTsKCX0KCXJldHVybiByZXNwb25zZTsKfQoKI2RlZmluZSBGV19MT0FEX1NJWkUJCTEwMjMKCnN0YXRpYyBpbnQgZW1pMjZfbG9hZF9maXJtd2FyZSAoc3RydWN0IHVzYl9kZXZpY2UgKmRldikKewoJaW50IGVycjsKCWludCBpOwoJaW50IHBvcyA9IDA7CS8qIFBvc2l0aW9uIGluIGhleCByZWNvcmQgKi8KCV9fdTMyIGFkZHI7CS8qIEFkZHJlc3MgdG8gd3JpdGUgKi8KCV9fdTggKmJ1ZjsKCglidWYgPSBrbWFsbG9jKEZXX0xPQURfU0laRSwgR0ZQX0tFUk5FTCk7CglpZiAoIWJ1ZikgewoJCWVyciggIiVzIC0gZXJyb3IgbG9hZGluZyBmaXJtd2FyZTogZXJyb3IgPSAlZCIsIF9fRlVOQ1RJT05fXywgLUVOT01FTSk7CgkJZXJyID0gLUVOT01FTTsKCQlnb3RvIHdyYXBlcnI7Cgl9CgoJLyogQXNzZXJ0IHJlc2V0IChzdG9wIHRoZSBDUFUgaW4gdGhlIEVNSSkgKi8KCWVyciA9IGVtaTI2X3NldF9yZXNldChkZXYsMSk7CglpZiAoZXJyIDwgMCkgewoJCWVyciggIiVzIC0gZXJyb3IgbG9hZGluZyBmaXJtd2FyZTogZXJyb3IgPSAlZCIsIF9fRlVOQ1RJT05fXywgZXJyKTsKCQlnb3RvIHdyYXBlcnI7Cgl9CgoJLyogMS4gV2UgbmVlZCB0byBwdXQgdGhlIGxvYWRlciBmb3IgdGhlIEZQR0EgaW50byB0aGUgRVotVVNCICovCglmb3IgKGk9MDsgZ19Mb2FkZXJbaV0udHlwZSA9PSAwOyBpKyspIHsKCQllcnIgPSBlbWkyNl93cml0ZW1lbW9yeShkZXYsIGdfTG9hZGVyW2ldLmFkZHJlc3MsIGdfTG9hZGVyW2ldLmRhdGEsIGdfTG9hZGVyW2ldLmxlbmd0aCwgQU5DSE9SX0xPQURfSU5URVJOQUwpOwoJCWlmIChlcnIgPCAwKSB7CgkJCWVycigiJXMgLSBlcnJvciBsb2FkaW5nIGZpcm13YXJlOiBlcnJvciA9ICVkIiwgX19GVU5DVElPTl9fLCBlcnIpOwoJCQlnb3RvIHdyYXBlcnI7CgkJfQoJfQoKCS8qIERlLWFzc2VydCByZXNldCAobGV0IHRoZSBDUFUgcnVuKSAqLwoJZXJyID0gZW1pMjZfc2V0X3Jlc2V0KGRldiwwKTsKCgkvKiAyLiBXZSB1cGxvYWQgdGhlIEZQR0EgZmlybXdhcmUgaW50byB0aGUgRU1JCgkgKiBOb3RlOiBjb2xsZWN0IHVwIHRvIDEwMjMgKHllcyEpIGJ5dGVzIGFuZCBzZW5kIHRoZW0gd2l0aAoJICogYSBzaW5nbGUgcmVxdWVzdC4gVGhpcyBpcyBfbXVjaF8gZmFzdGVyISAqLwoJZG8gewoJCWkgPSAwOwoJCWFkZHIgPSBnX2JpdHN0cmVhbVtwb3NdLmFkZHJlc3M7CgoJCS8qIGludGVsIGhleCByZWNvcmRzIGFyZSB0ZXJtaW5hdGVkIHdpdGggdHlwZSAwIGVsZW1lbnQgKi8KCQl3aGlsZSAoKGdfYml0c3RyZWFtW3Bvc10udHlwZSA9PSAwKSAmJiAoaSArIGdfYml0c3RyZWFtW3Bvc10ubGVuZ3RoIDwgRldfTE9BRF9TSVpFKSkgewoJCQltZW1jcHkoYnVmICsgaSwgZ19iaXRzdHJlYW1bcG9zXS5kYXRhLCBnX2JpdHN0cmVhbVtwb3NdLmxlbmd0aCk7CgkJCWkgKz0gZ19iaXRzdHJlYW1bcG9zXS5sZW5ndGg7CgkJCXBvcysrOwoJCX0KCQllcnIgPSBlbWkyNl93cml0ZW1lbW9yeShkZXYsIGFkZHIsIGJ1ZiwgaSwgQU5DSE9SX0xPQURfRlBHQSk7CgkJaWYgKGVyciA8IDApIHsKCQkJZXJyKCIlcyAtIGVycm9yIGxvYWRpbmcgZmlybXdhcmU6IGVycm9yID0gJWQiLCBfX0ZVTkNUSU9OX18sIGVycik7CgkJCWdvdG8gd3JhcGVycjsKCQl9Cgl9IHdoaWxlIChpID4gMCk7CgoJLyogQXNzZXJ0IHJlc2V0IChzdG9wIHRoZSBDUFUgaW4gdGhlIEVNSSkgKi8KCWVyciA9IGVtaTI2X3NldF9yZXNldChkZXYsMSk7CglpZiAoZXJyIDwgMCkgewoJCWVycigiJXMgLSBlcnJvciBsb2FkaW5nIGZpcm13YXJlOiBlcnJvciA9ICVkIiwgX19GVU5DVElPTl9fLCBlcnIpOwoJCWdvdG8gd3JhcGVycjsKCX0KCgkvKiAzLiBXZSBuZWVkIHRvIHB1dCB0aGUgbG9hZGVyIGZvciB0aGUgZmlybXdhcmUgaW50byB0aGUgRVotVVNCIChhZ2Fpbi4uLikgKi8KCWZvciAoaT0wOyBnX0xvYWRlcltpXS50eXBlID09IDA7IGkrKykgewoJCWVyciA9IGVtaTI2X3dyaXRlbWVtb3J5KGRldiwgZ19Mb2FkZXJbaV0uYWRkcmVzcywgZ19Mb2FkZXJbaV0uZGF0YSwgZ19Mb2FkZXJbaV0ubGVuZ3RoLCBBTkNIT1JfTE9BRF9JTlRFUk5BTCk7CgkJaWYgKGVyciA8IDApIHsKCQkJZXJyKCIlcyAtIGVycm9yIGxvYWRpbmcgZmlybXdhcmU6IGVycm9yID0gJWQiLCBfX0ZVTkNUSU9OX18sIGVycik7CgkJCWdvdG8gd3JhcGVycjsKCQl9Cgl9CgoJLyogRGUtYXNzZXJ0IHJlc2V0IChsZXQgdGhlIENQVSBydW4pICovCgllcnIgPSBlbWkyNl9zZXRfcmVzZXQoZGV2LDApOwoJaWYgKGVyciA8IDApIHsKCQllcnIoIiVzIC0gZXJyb3IgbG9hZGluZyBmaXJtd2FyZTogZXJyb3IgPSAlZCIsIF9fRlVOQ1RJT05fXywgZXJyKTsKCQlnb3RvIHdyYXBlcnI7Cgl9CgoJLyogNC4gV2UgcHV0IHRoZSBwYXJ0IG9mIHRoZSBmaXJtd2FyZSB0aGF0IGxpZXMgaW4gdGhlIGV4dGVybmFsIFJBTSBpbnRvIHRoZSBFWi1VU0IgKi8KCWZvciAoaT0wOyBnX0Zpcm13YXJlW2ldLnR5cGUgPT0gMDsgaSsrKSB7CgkJaWYgKCFJTlRFUk5BTF9SQU0oZ19GaXJtd2FyZVtpXS5hZGRyZXNzKSkgewoJCQllcnIgPSBlbWkyNl93cml0ZW1lbW9yeShkZXYsIGdfRmlybXdhcmVbaV0uYWRkcmVzcywgZ19GaXJtd2FyZVtpXS5kYXRhLCBnX0Zpcm13YXJlW2ldLmxlbmd0aCwgQU5DSE9SX0xPQURfRVhURVJOQUwpOwoJCQlpZiAoZXJyIDwgMCkgewoJCQkJZXJyKCIlcyAtIGVycm9yIGxvYWRpbmcgZmlybXdhcmU6IGVycm9yID0gJWQiLCBfX0ZVTkNUSU9OX18sIGVycik7CgkJCQlnb3RvIHdyYXBlcnI7CgkJCX0KCQl9Cgl9CgkKCS8qIEFzc2VydCByZXNldCAoc3RvcCB0aGUgQ1BVIGluIHRoZSBFTUkpICovCgllcnIgPSBlbWkyNl9zZXRfcmVzZXQoZGV2LDEpOwoJaWYgKGVyciA8IDApIHsKCQllcnIoIiVzIC0gZXJyb3IgbG9hZGluZyBmaXJtd2FyZTogZXJyb3IgPSAlZCIsIF9fRlVOQ1RJT05fXywgZXJyKTsKCQlnb3RvIHdyYXBlcnI7Cgl9CgoJZm9yIChpPTA7IGdfRmlybXdhcmVbaV0udHlwZSA9PSAwOyBpKyspIHsKCQlpZiAoSU5URVJOQUxfUkFNKGdfRmlybXdhcmVbaV0uYWRkcmVzcykpIHsKCQkJZXJyID0gZW1pMjZfd3JpdGVtZW1vcnkoZGV2LCBnX0Zpcm13YXJlW2ldLmFkZHJlc3MsIGdfRmlybXdhcmVbaV0uZGF0YSwgZ19GaXJtd2FyZVtpXS5sZW5ndGgsIEFOQ0hPUl9MT0FEX0lOVEVSTkFMKTsKCQkJaWYgKGVyciA8IDApIHsKCQkJCWVycigiJXMgLSBlcnJvciBsb2FkaW5nIGZpcm13YXJlOiBlcnJvciA9ICVkIiwgX19GVU5DVElPTl9fLCBlcnIpOwoJCQkJZ290byB3cmFwZXJyOwoJCQl9CgkJfQoJfQoKCS8qIERlLWFzc2VydCByZXNldCAobGV0IHRoZSBDUFUgcnVuKSAqLwoJZXJyID0gZW1pMjZfc2V0X3Jlc2V0KGRldiwwKTsKCWlmIChlcnIgPCAwKSB7CgkJZXJyKCIlcyAtIGVycm9yIGxvYWRpbmcgZmlybXdhcmU6IGVycm9yID0gJWQiLCBfX0ZVTkNUSU9OX18sIGVycik7CgkJZ290byB3cmFwZXJyOwoJfQoKCS8qIHJldHVybiAxIHRvIGZhaWwgdGhlIGRyaXZlciBpbmlhbGl6YXRpb24KCSAqIGFuZCBnaXZlIHJlYWwgZHJpdmVyIGNoYW5nZSB0byBsb2FkICovCgllcnIgPSAxOwoKd3JhcGVycjoKCWtmcmVlKGJ1Zik7CglyZXR1cm4gZXJyOwp9CgpzdGF0aWMgc3RydWN0IHVzYl9kZXZpY2VfaWQgaWRfdGFibGUgW10gPSB7Cgl7IFVTQl9ERVZJQ0UoRU1JMjZfVkVORE9SX0lELCBFTUkyNl9QUk9EVUNUX0lEKSB9LAoJeyB9ICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgLyogVGVybWluYXRpbmcgZW50cnkgKi8KfTsKCk1PRFVMRV9ERVZJQ0VfVEFCTEUgKHVzYiwgaWRfdGFibGUpOwoKc3RhdGljIGludCBlbWkyNl9wcm9iZShzdHJ1Y3QgdXNiX2ludGVyZmFjZSAqaW50ZiwgY29uc3Qgc3RydWN0IHVzYl9kZXZpY2VfaWQgKmlkKQp7CglzdHJ1Y3QgdXNiX2RldmljZSAqZGV2ID0gaW50ZXJmYWNlX3RvX3VzYmRldihpbnRmKTsKCglpbmZvKCIlcyBzdGFydCIsIF9fRlVOQ1RJT05fXyk7IAoKCWVtaTI2X2xvYWRfZmlybXdhcmUoZGV2KTsKCgkvKiBkbyBub3QgcmV0dXJuIHRoZSBkcml2ZXIgY29udGV4dCwgbGV0IHJlYWwgYXVkaW8gZHJpdmVyIGRvIHRoYXQgKi8KCXJldHVybiAtRUlPOwp9CgpzdGF0aWMgdm9pZCBlbWkyNl9kaXNjb25uZWN0KHN0cnVjdCB1c2JfaW50ZXJmYWNlICppbnRmKQp7Cn0KCnN0YXRpYyBzdHJ1Y3QgdXNiX2RyaXZlciBlbWkyNl9kcml2ZXIgPSB7Cgkub3duZXIJCT0gVEhJU19NT0RVTEUsCgkubmFtZQkJPSAiZW1pMjYgLSBmaXJtd2FyZSBsb2FkZXIiLAoJLnByb2JlCQk9IGVtaTI2X3Byb2JlLAoJLmRpc2Nvbm5lY3QJPSBlbWkyNl9kaXNjb25uZWN0LAoJLmlkX3RhYmxlCT0gaWRfdGFibGUsCn07CgpzdGF0aWMgaW50IF9faW5pdCBlbWkyNl9pbml0ICh2b2lkKQp7CglyZXR1cm4gdXNiX3JlZ2lzdGVyKCZlbWkyNl9kcml2ZXIpOwp9CgpzdGF0aWMgdm9pZCBfX2V4aXQgZW1pMjZfZXhpdCAodm9pZCkKewoJdXNiX2RlcmVnaXN0ZXIgKCZlbWkyNl9kcml2ZXIpOwp9Cgptb2R1bGVfaW5pdChlbWkyNl9pbml0KTsKbW9kdWxlX2V4aXQoZW1pMjZfZXhpdCk7CgpNT0RVTEVfQVVUSE9SKCJ0YXBpbyBsYXhzdHL2bSIpOwpNT0RVTEVfREVTQ1JJUFRJT04oIkVtYWdpYyBFTUkgMnw2IGZpcm13YXJlIGxvYWRlci4iKTsKTU9EVUxFX0xJQ0VOU0UoIkdQTCIpOwoKLyogdmk6YWk6c3ludGF4PWM6c3c9ODp0cz04OnR3PTgwCiAqLwo=