LyoKICogRE9TIGRldmljZXMKICoKICogQ29weXJpZ2h0IDE5OTkgT3ZlIEvldmVuCiAqLwoKI2luY2x1ZGUgPHN0ZGxpYi5oPgojaW5jbHVkZSA8c3RyaW5nLmg+CiNpbmNsdWRlICJ3aW5lL3dpbmJhc2UxNi5oIgojaW5jbHVkZSAibXNkb3MuaCIKI2luY2x1ZGUgIm1pc2NlbXUuaCIKI2luY2x1ZGUgImRvc2V4ZS5oIgojaW5jbHVkZSAiZGVidWd0b29scy5oIgoKI2luY2x1ZGUgInBzaHBhY2sxLmgiCgp0eXBlZGVmIHN0cnVjdCB7CiAgRE9TX0RFVklDRV9IRUFERVIgaGRyOwogIEJZVEUgbGptcDE7CiAgUk1DQlBST0Mgc3RyYXRlZ3k7CiAgQllURSBsam1wMjsKICBSTUNCUFJPQyBpbnRlcnJ1cHQ7Cn0gV0lORURFVjsKCnR5cGVkZWYgc3RydWN0IHsKICBCWVRFIHNpemU7IC8qIGxlbmd0aCBvZiBoZWFkZXIgKyBkYXRhICovCiAgQllURSB1bml0OyAvKiB1bml0IChibG9jayBkZXZpY2VzIG9ubHkpICovCiAgQllURSBjb21tYW5kOwogIFdPUkQgc3RhdHVzOwogIEJZVEUgcmVzZXJ2ZWRbOF07Cn0gUkVRVUVTVF9IRUFERVI7Cgp0eXBlZGVmIHN0cnVjdCB7CiAgUkVRVUVTVF9IRUFERVIgaGRyOwogIEJZVEUgbWVkaWE7IC8qIG1lZGlhIGRlc2NyaXB0b3IgZnJvbSBCUEIgKi8KICBTRUdQVFIgYnVmZmVyOwogIFdPUkQgY291bnQ7IC8qIGJ5dGUvc2VjdG9yIGNvdW50ICovCiAgV09SRCBzZWN0b3I7IC8qIHN0YXJ0aW5nIHNlY3RvciAoYmxvY2sgZGV2aWNlcykgKi8KICBEV09SRCB2b2x1bWU7IC8qIHZvbHVtZSBJRCAoYmxvY2sgZGV2aWNlcykgKi8KfSBSRVFfSU87Cgp0eXBlZGVmIHN0cnVjdCB7CiAgUkVRVUVTVF9IRUFERVIgaGRyOwogIEJZVEUgZGF0YTsKfSBSRVFfU0FGRUlOUFVUOwoKI2luY2x1ZGUgInBvcHBhY2suaCIKCiNkZWZpbmUgUkVRX1NDUkFUQ0ggc2l6ZW9mKFJFUV9JTykKCiNkZWZpbmUgU1lTVEVNX1NUUkFURUdZX05VTCAweDAxMDAKI2RlZmluZSBTWVNURU1fU1RSQVRFR1lfQ09OIDB4MDEwMQoKRFdPUkQgRE9TX0xPTFNlZzsKCiNkZWZpbmUgTk9ORVhUICgoRFdPUkQpLTEpCgojZGVmaW5lIEFUVFJfU1RESU4gICAgIDB4MDAwMQojZGVmaW5lIEFUVFJfU1RET1VUICAgIDB4MDAwMgojZGVmaW5lIEFUVFJfTlVMICAgICAgIDB4MDAwNAojZGVmaW5lIEFUVFJfQ0xPQ0sgICAgIDB4MDAwOAojZGVmaW5lIEFUVFJfRkFTVENPTiAgIDB4MDAxMAojZGVmaW5lIEFUVFJfUkFXICAgICAgIDB4MDAyMAojZGVmaW5lIEFUVFJfTk9URU9GICAgIDB4MDA0MAojZGVmaW5lIEFUVFJfREVWSUNFICAgIDB4MDA4MAojZGVmaW5lIEFUVFJfUkVNT1ZBQkxFIDB4MDgwMAojZGVmaW5lIEFUVFJfTk9OSUJNICAgIDB4MjAwMCAvKiBibG9jayBkZXZpY2VzICovCiNkZWZpbmUgQVRUUl9VTlRJTEJVU1kgMHgyMDAwIC8qIGNoYXIgZGV2aWNlcyAqLwojZGVmaW5lIEFUVFJfSU9DVEwgICAgIDB4NDAwMAojZGVmaW5lIEFUVFJfQ0hBUiAgICAgIDB4ODAwMAoKI2RlZmluZSBDTURfSU5JVCAgICAgICAwCiNkZWZpbmUgQ01EX01FRElBQ0hFQ0sgMSAvKiBibG9jayBkZXZpY2VzICovCiNkZWZpbmUgQ01EX0JVSUxEQlBCICAgMiAvKiBibG9jayBkZXZpY2VzICovCiNkZWZpbmUgQ01EX0lOSU9DVEwgICAgMwojZGVmaW5lIENNRF9JTlBVVCAgICAgIDQgLyogcmVhZCBkYXRhICovCiNkZWZpbmUgQ01EX1NBRkVJTlBVVCAgNSAvKiAibm9uLWRlc3RydWN0aXZlIGlucHV0IG5vIHdhaXQiLCBjaGFyIGRldmljZXMgKi8KI2RlZmluZSBDTURfSU5TVEFUVVMgICA2IC8qIGNoYXIgZGV2aWNlcyAqLwojZGVmaW5lIENNRF9JTkZMVVNIICAgIDcgLyogY2hhciBkZXZpY2VzICovCiNkZWZpbmUgQ01EX09VVFBVVCAgICAgOCAvKiB3cml0ZSBkYXRhICovCiNkZWZpbmUgQ01EX1NBRkVPVVRQVVQgOSAvKiB3cml0ZSBkYXRhIHdpdGggdmVyaWZ5ICovCiNkZWZpbmUgQ01EX09VVFNUQVRVUyAxMCAvKiBjaGFyIGRldmljZXMgKi8KI2RlZmluZSBDTURfT1VURkxVU0ggIDExIC8qIGNoYXIgZGV2aWNlcyAqLwojZGVmaW5lIENNRF9PVVRJT0NUTCAgMTIKI2RlZmluZSBDTURfREVWT1BFTiAgIDEzCiNkZWZpbmUgQ01EX0RFVkNMT1NFICAxNAojZGVmaW5lIENNRF9SRU1PVkFCTEUgMTUgLyogYmxvY2sgZGV2aWNlcyAqLwojZGVmaW5lIENNRF9VTlRJTEJVU1kgMTYgLyogb3V0cHV0IHVudGlsIGJ1c3kgKi8KCiNkZWZpbmUgU1RBVF9NQVNLICAweDAwRkYKI2RlZmluZSBTVEFUX0RPTkUgIDB4MDEwMAojZGVmaW5lIFNUQVRfQlVTWSAgMHgwMjAwCiNkZWZpbmUgU1RBVF9FUlJPUiAweDgwMDAKCiNkZWZpbmUgTEpNUCAweGVhCgojZGVmaW5lIERFVjBfT0ZTIChzaXplb2YoRE9TX0xJU1RPRkxJU1RTKSAtIHNpemVvZihET1NfREVWSUNFX0hFQURFUikpCiNkZWZpbmUgREVWMV9PRlMgKERFVjBfT0ZTICsgc2l6ZW9mKFdJTkVERVYpKQojZGVmaW5lIEFMTERFVl9PRlMgKERFVjFfT0ZTICsgc2l6ZW9mKGRldnMpKQojZGVmaW5lIEFMTF9PRlMgKEFMTERFVl9PRlMgKyBSRVFfU0NSQVRDSCkKCi8qIHByb3RvdHlwZXMgKi8Kc3RhdGljIHZvaWQgV0lOQVBJIG51bF9zdHJhdGVneShDT05URVhUODYqY3R4KTsKc3RhdGljIHZvaWQgV0lOQVBJIG51bF9pbnRlcnJ1cHQoQ09OVEVYVDg2KmN0eCk7CnN0YXRpYyB2b2lkIFdJTkFQSSBjb25fc3RyYXRlZ3koQ09OVEVYVDg2KmN0eCk7CnN0YXRpYyB2b2lkIFdJTkFQSSBjb25faW50ZXJydXB0KENPTlRFWFQ4NipjdHgpOwoKLyogdGhlIGRldmljZSBoZWFkZXJzICovCiNkZWZpbmUgU1RSQVRFR1lfT0ZTIHNpemVvZihET1NfREVWSUNFX0hFQURFUikKI2RlZmluZSBJTlRFUlJVUFRfT0ZTIFNUUkFURUdZX09GUys1CgpzdGF0aWMgRE9TX0RFVklDRV9IRUFERVIgZGV2X251bF9oZHI9ewogTk9ORVhULAogQVRUUl9DSEFSfEFUVFJfTlVMfEFUVFJfREVWSUNFLAogU1RSQVRFR1lfT0ZTLElOVEVSUlVQVF9PRlMsCiAiTlVMICAgICAiCn07CgpzdGF0aWMgV0lORURFViBkZXZzW109ewp7CiB7Tk9ORVhULAogIEFUVFJfQ0hBUnxBVFRSX1NURElOfEFUVFJfU1RET1VUfEFUVFJfRkFTVENPTnxBVFRSX05PVEVPRnxBVFRSX0RFVklDRSwKICBTVFJBVEVHWV9PRlMsSU5URVJSVVBUX09GUywKICAiQ09OICAgICAifSwKIExKTVAsY29uX3N0cmF0ZWd5LAogTEpNUCxjb25faW50ZXJydXB0fQp9OwojZGVmaW5lIG5yX2RldnMgKHNpemVvZihkZXZzKS9zaXplb2YoV0lORURFVikpCgovKiB0aGUgZGV2aWNlIGltcGxlbWVudGF0aW9ucyAqLwpzdGF0aWMgdm9pZCBkb19scmV0KENPTlRFWFQ4NipjdHgpCnsKICBXT1JEICpzdGFjayA9IENUWF9TRUdfT0ZGX1RPX0xJTihjdHgsIFNTX3JlZyhjdHgpLCBFU1BfcmVnKGN0eCkpOwoKICBFSVBfcmVnKGN0eCkgPSAqKHN0YWNrKyspOwogIENTX3JlZyhjdHgpICA9ICooc3RhY2srKyk7CiAgRVNQX3JlZyhjdHgpICs9IDIqc2l6ZW9mKFdPUkQpOwp9CgpzdGF0aWMgdm9pZCBkb19zdHJhdGVneShDT05URVhUODYqY3R4LCBpbnQgaWQsIGludCBleHRyYSkKewogIFJFUVVFU1RfSEVBREVSICpoZHIgPSBDVFhfU0VHX09GRl9UT19MSU4oY3R4LCBFU19yZWcoY3R4KSwgRUJYX3JlZyhjdHgpKTsKICB2b2lkICoqaGRyX3B0ciA9IERPU1ZNX0dldFN5c3RlbURhdGEoaWQpOwoKICBpZiAoIWhkcl9wdHIpIHsKICAgIGhkcl9wdHIgPSBjYWxsb2MoMSxzaXplb2Yodm9pZCAqKStleHRyYSk7CiAgICBET1NWTV9TZXRTeXN0ZW1EYXRhKGlkLCBoZHJfcHRyKTsKICB9CgogICpoZHJfcHRyID0gaGRyOwogIGRvX2xyZXQoY3R4KTsKfQoKc3RhdGljIFJFUVVFU1RfSEVBREVSICogZ2V0X2hkcihpbnQgaWQsIHZvaWQqKmV4dHJhKQp7CiAgdm9pZCAqKmhkcl9wdHIgPSBET1NWTV9HZXRTeXN0ZW1EYXRhKGlkKTsKICBpZiAoZXh0cmEpCiAgICAqZXh0cmEgPSBoZHJfcHRyID8gKHZvaWQqKShoZHJfcHRyKzEpIDogKHZvaWQgKilOVUxMOwogIHJldHVybiBoZHJfcHRyID8gKmhkcl9wdHIgOiAodm9pZCAqKU5VTEw7Cn0KCnN0YXRpYyB2b2lkIFdJTkFQSSBudWxfc3RyYXRlZ3koQ09OVEVYVDg2KmN0eCkKewogIGRvX3N0cmF0ZWd5KGN0eCwgU1lTVEVNX1NUUkFURUdZX05VTCwgMCk7Cn0KCnN0YXRpYyB2b2lkIFdJTkFQSSBudWxfaW50ZXJydXB0KENPTlRFWFQ4NipjdHgpCnsKICBSRVFVRVNUX0hFQURFUiAqaGRyID0gZ2V0X2hkcihTWVNURU1fU1RSQVRFR1lfTlVMLCBOVUxMKTsKICAvKiBlYXQgZXZlcnl0aGluZyBhbmQgcmVjeWNsZSBub3RoaW5nICovCiAgc3dpdGNoIChoZHItPmNvbW1hbmQpIHsKICBjYXNlIENNRF9JTlBVVDoKICAgICgoUkVRX0lPKiloZHIpLT5jb3VudCA9IDA7CiAgICBoZHItPnN0YXR1cyA9IFNUQVRfRE9ORTsKICAgIGJyZWFrOwogIGNhc2UgQ01EX1NBRkVJTlBVVDoKICAgIGhkci0+c3RhdHVzID0gU1RBVF9ET05FfFNUQVRfQlVTWTsKICAgIGJyZWFrOwogIGRlZmF1bHQ6CiAgICBoZHItPnN0YXR1cyA9IFNUQVRfRE9ORTsKICB9CiAgZG9fbHJldChjdHgpOwp9CgojZGVmaW5lIENPTl9CVUZGRVIgMTI4CgpzdGF0aWMgdm9pZCBXSU5BUEkgY29uX3N0cmF0ZWd5KENPTlRFWFQ4NipjdHgpCnsKICBkb19zdHJhdGVneShjdHgsIFNZU1RFTV9TVFJBVEVHWV9DT04sIHNpemVvZihpbnQpKTsKfQoKc3RhdGljIHZvaWQgV0lOQVBJIGNvbl9pbnRlcnJ1cHQoQ09OVEVYVDg2KmN0eCkKewogIGludCAqc2NhbjsKICBSRVFVRVNUX0hFQURFUiAqaGRyID0gZ2V0X2hkcihTWVNURU1fU1RSQVRFR1lfQ09OLCh2b2lkICoqKSZzY2FuKTsKICBCSU9TREFUQSAqYmlvcyA9IERPU01FTV9CaW9zRGF0YSgpOwogIFdPUkQgQ3VyT2ZzID0gYmlvcy0+TmV4dEtiZENoYXJQdHI7CiAgRE9TX0xJU1RPRkxJU1RTICpsb2wgPSBET1NNRU1fTE9MKCk7CiAgQllURSAqbGluZWJ1ZmZlciA9ICgoQllURSopbG9sKSArIEFMTF9PRlM7CiAgQllURSAqY3VyYnVmZmVyID0gKGxvbC0+b2Zmc191bnJlYWRfQ09OKSA/CiAgICAoKChCWVRFKilsb2wpICsgbG9sLT5vZmZzX3VucmVhZF9DT04pIDogKEJZVEUqKU5VTEw7CiAgRE9TX0RFVklDRV9IRUFERVIgKmNvbiA9IChET1NfREVWSUNFX0hFQURFUiopKCgoQllURSopbG9sKSArIERFVjFfT0ZTKTsKICBMUERPU1RBU0sgbHBEb3NUYXNrID0gTVpfQ3VycmVudCgpOwoKICBzd2l0Y2ggKGhkci0+Y29tbWFuZCkgewogIGNhc2UgQ01EX0lOUFVUOgogICAgewogICAgICBSRVFfSU8gKmlvID0gKFJFUV9JTyAqKWhkcjsKICAgICAgV09SRCBjb3VudCA9IGlvLT5jb3VudCwgbGVuID0gMDsKICAgICAgQllURSAqYnVmZmVyID0gQ1RYX1NFR19PRkZfVE9fTElOKGN0eCwKCQkJCQlTRUxFQ1RPUk9GKGlvLT5idWZmZXIpLAoJCQkJCShEV09SRClPRkZTRVRPRihpby0+YnVmZmVyKSk7CgogICAgICBoZHItPnN0YXR1cyA9IFNUQVRfQlVTWTsKICAgICAgLyogZmlyc3QsIGNoZWNrIHdoZXRoZXIgd2UgYWxyZWFkeSBoYXZlIGRhdGEgaW4gbGluZSBidWZmZXIgKi8KICAgICAgaWYgKGN1cmJ1ZmZlcikgewoJLyogeWVwLCBjb3B5IGFzIG11Y2ggYXMgd2UgY2FuICovCglCWVRFIGRhdGEgPSAwOwoJd2hpbGUgKChsZW48Y291bnQpICYmIChkYXRhICE9ICdccicpKSB7CgkgIGRhdGEgPSAqY3VyYnVmZmVyKys7CgkgIGJ1ZmZlcltsZW4rK10gPSBkYXRhOwoJfQoJaWYgKGRhdGEgPT0gJ1xyJykgewoJICAvKiBsaW5lIGJ1ZmZlciBlbXB0aWVkICovCgkgIGxvbC0+b2Zmc191bnJlYWRfQ09OID0gMDsKCSAgY3VyYnVmZmVyID0gTlVMTDsKCSAgLyogaWYgd2UncmUgbm90IGluIHJhdyBtb2RlLCBjYWxsIGl0IGEgZGF5Ki8KCSAgaWYgKCEoY29uLT5hdHRyICYgQVRUUl9SQVcpKSB7CgkgICAgaGRyLT5zdGF0dXMgPSBTVEFUX0RPTkU7CgkgICAgaW8tPmNvdW50ID0gbGVuOwoJICAgIGJyZWFrOwoJICB9Cgl9IGVsc2UgewoJICAvKiBzdGlsbCBzb21lIGRhdGEgbGVmdCAqLwoJICBsb2wtPm9mZnNfdW5yZWFkX0NPTiA9IGN1cmJ1ZmZlciAtIChCWVRFKilsb2w7CgkgIC8qIGJ1dCBidWZmZXIgd2FzIGZpbGxlZCwgd2UncmUgZG9uZSAqLwoJICBoZHItPnN0YXR1cyA9IFNUQVRfRE9ORTsKCSAgaW8tPmNvdW50ID0gbGVuOwoJICBicmVhazsKCX0KICAgICAgfQoKICAgICAgLyogaWYgd2UncmUgaW4gcmF3IG1vZGUsIHdlIGp1c3QgbmVlZCB0byBmaWxsIHRoZSBidWZmZXIgKi8KICAgICAgaWYgKGNvbi0+YXR0ciAmIEFUVFJfUkFXKSB7Cgl3aGlsZSAobGVuPGNvdW50KSB7CgkgIFdPUkQgZGF0YTsKCgkgIC8qIGRvIHdlIGhhdmUgYSB3YWl0aW5nIHNjYW5jb2RlPyAqLwoJICBpZiAoKnNjYW4pIHsKCSAgICAvKiB5ZXMsIHN0b3JlIHNjYW5jb2RlIGluIGJ1ZmZlciAqLwoJICAgIGJ1ZmZlcltsZW4rK10gPSAqc2NhbjsKCSAgICAqc2NhbiA9IDA7CgkgICAgaWYgKGxlbj09Y291bnQpIGJyZWFrOwoJICB9CgoJICAvKiBjaGVjayBmb3IgbmV3IGtleWJvYXJkIGlucHV0ICovCgkgIHdoaWxlIChDdXJPZnMgPT0gYmlvcy0+Rmlyc3RLYmRDaGFyUHRyKSB7CgkgICAgLyogbm8gaW5wdXQgYXZhaWxhYmxlIHlldCwgc28gd2FpdC4uLiAqLwoJICAgIERPU1ZNX1dhaXQoIC0xLCAwICk7CgkgIH0KCSAgLyogcmVhZCBmcm9tIGtleWJvYXJkIHF1ZXVlIChjYWxsIGludDE2PykgKi8KCSAgZGF0YSA9ICgoV09SRCopYmlvcylbQ3VyT2ZzXTsKCSAgQ3VyT2ZzICs9IDI7CgkgIGlmIChDdXJPZnMgPj0gYmlvcy0+S2JkQnVmZmVyRW5kKSBDdXJPZnMgPSBiaW9zLT5LYmRCdWZmZXJTdGFydDsKCSAgYmlvcy0+TmV4dEtiZENoYXJQdHIgPSBDdXJPZnM7CgkgIC8qIGlmIGl0J3MgYW4gZXh0ZW5kZWQga2V5LCBzYXZlIHNjYW5jb2RlICovCgkgIGlmIChMT0JZVEUoZGF0YSkgPT0gMCkgKnNjYW4gPSBISUJZVEUoZGF0YSk7CgkgIC8qIHN0b3JlIEFTQ0lJIGNoYXIgaW4gYnVmZmVyICovCgkgIGJ1ZmZlcltsZW4rK10gPSBMT0JZVEUoZGF0YSk7Cgl9CiAgICAgIH0gZWxzZSB7CgkvKiB3ZSdyZSBub3QgaW4gcmF3IG1vZGUsIHNvIHdlIG5lZWQgdG8gZG8gbGluZSBpbnB1dC4uLiAqLwoJd2hpbGUgKFRSVUUpIHsKCSAgV09SRCBkYXRhOwoJICAvKiBjaGVjayBmb3IgbmV3IGtleWJvYXJkIGlucHV0ICovCgkgIHdoaWxlIChDdXJPZnMgPT0gYmlvcy0+Rmlyc3RLYmRDaGFyUHRyKSB7CgkgICAgLyogbm8gaW5wdXQgYXZhaWxhYmxlIHlldCwgc28gd2FpdC4uLiAqLwoJICAgIERPU1ZNX1dhaXQoIC0xLCAwICk7CgkgIH0KCSAgLyogcmVhZCBmcm9tIGtleWJvYXJkIHF1ZXVlIChjYWxsIGludDE2PykgKi8KCSAgZGF0YSA9ICgoV09SRCopYmlvcylbQ3VyT2ZzXTsKCSAgQ3VyT2ZzICs9IDI7CgkgIGlmIChDdXJPZnMgPj0gYmlvcy0+S2JkQnVmZmVyRW5kKSBDdXJPZnMgPSBiaW9zLT5LYmRCdWZmZXJTdGFydDsKCSAgYmlvcy0+TmV4dEtiZENoYXJQdHIgPSBDdXJPZnM7CgoJICBpZiAoTE9CWVRFKGRhdGEpID09ICdccicpIHsKCSAgICAvKiBpdCdzIHRoZSByZXR1cm4ga2V5LCB3ZSdyZSBkb25lICovCgkgICAgbGluZWJ1ZmZlcltsZW4rK10gPSBMT0JZVEUoZGF0YSk7CgkgICAgYnJlYWs7CgkgIH0KCSAgZWxzZSBpZiAoTE9CWVRFKGRhdGEpID49ICcgJykgewoJICAgIC8qIGEgY2hhcmFjdGVyICovCgkgICAgaWYgKChsZW4rMSk8Q09OX0JVRkZFUikgewoJICAgICAgbGluZWJ1ZmZlcltsZW5dID0gTE9CWVRFKGRhdGEpOwoJICAgICAgV3JpdGVGaWxlKGxwRG9zVGFzay0+aENvbk91dHB1dCwgJmxpbmVidWZmZXJbbGVuKytdLCAxLCBOVUxMLCBOVUxMKTsKCSAgICB9CgkgICAgLyogZWxzZSBiZWVwLCBidXQgSSBkb24ndCBsaWtlIG5vaXNlICovCgkgIH0KCSAgZWxzZSBzd2l0Y2ggKExPQllURShkYXRhKSkgewoJICBjYXNlICdcYic6CgkgICAgaWYgKGxlbj4wKSB7CgkgICAgICBsZW4tLTsKCSAgICAgIFdyaXRlRmlsZShscERvc1Rhc2stPmhDb25PdXRwdXQsICJcYiBcYiIsIDMsIE5VTEwsIE5VTEwpOwoJICAgIH0KCSAgICBicmVhazsKCSAgfQoJfQoJaWYgKGxlbiA+IGNvdW50KSB7CgkgIC8qIHNhdmUgcmVzdCBvZiBsaW5lIGZvciBsYXRlciAqLwoJICBsb2wtPm9mZnNfdW5yZWFkX0NPTiA9IGxpbmVidWZmZXIgLSAoQllURSopbG9sICsgY291bnQ7CgkgIGxlbiA9IGNvdW50OwoJfQoJbWVtY3B5KGJ1ZmZlciwgbGluZWJ1ZmZlciwgbGVuKTsKICAgICAgfQogICAgICBoZHItPnN0YXR1cyA9IFNUQVRfRE9ORTsKICAgICAgaW8tPmNvdW50ID0gbGVuOwogICAgfQogICAgYnJlYWs7CiAgY2FzZSBDTURfU0FGRUlOUFVUOgogICAgaWYgKGN1cmJ1ZmZlcikgewogICAgICAvKiBzb21lIGxpbmUgaW5wdXQgd2FpdGluZyAqLwogICAgICBoZHItPnN0YXR1cyA9IFNUQVRfRE9ORTsKICAgICAgKChSRVFfU0FGRUlOUFVUKiloZHIpLT5kYXRhID0gKmN1cmJ1ZmZlcjsKICAgIH0KICAgIGVsc2UgaWYgKGNvbi0+YXR0ciAmIEFUVFJfUkFXKSB7CiAgICAgIGlmIChDdXJPZnMgPT0gYmlvcy0+Rmlyc3RLYmRDaGFyUHRyKSB7CgkvKiBubyBpbnB1dCAqLwoJaGRyLT5zdGF0dXMgPSBTVEFUX0RPTkV8U1RBVF9CVVNZOwogICAgICB9IGVsc2UgewoJLyogc29tZSBrZXlib2FyZCBpbnB1dCB3YWl0aW5nICovCgloZHItPnN0YXR1cyA9IFNUQVRfRE9ORTsKCSgoUkVRX1NBRkVJTlBVVCopaGRyKS0+ZGF0YSA9ICgoQllURSopYmlvcylbQ3VyT2ZzXTsKICAgICAgfQogICAgfSBlbHNlIHsKICAgICAgLyogbm8gbGluZSBpbnB1dCAqLwogICAgICBoZHItPnN0YXR1cyA9IFNUQVRfRE9ORXxTVEFUX0JVU1k7CiAgICB9CiAgICBicmVhazsKICBjYXNlIENNRF9JTlNUQVRVUzoKICAgIGlmIChjdXJidWZmZXIpIHsKICAgICAgLyogd2UgaGF2ZSBkYXRhICovCiAgICAgIGhkci0+c3RhdHVzID0gU1RBVF9ET05FOwogICAgfQogICAgZWxzZSBpZiAoY29uLT5hdHRyICYgQVRUUl9SQVcpIHsKICAgICAgaWYgKEN1ck9mcyA9PSBiaW9zLT5GaXJzdEtiZENoYXJQdHIpIHsKCS8qIG5vIGlucHV0ICovCgloZHItPnN0YXR1cyA9IFNUQVRfRE9ORXxTVEFUX0JVU1k7CiAgICAgIH0gZWxzZSB7CgkvKiBzb21lIGtleWJvYXJkIGlucHV0IHdhaXRpbmcgKi8KCWhkci0+c3RhdHVzID0gU1RBVF9ET05FOwogICAgICB9CiAgICB9IGVsc2UgewogICAgICAvKiBubyBsaW5lIGlucHV0ICovCiAgICAgIGhkci0+c3RhdHVzID0gU1RBVF9ET05FfFNUQVRfQlVTWTsKICAgIH0KCiAgICBicmVhazsKICBjYXNlIENNRF9JTkZMVVNIOgogICAgLyogZmx1c2ggbGluZSBhbmQga2V5Ym9hcmQgcXVldWUgKi8KICAgIGxvbC0+b2Zmc191bnJlYWRfQ09OID0gMDsKICAgIGJpb3MtPk5leHRLYmRDaGFyUHRyID0gYmlvcy0+Rmlyc3RLYmRDaGFyUHRyOwogICAgYnJlYWs7CiAgY2FzZSBDTURfT1VUUFVUOgogIGNhc2UgQ01EX1NBRkVPVVRQVVQ6CiAgICB7CiAgICAgIFJFUV9JTyAqaW8gPSAoUkVRX0lPICopaGRyOwogICAgICBCWVRFICpidWZmZXIgPSBDVFhfU0VHX09GRl9UT19MSU4oY3R4LAoJCQkJCVNFTEVDVE9ST0YoaW8tPmJ1ZmZlciksCgkJCQkJKERXT1JEKU9GRlNFVE9GKGlvLT5idWZmZXIpKTsKICAgICAgRFdPUkQgcmVzdWx0ID0gMDsKICAgICAgV3JpdGVGaWxlKGxwRG9zVGFzay0+aENvbk91dHB1dCwgYnVmZmVyLCBpby0+Y291bnQsICZyZXN1bHQsIE5VTEwpOwogICAgICBpby0+Y291bnQgPSByZXN1bHQ7CiAgICAgIGhkci0+c3RhdHVzID0gU1RBVF9ET05FOwogICAgfQogICAgYnJlYWs7CiAgZGVmYXVsdDoKICAgIGhkci0+c3RhdHVzID0gU1RBVF9ET05FOwogIH0KICBkb19scmV0KGN0eCk7Cn0KCnN0YXRpYyB2b2lkIEluaXRMaXN0T2ZMaXN0cyhET1NfTElTVE9GTElTVFMgKkRPU19MT0wpCnsKLyoKT3V0cHV0IG9mIERPUyA2LjIyOgoKMDEzMzowMDIwICAgICAgICAgICAgICAgICAgICA2QSAxMy0zMyAwMSBDQyAwMCAzMyAwMSA1OSAwMCAgICAgICAgIGouMy4uLjMuWS4KMDEzMzowMDMwICA3MCAwMCAwMCAwMCA3MiAwMiAwMCAwMi02RCAwMCAzMyAwMSAwMCAwMCAyRSAwNSAgIHAuLi5yLi4ubS4zLi4uLi4KMDEzMzowMDQwICAwMCAwMCBGQyAwNCAwMCAwMCAwMyAwOC05MiAyMSAxMSBFMCAwNCA4MCBDNiAwRCAgIC4uLi4uLi4uLiEuLi4uLi4KMDEzMzowMDUwICBDQyAwRCA0RSA1NSA0QyAyMCAyMCAyMC0yMCAyMCAwMCAwMCAwMCAwMCAwMCAwMCAgIC4uTlVMICAgICAuLi4uLi4KMDEzMzowMDYwICAwMCA0QiBCQSBDMSAwNiAxNCAwMCAwMC0wMCAwMyAwMSAwMCAwNCA3MCBDRSBGRiAgIC5LLi4uLi4uLi4uLi5wLi4KMDEzMzowMDcwICBGRiAwMCAwMCAwMCAwMCAwMCAwMCAwMC0wMCAwMSAwMCAwMCAwRCAwNSAwMCAwMCAgIC4uLi4uLi4uLi4uLi4uLi4KMDEzMzowMDgwICAwMCBGRiBGRiAwMCAwMCAwMCAwMCBGRS0wMCAwMCBGOCAwMyBGRiA5RiA3MCAwMiAgIC4uLi4uLi4uLi4uLi4ucC4KMDEzMzowMDkwICBEMCA0NCBDOCBGRCBENCA0NCBDOCBGRC1ENCA0NCBDOCBGRCBEMCA0NCBDOCBGRCAgIC5ELi4uRC4uLkQuLi5ELi4KMDEzMzowMEEwICBEMCA0NCBDOCBGRCBEMCA0NCAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIC5ELi4uRAoqLwogIERPU19MT0wtPkNYX0ludDIxXzVlMDEJCT0gMHgwOwogIERPU19MT0wtPkxSVV9jb3VudF9GQ0JfY2FjaGUJPSAweDA7CiAgRE9TX0xPTC0+TFJVX2NvdW50X0ZDQl9vcGVuCQk9IDB4MDsKICBET1NfTE9MLT5PRU1fZnVuY19oYW5kbGVyCQk9IC0xOyAvKiBub3QgYXZhaWxhYmxlICovCiAgRE9TX0xPTC0+SU5UMjFfb2Zmc2V0CQk9IDB4MDsKICBET1NfTE9MLT5zaGFyaW5nX3JldHJ5X2NvdW50CT0gMzsKICBET1NfTE9MLT5zaGFyaW5nX3JldHJ5X2RlbGF5CT0gMTsKICBET1NfTE9MLT5wdHJfZGlza19idWYJCT0gMHgwOwogIERPU19MT0wtPm9mZnNfdW5yZWFkX0NPTgkJPSAweDA7CiAgRE9TX0xPTC0+c2VnX2ZpcnN0X01DQgkJPSAweDA7CiAgRE9TX0xPTC0+cHRyX2ZpcnN0X0RQQgkJPSAweDA7CiAgRE9TX0xPTC0+cHRyX2ZpcnN0X1N5c0ZpbGVUYWJsZQk9IDB4MDsKICBET1NfTE9MLT5wdHJfY2xvY2tfZGV2X2hkcgkJPSAweDA7CiAgRE9TX0xPTC0+cHRyX0NPTl9kZXZfaGRyCQk9IDB4MDsKICBET1NfTE9MLT5tYXhfYnl0ZV9wZXJfc2VjCQk9IDUxMjsKICBET1NfTE9MLT5wdHJfZGlza19idWZfaW5mbwkJPSAweDA7CiAgRE9TX0xPTC0+cHRyX2FycmF5X0NEUwkJPSAweDA7CiAgRE9TX0xPTC0+cHRyX3N5c19GQ0IJCT0gMHgwOwogIERPU19MT0wtPm5yX3Byb3RlY3RfRkNCCQk9IDB4MDsKICBET1NfTE9MLT5ucl9ibG9ja19kZXYJCT0gMHgwOwogIERPU19MT0wtPm5yX2F2YWlsX2RyaXZlX2xldHRlcnMJPSAyNjsgLyogQSAtIFogKi8KICBET1NfTE9MLT5ucl9kcml2ZXNfSk9JTmVkCQk9IDB4MDsKICBET1NfTE9MLT5wdHJfc3BlY19wcmdfbmFtZXMJCT0gMHgwOwogIERPU19MT0wtPnB0cl9TRVRWRVJfcHJnX2xpc3QJPSAweDA7IC8qIG5vIFNFVFZFUiBsaXN0ICovCiAgRE9TX0xPTC0+RE9TX0hJR0hfQTIwX2Z1bmNfb2Zmcwk9IDB4MDsKICBET1NfTE9MLT5QU1BfbGFzdF9leGVjCQk9IDB4MDsKICBET1NfTE9MLT5CVUZGRVJTX3ZhbAkJPSA5OTsgLyogbWF4aW11bTogOTkgKi8KICBET1NfTE9MLT5CVUZGRVJTX25yX2xvb2thaGVhZAk9IDg7IC8qIG1heGltdW06IDggKi8KICBET1NfTE9MLT5ib290X2RyaXZlCQkJPSAzOyAvKiBDOiAqLwogIERPU19MT0wtPmZsYWdfRFdPUkRfbW92ZXMJCT0gMHgwMTsgLyogaTM4NisgKi8KICBET1NfTE9MLT5zaXplX2V4dGVuZGVkX21lbQkJPSAweGYwMDA7IC8qIHZlcnkgaGlnaCB2YWx1ZSAqLwp9Cgp2b2lkIERPU0RFVl9JbnN0YWxsRE9TRGV2aWNlcyh2b2lkKQp7CiAgV0lORURFViAqZGV2OwogIERPU19ERVZJQ0VfSEVBREVSICpwZGV2OwogIFVJTlQxNiBzZWc7CiAgaW50IG47CiAgV09SRCBvZnMgPSBERVYwX09GUzsKICBET1NfTElTVE9GTElTVFMgKkRPU19MT0w7CgogIC8qIGFsbG9jYXRlIERPUyBkYXRhIHNlZ21lbnQgb3Igc29tZXRoaW5nICovCiAgRE9TX0xPTFNlZyA9IEdsb2JhbERPU0FsbG9jMTYoQUxMX09GUytDT05fQlVGRkVSKTsKICBzZWcgPSBISVdPUkQoRE9TX0xPTFNlZyk7CiAgRE9TX0xPTCA9IFBUUl9TRUdfT0ZGX1RPX0xJTihMT1dPUkQoRE9TX0xPTFNlZyksIDApOwoKICAvKiBpbml0aWFsaXplIHRoZSBtYWduaWZpY2VudCBMaXN0IE9mIExpc3RzICovCiAgSW5pdExpc3RPZkxpc3RzKERPU19MT0wpOwoKICAvKiBjb3B5IGZpcnN0IGRldmljZSAoTlVMKSAqLwogIHBkZXYgPSAmKERPU19MT0wtPk5VTF9kZXYpOwogIG1lbWNweShwZGV2LCZkZXZfbnVsX2hkcixzaXplb2YoRE9TX0RFVklDRV9IRUFERVIpKTsKICBwZGV2LT5zdHJhdGVneSArPSBvZnM7CiAgcGRldi0+aW50ZXJydXB0ICs9IG9mczsKICAvKiBzZXQgdXAgZGV2IHNvIHdlIGNhbiBjb3B5IG92ZXIgdGhlIHJlc3QgKi8KICBkZXYgPSAoV0lORURFViopKCgoY2hhciopRE9TX0xPTCkrb2ZzKTsKICBkZXZbMF0ubGptcDEgPSBMSk1QOwogIGRldlswXS5zdHJhdGVneSA9IChSTUNCUFJPQylEUE1JX0FsbG9jSW50ZXJuYWxSTUNCKG51bF9zdHJhdGVneSk7CiAgZGV2WzBdLmxqbXAyID0gTEpNUDsKICBkZXZbMF0uaW50ZXJydXB0ID0gKFJNQ0JQUk9DKURQTUlfQWxsb2NJbnRlcm5hbFJNQ0IobnVsX2ludGVycnVwdCk7CgogIGRldisrOwogIG9mcyArPSBzaXplb2YoV0lORURFVik7CgogIC8qIGZpcnN0IG9mIHJlbWFpbmluZyBkZXZpY2VzIGlzIENPTiAqLwogIERPU19MT0wtPnB0cl9DT05fZGV2X2hkciA9IFBUUl9TRUdfT0ZGX1RPX1NFR1BUUihzZWcsIG9mcyk7CgogIC8qIGNvcHkgcmVtYWluaW5nIGRldmljZXMgKi8KICBtZW1jcHkoZGV2LCZkZXZzLHNpemVvZihkZXZzKSk7CiAgZm9yIChuPTA7IG48bnJfZGV2czsgbisrKSB7CiAgICBwZGV2LT5uZXh0X2RldiA9IFBUUl9TRUdfT0ZGX1RPX1NFR1BUUihzZWcsIG9mcyk7CiAgICBkZXZbbl0uaGRyLnN0cmF0ZWd5ICs9IG9mczsKICAgIGRldltuXS5oZHIuaW50ZXJydXB0ICs9IG9mczsKICAgIGRldltuXS5zdHJhdGVneSA9IChSTUNCUFJPQylEUE1JX0FsbG9jSW50ZXJuYWxSTUNCKGRldltuXS5zdHJhdGVneSk7CiAgICBkZXZbbl0uaW50ZXJydXB0ID0gKFJNQ0JQUk9DKURQTUlfQWxsb2NJbnRlcm5hbFJNQ0IoZGV2W25dLmludGVycnVwdCk7CiAgICBvZnMgKz0gc2l6ZW9mKFdJTkVERVYpOwogICAgcGRldiA9ICYoZGV2W25dLmhkcik7CiAgfQp9CgpEV09SRCBET1NERVZfQ29uc29sZSh2b2lkKQp7CiAgcmV0dXJuIERPU01FTV9MT0woKS0+cHRyX0NPTl9kZXZfaGRyOwp9CgpEV09SRCBET1NERVZfRmluZENoYXJEZXZpY2UoY2hhcipuYW1lKQp7CiAgU0VHUFRSIGN1cl9wdHIgPSBQVFJfU0VHX09GRl9UT19TRUdQVFIoSElXT1JEKERPU19MT0xTZWcpLAoJCQkJCSBGSUVMRF9PRkZTRVQoRE9TX0xJU1RPRkxJU1RTLE5VTF9kZXYpKTsKICBET1NfREVWSUNFX0hFQURFUiAqY3VyID0gRE9TTUVNX01hcFJlYWxUb0xpbmVhcihjdXJfcHRyKTsKICBjaGFyIGRuYW1lWzhdOwogIGludCBjbnQ7CgogIC8qIGdldCBmaXJzdCA4IGNoYXJhY3RlcnMgKi8KICBzdHJuY3B5KGRuYW1lLG5hbWUsOCk7CiAgLyogaWYgbGVzcyB0aGFuIDggY2hhcmFjdGVycywgcGFkIHdpdGggc3BhY2VzICovCiAgZm9yIChjbnQ9MDsgY250PDg7IGNudCsrKQogICAgaWYgKCFkbmFtZVtjbnRdKSBkbmFtZVtjbnRdPScgJzsKCiAgLyogc2VhcmNoIGZvciBjaGFyIGRldmljZXMgd2l0aCB0aGUgcmlnaHQgbmFtZSAqLwogIHdoaWxlIChjdXIgJiYKCSAoKCEoY3VyLT5hdHRyICYgQVRUUl9DSEFSKSkgfHwKCSAgbWVtY21wKGN1ci0+bmFtZSxkbmFtZSw4KSkpIHsKICAgIGN1cl9wdHIgPSBjdXItPm5leHRfZGV2OwogICAgaWYgKGN1cl9wdHIgPT0gTk9ORVhUKSBjdXI9TlVMTDsKICAgIGVsc2UgY3VyID0gRE9TTUVNX01hcFJlYWxUb0xpbmVhcihjdXJfcHRyKTsKICB9CiAgcmV0dXJuIGN1cl9wdHI7Cn0KCnN0YXRpYyB2b2lkIERPU0RFVl9Eb1JlcSh2b2lkKnJlcSwgRFdPUkQgZGV2KQp7CiAgUkVRVUVTVF9IRUFERVIgKmhkciA9IChSRVFVRVNUX0hFQURFUiAqKXJlcTsKICBET1NfREVWSUNFX0hFQURFUiAqZGhkcjsKICBDT05URVhUODYgY3R4OwogIGNoYXIgKnBoZHI7CgogIGRoZHIgPSBET1NNRU1fTWFwUmVhbFRvTGluZWFyKGRldik7CiAgcGhkciA9ICgoY2hhciopRE9TTUVNX0xPTCgpKSArIEFMTERFVl9PRlM7CgogIC8qIGNvcHkgcmVxdWVzdCB0byByZXF1ZXN0IHNjcmF0Y2ggYXJlYSAqLwogIG1lbWNweShwaGRyLCByZXEsIGhkci0+c2l6ZSk7CgogIC8qIHByZXBhcmUgdG8gY2FsbCBkZXZpY2UgZHJpdmVyICovCiAgbWVtc2V0KCZjdHgsIDAsIHNpemVvZihjdHgpKTsKCiAgLyogRVM6QlggcG9pbnRzIHRvIHJlcXVlc3QgZm9yIHN0cmF0ZWd5IHJvdXRpbmUgKi8KICBFU19yZWcoJmN0eCkgID0gSElXT1JEKERPU19MT0xTZWcpOwogIEVCWF9yZWcoJmN0eCkgPSBBTExERVZfT0ZTOwoKICAvKiBjYWxsIHN0cmF0ZWd5IHJvdXRpbmUgKi8KICBDU19yZWcoJmN0eCkgPSBTRUxFQ1RPUk9GKGRldik7CiAgRUlQX3JlZygmY3R4KSA9IGRoZHItPnN0cmF0ZWd5OwogIERQTUlfQ2FsbFJNUHJvYygmY3R4LCAwLCAwLCAwKTsKCiAgLyogY2FsbCBpbnRlcnJ1cHQgcm91dGluZSAqLwogIENTX3JlZygmY3R4KSA9IFNFTEVDVE9ST0YoZGV2KTsKICBFSVBfcmVnKCZjdHgpID0gZGhkci0+aW50ZXJydXB0OwogIERQTUlfQ2FsbFJNUHJvYygmY3R4LCAwLCAwLCAwKTsKCiAgLyogY29tcGxldGVkLCBjb3B5IHJlcXVlc3QgYmFjayAqLwogIG1lbWNweShyZXEsIHBoZHIsIGhkci0+c2l6ZSk7CgogIGlmIChoZHItPnN0YXR1cyAmIFNUQVRfRVJST1IpIHsKICAgIHN3aXRjaCAoaGRyLT5zdGF0dXMgJiBTVEFUX01BU0spIHsKICAgIGNhc2UgMHgwRjogLyogaW52YWxpZCBkaXNrIGNoYW5nZSAqLwogICAgICAvKiB0aGlzIGVycm9yIHNlZW1zIHRvIGZpdCB0aGUgYmlsbCAqLwogICAgICBTZXRMYXN0RXJyb3IoRVJfTm90U2FtZURldmljZSk7CiAgICAgIGJyZWFrOwogICAgZGVmYXVsdDoKICAgICAgU2V0TGFzdEVycm9yKChoZHItPnN0YXR1cyAmIFNUQVRfTUFTSykgKyAweDEzKTsKICAgICAgYnJlYWs7CiAgICB9CiAgfQp9CgpzdGF0aWMgaW50IERPU0RFVl9JTyh1bnNpZ25lZCBjbWQsIERXT1JEIGRldiwgRFdPUkQgYnVmLCBpbnQgYnVmbGVuKQp7CiAgUkVRX0lPIHJlcTsKCiAgcmVxLmhkci5zaXplPXNpemVvZihyZXEpOwogIHJlcS5oZHIudW5pdD0wOyAvKiBub3QgZGVhbGluZyB3aXRoIGJsb2NrIGRldmljZXMgeWV0ICovCiAgcmVxLmhkci5jb21tYW5kPWNtZDsKICByZXEuaGRyLnN0YXR1cz1TVEFUX0JVU1k7CiAgcmVxLm1lZGlhPTA7IC8qIG5vdCBkZWFsaW5nIHdpdGggYmxvY2sgZGV2aWNlcyB5ZXQgKi8KICByZXEuYnVmZmVyPWJ1ZjsKICByZXEuY291bnQ9YnVmbGVuOwogIHJlcS5zZWN0b3I9MDsgLyogYmxvY2sgZGV2aWNlcyAqLwogIHJlcS52b2x1bWU9MDsgLyogYmxvY2sgZGV2aWNlcyAqLwoKICBET1NERVZfRG9SZXEoJnJlcSwgZGV2KTsKCiAgcmV0dXJuIHJlcS5jb3VudDsKfQoKaW50IERPU0RFVl9QZWVrKERXT1JEIGRldiwgQllURSpkYXRhKQp7CiAgUkVRX1NBRkVJTlBVVCByZXE7CgogIHJlcS5oZHIuc2l6ZT1zaXplb2YocmVxKTsKICByZXEuaGRyLnVuaXQ9MDsgLyogbm90IGRlYWxpbmcgd2l0aCBibG9jayBkZXZpY2VzIHlldCAqLwogIHJlcS5oZHIuY29tbWFuZD1DTURfU0FGRUlOUFVUOwogIHJlcS5oZHIuc3RhdHVzPVNUQVRfQlVTWTsKICByZXEuZGF0YT0wOwoKICBET1NERVZfRG9SZXEoJnJlcSwgZGV2KTsKCiAgaWYgKHJlcS5oZHIuc3RhdHVzICYgU1RBVF9CVVNZKSByZXR1cm4gMDsKCiAgKmRhdGEgPSByZXEuZGF0YTsKICByZXR1cm4gMTsKfQoKaW50IERPU0RFVl9SZWFkKERXT1JEIGRldiwgRFdPUkQgYnVmLCBpbnQgYnVmbGVuKQp7CiAgcmV0dXJuIERPU0RFVl9JTyhDTURfSU5QVVQsIGRldiwgYnVmLCBidWZsZW4pOwp9CgppbnQgRE9TREVWX1dyaXRlKERXT1JEIGRldiwgRFdPUkQgYnVmLCBpbnQgYnVmbGVuLCBpbnQgdmVyaWZ5KQp7CiAgcmV0dXJuIERPU0RFVl9JTyh2ZXJpZnk/Q01EX1NBRkVPVVRQVVQ6Q01EX09VVFBVVCwgZGV2LCBidWYsIGJ1Zmxlbik7Cn0KCmludCBET1NERVZfSW9jdGxSZWFkKERXT1JEIGRldiwgRFdPUkQgYnVmLCBpbnQgYnVmbGVuKQp7CiAgcmV0dXJuIERPU0RFVl9JTyhDTURfSU5JT0NUTCwgZGV2LCBidWYsIGJ1Zmxlbik7Cn0KCmludCBET1NERVZfSW9jdGxXcml0ZShEV09SRCBkZXYsIERXT1JEIGJ1ZiwgaW50IGJ1ZmxlbikKewogIHJldHVybiBET1NERVZfSU8oQ01EX09VVElPQ1RMLCBkZXYsIGJ1ZiwgYnVmbGVuKTsKfQo=