LyoKICogRE9TIGRldmljZXMKICoKICogQ29weXJpZ2h0IDE5OTkgT3ZlIEvldmVuCiAqLwoKI2luY2x1ZGUgPHN0ZGxpYi5oPgojaW5jbHVkZSA8c3RyaW5nLmg+CiNpbmNsdWRlICJ3aW5lL3dpbmJhc2UxNi5oIgojaW5jbHVkZSAibXNkb3MuaCIKI2luY2x1ZGUgIm1pc2NlbXUuaCIKI2luY2x1ZGUgImRvc2V4ZS5oIgojaW5jbHVkZSAiZGVidWcuaCIKCiNpbmNsdWRlICJwc2hwYWNrMS5oIgoKdHlwZWRlZiBzdHJ1Y3QgewogIERPU19ERVZJQ0VfSEVBREVSIGhkcjsKICBCWVRFIGxqbXAxOwogIFJNQ0JQUk9DIHN0cmF0ZWd5OwogIEJZVEUgbGptcDI7CiAgUk1DQlBST0MgaW50ZXJydXB0Owp9IFdJTkVERVY7Cgp0eXBlZGVmIHN0cnVjdCB7CiAgQllURSBzaXplOyAvKiBsZW5ndGggb2YgaGVhZGVyICsgZGF0YSAqLwogIEJZVEUgdW5pdDsgLyogdW5pdCAoYmxvY2sgZGV2aWNlcyBvbmx5KSAqLwogIEJZVEUgY29tbWFuZDsKICBXT1JEIHN0YXR1czsKICBCWVRFIHJlc2VydmVkWzhdOwp9IFJFUVVFU1RfSEVBREVSOwoKdHlwZWRlZiBzdHJ1Y3QgewogIFJFUVVFU1RfSEVBREVSIGhkcjsKICBCWVRFIG1lZGlhOyAvKiBtZWRpYSBkZXNjcmlwdG9yIGZyb20gQlBCICovCiAgU0VHUFRSIGJ1ZmZlcjsKICBXT1JEIGNvdW50OyAvKiBieXRlL3NlY3RvciBjb3VudCAqLwogIFdPUkQgc2VjdG9yOyAvKiBzdGFydGluZyBzZWN0b3IgKGJsb2NrIGRldmljZXMpICovCiAgRFdPUkQgdm9sdW1lOyAvKiB2b2x1bWUgSUQgKGJsb2NrIGRldmljZXMpICovCn0gUkVRX0lPOwoKdHlwZWRlZiBzdHJ1Y3QgewogIFJFUVVFU1RfSEVBREVSIGhkcjsKICBCWVRFIGRhdGE7Cn0gUkVRX1NBRkVJTlBVVDsKCiNpbmNsdWRlICJwb3BwYWNrLmgiCgojZGVmaW5lIFJFUV9TQ1JBVENIIHNpemVvZihSRVFfSU8pCgojZGVmaW5lIFNZU1RFTV9TVFJBVEVHWV9OVUwgMHgwMTAwCiNkZWZpbmUgU1lTVEVNX1NUUkFURUdZX0NPTiAweDAxMDEKCkRXT1JEIERPU19MT0xTZWc7CgojZGVmaW5lIE5PTkVYVCAoKERXT1JEKS0xKQoKI2RlZmluZSBBVFRSX1NURElOICAgICAweDAwMDEKI2RlZmluZSBBVFRSX1NURE9VVCAgICAweDAwMDIKI2RlZmluZSBBVFRSX05VTCAgICAgICAweDAwMDQKI2RlZmluZSBBVFRSX0NMT0NLICAgICAweDAwMDgKI2RlZmluZSBBVFRSX0ZBU1RDT04gICAweDAwMTAKI2RlZmluZSBBVFRSX1JBVyAgICAgICAweDAwMjAKI2RlZmluZSBBVFRSX05PVEVPRiAgICAweDAwNDAKI2RlZmluZSBBVFRSX0RFVklDRSAgICAweDAwODAKI2RlZmluZSBBVFRSX1JFTU9WQUJMRSAweDA4MDAKI2RlZmluZSBBVFRSX05PTklCTSAgICAweDIwMDAgLyogYmxvY2sgZGV2aWNlcyAqLwojZGVmaW5lIEFUVFJfVU5USUxCVVNZIDB4MjAwMCAvKiBjaGFyIGRldmljZXMgKi8KI2RlZmluZSBBVFRSX0lPQ1RMICAgICAweDQwMDAKI2RlZmluZSBBVFRSX0NIQVIgICAgICAweDgwMDAKCiNkZWZpbmUgQ01EX0lOSVQgICAgICAgMAojZGVmaW5lIENNRF9NRURJQUNIRUNLIDEgLyogYmxvY2sgZGV2aWNlcyAqLwojZGVmaW5lIENNRF9CVUlMREJQQiAgIDIgLyogYmxvY2sgZGV2aWNlcyAqLwojZGVmaW5lIENNRF9JTklPQ1RMICAgIDMKI2RlZmluZSBDTURfSU5QVVQgICAgICA0IC8qIHJlYWQgZGF0YSAqLwojZGVmaW5lIENNRF9TQUZFSU5QVVQgIDUgLyogIm5vbi1kZXN0cnVjdGl2ZSBpbnB1dCBubyB3YWl0IiwgY2hhciBkZXZpY2VzICovCiNkZWZpbmUgQ01EX0lOU1RBVFVTICAgNiAvKiBjaGFyIGRldmljZXMgKi8KI2RlZmluZSBDTURfSU5GTFVTSCAgICA3IC8qIGNoYXIgZGV2aWNlcyAqLwojZGVmaW5lIENNRF9PVVRQVVQgICAgIDggLyogd3JpdGUgZGF0YSAqLwojZGVmaW5lIENNRF9TQUZFT1VUUFVUIDkgLyogd3JpdGUgZGF0YSB3aXRoIHZlcmlmeSAqLwojZGVmaW5lIENNRF9PVVRTVEFUVVMgMTAgLyogY2hhciBkZXZpY2VzICovCiNkZWZpbmUgQ01EX09VVEZMVVNIICAxMSAvKiBjaGFyIGRldmljZXMgKi8KI2RlZmluZSBDTURfT1VUSU9DVEwgIDEyCiNkZWZpbmUgQ01EX0RFVk9QRU4gICAxMwojZGVmaW5lIENNRF9ERVZDTE9TRSAgMTQKI2RlZmluZSBDTURfUkVNT1ZBQkxFIDE1IC8qIGJsb2NrIGRldmljZXMgKi8KI2RlZmluZSBDTURfVU5USUxCVVNZIDE2IC8qIG91dHB1dCB1bnRpbCBidXN5ICovCgojZGVmaW5lIFNUQVRfTUFTSyAgMHgwMEZGCiNkZWZpbmUgU1RBVF9ET05FICAweDAxMDAKI2RlZmluZSBTVEFUX0JVU1kgIDB4MDIwMAojZGVmaW5lIFNUQVRfRVJST1IgMHg4MDAwCgojZGVmaW5lIExKTVAgMHhlYQoKI2RlZmluZSBERVYwX09GUyAoc2l6ZW9mKERPU19MSVNUT0ZMSVNUUykgLSBzaXplb2YoRE9TX0RFVklDRV9IRUFERVIpKQojZGVmaW5lIERFVjFfT0ZTIChERVYwX09GUyArIHNpemVvZihXSU5FREVWKSkKI2RlZmluZSBBTExERVZfT0ZTIChERVYxX09GUyArIHNpemVvZihkZXZzKSkKI2RlZmluZSBBTExfT0ZTIChBTExERVZfT0ZTICsgUkVRX1NDUkFUQ0gpCgovKiBwcm90b3R5cGVzICovCnN0YXRpYyB2b2lkIFdJTkFQSSBudWxfc3RyYXRlZ3koQ09OVEVYVCpjdHgpOwpzdGF0aWMgdm9pZCBXSU5BUEkgbnVsX2ludGVycnVwdChDT05URVhUKmN0eCk7CnN0YXRpYyB2b2lkIFdJTkFQSSBjb25fc3RyYXRlZ3koQ09OVEVYVCpjdHgpOwpzdGF0aWMgdm9pZCBXSU5BUEkgY29uX2ludGVycnVwdChDT05URVhUKmN0eCk7CgovKiB0aGUgZGV2aWNlIGhlYWRlcnMgKi8KI2RlZmluZSBTVFJBVEVHWV9PRlMgc2l6ZW9mKERPU19ERVZJQ0VfSEVBREVSKQojZGVmaW5lIElOVEVSUlVQVF9PRlMgU1RSQVRFR1lfT0ZTKzUKCnN0YXRpYyBET1NfREVWSUNFX0hFQURFUiBkZXZfbnVsX2hkcj17CiBOT05FWFQsCiBBVFRSX0NIQVJ8QVRUUl9OVUx8QVRUUl9ERVZJQ0UsCiBTVFJBVEVHWV9PRlMsSU5URVJSVVBUX09GUywKICJOVUwgICAgICIKfTsKCnN0YXRpYyBXSU5FREVWIGRldnNbXT17CnsKIHtOT05FWFQsCiAgQVRUUl9DSEFSfEFUVFJfU1RESU58QVRUUl9TVERPVVR8QVRUUl9GQVNUQ09OfEFUVFJfTk9URU9GfEFUVFJfREVWSUNFLAogIFNUUkFURUdZX09GUyxJTlRFUlJVUFRfT0ZTLAogICJDT04gICAgICJ9LAogTEpNUCxjb25fc3RyYXRlZ3ksCiBMSk1QLGNvbl9pbnRlcnJ1cHR9Cn07CiNkZWZpbmUgbnJfZGV2cyAoc2l6ZW9mKGRldnMpL3NpemVvZihXSU5FREVWKSkKCi8qIHRoZSBkZXZpY2UgaW1wbGVtZW50YXRpb25zICovCnN0YXRpYyB2b2lkIGRvX2xyZXQoQ09OVEVYVCpjdHgpCnsKICBXT1JEICpzdGFjayA9IENUWF9TRUdfT0ZGX1RPX0xJTihjdHgsIFNTX3JlZyhjdHgpLCBFU1BfcmVnKGN0eCkpOwoKICBJUF9yZWcoY3R4KSA9ICooc3RhY2srKyk7CiAgQ1NfcmVnKGN0eCkgPSAqKHN0YWNrKyspOwogIFNQX3JlZyhjdHgpICs9IDIqc2l6ZW9mKFdPUkQpOwp9CgpzdGF0aWMgdm9pZCBkb19zdHJhdGVneShDT05URVhUKmN0eCwgaW50IGlkLCBpbnQgZXh0cmEpCnsKICBSRVFVRVNUX0hFQURFUiAqaGRyID0gQ1RYX1NFR19PRkZfVE9fTElOKGN0eCwgRVNfcmVnKGN0eCksIEVCWF9yZWcoY3R4KSk7CiAgdm9pZCAqKmhkcl9wdHIgPSBET1NWTV9HZXRTeXN0ZW1EYXRhKGlkKTsKCiAgaWYgKCFoZHJfcHRyKSB7CiAgICBoZHJfcHRyID0gY2FsbG9jKDEsc2l6ZW9mKHZvaWQgKikrZXh0cmEpOwogICAgRE9TVk1fU2V0U3lzdGVtRGF0YShpZCwgaGRyX3B0cik7CiAgfQoKICAqaGRyX3B0ciA9IGhkcjsKICBkb19scmV0KGN0eCk7Cn0KCnN0YXRpYyBSRVFVRVNUX0hFQURFUiAqIGdldF9oZHIoaW50IGlkLCB2b2lkKipleHRyYSkKewogIHZvaWQgKipoZHJfcHRyID0gRE9TVk1fR2V0U3lzdGVtRGF0YShpZCk7CiAgaWYgKGV4dHJhKQogICAgKmV4dHJhID0gaGRyX3B0ciA/ICh2b2lkKikoaGRyX3B0cisxKSA6ICh2b2lkICopTlVMTDsKICByZXR1cm4gaGRyX3B0ciA/ICpoZHJfcHRyIDogKHZvaWQgKilOVUxMOwp9CgpzdGF0aWMgdm9pZCBXSU5BUEkgbnVsX3N0cmF0ZWd5KENPTlRFWFQqY3R4KQp7CiAgZG9fc3RyYXRlZ3koY3R4LCBTWVNURU1fU1RSQVRFR1lfTlVMLCAwKTsKfQoKc3RhdGljIHZvaWQgV0lOQVBJIG51bF9pbnRlcnJ1cHQoQ09OVEVYVCpjdHgpCnsKICBSRVFVRVNUX0hFQURFUiAqaGRyID0gZ2V0X2hkcihTWVNURU1fU1RSQVRFR1lfTlVMLCBOVUxMKTsKICAvKiBlYXQgZXZlcnl0aGluZyBhbmQgcmVjeWNsZSBub3RoaW5nICovCiAgc3dpdGNoIChoZHItPmNvbW1hbmQpIHsKICBjYXNlIENNRF9JTlBVVDoKICAgICgoUkVRX0lPKiloZHIpLT5jb3VudCA9IDA7CiAgICBoZHItPnN0YXR1cyA9IFNUQVRfRE9ORTsKICAgIGJyZWFrOwogIGNhc2UgQ01EX1NBRkVJTlBVVDoKICAgIGhkci0+c3RhdHVzID0gU1RBVF9ET05FfFNUQVRfQlVTWTsKICAgIGJyZWFrOwogIGRlZmF1bHQ6CiAgICBoZHItPnN0YXR1cyA9IFNUQVRfRE9ORTsKICB9CiAgZG9fbHJldChjdHgpOwp9CgojZGVmaW5lIENPTl9CVUZGRVIgMTI4CgpzdGF0aWMgdm9pZCBXSU5BUEkgY29uX3N0cmF0ZWd5KENPTlRFWFQqY3R4KQp7CiAgZG9fc3RyYXRlZ3koY3R4LCBTWVNURU1fU1RSQVRFR1lfQ09OLCBzaXplb2YoaW50KSk7Cn0KCnN0YXRpYyB2b2lkIFdJTkFQSSBjb25faW50ZXJydXB0KENPTlRFWFQqY3R4KQp7CiAgaW50ICpzY2FuOwogIFJFUVVFU1RfSEVBREVSICpoZHIgPSBnZXRfaGRyKFNZU1RFTV9TVFJBVEVHWV9DT04sKHZvaWQgKiopJnNjYW4pOwogIEJJT1NEQVRBICpiaW9zID0gRE9TTUVNX0Jpb3NEYXRhKCk7CiAgV09SRCBDdXJPZnMgPSBiaW9zLT5OZXh0S2JkQ2hhclB0cjsKICBET1NfTElTVE9GTElTVFMgKmxvbCA9IERPU01FTV9MT0woKTsKICBCWVRFICpsaW5lYnVmZmVyID0gKChCWVRFKilsb2wpICsgQUxMX09GUzsKICBCWVRFICpjdXJidWZmZXIgPSAobG9sLT5vZmZzX3VucmVhZF9DT04pID8KICAgICgoKEJZVEUqKWxvbCkgKyBsb2wtPm9mZnNfdW5yZWFkX0NPTikgOiAoQllURSopTlVMTDsKICBET1NfREVWSUNFX0hFQURFUiAqY29uID0gKERPU19ERVZJQ0VfSEVBREVSKikoKChCWVRFKilsb2wpICsgREVWMV9PRlMpOwogIExQRE9TVEFTSyBscERvc1Rhc2sgPSBNWl9DdXJyZW50KCk7CgogIHN3aXRjaCAoaGRyLT5jb21tYW5kKSB7CiAgY2FzZSBDTURfSU5QVVQ6CiAgICB7CiAgICAgIFJFUV9JTyAqaW8gPSAoUkVRX0lPICopaGRyOwogICAgICBXT1JEIGNvdW50ID0gaW8tPmNvdW50LCBsZW4gPSAwOwogICAgICBCWVRFICpidWZmZXIgPSBDVFhfU0VHX09GRl9UT19MSU4oY3R4LAoJCQkJCVNFTEVDVE9ST0YoaW8tPmJ1ZmZlciksCgkJCQkJKERXT1JEKU9GRlNFVE9GKGlvLT5idWZmZXIpKTsKCiAgICAgIGhkci0+c3RhdHVzID0gU1RBVF9CVVNZOwogICAgICAvKiBmaXJzdCwgY2hlY2sgd2hldGhlciB3ZSBhbHJlYWR5IGhhdmUgZGF0YSBpbiBsaW5lIGJ1ZmZlciAqLwogICAgICBpZiAoY3VyYnVmZmVyKSB7CgkvKiB5ZXAsIGNvcHkgYXMgbXVjaCBhcyB3ZSBjYW4gKi8KCUJZVEUgZGF0YSA9IDA7Cgl3aGlsZSAoKGxlbjxjb3VudCkgJiYgKGRhdGEgIT0gJ1xyJykpIHsKCSAgZGF0YSA9ICpjdXJidWZmZXIrKzsKCSAgYnVmZmVyW2xlbisrXSA9IGRhdGE7Cgl9CglpZiAoZGF0YSA9PSAnXHInKSB7CgkgIC8qIGxpbmUgYnVmZmVyIGVtcHRpZWQgKi8KCSAgbG9sLT5vZmZzX3VucmVhZF9DT04gPSAwOwoJICBjdXJidWZmZXIgPSBOVUxMOwoJICAvKiBpZiB3ZSdyZSBub3QgaW4gcmF3IG1vZGUsIGNhbGwgaXQgYSBkYXkqLwoJICBpZiAoIShjb24tPmF0dHIgJiBBVFRSX1JBVykpIHsKCSAgICBoZHItPnN0YXR1cyA9IFNUQVRfRE9ORTsKCSAgICBpby0+Y291bnQgPSBsZW47CgkgICAgYnJlYWs7CgkgIH0KCX0gZWxzZSB7CgkgIC8qIHN0aWxsIHNvbWUgZGF0YSBsZWZ0ICovCgkgIGxvbC0+b2Zmc191bnJlYWRfQ09OID0gY3VyYnVmZmVyIC0gKEJZVEUqKWxvbDsKCSAgLyogYnV0IGJ1ZmZlciB3YXMgZmlsbGVkLCB3ZSdyZSBkb25lICovCgkgIGhkci0+c3RhdHVzID0gU1RBVF9ET05FOwoJICBpby0+Y291bnQgPSBsZW47CgkgIGJyZWFrOwoJfQogICAgICB9CgogICAgICAvKiBpZiB3ZSdyZSBpbiByYXcgbW9kZSwgd2UganVzdCBuZWVkIHRvIGZpbGwgdGhlIGJ1ZmZlciAqLwogICAgICBpZiAoY29uLT5hdHRyICYgQVRUUl9SQVcpIHsKCXdoaWxlIChsZW48Y291bnQpIHsKCSAgV09SRCBkYXRhOwoKCSAgLyogZG8gd2UgaGF2ZSBhIHdhaXRpbmcgc2NhbmNvZGU/ICovCgkgIGlmICgqc2NhbikgewoJICAgIC8qIHllcywgc3RvcmUgc2NhbmNvZGUgaW4gYnVmZmVyICovCgkgICAgYnVmZmVyW2xlbisrXSA9ICpzY2FuOwoJICAgICpzY2FuID0gMDsKCSAgICBpZiAobGVuPT1jb3VudCkgYnJlYWs7CgkgIH0KCgkgIC8qIGNoZWNrIGZvciBuZXcga2V5Ym9hcmQgaW5wdXQgKi8KCSAgd2hpbGUgKEN1ck9mcyA9PSBiaW9zLT5GaXJzdEtiZENoYXJQdHIpIHsKCSAgICAvKiBubyBpbnB1dCBhdmFpbGFibGUgeWV0LCBzbyB3YWl0Li4uICovCgkgICAgRE9TVk1fV2FpdCggLTEsIDAgKTsKCSAgfQoJICAvKiByZWFkIGZyb20ga2V5Ym9hcmQgcXVldWUgKGNhbGwgaW50MTY/KSAqLwoJICBkYXRhID0gKChXT1JEKiliaW9zKVtDdXJPZnNdOwoJICBDdXJPZnMgKz0gMjsKCSAgaWYgKEN1ck9mcyA+PSBiaW9zLT5LYmRCdWZmZXJFbmQpIEN1ck9mcyA9IGJpb3MtPktiZEJ1ZmZlclN0YXJ0OwoJICBiaW9zLT5OZXh0S2JkQ2hhclB0ciA9IEN1ck9mczsKCSAgLyogaWYgaXQncyBhbiBleHRlbmRlZCBrZXksIHNhdmUgc2NhbmNvZGUgKi8KCSAgaWYgKExPQllURShkYXRhKSA9PSAwKSAqc2NhbiA9IEhJQllURShkYXRhKTsKCSAgLyogc3RvcmUgQVNDSUkgY2hhciBpbiBidWZmZXIgKi8KCSAgYnVmZmVyW2xlbisrXSA9IExPQllURShkYXRhKTsKCX0KICAgICAgfSBlbHNlIHsKCS8qIHdlJ3JlIG5vdCBpbiByYXcgbW9kZSwgc28gd2UgbmVlZCB0byBkbyBsaW5lIGlucHV0Li4uICovCgl3aGlsZSAoVFJVRSkgewoJICBXT1JEIGRhdGE7CgkgIC8qIGNoZWNrIGZvciBuZXcga2V5Ym9hcmQgaW5wdXQgKi8KCSAgd2hpbGUgKEN1ck9mcyA9PSBiaW9zLT5GaXJzdEtiZENoYXJQdHIpIHsKCSAgICAvKiBubyBpbnB1dCBhdmFpbGFibGUgeWV0LCBzbyB3YWl0Li4uICovCgkgICAgRE9TVk1fV2FpdCggLTEsIDAgKTsKCSAgfQoJICAvKiByZWFkIGZyb20ga2V5Ym9hcmQgcXVldWUgKGNhbGwgaW50MTY/KSAqLwoJICBkYXRhID0gKChXT1JEKiliaW9zKVtDdXJPZnNdOwoJICBDdXJPZnMgKz0gMjsKCSAgaWYgKEN1ck9mcyA+PSBiaW9zLT5LYmRCdWZmZXJFbmQpIEN1ck9mcyA9IGJpb3MtPktiZEJ1ZmZlclN0YXJ0OwoJICBiaW9zLT5OZXh0S2JkQ2hhclB0ciA9IEN1ck9mczsKCgkgIGlmIChMT0JZVEUoZGF0YSkgPT0gJ1xyJykgewoJICAgIC8qIGl0J3MgdGhlIHJldHVybiBrZXksIHdlJ3JlIGRvbmUgKi8KCSAgICBsaW5lYnVmZmVyW2xlbisrXSA9IExPQllURShkYXRhKTsKCSAgICBicmVhazsKCSAgfQoJICBlbHNlIGlmIChMT0JZVEUoZGF0YSkgPj0gJyAnKSB7CgkgICAgLyogYSBjaGFyYWN0ZXIgKi8KCSAgICBpZiAoKGxlbisxKTxDT05fQlVGRkVSKSB7CgkgICAgICBsaW5lYnVmZmVyW2xlbl0gPSBMT0JZVEUoZGF0YSk7CgkgICAgICBXcml0ZUZpbGUobHBEb3NUYXNrLT5oQ29uT3V0cHV0LCAmbGluZWJ1ZmZlcltsZW4rK10sIDEsIE5VTEwsIE5VTEwpOwoJICAgIH0KCSAgICAvKiBlbHNlIGJlZXAsIGJ1dCBJIGRvbid0IGxpa2Ugbm9pc2UgKi8KCSAgfQoJICBlbHNlIHN3aXRjaCAoTE9CWVRFKGRhdGEpKSB7CgkgIGNhc2UgJ1xiJzoKCSAgICBpZiAobGVuPjApIHsKCSAgICAgIGxlbi0tOwoJICAgICAgV3JpdGVGaWxlKGxwRG9zVGFzay0+aENvbk91dHB1dCwgIlxiIFxiIiwgMywgTlVMTCwgTlVMTCk7CgkgICAgfQoJICAgIGJyZWFrOwoJICB9Cgl9CglpZiAobGVuID4gY291bnQpIHsKCSAgLyogc2F2ZSByZXN0IG9mIGxpbmUgZm9yIGxhdGVyICovCgkgIGxvbC0+b2Zmc191bnJlYWRfQ09OID0gbGluZWJ1ZmZlciAtIChCWVRFKilsb2wgKyBjb3VudDsKCSAgbGVuID0gY291bnQ7Cgl9CgltZW1jcHkoYnVmZmVyLCBsaW5lYnVmZmVyLCBsZW4pOwogICAgICB9CiAgICAgIGhkci0+c3RhdHVzID0gU1RBVF9ET05FOwogICAgICBpby0+Y291bnQgPSBsZW47CiAgICB9CiAgICBicmVhazsKICBjYXNlIENNRF9TQUZFSU5QVVQ6CiAgICBpZiAoY3VyYnVmZmVyKSB7CiAgICAgIC8qIHNvbWUgbGluZSBpbnB1dCB3YWl0aW5nICovCiAgICAgIGhkci0+c3RhdHVzID0gU1RBVF9ET05FOwogICAgICAoKFJFUV9TQUZFSU5QVVQqKWhkciktPmRhdGEgPSAqY3VyYnVmZmVyOwogICAgfQogICAgZWxzZSBpZiAoY29uLT5hdHRyICYgQVRUUl9SQVcpIHsKICAgICAgaWYgKEN1ck9mcyA9PSBiaW9zLT5GaXJzdEtiZENoYXJQdHIpIHsKCS8qIG5vIGlucHV0ICovCgloZHItPnN0YXR1cyA9IFNUQVRfRE9ORXxTVEFUX0JVU1k7CiAgICAgIH0gZWxzZSB7CgkvKiBzb21lIGtleWJvYXJkIGlucHV0IHdhaXRpbmcgKi8KCWhkci0+c3RhdHVzID0gU1RBVF9ET05FOwoJKChSRVFfU0FGRUlOUFVUKiloZHIpLT5kYXRhID0gKChCWVRFKiliaW9zKVtDdXJPZnNdOwogICAgICB9CiAgICB9IGVsc2UgewogICAgICAvKiBubyBsaW5lIGlucHV0ICovCiAgICAgIGhkci0+c3RhdHVzID0gU1RBVF9ET05FfFNUQVRfQlVTWTsKICAgIH0KICAgIGJyZWFrOwogIGNhc2UgQ01EX0lOU1RBVFVTOgogICAgaWYgKGN1cmJ1ZmZlcikgewogICAgICAvKiB3ZSBoYXZlIGRhdGEgKi8KICAgICAgaGRyLT5zdGF0dXMgPSBTVEFUX0RPTkU7CiAgICB9CiAgICBlbHNlIGlmIChjb24tPmF0dHIgJiBBVFRSX1JBVykgewogICAgICBpZiAoQ3VyT2ZzID09IGJpb3MtPkZpcnN0S2JkQ2hhclB0cikgewoJLyogbm8gaW5wdXQgKi8KCWhkci0+c3RhdHVzID0gU1RBVF9ET05FfFNUQVRfQlVTWTsKICAgICAgfSBlbHNlIHsKCS8qIHNvbWUga2V5Ym9hcmQgaW5wdXQgd2FpdGluZyAqLwoJaGRyLT5zdGF0dXMgPSBTVEFUX0RPTkU7CiAgICAgIH0KICAgIH0gZWxzZSB7CiAgICAgIC8qIG5vIGxpbmUgaW5wdXQgKi8KICAgICAgaGRyLT5zdGF0dXMgPSBTVEFUX0RPTkV8U1RBVF9CVVNZOwogICAgfQoKICAgIGJyZWFrOwogIGNhc2UgQ01EX0lORkxVU0g6CiAgICAvKiBmbHVzaCBsaW5lIGFuZCBrZXlib2FyZCBxdWV1ZSAqLwogICAgbG9sLT5vZmZzX3VucmVhZF9DT04gPSAwOwogICAgYmlvcy0+TmV4dEtiZENoYXJQdHIgPSBiaW9zLT5GaXJzdEtiZENoYXJQdHI7CiAgICBicmVhazsKICBjYXNlIENNRF9PVVRQVVQ6CiAgY2FzZSBDTURfU0FGRU9VVFBVVDoKICAgIHsKICAgICAgUkVRX0lPICppbyA9IChSRVFfSU8gKiloZHI7CiAgICAgIEJZVEUgKmJ1ZmZlciA9IENUWF9TRUdfT0ZGX1RPX0xJTihjdHgsCgkJCQkJU0VMRUNUT1JPRihpby0+YnVmZmVyKSwKCQkJCQkoRFdPUkQpT0ZGU0VUT0YoaW8tPmJ1ZmZlcikpOwogICAgICBEV09SRCByZXN1bHQgPSAwOwogICAgICBXcml0ZUZpbGUobHBEb3NUYXNrLT5oQ29uT3V0cHV0LCBidWZmZXIsIGlvLT5jb3VudCwgJnJlc3VsdCwgTlVMTCk7CiAgICAgIGlvLT5jb3VudCA9IHJlc3VsdDsKICAgICAgaGRyLT5zdGF0dXMgPSBTVEFUX0RPTkU7CiAgICB9CiAgICBicmVhazsKICBkZWZhdWx0OgogICAgaGRyLT5zdGF0dXMgPSBTVEFUX0RPTkU7CiAgfQogIGRvX2xyZXQoY3R4KTsKfQoKc3RhdGljIHZvaWQgSW5pdExpc3RPZkxpc3RzKERPU19MSVNUT0ZMSVNUUyAqRE9TX0xPTCkKewovKgpPdXRwdXQgb2YgRE9TIDYuMjI6CgowMTMzOjAwMjAgICAgICAgICAgICAgICAgICAgIDZBIDEzLTMzIDAxIENDIDAwIDMzIDAxIDU5IDAwICAgICAgICAgai4zLi4uMy5ZLgowMTMzOjAwMzAgIDcwIDAwIDAwIDAwIDcyIDAyIDAwIDAyLTZEIDAwIDMzIDAxIDAwIDAwIDJFIDA1ICAgcC4uLnIuLi5tLjMuLi4uLgowMTMzOjAwNDAgIDAwIDAwIEZDIDA0IDAwIDAwIDAzIDA4LTkyIDIxIDExIEUwIDA0IDgwIEM2IDBEICAgLi4uLi4uLi4uIS4uLi4uLgowMTMzOjAwNTAgIENDIDBEIDRFIDU1IDRDIDIwIDIwIDIwLTIwIDIwIDAwIDAwIDAwIDAwIDAwIDAwICAgLi5OVUwgICAgIC4uLi4uLgowMTMzOjAwNjAgIDAwIDRCIEJBIEMxIDA2IDE0IDAwIDAwLTAwIDAzIDAxIDAwIDA0IDcwIENFIEZGICAgLksuLi4uLi4uLi4uLnAuLgowMTMzOjAwNzAgIEZGIDAwIDAwIDAwIDAwIDAwIDAwIDAwLTAwIDAxIDAwIDAwIDBEIDA1IDAwIDAwICAgLi4uLi4uLi4uLi4uLi4uLgowMTMzOjAwODAgIDAwIEZGIEZGIDAwIDAwIDAwIDAwIEZFLTAwIDAwIEY4IDAzIEZGIDlGIDcwIDAyICAgLi4uLi4uLi4uLi4uLi5wLgowMTMzOjAwOTAgIEQwIDQ0IEM4IEZEIEQ0IDQ0IEM4IEZELUQ0IDQ0IEM4IEZEIEQwIDQ0IEM4IEZEICAgLkQuLi5ELi4uRC4uLkQuLgowMTMzOjAwQTAgIEQwIDQ0IEM4IEZEIEQwIDQ0ICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgLkQuLi5ECiovCiAgRE9TX0xPTC0+Q1hfSW50MjFfNWUwMQkJPSAweDA7CiAgRE9TX0xPTC0+TFJVX2NvdW50X0ZDQl9jYWNoZQk9IDB4MDsKICBET1NfTE9MLT5MUlVfY291bnRfRkNCX29wZW4JCT0gMHgwOwogIERPU19MT0wtPk9FTV9mdW5jX2hhbmRsZXIJCT0gLTE7IC8qIG5vdCBhdmFpbGFibGUgKi8KICBET1NfTE9MLT5JTlQyMV9vZmZzZXQJCT0gMHgwOwogIERPU19MT0wtPnNoYXJpbmdfcmV0cnlfY291bnQJPSAzOwogIERPU19MT0wtPnNoYXJpbmdfcmV0cnlfZGVsYXkJPSAxOwogIERPU19MT0wtPnB0cl9kaXNrX2J1ZgkJPSAweDA7CiAgRE9TX0xPTC0+b2Zmc191bnJlYWRfQ09OCQk9IDB4MDsKICBET1NfTE9MLT5zZWdfZmlyc3RfTUNCCQk9IDB4MDsKICBET1NfTE9MLT5wdHJfZmlyc3RfRFBCCQk9IDB4MDsKICBET1NfTE9MLT5wdHJfZmlyc3RfU3lzRmlsZVRhYmxlCT0gMHgwOwogIERPU19MT0wtPnB0cl9jbG9ja19kZXZfaGRyCQk9IDB4MDsKICBET1NfTE9MLT5wdHJfQ09OX2Rldl9oZHIJCT0gMHgwOwogIERPU19MT0wtPm1heF9ieXRlX3Blcl9zZWMJCT0gNTEyOwogIERPU19MT0wtPnB0cl9kaXNrX2J1Zl9pbmZvCQk9IDB4MDsKICBET1NfTE9MLT5wdHJfYXJyYXlfQ0RTCQk9IDB4MDsKICBET1NfTE9MLT5wdHJfc3lzX0ZDQgkJPSAweDA7CiAgRE9TX0xPTC0+bnJfcHJvdGVjdF9GQ0IJCT0gMHgwOwogIERPU19MT0wtPm5yX2Jsb2NrX2RldgkJPSAweDA7CiAgRE9TX0xPTC0+bnJfYXZhaWxfZHJpdmVfbGV0dGVycwk9IDI2OyAvKiBBIC0gWiAqLwogIERPU19MT0wtPm5yX2RyaXZlc19KT0lOZWQJCT0gMHgwOwogIERPU19MT0wtPnB0cl9zcGVjX3ByZ19uYW1lcwkJPSAweDA7CiAgRE9TX0xPTC0+cHRyX1NFVFZFUl9wcmdfbGlzdAk9IDB4MDsgLyogbm8gU0VUVkVSIGxpc3QgKi8KICBET1NfTE9MLT5ET1NfSElHSF9BMjBfZnVuY19vZmZzCT0gMHgwOwogIERPU19MT0wtPlBTUF9sYXN0X2V4ZWMJCT0gMHgwOwogIERPU19MT0wtPkJVRkZFUlNfdmFsCQk9IDk5OyAvKiBtYXhpbXVtOiA5OSAqLwogIERPU19MT0wtPkJVRkZFUlNfbnJfbG9va2FoZWFkCT0gODsgLyogbWF4aW11bTogOCAqLwogIERPU19MT0wtPmJvb3RfZHJpdmUJCQk9IDM7IC8qIEM6ICovCiAgRE9TX0xPTC0+ZmxhZ19EV09SRF9tb3ZlcwkJPSAweDAxOyAvKiBpMzg2KyAqLwogIERPU19MT0wtPnNpemVfZXh0ZW5kZWRfbWVtCQk9IDB4ZjAwMDsgLyogdmVyeSBoaWdoIHZhbHVlICovCn0KCnZvaWQgRE9TREVWX0luc3RhbGxET1NEZXZpY2VzKHZvaWQpCnsKICBXSU5FREVWICpkZXY7CiAgRE9TX0RFVklDRV9IRUFERVIgKnBkZXY7CiAgVUlOVDE2IHNlZzsKICBpbnQgbjsKICBXT1JEIG9mcyA9IERFVjBfT0ZTOwogIERPU19MSVNUT0ZMSVNUUyAqRE9TX0xPTDsKCiAgLyogYWxsb2NhdGUgRE9TIGRhdGEgc2VnbWVudCBvciBzb21ldGhpbmcgKi8KICBET1NfTE9MU2VnID0gR2xvYmFsRE9TQWxsb2MxNihBTExfT0ZTK0NPTl9CVUZGRVIpOwogIHNlZyA9IEhJV09SRChET1NfTE9MU2VnKTsKICBET1NfTE9MID0gUFRSX1NFR19PRkZfVE9fTElOKExPV09SRChET1NfTE9MU2VnKSwgMCk7CgogIC8qIGluaXRpYWxpemUgdGhlIG1hZ25pZmljZW50IExpc3QgT2YgTGlzdHMgKi8KICBJbml0TGlzdE9mTGlzdHMoRE9TX0xPTCk7CgogIC8qIGNvcHkgZmlyc3QgZGV2aWNlIChOVUwpICovCiAgcGRldiA9ICYoRE9TX0xPTC0+TlVMX2Rldik7CiAgbWVtY3B5KHBkZXYsJmRldl9udWxfaGRyLHNpemVvZihET1NfREVWSUNFX0hFQURFUikpOwogIHBkZXYtPnN0cmF0ZWd5ICs9IG9mczsKICBwZGV2LT5pbnRlcnJ1cHQgKz0gb2ZzOwogIC8qIHNldCB1cCBkZXYgc28gd2UgY2FuIGNvcHkgb3ZlciB0aGUgcmVzdCAqLwogIGRldiA9IChXSU5FREVWKikoKChjaGFyKilET1NfTE9MKStvZnMpOwogIGRldlswXS5sam1wMSA9IExKTVA7CiAgZGV2WzBdLnN0cmF0ZWd5ID0gKFJNQ0JQUk9DKURQTUlfQWxsb2NJbnRlcm5hbFJNQ0IobnVsX3N0cmF0ZWd5KTsKICBkZXZbMF0ubGptcDIgPSBMSk1QOwogIGRldlswXS5pbnRlcnJ1cHQgPSAoUk1DQlBST0MpRFBNSV9BbGxvY0ludGVybmFsUk1DQihudWxfaW50ZXJydXB0KTsKCiAgZGV2Kys7CiAgb2ZzICs9IHNpemVvZihXSU5FREVWKTsKCiAgLyogZmlyc3Qgb2YgcmVtYWluaW5nIGRldmljZXMgaXMgQ09OICovCiAgRE9TX0xPTC0+cHRyX0NPTl9kZXZfaGRyID0gUFRSX1NFR19PRkZfVE9fU0VHUFRSKHNlZywgb2ZzKTsKCiAgLyogY29weSByZW1haW5pbmcgZGV2aWNlcyAqLwogIG1lbWNweShkZXYsJmRldnMsc2l6ZW9mKGRldnMpKTsKICBmb3IgKG49MDsgbjxucl9kZXZzOyBuKyspIHsKICAgIHBkZXYtPm5leHRfZGV2ID0gUFRSX1NFR19PRkZfVE9fU0VHUFRSKHNlZywgb2ZzKTsKICAgIGRldltuXS5oZHIuc3RyYXRlZ3kgKz0gb2ZzOwogICAgZGV2W25dLmhkci5pbnRlcnJ1cHQgKz0gb2ZzOwogICAgZGV2W25dLnN0cmF0ZWd5ID0gKFJNQ0JQUk9DKURQTUlfQWxsb2NJbnRlcm5hbFJNQ0IoZGV2W25dLnN0cmF0ZWd5KTsKICAgIGRldltuXS5pbnRlcnJ1cHQgPSAoUk1DQlBST0MpRFBNSV9BbGxvY0ludGVybmFsUk1DQihkZXZbbl0uaW50ZXJydXB0KTsKICAgIG9mcyArPSBzaXplb2YoV0lORURFVik7CiAgICBwZGV2ID0gJihkZXZbbl0uaGRyKTsKICB9Cn0KCkRXT1JEIERPU0RFVl9Db25zb2xlKHZvaWQpCnsKICByZXR1cm4gRE9TTUVNX0xPTCgpLT5wdHJfQ09OX2Rldl9oZHI7Cn0KCkRXT1JEIERPU0RFVl9GaW5kQ2hhckRldmljZShjaGFyKm5hbWUpCnsKICBTRUdQVFIgY3VyX3B0ciA9IFBUUl9TRUdfT0ZGX1RPX1NFR1BUUihISVdPUkQoRE9TX0xPTFNlZyksCgkJCQkJIEZJRUxEX09GRlNFVChET1NfTElTVE9GTElTVFMsTlVMX2RldikpOwogIERPU19ERVZJQ0VfSEVBREVSICpjdXIgPSBET1NNRU1fTWFwUmVhbFRvTGluZWFyKGN1cl9wdHIpOwogIGNoYXIgZG5hbWVbOF07CiAgaW50IGNudDsKCiAgLyogZ2V0IGZpcnN0IDggY2hhcmFjdGVycyAqLwogIHN0cm5jcHkoZG5hbWUsbmFtZSw4KTsKICAvKiBpZiBsZXNzIHRoYW4gOCBjaGFyYWN0ZXJzLCBwYWQgd2l0aCBzcGFjZXMgKi8KICBmb3IgKGNudD0wOyBjbnQ8ODsgY250KyspCiAgICBpZiAoIWRuYW1lW2NudF0pIGRuYW1lW2NudF09JyAnOwoKICAvKiBzZWFyY2ggZm9yIGNoYXIgZGV2aWNlcyB3aXRoIHRoZSByaWdodCBuYW1lICovCiAgd2hpbGUgKGN1ciAmJgoJICgoIShjdXItPmF0dHIgJiBBVFRSX0NIQVIpKSB8fAoJICBtZW1jbXAoY3VyLT5uYW1lLGRuYW1lLDgpKSkgewogICAgY3VyX3B0ciA9IGN1ci0+bmV4dF9kZXY7CiAgICBpZiAoY3VyX3B0ciA9PSBOT05FWFQpIGN1cj1OVUxMOwogICAgZWxzZSBjdXIgPSBET1NNRU1fTWFwUmVhbFRvTGluZWFyKGN1cl9wdHIpOwogIH0KICByZXR1cm4gY3VyX3B0cjsKfQoKc3RhdGljIHZvaWQgRE9TREVWX0RvUmVxKHZvaWQqcmVxLCBEV09SRCBkZXYpCnsKICBSRVFVRVNUX0hFQURFUiAqaGRyID0gKFJFUVVFU1RfSEVBREVSICopcmVxOwogIERPU19ERVZJQ0VfSEVBREVSICpkaGRyOwogIENPTlRFWFQgY3R4OwogIGNoYXIgKnBoZHI7CgogIGRoZHIgPSBET1NNRU1fTWFwUmVhbFRvTGluZWFyKGRldik7CiAgcGhkciA9ICgoY2hhciopRE9TTUVNX0xPTCgpKSArIEFMTERFVl9PRlM7CgogIC8qIGNvcHkgcmVxdWVzdCB0byByZXF1ZXN0IHNjcmF0Y2ggYXJlYSAqLwogIG1lbWNweShwaGRyLCByZXEsIGhkci0+c2l6ZSk7CgogIC8qIHByZXBhcmUgdG8gY2FsbCBkZXZpY2UgZHJpdmVyICovCiAgbWVtc2V0KCZjdHgsIDAsIHNpemVvZihjdHgpKTsKCiAgLyogRVM6QlggcG9pbnRzIHRvIHJlcXVlc3QgZm9yIHN0cmF0ZWd5IHJvdXRpbmUgKi8KICBFU19yZWcoJmN0eCkgPSBISVdPUkQoRE9TX0xPTFNlZyk7CiAgQlhfcmVnKCZjdHgpID0gQUxMREVWX09GUzsKCiAgLyogY2FsbCBzdHJhdGVneSByb3V0aW5lICovCiAgQ1NfcmVnKCZjdHgpID0gU0VMRUNUT1JPRihkZXYpOwogIElQX3JlZygmY3R4KSA9IGRoZHItPnN0cmF0ZWd5OwogIERQTUlfQ2FsbFJNUHJvYygmY3R4LCAwLCAwLCAwKTsKCiAgLyogY2FsbCBpbnRlcnJ1cHQgcm91dGluZSAqLwogIENTX3JlZygmY3R4KSA9IFNFTEVDVE9ST0YoZGV2KTsKICBJUF9yZWcoJmN0eCkgPSBkaGRyLT5pbnRlcnJ1cHQ7CiAgRFBNSV9DYWxsUk1Qcm9jKCZjdHgsIDAsIDAsIDApOwoKICAvKiBjb21wbGV0ZWQsIGNvcHkgcmVxdWVzdCBiYWNrICovCiAgbWVtY3B5KHJlcSwgcGhkciwgaGRyLT5zaXplKTsKCiAgaWYgKGhkci0+c3RhdHVzICYgU1RBVF9FUlJPUikgewogICAgc3dpdGNoIChoZHItPnN0YXR1cyAmIFNUQVRfTUFTSykgewogICAgY2FzZSAweDBGOiAvKiBpbnZhbGlkIGRpc2sgY2hhbmdlICovCiAgICAgIC8qIHRoaXMgZXJyb3Igc2VlbXMgdG8gZml0IHRoZSBiaWxsICovCiAgICAgIFNldExhc3RFcnJvcihFUl9Ob3RTYW1lRGV2aWNlKTsKICAgICAgYnJlYWs7CiAgICBkZWZhdWx0OgogICAgICBTZXRMYXN0RXJyb3IoKGhkci0+c3RhdHVzICYgU1RBVF9NQVNLKSArIDB4MTMpOwogICAgICBicmVhazsKICAgIH0KICB9Cn0KCnN0YXRpYyBpbnQgRE9TREVWX0lPKHVuc2lnbmVkIGNtZCwgRFdPUkQgZGV2LCBEV09SRCBidWYsIGludCBidWZsZW4pCnsKICBSRVFfSU8gcmVxOwoKICByZXEuaGRyLnNpemU9c2l6ZW9mKHJlcSk7CiAgcmVxLmhkci51bml0PTA7IC8qIG5vdCBkZWFsaW5nIHdpdGggYmxvY2sgZGV2aWNlcyB5ZXQgKi8KICByZXEuaGRyLmNvbW1hbmQ9Y21kOwogIHJlcS5oZHIuc3RhdHVzPVNUQVRfQlVTWTsKICByZXEubWVkaWE9MDsgLyogbm90IGRlYWxpbmcgd2l0aCBibG9jayBkZXZpY2VzIHlldCAqLwogIHJlcS5idWZmZXI9YnVmOwogIHJlcS5jb3VudD1idWZsZW47CiAgcmVxLnNlY3Rvcj0wOyAvKiBibG9jayBkZXZpY2VzICovCiAgcmVxLnZvbHVtZT0wOyAvKiBibG9jayBkZXZpY2VzICovCgogIERPU0RFVl9Eb1JlcSgmcmVxLCBkZXYpOwoKICByZXR1cm4gcmVxLmNvdW50Owp9CgppbnQgRE9TREVWX1BlZWsoRFdPUkQgZGV2LCBCWVRFKmRhdGEpCnsKICBSRVFfU0FGRUlOUFVUIHJlcTsKCiAgcmVxLmhkci5zaXplPXNpemVvZihyZXEpOwogIHJlcS5oZHIudW5pdD0wOyAvKiBub3QgZGVhbGluZyB3aXRoIGJsb2NrIGRldmljZXMgeWV0ICovCiAgcmVxLmhkci5jb21tYW5kPUNNRF9TQUZFSU5QVVQ7CiAgcmVxLmhkci5zdGF0dXM9U1RBVF9CVVNZOwogIHJlcS5kYXRhPTA7CgogIERPU0RFVl9Eb1JlcSgmcmVxLCBkZXYpOwoKICBpZiAocmVxLmhkci5zdGF0dXMgJiBTVEFUX0JVU1kpIHJldHVybiAwOwoKICAqZGF0YSA9IHJlcS5kYXRhOwogIHJldHVybiAxOwp9CgppbnQgRE9TREVWX1JlYWQoRFdPUkQgZGV2LCBEV09SRCBidWYsIGludCBidWZsZW4pCnsKICByZXR1cm4gRE9TREVWX0lPKENNRF9JTlBVVCwgZGV2LCBidWYsIGJ1Zmxlbik7Cn0KCmludCBET1NERVZfV3JpdGUoRFdPUkQgZGV2LCBEV09SRCBidWYsIGludCBidWZsZW4sIGludCB2ZXJpZnkpCnsKICByZXR1cm4gRE9TREVWX0lPKHZlcmlmeT9DTURfU0FGRU9VVFBVVDpDTURfT1VUUFVULCBkZXYsIGJ1ZiwgYnVmbGVuKTsKfQoKaW50IERPU0RFVl9Jb2N0bFJlYWQoRFdPUkQgZGV2LCBEV09SRCBidWYsIGludCBidWZsZW4pCnsKICByZXR1cm4gRE9TREVWX0lPKENNRF9JTklPQ1RMLCBkZXYsIGJ1ZiwgYnVmbGVuKTsKfQoKaW50IERPU0RFVl9Jb2N0bFdyaXRlKERXT1JEIGRldiwgRFdPUkQgYnVmLCBpbnQgYnVmbGVuKQp7CiAgcmV0dXJuIERPU0RFVl9JTyhDTURfT1VUSU9DVEwsIGRldiwgYnVmLCBidWZsZW4pOwp9Cg==