LyoKICogRE9TIGRldmljZXMKICoKICogQ29weXJpZ2h0IDE5OTkgT3ZlIEvldmVuCiAqCiAqIFRoaXMgbGlicmFyeSBpcyBmcmVlIHNvZnR3YXJlOyB5b3UgY2FuIHJlZGlzdHJpYnV0ZSBpdCBhbmQvb3IKICogbW9kaWZ5IGl0IHVuZGVyIHRoZSB0ZXJtcyBvZiB0aGUgR05VIExlc3NlciBHZW5lcmFsIFB1YmxpYwogKiBMaWNlbnNlIGFzIHB1Ymxpc2hlZCBieSB0aGUgRnJlZSBTb2Z0d2FyZSBGb3VuZGF0aW9uOyBlaXRoZXIKICogdmVyc2lvbiAyLjEgb2YgdGhlIExpY2Vuc2UsIG9yIChhdCB5b3VyIG9wdGlvbikgYW55IGxhdGVyIHZlcnNpb24uCiAqCiAqIFRoaXMgbGlicmFyeSBpcyBkaXN0cmlidXRlZCBpbiB0aGUgaG9wZSB0aGF0IGl0IHdpbGwgYmUgdXNlZnVsLAogKiBidXQgV0lUSE9VVCBBTlkgV0FSUkFOVFk7IHdpdGhvdXQgZXZlbiB0aGUgaW1wbGllZCB3YXJyYW50eSBvZgogKiBNRVJDSEFOVEFCSUxJVFkgb3IgRklUTkVTUyBGT1IgQSBQQVJUSUNVTEFSIFBVUlBPU0UuICBTZWUgdGhlIEdOVQogKiBMZXNzZXIgR2VuZXJhbCBQdWJsaWMgTGljZW5zZSBmb3IgbW9yZSBkZXRhaWxzLgogKgogKiBZb3Ugc2hvdWxkIGhhdmUgcmVjZWl2ZWQgYSBjb3B5IG9mIHRoZSBHTlUgTGVzc2VyIEdlbmVyYWwgUHVibGljCiAqIExpY2Vuc2UgYWxvbmcgd2l0aCB0aGlzIGxpYnJhcnk7IGlmIG5vdCwgd3JpdGUgdG8gdGhlIEZyZWUgU29mdHdhcmUKICogRm91bmRhdGlvbiwgSW5jLiwgNTkgVGVtcGxlIFBsYWNlLCBTdWl0ZSAzMzAsIEJvc3RvbiwgTUEgIDAyMTExLTEzMDcgIFVTQQogKi8KCiNpbmNsdWRlIDxzdGRsaWIuaD4KI2luY2x1ZGUgPHN0cmluZy5oPgojaW5jbHVkZSAid2luZS93aW5iYXNlMTYuaCIKI2luY2x1ZGUgIm1zZG9zLmgiCiNpbmNsdWRlICJtaXNjZW11LmgiCiNpbmNsdWRlICJkb3NleGUuaCIKI2luY2x1ZGUgIndpbmUvZGVidWcuaCIKCiNpbmNsdWRlICJwc2hwYWNrMS5oIgoKdHlwZWRlZiBzdHJ1Y3QgewogIEJZVEUgbGptcDE7CiAgUk1DQlBST0Mgc3RyYXRlZ3k7CiAgQllURSBsam1wMjsKICBSTUNCUFJPQyBpbnRlcnJ1cHQ7Cn0gV0lORURFVl9USFVOSzsKCnR5cGVkZWYgc3RydWN0IHsKICBCWVRFIHNpemU7IC8qIGxlbmd0aCBvZiBoZWFkZXIgKyBkYXRhICovCiAgQllURSB1bml0OyAvKiB1bml0IChibG9jayBkZXZpY2VzIG9ubHkpICovCiAgQllURSBjb21tYW5kOwogIFdPUkQgc3RhdHVzOwogIEJZVEUgcmVzZXJ2ZWRbOF07Cn0gUkVRVUVTVF9IRUFERVI7Cgp0eXBlZGVmIHN0cnVjdCB7CiAgUkVRVUVTVF9IRUFERVIgaGRyOwogIEJZVEUgbWVkaWE7IC8qIG1lZGlhIGRlc2NyaXB0b3IgZnJvbSBCUEIgKi8KICBTRUdQVFIgYnVmZmVyOwogIFdPUkQgY291bnQ7IC8qIGJ5dGUvc2VjdG9yIGNvdW50ICovCiAgV09SRCBzZWN0b3I7IC8qIHN0YXJ0aW5nIHNlY3RvciAoYmxvY2sgZGV2aWNlcykgKi8KICBEV09SRCB2b2x1bWU7IC8qIHZvbHVtZSBJRCAoYmxvY2sgZGV2aWNlcykgKi8KfSBSRVFfSU87Cgp0eXBlZGVmIHN0cnVjdCB7CiAgUkVRVUVTVF9IRUFERVIgaGRyOwogIEJZVEUgZGF0YTsKfSBSRVFfU0FGRUlOUFVUOwoKI2luY2x1ZGUgInBvcHBhY2suaCIKCiNkZWZpbmUgQ09OX0JVRkZFUiAxMjgKCmVudW0gc3RyYXRlZ3kgeyBTWVNURU1fU1RSQVRFR1lfTlVMLCBTWVNURU1fU1RSQVRFR1lfQ09OLCBOQl9TWVNURU1fU1RSQVRFR0lFUyB9OwoKc3RhdGljIHZvaWQgKnN0cmF0ZWd5X2RhdGFbTkJfU1lTVEVNX1NUUkFURUdJRVNdOwoKI2RlZmluZSBOT05FWFQgKChEV09SRCktMSkKCiNkZWZpbmUgQVRUUl9TVERJTiAgICAgMHgwMDAxCiNkZWZpbmUgQVRUUl9TVERPVVQgICAgMHgwMDAyCiNkZWZpbmUgQVRUUl9OVUwgICAgICAgMHgwMDA0CiNkZWZpbmUgQVRUUl9DTE9DSyAgICAgMHgwMDA4CiNkZWZpbmUgQVRUUl9GQVNUQ09OICAgMHgwMDEwCiNkZWZpbmUgQVRUUl9SQVcgICAgICAgMHgwMDIwCiNkZWZpbmUgQVRUUl9OT1RFT0YgICAgMHgwMDQwCiNkZWZpbmUgQVRUUl9ERVZJQ0UgICAgMHgwMDgwCiNkZWZpbmUgQVRUUl9SRU1PVkFCTEUgMHgwODAwCiNkZWZpbmUgQVRUUl9OT05JQk0gICAgMHgyMDAwIC8qIGJsb2NrIGRldmljZXMgKi8KI2RlZmluZSBBVFRSX1VOVElMQlVTWSAweDIwMDAgLyogY2hhciBkZXZpY2VzICovCiNkZWZpbmUgQVRUUl9JT0NUTCAgICAgMHg0MDAwCiNkZWZpbmUgQVRUUl9DSEFSICAgICAgMHg4MDAwCgojZGVmaW5lIENNRF9JTklUICAgICAgIDAKI2RlZmluZSBDTURfTUVESUFDSEVDSyAxIC8qIGJsb2NrIGRldmljZXMgKi8KI2RlZmluZSBDTURfQlVJTERCUEIgICAyIC8qIGJsb2NrIGRldmljZXMgKi8KI2RlZmluZSBDTURfSU5JT0NUTCAgICAzCiNkZWZpbmUgQ01EX0lOUFVUICAgICAgNCAvKiByZWFkIGRhdGEgKi8KI2RlZmluZSBDTURfU0FGRUlOUFVUICA1IC8qICJub24tZGVzdHJ1Y3RpdmUgaW5wdXQgbm8gd2FpdCIsIGNoYXIgZGV2aWNlcyAqLwojZGVmaW5lIENNRF9JTlNUQVRVUyAgIDYgLyogY2hhciBkZXZpY2VzICovCiNkZWZpbmUgQ01EX0lORkxVU0ggICAgNyAvKiBjaGFyIGRldmljZXMgKi8KI2RlZmluZSBDTURfT1VUUFVUICAgICA4IC8qIHdyaXRlIGRhdGEgKi8KI2RlZmluZSBDTURfU0FGRU9VVFBVVCA5IC8qIHdyaXRlIGRhdGEgd2l0aCB2ZXJpZnkgKi8KI2RlZmluZSBDTURfT1VUU1RBVFVTIDEwIC8qIGNoYXIgZGV2aWNlcyAqLwojZGVmaW5lIENNRF9PVVRGTFVTSCAgMTEgLyogY2hhciBkZXZpY2VzICovCiNkZWZpbmUgQ01EX09VVElPQ1RMICAxMgojZGVmaW5lIENNRF9ERVZPUEVOICAgMTMKI2RlZmluZSBDTURfREVWQ0xPU0UgIDE0CiNkZWZpbmUgQ01EX1JFTU9WQUJMRSAxNSAvKiBibG9jayBkZXZpY2VzICovCiNkZWZpbmUgQ01EX1VOVElMQlVTWSAxNiAvKiBvdXRwdXQgdW50aWwgYnVzeSAqLwoKI2RlZmluZSBTVEFUX01BU0sgIDB4MDBGRgojZGVmaW5lIFNUQVRfRE9ORSAgMHgwMTAwCiNkZWZpbmUgU1RBVF9CVVNZICAweDAyMDAKI2RlZmluZSBTVEFUX0VSUk9SIDB4ODAwMAoKI2RlZmluZSBMSk1QIDB4ZWEKCgovKiBwcm90b3R5cGVzICovCnN0YXRpYyB2b2lkIFdJTkFQSSBudWxfc3RyYXRlZ3koQ09OVEVYVDg2KmN0eCk7CnN0YXRpYyB2b2lkIFdJTkFQSSBudWxfaW50ZXJydXB0KENPTlRFWFQ4NipjdHgpOwpzdGF0aWMgdm9pZCBXSU5BUEkgY29uX3N0cmF0ZWd5KENPTlRFWFQ4NipjdHgpOwpzdGF0aWMgdm9pZCBXSU5BUEkgY29uX2ludGVycnVwdChDT05URVhUODYqY3R4KTsKCi8qIGRldmljZXMgKi8KdHlwZWRlZiBzdHJ1Y3QKewogICAgY2hhciBuYW1lWzhdOwogICAgV09SRCBhdHRyOwogICAgUk1DQlBST0Mgc3RyYXRlZ3k7CiAgICBSTUNCUFJPQyBpbnRlcnJ1cHQ7Cn0gV0lORURFVjsKCnN0YXRpYyBXSU5FREVWIGRldnNbXSA9CnsKICB7ICJOVUwgICAgICIsCiAgICBBVFRSX0NIQVJ8QVRUUl9OVUx8QVRUUl9ERVZJQ0UsCiAgICBudWxfc3RyYXRlZ3ksIG51bF9pbnRlcnJ1cHQgfSwKCiAgeyAiQ09OICAgICAiLAogICAgQVRUUl9DSEFSfEFUVFJfU1RESU58QVRUUl9TVERPVVR8QVRUUl9GQVNUQ09OfEFUVFJfTk9URU9GfEFUVFJfREVWSUNFLAogICAgY29uX3N0cmF0ZWd5LCBjb25faW50ZXJydXB0IH0KfTsKCiNkZWZpbmUgTlJfREVWUyAoc2l6ZW9mKGRldnMpL3NpemVvZihXSU5FREVWKSkKCi8qIERPUyBkYXRhIHNlZ21lbnQgKi8KdHlwZWRlZiBzdHJ1Y3QKewogICAgRE9TX0xJU1RPRkxJU1RTICAgIGxvbDsKICAgIERPU19ERVZJQ0VfSEVBREVSICBkZXZbTlJfREVWUy0xXTsKICAgIFdJTkVERVZfVEhVTksgICAgICB0aHVua1tOUl9ERVZTXTsKICAgIFJFUV9JTyAgICAgICAgICAgICByZXE7CiAgICBCWVRFICAgICAgICAgICAgICAgYnVmZmVyW0NPTl9CVUZGRVJdOwoKfSBET1NfREFUQVNFRzsKCiNkZWZpbmUgRE9TX0RBVEFTRUdfT0ZGKHh4eCkgRklFTERfT0ZGU0VUKERPU19EQVRBU0VHLCB4eHgpCgpEV09SRCBET1NfTE9MU2VnOwoKc3RydWN0IF9ET1NfTElTVE9GTElTVFMgKiBET1NNRU1fTE9MKCkKewogICAgcmV0dXJuIFBUUl9SRUFMX1RPX0xJTihISVdPUkQoRE9TX0xPTFNlZyksMCk7Cn0KCgovKiB0aGUgZGV2aWNlIGltcGxlbWVudGF0aW9ucyAqLwpzdGF0aWMgdm9pZCBkb19scmV0KENPTlRFWFQ4NipjdHgpCnsKICBXT1JEICpzdGFjayA9IENUWF9TRUdfT0ZGX1RPX0xJTihjdHgsIGN0eC0+U2VnU3MsIGN0eC0+RXNwKTsKCiAgY3R4LT5FaXAgICA9ICooc3RhY2srKyk7CiAgY3R4LT5TZWdDcyA9ICooc3RhY2srKyk7CiAgY3R4LT5Fc3AgICs9IDIqc2l6ZW9mKFdPUkQpOwp9CgpzdGF0aWMgdm9pZCBkb19zdHJhdGVneShDT05URVhUODYqY3R4LCBpbnQgaWQsIGludCBleHRyYSkKewogIFJFUVVFU1RfSEVBREVSICpoZHIgPSBDVFhfU0VHX09GRl9UT19MSU4oY3R4LCBjdHgtPlNlZ0VzLCBjdHgtPkVieCk7CiAgdm9pZCAqKmhkcl9wdHIgPSBzdHJhdGVneV9kYXRhW2lkXTsKCiAgaWYgKCFoZHJfcHRyKSB7CiAgICBoZHJfcHRyID0gY2FsbG9jKDEsc2l6ZW9mKHZvaWQgKikrZXh0cmEpOwogICAgc3RyYXRlZ3lfZGF0YVtpZF0gPSBoZHJfcHRyOwogIH0KICAqaGRyX3B0ciA9IGhkcjsKICBkb19scmV0KGN0eCk7Cn0KCnN0YXRpYyBSRVFVRVNUX0hFQURFUiAqIGdldF9oZHIoaW50IGlkLCB2b2lkKipleHRyYSkKewogIHZvaWQgKipoZHJfcHRyID0gc3RyYXRlZ3lfZGF0YVtpZF07CiAgaWYgKGV4dHJhKQogICAgKmV4dHJhID0gaGRyX3B0ciA/ICh2b2lkKikoaGRyX3B0cisxKSA6ICh2b2lkICopTlVMTDsKICByZXR1cm4gaGRyX3B0ciA/ICpoZHJfcHRyIDogKHZvaWQgKilOVUxMOwp9CgpzdGF0aWMgdm9pZCBXSU5BUEkgbnVsX3N0cmF0ZWd5KENPTlRFWFQ4NipjdHgpCnsKICBkb19zdHJhdGVneShjdHgsIFNZU1RFTV9TVFJBVEVHWV9OVUwsIDApOwp9CgpzdGF0aWMgdm9pZCBXSU5BUEkgbnVsX2ludGVycnVwdChDT05URVhUODYqY3R4KQp7CiAgUkVRVUVTVF9IRUFERVIgKmhkciA9IGdldF9oZHIoU1lTVEVNX1NUUkFURUdZX05VTCwgTlVMTCk7CiAgLyogZWF0IGV2ZXJ5dGhpbmcgYW5kIHJlY3ljbGUgbm90aGluZyAqLwogIHN3aXRjaCAoaGRyLT5jb21tYW5kKSB7CiAgY2FzZSBDTURfSU5QVVQ6CiAgICAoKFJFUV9JTyopaGRyKS0+Y291bnQgPSAwOwogICAgaGRyLT5zdGF0dXMgPSBTVEFUX0RPTkU7CiAgICBicmVhazsKICBjYXNlIENNRF9TQUZFSU5QVVQ6CiAgICBoZHItPnN0YXR1cyA9IFNUQVRfRE9ORXxTVEFUX0JVU1k7CiAgICBicmVhazsKICBkZWZhdWx0OgogICAgaGRyLT5zdGF0dXMgPSBTVEFUX0RPTkU7CiAgfQogIGRvX2xyZXQoY3R4KTsKfQoKc3RhdGljIHZvaWQgV0lOQVBJIGNvbl9zdHJhdGVneShDT05URVhUODYqY3R4KQp7CiAgZG9fc3RyYXRlZ3koY3R4LCBTWVNURU1fU1RSQVRFR1lfQ09OLCBzaXplb2YoaW50KSk7Cn0KCnN0YXRpYyB2b2lkIFdJTkFQSSBjb25faW50ZXJydXB0KENPTlRFWFQ4NipjdHgpCnsKICBpbnQgKnNjYW47CiAgUkVRVUVTVF9IRUFERVIgKmhkciA9IGdldF9oZHIoU1lTVEVNX1NUUkFURUdZX0NPTiwodm9pZCAqKikmc2Nhbik7CiAgQklPU0RBVEEgKmJpb3MgPSBCSU9TX0RBVEE7CiAgV09SRCBDdXJPZnMgPSBiaW9zLT5OZXh0S2JkQ2hhclB0cjsKICBET1NfTElTVE9GTElTVFMgKmxvbCA9IERPU01FTV9MT0woKTsKICBET1NfREFUQVNFRyAqZGF0YXNlZyA9IChET1NfREFUQVNFRyAqKWxvbDsKICBCWVRFICpsaW5lYnVmZmVyID0gZGF0YXNlZy0+YnVmZmVyOwogIEJZVEUgKmN1cmJ1ZmZlciA9IChsb2wtPm9mZnNfdW5yZWFkX0NPTikgPwogICAgKCgoQllURSopZGF0YXNlZykgKyBsb2wtPm9mZnNfdW5yZWFkX0NPTikgOiAoQllURSopTlVMTDsKICBET1NfREVWSUNFX0hFQURFUiAqY29uID0gZGF0YXNlZy0+ZGV2OwoKICBzd2l0Y2ggKGhkci0+Y29tbWFuZCkgewogIGNhc2UgQ01EX0lOUFVUOgogICAgewogICAgICBSRVFfSU8gKmlvID0gKFJFUV9JTyAqKWhkcjsKICAgICAgV09SRCBjb3VudCA9IGlvLT5jb3VudCwgbGVuID0gMDsKICAgICAgQllURSAqYnVmZmVyID0gQ1RYX1NFR19PRkZfVE9fTElOKGN0eCwKCQkJCQlTRUxFQ1RPUk9GKGlvLT5idWZmZXIpLAoJCQkJCShEV09SRClPRkZTRVRPRihpby0+YnVmZmVyKSk7CgogICAgICBoZHItPnN0YXR1cyA9IFNUQVRfQlVTWTsKICAgICAgLyogZmlyc3QsIGNoZWNrIHdoZXRoZXIgd2UgYWxyZWFkeSBoYXZlIGRhdGEgaW4gbGluZSBidWZmZXIgKi8KICAgICAgaWYgKGN1cmJ1ZmZlcikgewoJLyogeWVwLCBjb3B5IGFzIG11Y2ggYXMgd2UgY2FuICovCglCWVRFIGRhdGEgPSAwOwoJd2hpbGUgKChsZW48Y291bnQpICYmIChkYXRhICE9ICdccicpKSB7CgkgIGRhdGEgPSAqY3VyYnVmZmVyKys7CgkgIGJ1ZmZlcltsZW4rK10gPSBkYXRhOwoJfQoJaWYgKGRhdGEgPT0gJ1xyJykgewoJICAvKiBsaW5lIGJ1ZmZlciBlbXB0aWVkICovCgkgIGxvbC0+b2Zmc191bnJlYWRfQ09OID0gMDsKCSAgY3VyYnVmZmVyID0gTlVMTDsKCSAgLyogaWYgd2UncmUgbm90IGluIHJhdyBtb2RlLCBjYWxsIGl0IGEgZGF5ICovCgkgIGlmICghKGNvbi0+YXR0ciAmIEFUVFJfUkFXKSkgewoJICAgIGhkci0+c3RhdHVzID0gU1RBVF9ET05FOwoJICAgIGlvLT5jb3VudCA9IGxlbjsKCSAgICBicmVhazsKCSAgfQoJfSBlbHNlIHsKCSAgLyogc3RpbGwgc29tZSBkYXRhIGxlZnQgKi8KCSAgbG9sLT5vZmZzX3VucmVhZF9DT04gPSBjdXJidWZmZXIgLSAoQllURSopbG9sOwoJICAvKiBidXQgYnVmZmVyIHdhcyBmaWxsZWQsIHdlJ3JlIGRvbmUgKi8KCSAgaGRyLT5zdGF0dXMgPSBTVEFUX0RPTkU7CgkgIGlvLT5jb3VudCA9IGxlbjsKCSAgYnJlYWs7Cgl9CiAgICAgIH0KCiAgICAgIC8qIGlmIHdlJ3JlIGluIHJhdyBtb2RlLCB3ZSBqdXN0IG5lZWQgdG8gZmlsbCB0aGUgYnVmZmVyICovCiAgICAgIGlmIChjb24tPmF0dHIgJiBBVFRSX1JBVykgewoJd2hpbGUgKGxlbjxjb3VudCkgewoJICBXT1JEIGRhdGE7CgoJICAvKiBkbyB3ZSBoYXZlIGEgd2FpdGluZyBzY2FuY29kZT8gKi8KCSAgaWYgKCpzY2FuKSB7CgkgICAgLyogeWVzLCBzdG9yZSBzY2FuY29kZSBpbiBidWZmZXIgKi8KCSAgICBidWZmZXJbbGVuKytdID0gKnNjYW47CgkgICAgKnNjYW4gPSAwOwoJICAgIGlmIChsZW49PWNvdW50KSBicmVhazsKCSAgfQoKCSAgLyogY2hlY2sgZm9yIG5ldyBrZXlib2FyZCBpbnB1dCAqLwoJICB3aGlsZSAoQ3VyT2ZzID09IGJpb3MtPkZpcnN0S2JkQ2hhclB0cikgewoJICAgIC8qIG5vIGlucHV0IGF2YWlsYWJsZSB5ZXQsIHNvIHdhaXQuLi4gKi8KCSAgICBET1NWTV9XYWl0KCBjdHggKTsKCSAgfQoJICAvKiByZWFkIGZyb20ga2V5Ym9hcmQgcXVldWUgKGNhbGwgaW50MTY/KSAqLwoJICBkYXRhID0gKChXT1JEKiliaW9zKVtDdXJPZnNdOwoJICBDdXJPZnMgKz0gMjsKCSAgaWYgKEN1ck9mcyA+PSBiaW9zLT5LYmRCdWZmZXJFbmQpIEN1ck9mcyA9IGJpb3MtPktiZEJ1ZmZlclN0YXJ0OwoJICBiaW9zLT5OZXh0S2JkQ2hhclB0ciA9IEN1ck9mczsKCSAgLyogaWYgaXQncyBhbiBleHRlbmRlZCBrZXksIHNhdmUgc2NhbmNvZGUgKi8KCSAgaWYgKExPQllURShkYXRhKSA9PSAwKSAqc2NhbiA9IEhJQllURShkYXRhKTsKCSAgLyogc3RvcmUgQVNDSUkgY2hhciBpbiBidWZmZXIgKi8KCSAgYnVmZmVyW2xlbisrXSA9IExPQllURShkYXRhKTsKCX0KICAgICAgfSBlbHNlIHsKCS8qIHdlJ3JlIG5vdCBpbiByYXcgbW9kZSwgc28gd2UgbmVlZCB0byBkbyBsaW5lIGlucHV0Li4uICovCgl3aGlsZSAoVFJVRSkgewoJICBXT1JEIGRhdGE7CgkgIC8qIGNoZWNrIGZvciBuZXcga2V5Ym9hcmQgaW5wdXQgKi8KCSAgd2hpbGUgKEN1ck9mcyA9PSBiaW9zLT5GaXJzdEtiZENoYXJQdHIpIHsKCSAgICAvKiBubyBpbnB1dCBhdmFpbGFibGUgeWV0LCBzbyB3YWl0Li4uICovCgkgICAgRE9TVk1fV2FpdCggY3R4ICk7CgkgIH0KCSAgLyogcmVhZCBmcm9tIGtleWJvYXJkIHF1ZXVlIChjYWxsIGludDE2PykgKi8KCSAgZGF0YSA9ICgoV09SRCopYmlvcylbQ3VyT2ZzXTsKCSAgQ3VyT2ZzICs9IDI7CgkgIGlmIChDdXJPZnMgPj0gYmlvcy0+S2JkQnVmZmVyRW5kKSBDdXJPZnMgPSBiaW9zLT5LYmRCdWZmZXJTdGFydDsKCSAgYmlvcy0+TmV4dEtiZENoYXJQdHIgPSBDdXJPZnM7CgoJICBpZiAoTE9CWVRFKGRhdGEpID09ICdccicpIHsKCSAgICAvKiBpdCdzIHRoZSByZXR1cm4ga2V5LCB3ZSdyZSBkb25lICovCgkgICAgbGluZWJ1ZmZlcltsZW4rK10gPSBMT0JZVEUoZGF0YSk7CgkgICAgYnJlYWs7CgkgIH0KCSAgZWxzZSBpZiAoTE9CWVRFKGRhdGEpID49ICcgJykgewoJICAgIC8qIGEgY2hhcmFjdGVyICovCgkgICAgaWYgKChsZW4rMSk8Q09OX0JVRkZFUikgewoJICAgICAgbGluZWJ1ZmZlcltsZW5dID0gTE9CWVRFKGRhdGEpOwoJICAgICAgV3JpdGVGaWxlKEdldFN0ZEhhbmRsZShTVERfT1VUUFVUX0hBTkRMRSksICZsaW5lYnVmZmVyW2xlbisrXSwgMSwgTlVMTCwgTlVMTCk7CgkgICAgfQoJICAgIC8qIGVsc2UgYmVlcCwgYnV0IEkgZG9uJ3QgbGlrZSBub2lzZSAqLwoJICB9CgkgIGVsc2Ugc3dpdGNoIChMT0JZVEUoZGF0YSkpIHsKCSAgY2FzZSAnXGInOgoJICAgIGlmIChsZW4+MCkgewoJICAgICAgbGVuLS07CgkgICAgICBXcml0ZUZpbGUoR2V0U3RkSGFuZGxlKFNURF9PVVRQVVRfSEFORExFKSwgIlxiIFxiIiwgMywgTlVMTCwgTlVMTCk7CgkgICAgfQoJICAgIGJyZWFrOwoJICB9Cgl9CglpZiAobGVuID4gY291bnQpIHsKCSAgLyogc2F2ZSByZXN0IG9mIGxpbmUgZm9yIGxhdGVyICovCgkgIGxvbC0+b2Zmc191bnJlYWRfQ09OID0gbGluZWJ1ZmZlciAtIChCWVRFKilsb2wgKyBjb3VudDsKCSAgbGVuID0gY291bnQ7Cgl9CgltZW1jcHkoYnVmZmVyLCBsaW5lYnVmZmVyLCBsZW4pOwogICAgICB9CiAgICAgIGhkci0+c3RhdHVzID0gU1RBVF9ET05FOwogICAgICBpby0+Y291bnQgPSBsZW47CiAgICB9CiAgICBicmVhazsKICBjYXNlIENNRF9TQUZFSU5QVVQ6CiAgICBpZiAoY3VyYnVmZmVyKSB7CiAgICAgIC8qIHNvbWUgbGluZSBpbnB1dCB3YWl0aW5nICovCiAgICAgIGhkci0+c3RhdHVzID0gU1RBVF9ET05FOwogICAgICAoKFJFUV9TQUZFSU5QVVQqKWhkciktPmRhdGEgPSAqY3VyYnVmZmVyOwogICAgfQogICAgZWxzZSBpZiAoY29uLT5hdHRyICYgQVRUUl9SQVcpIHsKICAgICAgaWYgKEN1ck9mcyA9PSBiaW9zLT5GaXJzdEtiZENoYXJQdHIpIHsKCS8qIG5vIGlucHV0ICovCgloZHItPnN0YXR1cyA9IFNUQVRfRE9ORXxTVEFUX0JVU1k7CiAgICAgIH0gZWxzZSB7CgkvKiBzb21lIGtleWJvYXJkIGlucHV0IHdhaXRpbmcgKi8KCWhkci0+c3RhdHVzID0gU1RBVF9ET05FOwoJKChSRVFfU0FGRUlOUFVUKiloZHIpLT5kYXRhID0gKChCWVRFKiliaW9zKVtDdXJPZnNdOwogICAgICB9CiAgICB9IGVsc2UgewogICAgICAvKiBubyBsaW5lIGlucHV0ICovCiAgICAgIGhkci0+c3RhdHVzID0gU1RBVF9ET05FfFNUQVRfQlVTWTsKICAgIH0KICAgIGJyZWFrOwogIGNhc2UgQ01EX0lOU1RBVFVTOgogICAgaWYgKGN1cmJ1ZmZlcikgewogICAgICAvKiB3ZSBoYXZlIGRhdGEgKi8KICAgICAgaGRyLT5zdGF0dXMgPSBTVEFUX0RPTkU7CiAgICB9CiAgICBlbHNlIGlmIChjb24tPmF0dHIgJiBBVFRSX1JBVykgewogICAgICBpZiAoQ3VyT2ZzID09IGJpb3MtPkZpcnN0S2JkQ2hhclB0cikgewoJLyogbm8gaW5wdXQgKi8KCWhkci0+c3RhdHVzID0gU1RBVF9ET05FfFNUQVRfQlVTWTsKICAgICAgfSBlbHNlIHsKCS8qIHNvbWUga2V5Ym9hcmQgaW5wdXQgd2FpdGluZyAqLwoJaGRyLT5zdGF0dXMgPSBTVEFUX0RPTkU7CiAgICAgIH0KICAgIH0gZWxzZSB7CiAgICAgIC8qIG5vIGxpbmUgaW5wdXQgKi8KICAgICAgaGRyLT5zdGF0dXMgPSBTVEFUX0RPTkV8U1RBVF9CVVNZOwogICAgfQoKICAgIGJyZWFrOwogIGNhc2UgQ01EX0lORkxVU0g6CiAgICAvKiBmbHVzaCBsaW5lIGFuZCBrZXlib2FyZCBxdWV1ZSAqLwogICAgbG9sLT5vZmZzX3VucmVhZF9DT04gPSAwOwogICAgYmlvcy0+TmV4dEtiZENoYXJQdHIgPSBiaW9zLT5GaXJzdEtiZENoYXJQdHI7CiAgICBicmVhazsKICBjYXNlIENNRF9PVVRQVVQ6CiAgY2FzZSBDTURfU0FGRU9VVFBVVDoKICAgIHsKICAgICAgUkVRX0lPICppbyA9IChSRVFfSU8gKiloZHI7CiAgICAgIEJZVEUgKmJ1ZmZlciA9IENUWF9TRUdfT0ZGX1RPX0xJTihjdHgsCgkJCQkJU0VMRUNUT1JPRihpby0+YnVmZmVyKSwKCQkJCQkoRFdPUkQpT0ZGU0VUT0YoaW8tPmJ1ZmZlcikpOwogICAgICBEV09SRCByZXN1bHQgPSAwOwogICAgICBXcml0ZUZpbGUoR2V0U3RkSGFuZGxlKFNURF9PVVRQVVRfSEFORExFKSwgYnVmZmVyLCBpby0+Y291bnQsICZyZXN1bHQsIE5VTEwpOwogICAgICBpby0+Y291bnQgPSByZXN1bHQ7CiAgICAgIGhkci0+c3RhdHVzID0gU1RBVF9ET05FOwogICAgfQogICAgYnJlYWs7CiAgZGVmYXVsdDoKICAgIGhkci0+c3RhdHVzID0gU1RBVF9ET05FOwogIH0KICBkb19scmV0KGN0eCk7Cn0KCnN0YXRpYyB2b2lkIEluaXRMaXN0T2ZMaXN0cyhET1NfTElTVE9GTElTVFMgKkRPU19MT0wpCnsKLyoKT3V0cHV0IG9mIERPUyA2LjIyOgoKMDEzMzowMDIwICAgICAgICAgICAgICAgICAgICA2QSAxMy0zMyAwMSBDQyAwMCAzMyAwMSA1OSAwMCAgICAgICAgIGouMy4uLjMuWS4KMDEzMzowMDMwICA3MCAwMCAwMCAwMCA3MiAwMiAwMCAwMi02RCAwMCAzMyAwMSAwMCAwMCAyRSAwNSAgIHAuLi5yLi4ubS4zLi4uLi4KMDEzMzowMDQwICAwMCAwMCBGQyAwNCAwMCAwMCAwMyAwOC05MiAyMSAxMSBFMCAwNCA4MCBDNiAwRCAgIC4uLi4uLi4uLiEuLi4uLi4KMDEzMzowMDUwICBDQyAwRCA0RSA1NSA0QyAyMCAyMCAyMC0yMCAyMCAwMCAwMCAwMCAwMCAwMCAwMCAgIC4uTlVMICAgICAuLi4uLi4KMDEzMzowMDYwICAwMCA0QiBCQSBDMSAwNiAxNCAwMCAwMC0wMCAwMyAwMSAwMCAwNCA3MCBDRSBGRiAgIC5LLi4uLi4uLi4uLi5wLi4KMDEzMzowMDcwICBGRiAwMCAwMCAwMCAwMCAwMCAwMCAwMC0wMCAwMSAwMCAwMCAwRCAwNSAwMCAwMCAgIC4uLi4uLi4uLi4uLi4uLi4KMDEzMzowMDgwICAwMCBGRiBGRiAwMCAwMCAwMCAwMCBGRS0wMCAwMCBGOCAwMyBGRiA5RiA3MCAwMiAgIC4uLi4uLi4uLi4uLi4ucC4KMDEzMzowMDkwICBEMCA0NCBDOCBGRCBENCA0NCBDOCBGRC1ENCA0NCBDOCBGRCBEMCA0NCBDOCBGRCAgIC5ELi4uRC4uLkQuLi5ELi4KMDEzMzowMEEwICBEMCA0NCBDOCBGRCBEMCA0NCAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIC5ELi4uRAoqLwogIERPU19MT0wtPkNYX0ludDIxXzVlMDEJCT0gMHgwOwogIERPU19MT0wtPkxSVV9jb3VudF9GQ0JfY2FjaGUJPSAweDA7CiAgRE9TX0xPTC0+TFJVX2NvdW50X0ZDQl9vcGVuCQk9IDB4MDsKICBET1NfTE9MLT5PRU1fZnVuY19oYW5kbGVyCQk9IC0xOyAvKiBub3QgYXZhaWxhYmxlICovCiAgRE9TX0xPTC0+SU5UMjFfb2Zmc2V0CQk9IDB4MDsKICBET1NfTE9MLT5zaGFyaW5nX3JldHJ5X2NvdW50CT0gMzsKICBET1NfTE9MLT5zaGFyaW5nX3JldHJ5X2RlbGF5CT0gMTsKICBET1NfTE9MLT5wdHJfZGlza19idWYJCT0gMHgwOwogIERPU19MT0wtPm9mZnNfdW5yZWFkX0NPTgkJPSAweDA7CiAgRE9TX0xPTC0+c2VnX2ZpcnN0X01DQgkJPSAweDA7CiAgRE9TX0xPTC0+cHRyX2ZpcnN0X0RQQgkJPSAweDA7CiAgRE9TX0xPTC0+cHRyX2ZpcnN0X1N5c0ZpbGVUYWJsZQk9IDB4MDsKICBET1NfTE9MLT5wdHJfY2xvY2tfZGV2X2hkcgkJPSAweDA7CiAgRE9TX0xPTC0+cHRyX0NPTl9kZXZfaGRyCQk9IDB4MDsKICBET1NfTE9MLT5tYXhfYnl0ZV9wZXJfc2VjCQk9IDUxMjsKICBET1NfTE9MLT5wdHJfZGlza19idWZfaW5mbwkJPSAweDA7CiAgRE9TX0xPTC0+cHRyX2FycmF5X0NEUwkJPSAweDA7CiAgRE9TX0xPTC0+cHRyX3N5c19GQ0IJCT0gMHgwOwogIERPU19MT0wtPm5yX3Byb3RlY3RfRkNCCQk9IDB4MDsKICBET1NfTE9MLT5ucl9ibG9ja19kZXYJCT0gMHgwOwogIERPU19MT0wtPm5yX2F2YWlsX2RyaXZlX2xldHRlcnMJPSAyNjsgLyogQSAtIFogKi8KICBET1NfTE9MLT5ucl9kcml2ZXNfSk9JTmVkCQk9IDB4MDsKICBET1NfTE9MLT5wdHJfc3BlY19wcmdfbmFtZXMJCT0gMHgwOwogIERPU19MT0wtPnB0cl9TRVRWRVJfcHJnX2xpc3QJPSAweDA7IC8qIG5vIFNFVFZFUiBsaXN0ICovCiAgRE9TX0xPTC0+RE9TX0hJR0hfQTIwX2Z1bmNfb2Zmcwk9IDB4MDsKICBET1NfTE9MLT5QU1BfbGFzdF9leGVjCQk9IDB4MDsKICBET1NfTE9MLT5CVUZGRVJTX3ZhbAkJPSA5OTsgLyogbWF4aW11bTogOTkgKi8KICBET1NfTE9MLT5CVUZGRVJTX25yX2xvb2thaGVhZAk9IDg7IC8qIG1heGltdW06IDggKi8KICBET1NfTE9MLT5ib290X2RyaXZlCQkJPSAzOyAvKiBDOiAqLwogIERPU19MT0wtPmZsYWdfRFdPUkRfbW92ZXMJCT0gMHgwMTsgLyogaTM4NisgKi8KICBET1NfTE9MLT5zaXplX2V4dGVuZGVkX21lbQkJPSAweGYwMDA7IC8qIHZlcnkgaGlnaCB2YWx1ZSAqLwp9Cgp2b2lkIERPU0RFVl9JbnN0YWxsRE9TRGV2aWNlcyh2b2lkKQp7CiAgRE9TX0RBVEFTRUcgKmRhdGFzZWc7CiAgV09SRCBzZWc7CiAgV09SRCBzZWxlY3RvcjsKICB1bnNpZ25lZCBpbnQgbjsKCiAgLyogYWxsb2NhdGUgRE9TIGRhdGEgc2VnbWVudCBvciBzb21ldGhpbmcgKi8KICBkYXRhc2VnID0gRE9TVk1fQWxsb2NEYXRhVU1CKCBzaXplb2YoRE9TX0RBVEFTRUcpLCAmc2VnLCAmc2VsZWN0b3IgKTsKCiAgRE9TX0xPTFNlZyA9IE1BS0VTRUdQVFIoIHNlZywgMCApOwogIERPU01FTV9MT0woKS0+d2luZV9ybV9sb2wgPSAKICAgICAgTUFLRVNFR1BUUiggc2VnLCBGSUVMRF9PRkZTRVQoRE9TX0xJU1RPRkxJU1RTLCBwdHJfZmlyc3RfRFBCKSApOwogIERPU01FTV9MT0woKS0+d2luZV9wbV9sb2wgPSAKICAgICAgTUFLRVNFR1BUUiggc2VsZWN0b3IsIEZJRUxEX09GRlNFVChET1NfTElTVE9GTElTVFMsIHB0cl9maXJzdF9EUEIpICk7CgogIC8qIGluaXRpYWxpemUgdGhlIG1hZ25pZmljZW50IExpc3QgT2YgTGlzdHMgKi8KICBJbml0TGlzdE9mTGlzdHMoJmRhdGFzZWctPmxvbCk7CgogIC8qIFNldCB1cCBmaXJzdCBkZXZpY2UgKE5VTCkgKi8KICBkYXRhc2VnLT5sb2wuTlVMX2Rldi5uZXh0X2RldiAgPSBNQUtFU0VHUFRSKHNlZywgRE9TX0RBVEFTRUdfT0ZGKGRldlswXSkpOwogIGRhdGFzZWctPmxvbC5OVUxfZGV2LmF0dHIgICAgICA9IGRldnNbMF0uYXR0cjsKICBkYXRhc2VnLT5sb2wuTlVMX2Rldi5zdHJhdGVneSAgPSBET1NfREFUQVNFR19PRkYodGh1bmtbMF0ubGptcDEpOwogIGRhdGFzZWctPmxvbC5OVUxfZGV2LmludGVycnVwdCA9IERPU19EQVRBU0VHX09GRih0aHVua1swXS5sam1wMik7CiAgbWVtY3B5KGRhdGFzZWctPmxvbC5OVUxfZGV2Lm5hbWUsIGRldnNbMF0ubmFtZSwgOCk7CgogIC8qIFNldCB1cCB0aGUgcmVtYWluaW5nIGRldmljZXMgKi8KICBmb3IgKG4gPSAxOyBuIDwgTlJfREVWUzsgbisrKQogIHsKICAgIGRhdGFzZWctPmRldltuLTFdLm5leHRfZGV2ICA9IChuKzEpID09IE5SX0RFVlMgPyBOT05FWFQgOgogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgTUFLRVNFR1BUUihzZWcsIERPU19EQVRBU0VHX09GRihkZXZbbl0pKTsKICAgIGRhdGFzZWctPmRldltuLTFdLmF0dHIgICAgICA9IGRldnNbbl0uYXR0cjsKICAgIGRhdGFzZWctPmRldltuLTFdLnN0cmF0ZWd5ICA9IERPU19EQVRBU0VHX09GRih0aHVua1tuXS5sam1wMSk7CiAgICBkYXRhc2VnLT5kZXZbbi0xXS5pbnRlcnJ1cHQgPSBET1NfREFUQVNFR19PRkYodGh1bmtbbl0ubGptcDIpOwogICAgbWVtY3B5KGRhdGFzZWctPmRldltuLTFdLm5hbWUsIGRldnNbbl0ubmFtZSwgOCk7CiAgfQoKICAvKiBTZXQgdXAgdGh1bmtzICovCiAgZm9yIChuID0gMDsgbiA8IE5SX0RFVlM7IG4rKykKICB7CiAgICBkYXRhc2VnLT50aHVua1tuXS5sam1wMSAgICAgPSBMSk1QOwogICAgZGF0YXNlZy0+dGh1bmtbbl0uc3RyYXRlZ3kgID0gKFJNQ0JQUk9DKURQTUlfQWxsb2NJbnRlcm5hbFJNQ0IoZGV2c1tuXS5zdHJhdGVneSk7CiAgICBkYXRhc2VnLT50aHVua1tuXS5sam1wMiAgICAgPSBMSk1QOwogICAgZGF0YXNlZy0+dGh1bmtbbl0uaW50ZXJydXB0ID0gKFJNQ0JQUk9DKURQTUlfQWxsb2NJbnRlcm5hbFJNQ0IoZGV2c1tuXS5pbnRlcnJ1cHQpOwogIH0KCiAgLyogQ09OIGlzIGRldmljZSAxICovCiAgZGF0YXNlZy0+bG9sLnB0cl9DT05fZGV2X2hkciA9IE1BS0VTRUdQVFIoc2VnLCBET1NfREFUQVNFR19PRkYoZGV2WzBdKSk7Cn0KCkRXT1JEIERPU0RFVl9Db25zb2xlKHZvaWQpCnsKICByZXR1cm4gRE9TTUVNX0xPTCgpLT5wdHJfQ09OX2Rldl9oZHI7Cn0KCkRXT1JEIERPU0RFVl9GaW5kQ2hhckRldmljZShjaGFyKm5hbWUpCnsKICBTRUdQVFIgY3VyX3B0ciA9IE1BS0VTRUdQVFIoSElXT1JEKERPU19MT0xTZWcpLCBGSUVMRF9PRkZTRVQoRE9TX0xJU1RPRkxJU1RTLE5VTF9kZXYpKTsKICBET1NfREVWSUNFX0hFQURFUiAqY3VyID0gUFRSX1JFQUxfVE9fTElOKFNFTEVDVE9ST0YoY3VyX3B0ciksT0ZGU0VUT0YoY3VyX3B0cikpOwogIGNoYXIgZG5hbWVbOF07CiAgaW50IGNudDsKCiAgLyogZ2V0IGZpcnN0IDggY2hhcmFjdGVycyAqLwogIHN0cm5jcHkoZG5hbWUsbmFtZSw4KTsKICAvKiBpZiBsZXNzIHRoYW4gOCBjaGFyYWN0ZXJzLCBwYWQgd2l0aCBzcGFjZXMgKi8KICBmb3IgKGNudD0wOyBjbnQ8ODsgY250KyspCiAgICBpZiAoIWRuYW1lW2NudF0pIGRuYW1lW2NudF09JyAnOwoKICAvKiBzZWFyY2ggZm9yIGNoYXIgZGV2aWNlcyB3aXRoIHRoZSByaWdodCBuYW1lICovCiAgd2hpbGUgKGN1ciAmJgoJICgoIShjdXItPmF0dHIgJiBBVFRSX0NIQVIpKSB8fAoJICBtZW1jbXAoY3VyLT5uYW1lLGRuYW1lLDgpKSkgewogICAgY3VyX3B0ciA9IGN1ci0+bmV4dF9kZXY7CiAgICBpZiAoY3VyX3B0ciA9PSBOT05FWFQpIGN1cj1OVUxMOwogICAgZWxzZSBjdXIgPSBQVFJfUkVBTF9UT19MSU4oU0VMRUNUT1JPRihjdXJfcHRyKSxPRkZTRVRPRihjdXJfcHRyKSk7CiAgfQogIHJldHVybiBjdXJfcHRyOwp9CgpzdGF0aWMgdm9pZCBET1NERVZfRG9SZXEodm9pZCpyZXEsIERXT1JEIGRldikKewogIFJFUVVFU1RfSEVBREVSICpoZHIgPSAoUkVRVUVTVF9IRUFERVIgKilyZXE7CiAgRE9TX0RFVklDRV9IRUFERVIgKmRoZHI7CiAgQ09OVEVYVDg2IGN0eDsKICBjaGFyICpwaGRyOwoKICBkaGRyID0gUFRSX1JFQUxfVE9fTElOKFNFTEVDVE9ST0YoZGV2KSxPRkZTRVRPRihkZXYpKTsKICBwaGRyID0gKChjaGFyKilET1NNRU1fTE9MKCkpICsgRE9TX0RBVEFTRUdfT0ZGKHJlcSk7CgogIC8qIGNvcHkgcmVxdWVzdCB0byByZXF1ZXN0IHNjcmF0Y2ggYXJlYSAqLwogIG1lbWNweShwaGRyLCByZXEsIGhkci0+c2l6ZSk7CgogIC8qIHByZXBhcmUgdG8gY2FsbCBkZXZpY2UgZHJpdmVyICovCiAgbWVtc2V0KCZjdHgsIDAsIHNpemVvZihjdHgpKTsKCiAgLyogRVM6QlggcG9pbnRzIHRvIHJlcXVlc3QgZm9yIHN0cmF0ZWd5IHJvdXRpbmUgKi8KICBjdHguU2VnRXMgPSBISVdPUkQoRE9TX0xPTFNlZyk7CiAgY3R4LkVieCAgID0gRE9TX0RBVEFTRUdfT0ZGKHJlcSk7CgogIC8qIGNhbGwgc3RyYXRlZ3kgcm91dGluZSAqLwogIGN0eC5TZWdDcyA9IFNFTEVDVE9ST0YoZGV2KTsKICBjdHguRWlwICAgPSBkaGRyLT5zdHJhdGVneTsKICBEUE1JX0NhbGxSTVByb2MoJmN0eCwgMCwgMCwgMCk7CgogIC8qIGNhbGwgaW50ZXJydXB0IHJvdXRpbmUgKi8KICBjdHguU2VnQ3MgPSBTRUxFQ1RPUk9GKGRldik7CiAgY3R4LkVpcCAgID0gZGhkci0+aW50ZXJydXB0OwogIERQTUlfQ2FsbFJNUHJvYygmY3R4LCAwLCAwLCAwKTsKCiAgLyogY29tcGxldGVkLCBjb3B5IHJlcXVlc3QgYmFjayAqLwogIG1lbWNweShyZXEsIHBoZHIsIGhkci0+c2l6ZSk7CgogIGlmIChoZHItPnN0YXR1cyAmIFNUQVRfRVJST1IpIHsKICAgIHN3aXRjaCAoaGRyLT5zdGF0dXMgJiBTVEFUX01BU0spIHsKICAgIGNhc2UgMHgwRjogLyogaW52YWxpZCBkaXNrIGNoYW5nZSAqLwogICAgICAvKiB0aGlzIGVycm9yIHNlZW1zIHRvIGZpdCB0aGUgYmlsbCAqLwogICAgICBTZXRMYXN0RXJyb3IoRVJfTm90U2FtZURldmljZSk7CiAgICAgIGJyZWFrOwogICAgZGVmYXVsdDoKICAgICAgU2V0TGFzdEVycm9yKChoZHItPnN0YXR1cyAmIFNUQVRfTUFTSykgKyAweDEzKTsKICAgICAgYnJlYWs7CiAgICB9CiAgfQp9CgpzdGF0aWMgaW50IERPU0RFVl9JTyh1bnNpZ25lZCBjbWQsIERXT1JEIGRldiwgRFdPUkQgYnVmLCBpbnQgYnVmbGVuKQp7CiAgUkVRX0lPIHJlcTsKCiAgcmVxLmhkci5zaXplPXNpemVvZihyZXEpOwogIHJlcS5oZHIudW5pdD0wOyAvKiBub3QgZGVhbGluZyB3aXRoIGJsb2NrIGRldmljZXMgeWV0ICovCiAgcmVxLmhkci5jb21tYW5kPWNtZDsKICByZXEuaGRyLnN0YXR1cz1TVEFUX0JVU1k7CiAgcmVxLm1lZGlhPTA7IC8qIG5vdCBkZWFsaW5nIHdpdGggYmxvY2sgZGV2aWNlcyB5ZXQgKi8KICByZXEuYnVmZmVyPWJ1ZjsKICByZXEuY291bnQ9YnVmbGVuOwogIHJlcS5zZWN0b3I9MDsgLyogYmxvY2sgZGV2aWNlcyAqLwogIHJlcS52b2x1bWU9MDsgLyogYmxvY2sgZGV2aWNlcyAqLwoKICBET1NERVZfRG9SZXEoJnJlcSwgZGV2KTsKCiAgcmV0dXJuIHJlcS5jb3VudDsKfQoKaW50IERPU0RFVl9QZWVrKERXT1JEIGRldiwgQllURSpkYXRhKQp7CiAgUkVRX1NBRkVJTlBVVCByZXE7CgogIHJlcS5oZHIuc2l6ZT1zaXplb2YocmVxKTsKICByZXEuaGRyLnVuaXQ9MDsgLyogbm90IGRlYWxpbmcgd2l0aCBibG9jayBkZXZpY2VzIHlldCAqLwogIHJlcS5oZHIuY29tbWFuZD1DTURfU0FGRUlOUFVUOwogIHJlcS5oZHIuc3RhdHVzPVNUQVRfQlVTWTsKICByZXEuZGF0YT0wOwoKICBET1NERVZfRG9SZXEoJnJlcSwgZGV2KTsKCiAgaWYgKHJlcS5oZHIuc3RhdHVzICYgU1RBVF9CVVNZKSByZXR1cm4gMDsKCiAgKmRhdGEgPSByZXEuZGF0YTsKICByZXR1cm4gMTsKfQoKaW50IERPU0RFVl9SZWFkKERXT1JEIGRldiwgRFdPUkQgYnVmLCBpbnQgYnVmbGVuKQp7CiAgcmV0dXJuIERPU0RFVl9JTyhDTURfSU5QVVQsIGRldiwgYnVmLCBidWZsZW4pOwp9CgppbnQgRE9TREVWX1dyaXRlKERXT1JEIGRldiwgRFdPUkQgYnVmLCBpbnQgYnVmbGVuLCBpbnQgdmVyaWZ5KQp7CiAgcmV0dXJuIERPU0RFVl9JTyh2ZXJpZnk/Q01EX1NBRkVPVVRQVVQ6Q01EX09VVFBVVCwgZGV2LCBidWYsIGJ1Zmxlbik7Cn0KCmludCBET1NERVZfSW9jdGxSZWFkKERXT1JEIGRldiwgRFdPUkQgYnVmLCBpbnQgYnVmbGVuKQp7CiAgcmV0dXJuIERPU0RFVl9JTyhDTURfSU5JT0NUTCwgZGV2LCBidWYsIGJ1Zmxlbik7Cn0KCmludCBET1NERVZfSW9jdGxXcml0ZShEV09SRCBkZXYsIERXT1JEIGJ1ZiwgaW50IGJ1ZmxlbikKewogIHJldHVybiBET1NERVZfSU8oQ01EX09VVElPQ1RMLCBkZXYsIGJ1ZiwgYnVmbGVuKTsKfQo=