LyoKICogRE9TIGRldmljZXMKICoKICogQ29weXJpZ2h0IDE5OTkgT3ZlIEvldmVuCiAqCiAqIFRoaXMgbGlicmFyeSBpcyBmcmVlIHNvZnR3YXJlOyB5b3UgY2FuIHJlZGlzdHJpYnV0ZSBpdCBhbmQvb3IKICogbW9kaWZ5IGl0IHVuZGVyIHRoZSB0ZXJtcyBvZiB0aGUgR05VIExlc3NlciBHZW5lcmFsIFB1YmxpYwogKiBMaWNlbnNlIGFzIHB1Ymxpc2hlZCBieSB0aGUgRnJlZSBTb2Z0d2FyZSBGb3VuZGF0aW9uOyBlaXRoZXIKICogdmVyc2lvbiAyLjEgb2YgdGhlIExpY2Vuc2UsIG9yIChhdCB5b3VyIG9wdGlvbikgYW55IGxhdGVyIHZlcnNpb24uCiAqCiAqIFRoaXMgbGlicmFyeSBpcyBkaXN0cmlidXRlZCBpbiB0aGUgaG9wZSB0aGF0IGl0IHdpbGwgYmUgdXNlZnVsLAogKiBidXQgV0lUSE9VVCBBTlkgV0FSUkFOVFk7IHdpdGhvdXQgZXZlbiB0aGUgaW1wbGllZCB3YXJyYW50eSBvZgogKiBNRVJDSEFOVEFCSUxJVFkgb3IgRklUTkVTUyBGT1IgQSBQQVJUSUNVTEFSIFBVUlBPU0UuICBTZWUgdGhlIEdOVQogKiBMZXNzZXIgR2VuZXJhbCBQdWJsaWMgTGljZW5zZSBmb3IgbW9yZSBkZXRhaWxzLgogKgogKiBZb3Ugc2hvdWxkIGhhdmUgcmVjZWl2ZWQgYSBjb3B5IG9mIHRoZSBHTlUgTGVzc2VyIEdlbmVyYWwgUHVibGljCiAqIExpY2Vuc2UgYWxvbmcgd2l0aCB0aGlzIGxpYnJhcnk7IGlmIG5vdCwgd3JpdGUgdG8gdGhlIEZyZWUgU29mdHdhcmUKICogRm91bmRhdGlvbiwgSW5jLiwgNTkgVGVtcGxlIFBsYWNlLCBTdWl0ZSAzMzAsIEJvc3RvbiwgTUEgIDAyMTExLTEzMDcgIFVTQQogKi8KCiNpbmNsdWRlIDxzdGRsaWIuaD4KI2luY2x1ZGUgPHN0cmluZy5oPgojaW5jbHVkZSAid2luZS93aW5iYXNlMTYuaCIKI2luY2x1ZGUgImRvc2V4ZS5oIgojaW5jbHVkZSAid2luZS9kZWJ1Zy5oIgoKI2luY2x1ZGUgInBzaHBhY2sxLmgiCgp0eXBlZGVmIHN0cnVjdCB7CiAgQllURSBsam1wMTsKICBSTUNCUFJPQyBzdHJhdGVneTsKICBCWVRFIGxqbXAyOwogIFJNQ0JQUk9DIGludGVycnVwdDsKfSBXSU5FREVWX1RIVU5LOwoKdHlwZWRlZiBzdHJ1Y3QgewogIEJZVEUgc2l6ZTsgLyogbGVuZ3RoIG9mIGhlYWRlciArIGRhdGEgKi8KICBCWVRFIHVuaXQ7IC8qIHVuaXQgKGJsb2NrIGRldmljZXMgb25seSkgKi8KICBCWVRFIGNvbW1hbmQ7CiAgV09SRCBzdGF0dXM7CiAgQllURSByZXNlcnZlZFs4XTsKfSBSRVFVRVNUX0hFQURFUjsKCnR5cGVkZWYgc3RydWN0IHsKICBSRVFVRVNUX0hFQURFUiBoZHI7CiAgQllURSBtZWRpYTsgLyogbWVkaWEgZGVzY3JpcHRvciBmcm9tIEJQQiAqLwogIFNFR1BUUiBidWZmZXI7CiAgV09SRCBjb3VudDsgLyogYnl0ZS9zZWN0b3IgY291bnQgKi8KICBXT1JEIHNlY3RvcjsgLyogc3RhcnRpbmcgc2VjdG9yIChibG9jayBkZXZpY2VzKSAqLwogIERXT1JEIHZvbHVtZTsgLyogdm9sdW1lIElEIChibG9jayBkZXZpY2VzKSAqLwp9IFJFUV9JTzsKCnR5cGVkZWYgc3RydWN0IHsKICBSRVFVRVNUX0hFQURFUiBoZHI7CiAgQllURSBkYXRhOwp9IFJFUV9TQUZFSU5QVVQ7Cgp0eXBlZGVmIHN0cnVjdAp7CiAgICBEV09SRCBuZXh0X2RldjsKICAgIFdPUkQgIGF0dHI7CiAgICBXT1JEICBzdHJhdGVneTsKICAgIFdPUkQgIGludGVycnVwdDsKICAgIGNoYXIgIG5hbWVbOF07Cn0gRE9TX0RFVklDRV9IRUFERVI7CgovKiBXYXJuaW5nOiBuZWVkIHRvIHJldHVybiBMT0wgcHRyIHcvIG9mZnNldCAwICgmcHRyX2ZpcnN0X0RQQikgdG8gcHJvZ3JhbXMgISAqLwp0eXBlZGVmIHN0cnVjdCBfRE9TX0xJU1RPRkxJU1RTCnsKICAgIFdPUkQgIENYX0ludDIxXzVlMDE7ICAgICAgICAvKiAtMjRkIGNvbnRlbnRzIG9mIENYIGZyb20gSU5UIDIxL0FYPTVFMDFoICovCiAgICBXT1JEICBMUlVfY291bnRfRkNCX2NhY2hlOyAgLyogLTIyZCAqLwogICAgV09SRCAgTFJVX2NvdW50X0ZDQl9vcGVuOyAgIC8qIC0yMGQgKi8KICAgIERXT1JEIE9FTV9mdW5jX2hhbmRsZXI7ICAgICAvKiAtMThkIE9FTSBmdW5jdGlvbiBvZiBJTlQgMjEvQUg9RjhoICovCiAgICBXT1JEICBJTlQyMV9vZmZzZXQ7ICAgICAgICAgLyogLTE0ZCBvZmZzZXQgaW4gRE9TIENTIG9mIGNvZGUgdG8gcmV0dXJuIGZyb20gSU5UIDIxIGNhbGwgKi8KICAgIFdPUkQgIHNoYXJpbmdfcmV0cnlfY291bnQ7ICAvKiAtMTJkICovCiAgICBXT1JEICBzaGFyaW5nX3JldHJ5X2RlbGF5OyAgLyogLTEwZCAqLwogICAgRFdPUkQgcHRyX2Rpc2tfYnVmOyAgICAgICAgIC8qIC04ZCBwdHIgdG8gY3VycmVudCBkaXNrIGJ1ZiAqLwogICAgV09SRCAgb2Zmc191bnJlYWRfQ09OOyAgICAgIC8qIC00ZCBwb2ludGVyIGluIERPUyBkYXRhIHNlZ21lbnQgb2YgdW5yZWFkIENPTiBpbnB1dCAqLwogICAgV09SRCAgc2VnX2ZpcnN0X01DQjsgICAgICAgIC8qIC0yZCAqLwogICAgRFdPUkQgcHRyX2ZpcnN0X0RQQjsgICAgICAgIC8qIDAwICovCiAgICBEV09SRCBwdHJfZmlyc3RfU3lzRmlsZVRhYmxlOyAvKiAwNCAqLwogICAgRFdPUkQgcHRyX2Nsb2NrX2Rldl9oZHI7ICAgIC8qIDA4ICovCiAgICBEV09SRCBwdHJfQ09OX2Rldl9oZHI7ICAgICAgLyogMEMgKi8KICAgIFdPUkQgIG1heF9ieXRlX3Blcl9zZWM7ICAgICAvKiAxMCBtYXhpbXVtIGJ5dGVzIHBlciBzZWN0b3Igb2YgYW55IGJsb2NrIGRldmljZSAqLwogICAgRFdPUkQgcHRyX2Rpc2tfYnVmX2luZm87ICAgIC8qIDEyICovCiAgICBEV09SRCBwdHJfYXJyYXlfQ0RTOyAgICAgICAgLyogMTYgY3VycmVudCBkaXJlY3Rvcnkgc3RydWN0dXJlICovCiAgICBEV09SRCBwdHJfc3lzX0ZDQjsgICAgICAgICAgLyogMUEgKi8KICAgIFdPUkQgIG5yX3Byb3RlY3RfRkNCOyAgICAgICAvKiAxRSAqLwogICAgQllURSAgbnJfYmxvY2tfZGV2OyAgICAgICAgIC8qIDIwICovCiAgICBCWVRFICBucl9hdmFpbF9kcml2ZV9sZXR0ZXJzOyAvKiAyMSAqLwogICAgRE9TX0RFVklDRV9IRUFERVIgTlVMX2RldjsgIC8qIDIyICovCiAgICBCWVRFICBucl9kcml2ZXNfSk9JTmVkOyAgICAgLyogMzQgKi8KICAgIFdPUkQgIHB0cl9zcGVjX3ByZ19uYW1lczsgICAvKiAzNSAqLwogICAgRFdPUkQgcHRyX1NFVFZFUl9wcmdfbGlzdDsgIC8qIDM3ICovCiAgICBXT1JEIERPU19ISUdIX0EyMF9mdW5jX29mZnM7LyogM0IgKi8KICAgIFdPUkQgUFNQX2xhc3RfZXhlYzsgICAgICAgICAvKiAzRCBpZiBET1MgaW4gSE1BOiBQU1Agb2YgcHJvZ3JhbSBleGVjdXRlZCBsYXN0OyBpZiBET1MgbG93OiAwMDAwaCAqLwogICAgV09SRCBCVUZGRVJTX3ZhbDsgICAgICAgICAgIC8qIDNGICovCiAgICBXT1JEIEJVRkZFUlNfbnJfbG9va2FoZWFkOyAgLyogNDEgKi8KICAgIEJZVEUgYm9vdF9kcml2ZTsgICAgICAgICAgICAvKiA0MyAqLwogICAgQllURSBmbGFnX0RXT1JEX21vdmVzOyAgICAgIC8qIDQ0IDAxaCBmb3IgMzg2KywgMDBoIG90aGVyd2lzZSAqLwogICAgV09SRCBzaXplX2V4dGVuZGVkX21lbTsgICAgIC8qIDQ1IHNpemUgb2YgZXh0ZW5kZWQgbWVtIGluIEtCICovCiAgICBTRUdQVFIgd2luZV9ybV9sb2w7ICAgICAgICAgLyogLS0gd2luZTogUmVhbCBtb2RlIHBvaW50ZXIgdG8gTE9MICovCiAgICBTRUdQVFIgd2luZV9wbV9sb2w7ICAgICAgICAgLyogLS0gd2luZTogUHJvdGVjdGVkIG1vZGUgcG9pbnRlciB0byBMT0wgKi8KfSBET1NfTElTVE9GTElTVFM7CgojaW5jbHVkZSAicG9wcGFjay5oIgoKI2RlZmluZSBDT05fQlVGRkVSIDEyOAoKZW51bSBzdHJhdGVneSB7IFNZU1RFTV9TVFJBVEVHWV9OVUwsIFNZU1RFTV9TVFJBVEVHWV9DT04sIE5CX1NZU1RFTV9TVFJBVEVHSUVTIH07CgpzdGF0aWMgdm9pZCAqc3RyYXRlZ3lfZGF0YVtOQl9TWVNURU1fU1RSQVRFR0lFU107CgojZGVmaW5lIE5PTkVYVCAoKERXT1JEKS0xKQoKI2RlZmluZSBBVFRSX1NURElOICAgICAweDAwMDEKI2RlZmluZSBBVFRSX1NURE9VVCAgICAweDAwMDIKI2RlZmluZSBBVFRSX05VTCAgICAgICAweDAwMDQKI2RlZmluZSBBVFRSX0NMT0NLICAgICAweDAwMDgKI2RlZmluZSBBVFRSX0ZBU1RDT04gICAweDAwMTAKI2RlZmluZSBBVFRSX1JBVyAgICAgICAweDAwMjAKI2RlZmluZSBBVFRSX05PVEVPRiAgICAweDAwNDAKI2RlZmluZSBBVFRSX0RFVklDRSAgICAweDAwODAKI2RlZmluZSBBVFRSX1JFTU9WQUJMRSAweDA4MDAKI2RlZmluZSBBVFRSX05PTklCTSAgICAweDIwMDAgLyogYmxvY2sgZGV2aWNlcyAqLwojZGVmaW5lIEFUVFJfVU5USUxCVVNZIDB4MjAwMCAvKiBjaGFyIGRldmljZXMgKi8KI2RlZmluZSBBVFRSX0lPQ1RMICAgICAweDQwMDAKI2RlZmluZSBBVFRSX0NIQVIgICAgICAweDgwMDAKCiNkZWZpbmUgQ01EX0lOSVQgICAgICAgMAojZGVmaW5lIENNRF9NRURJQUNIRUNLIDEgLyogYmxvY2sgZGV2aWNlcyAqLwojZGVmaW5lIENNRF9CVUlMREJQQiAgIDIgLyogYmxvY2sgZGV2aWNlcyAqLwojZGVmaW5lIENNRF9JTklPQ1RMICAgIDMKI2RlZmluZSBDTURfSU5QVVQgICAgICA0IC8qIHJlYWQgZGF0YSAqLwojZGVmaW5lIENNRF9TQUZFSU5QVVQgIDUgLyogIm5vbi1kZXN0cnVjdGl2ZSBpbnB1dCBubyB3YWl0IiwgY2hhciBkZXZpY2VzICovCiNkZWZpbmUgQ01EX0lOU1RBVFVTICAgNiAvKiBjaGFyIGRldmljZXMgKi8KI2RlZmluZSBDTURfSU5GTFVTSCAgICA3IC8qIGNoYXIgZGV2aWNlcyAqLwojZGVmaW5lIENNRF9PVVRQVVQgICAgIDggLyogd3JpdGUgZGF0YSAqLwojZGVmaW5lIENNRF9TQUZFT1VUUFVUIDkgLyogd3JpdGUgZGF0YSB3aXRoIHZlcmlmeSAqLwojZGVmaW5lIENNRF9PVVRTVEFUVVMgMTAgLyogY2hhciBkZXZpY2VzICovCiNkZWZpbmUgQ01EX09VVEZMVVNIICAxMSAvKiBjaGFyIGRldmljZXMgKi8KI2RlZmluZSBDTURfT1VUSU9DVEwgIDEyCiNkZWZpbmUgQ01EX0RFVk9QRU4gICAxMwojZGVmaW5lIENNRF9ERVZDTE9TRSAgMTQKI2RlZmluZSBDTURfUkVNT1ZBQkxFIDE1IC8qIGJsb2NrIGRldmljZXMgKi8KI2RlZmluZSBDTURfVU5USUxCVVNZIDE2IC8qIG91dHB1dCB1bnRpbCBidXN5ICovCgojZGVmaW5lIFNUQVRfTUFTSyAgMHgwMEZGCiNkZWZpbmUgU1RBVF9ET05FICAweDAxMDAKI2RlZmluZSBTVEFUX0JVU1kgIDB4MDIwMAojZGVmaW5lIFNUQVRfRVJST1IgMHg4MDAwCgojZGVmaW5lIExKTVAgMHhlYQoKCi8qIHByb3RvdHlwZXMgKi8Kc3RhdGljIHZvaWQgV0lOQVBJIG51bF9zdHJhdGVneShDT05URVhUODYqY3R4KTsKc3RhdGljIHZvaWQgV0lOQVBJIG51bF9pbnRlcnJ1cHQoQ09OVEVYVDg2KmN0eCk7CnN0YXRpYyB2b2lkIFdJTkFQSSBjb25fc3RyYXRlZ3koQ09OVEVYVDg2KmN0eCk7CnN0YXRpYyB2b2lkIFdJTkFQSSBjb25faW50ZXJydXB0KENPTlRFWFQ4NipjdHgpOwoKLyogZGV2aWNlcyAqLwp0eXBlZGVmIHN0cnVjdAp7CiAgICBjaGFyIG5hbWVbOF07CiAgICBXT1JEIGF0dHI7CiAgICBSTUNCUFJPQyBzdHJhdGVneTsKICAgIFJNQ0JQUk9DIGludGVycnVwdDsKfSBXSU5FREVWOwoKc3RhdGljIFdJTkVERVYgZGV2c1tdID0KewogIHsgIk5VTCAgICAgIiwKICAgIEFUVFJfQ0hBUnxBVFRSX05VTHxBVFRSX0RFVklDRSwKICAgIG51bF9zdHJhdGVneSwgbnVsX2ludGVycnVwdCB9LAoKICB7ICJDT04gICAgICIsCiAgICBBVFRSX0NIQVJ8QVRUUl9TVERJTnxBVFRSX1NURE9VVHxBVFRSX0ZBU1RDT058QVRUUl9OT1RFT0Z8QVRUUl9ERVZJQ0UsCiAgICBjb25fc3RyYXRlZ3ksIGNvbl9pbnRlcnJ1cHQgfQp9OwoKI2RlZmluZSBOUl9ERVZTIChzaXplb2YoZGV2cykvc2l6ZW9mKFdJTkVERVYpKQoKLyogRE9TIGRhdGEgc2VnbWVudCAqLwp0eXBlZGVmIHN0cnVjdAp7CiAgICBET1NfTElTVE9GTElTVFMgICAgbG9sOwogICAgRE9TX0RFVklDRV9IRUFERVIgIGRldltOUl9ERVZTLTFdOwogICAgV0lORURFVl9USFVOSyAgICAgIHRodW5rW05SX0RFVlNdOwogICAgUkVRX0lPICAgICAgICAgICAgIHJlcTsKICAgIEJZVEUgICAgICAgICAgICAgICBidWZmZXJbQ09OX0JVRkZFUl07Cgp9IERPU19EQVRBU0VHOwoKI2RlZmluZSBET1NfREFUQVNFR19PRkYoeHh4KSBGSUVMRF9PRkZTRVQoRE9TX0RBVEFTRUcsIHh4eCkKCkRXT1JEIERPU19MT0xTZWc7CgpzdGF0aWMgc3RydWN0IF9ET1NfTElTVE9GTElTVFMgKiBET1NNRU1fTE9MKCkKewogICAgcmV0dXJuIFBUUl9SRUFMX1RPX0xJTihISVdPUkQoRE9TX0xPTFNlZyksMCk7Cn0KCgovKiB0aGUgZGV2aWNlIGltcGxlbWVudGF0aW9ucyAqLwpzdGF0aWMgdm9pZCBkb19scmV0KENPTlRFWFQ4NipjdHgpCnsKICBXT1JEICpzdGFjayA9IENUWF9TRUdfT0ZGX1RPX0xJTihjdHgsIGN0eC0+U2VnU3MsIGN0eC0+RXNwKTsKCiAgY3R4LT5FaXAgICA9ICooc3RhY2srKyk7CiAgY3R4LT5TZWdDcyA9ICooc3RhY2srKyk7CiAgY3R4LT5Fc3AgICs9IDIqc2l6ZW9mKFdPUkQpOwp9CgpzdGF0aWMgdm9pZCBkb19zdHJhdGVneShDT05URVhUODYqY3R4LCBpbnQgaWQsIGludCBleHRyYSkKewogIFJFUVVFU1RfSEVBREVSICpoZHIgPSBDVFhfU0VHX09GRl9UT19MSU4oY3R4LCBjdHgtPlNlZ0VzLCBjdHgtPkVieCk7CiAgdm9pZCAqKmhkcl9wdHIgPSBzdHJhdGVneV9kYXRhW2lkXTsKCiAgaWYgKCFoZHJfcHRyKSB7CiAgICBoZHJfcHRyID0gY2FsbG9jKDEsc2l6ZW9mKHZvaWQgKikrZXh0cmEpOwogICAgc3RyYXRlZ3lfZGF0YVtpZF0gPSBoZHJfcHRyOwogIH0KICAqaGRyX3B0ciA9IGhkcjsKICBkb19scmV0KGN0eCk7Cn0KCnN0YXRpYyBSRVFVRVNUX0hFQURFUiAqIGdldF9oZHIoaW50IGlkLCB2b2lkKipleHRyYSkKewogIHZvaWQgKipoZHJfcHRyID0gc3RyYXRlZ3lfZGF0YVtpZF07CiAgaWYgKGV4dHJhKQogICAgKmV4dHJhID0gaGRyX3B0ciA/ICh2b2lkKikoaGRyX3B0cisxKSA6ICh2b2lkICopTlVMTDsKICByZXR1cm4gaGRyX3B0ciA/ICpoZHJfcHRyIDogKHZvaWQgKilOVUxMOwp9CgpzdGF0aWMgdm9pZCBXSU5BUEkgbnVsX3N0cmF0ZWd5KENPTlRFWFQ4NipjdHgpCnsKICBkb19zdHJhdGVneShjdHgsIFNZU1RFTV9TVFJBVEVHWV9OVUwsIDApOwp9CgpzdGF0aWMgdm9pZCBXSU5BUEkgbnVsX2ludGVycnVwdChDT05URVhUODYqY3R4KQp7CiAgUkVRVUVTVF9IRUFERVIgKmhkciA9IGdldF9oZHIoU1lTVEVNX1NUUkFURUdZX05VTCwgTlVMTCk7CiAgLyogZWF0IGV2ZXJ5dGhpbmcgYW5kIHJlY3ljbGUgbm90aGluZyAqLwogIHN3aXRjaCAoaGRyLT5jb21tYW5kKSB7CiAgY2FzZSBDTURfSU5QVVQ6CiAgICAoKFJFUV9JTyopaGRyKS0+Y291bnQgPSAwOwogICAgaGRyLT5zdGF0dXMgPSBTVEFUX0RPTkU7CiAgICBicmVhazsKICBjYXNlIENNRF9TQUZFSU5QVVQ6CiAgICBoZHItPnN0YXR1cyA9IFNUQVRfRE9ORXxTVEFUX0JVU1k7CiAgICBicmVhazsKICBkZWZhdWx0OgogICAgaGRyLT5zdGF0dXMgPSBTVEFUX0RPTkU7CiAgfQogIGRvX2xyZXQoY3R4KTsKfQoKc3RhdGljIHZvaWQgV0lOQVBJIGNvbl9zdHJhdGVneShDT05URVhUODYqY3R4KQp7CiAgZG9fc3RyYXRlZ3koY3R4LCBTWVNURU1fU1RSQVRFR1lfQ09OLCBzaXplb2YoaW50KSk7Cn0KCnN0YXRpYyB2b2lkIFdJTkFQSSBjb25faW50ZXJydXB0KENPTlRFWFQ4NipjdHgpCnsKICBpbnQgKnNjYW47CiAgUkVRVUVTVF9IRUFERVIgKmhkciA9IGdldF9oZHIoU1lTVEVNX1NUUkFURUdZX0NPTiwodm9pZCAqKikmc2Nhbik7CiAgQklPU0RBVEEgKmJpb3MgPSBET1NWTV9CaW9zRGF0YSgpOwogIFdPUkQgQ3VyT2ZzID0gYmlvcy0+TmV4dEtiZENoYXJQdHI7CiAgRE9TX0xJU1RPRkxJU1RTICpsb2wgPSBET1NNRU1fTE9MKCk7CiAgRE9TX0RBVEFTRUcgKmRhdGFzZWcgPSAoRE9TX0RBVEFTRUcgKilsb2w7CiAgQllURSAqbGluZWJ1ZmZlciA9IGRhdGFzZWctPmJ1ZmZlcjsKICBCWVRFICpjdXJidWZmZXIgPSAobG9sLT5vZmZzX3VucmVhZF9DT04pID8KICAgICgoKEJZVEUqKWRhdGFzZWcpICsgbG9sLT5vZmZzX3VucmVhZF9DT04pIDogKEJZVEUqKU5VTEw7CiAgRE9TX0RFVklDRV9IRUFERVIgKmNvbiA9IGRhdGFzZWctPmRldjsKCiAgc3dpdGNoIChoZHItPmNvbW1hbmQpIHsKICBjYXNlIENNRF9JTlBVVDoKICAgIHsKICAgICAgUkVRX0lPICppbyA9IChSRVFfSU8gKiloZHI7CiAgICAgIFdPUkQgY291bnQgPSBpby0+Y291bnQsIGxlbiA9IDA7CiAgICAgIEJZVEUgKmJ1ZmZlciA9IENUWF9TRUdfT0ZGX1RPX0xJTihjdHgsCgkJCQkJU0VMRUNUT1JPRihpby0+YnVmZmVyKSwKCQkJCQkoRFdPUkQpT0ZGU0VUT0YoaW8tPmJ1ZmZlcikpOwoKICAgICAgaGRyLT5zdGF0dXMgPSBTVEFUX0JVU1k7CiAgICAgIC8qIGZpcnN0LCBjaGVjayB3aGV0aGVyIHdlIGFscmVhZHkgaGF2ZSBkYXRhIGluIGxpbmUgYnVmZmVyICovCiAgICAgIGlmIChjdXJidWZmZXIpIHsKCS8qIHllcCwgY29weSBhcyBtdWNoIGFzIHdlIGNhbiAqLwoJQllURSBkYXRhID0gMDsKCXdoaWxlICgobGVuPGNvdW50KSAmJiAoZGF0YSAhPSAnXHInKSkgewoJICBkYXRhID0gKmN1cmJ1ZmZlcisrOwoJICBidWZmZXJbbGVuKytdID0gZGF0YTsKCX0KCWlmIChkYXRhID09ICdccicpIHsKCSAgLyogbGluZSBidWZmZXIgZW1wdGllZCAqLwoJICBsb2wtPm9mZnNfdW5yZWFkX0NPTiA9IDA7CgkgIGN1cmJ1ZmZlciA9IE5VTEw7CgkgIC8qIGlmIHdlJ3JlIG5vdCBpbiByYXcgbW9kZSwgY2FsbCBpdCBhIGRheSAqLwoJICBpZiAoIShjb24tPmF0dHIgJiBBVFRSX1JBVykpIHsKCSAgICBoZHItPnN0YXR1cyA9IFNUQVRfRE9ORTsKCSAgICBpby0+Y291bnQgPSBsZW47CgkgICAgYnJlYWs7CgkgIH0KCX0gZWxzZSB7CgkgIC8qIHN0aWxsIHNvbWUgZGF0YSBsZWZ0ICovCgkgIGxvbC0+b2Zmc191bnJlYWRfQ09OID0gY3VyYnVmZmVyIC0gKEJZVEUqKWxvbDsKCSAgLyogYnV0IGJ1ZmZlciB3YXMgZmlsbGVkLCB3ZSdyZSBkb25lICovCgkgIGhkci0+c3RhdHVzID0gU1RBVF9ET05FOwoJICBpby0+Y291bnQgPSBsZW47CgkgIGJyZWFrOwoJfQogICAgICB9CgogICAgICAvKiBpZiB3ZSdyZSBpbiByYXcgbW9kZSwgd2UganVzdCBuZWVkIHRvIGZpbGwgdGhlIGJ1ZmZlciAqLwogICAgICBpZiAoY29uLT5hdHRyICYgQVRUUl9SQVcpIHsKCXdoaWxlIChsZW48Y291bnQpIHsKCSAgV09SRCBkYXRhOwoKCSAgLyogZG8gd2UgaGF2ZSBhIHdhaXRpbmcgc2NhbmNvZGU/ICovCgkgIGlmICgqc2NhbikgewoJICAgIC8qIHllcywgc3RvcmUgc2NhbmNvZGUgaW4gYnVmZmVyICovCgkgICAgYnVmZmVyW2xlbisrXSA9ICpzY2FuOwoJICAgICpzY2FuID0gMDsKCSAgICBpZiAobGVuPT1jb3VudCkgYnJlYWs7CgkgIH0KCgkgIC8qIGNoZWNrIGZvciBuZXcga2V5Ym9hcmQgaW5wdXQgKi8KCSAgd2hpbGUgKEN1ck9mcyA9PSBiaW9zLT5GaXJzdEtiZENoYXJQdHIpIHsKCSAgICAvKiBubyBpbnB1dCBhdmFpbGFibGUgeWV0LCBzbyB3YWl0Li4uICovCgkgICAgRE9TVk1fV2FpdCggY3R4ICk7CgkgIH0KCSAgLyogcmVhZCBmcm9tIGtleWJvYXJkIHF1ZXVlIChjYWxsIGludDE2PykgKi8KCSAgZGF0YSA9ICgoV09SRCopYmlvcylbQ3VyT2ZzXTsKCSAgQ3VyT2ZzICs9IDI7CgkgIGlmIChDdXJPZnMgPj0gYmlvcy0+S2JkQnVmZmVyRW5kKSBDdXJPZnMgPSBiaW9zLT5LYmRCdWZmZXJTdGFydDsKCSAgYmlvcy0+TmV4dEtiZENoYXJQdHIgPSBDdXJPZnM7CgkgIC8qIGlmIGl0J3MgYW4gZXh0ZW5kZWQga2V5LCBzYXZlIHNjYW5jb2RlICovCgkgIGlmIChMT0JZVEUoZGF0YSkgPT0gMCkgKnNjYW4gPSBISUJZVEUoZGF0YSk7CgkgIC8qIHN0b3JlIEFTQ0lJIGNoYXIgaW4gYnVmZmVyICovCgkgIGJ1ZmZlcltsZW4rK10gPSBMT0JZVEUoZGF0YSk7Cgl9CiAgICAgIH0gZWxzZSB7CgkvKiB3ZSdyZSBub3QgaW4gcmF3IG1vZGUsIHNvIHdlIG5lZWQgdG8gZG8gbGluZSBpbnB1dC4uLiAqLwoJd2hpbGUgKFRSVUUpIHsKCSAgV09SRCBkYXRhOwoJICAvKiBjaGVjayBmb3IgbmV3IGtleWJvYXJkIGlucHV0ICovCgkgIHdoaWxlIChDdXJPZnMgPT0gYmlvcy0+Rmlyc3RLYmRDaGFyUHRyKSB7CgkgICAgLyogbm8gaW5wdXQgYXZhaWxhYmxlIHlldCwgc28gd2FpdC4uLiAqLwoJICAgIERPU1ZNX1dhaXQoIGN0eCApOwoJICB9CgkgIC8qIHJlYWQgZnJvbSBrZXlib2FyZCBxdWV1ZSAoY2FsbCBpbnQxNj8pICovCgkgIGRhdGEgPSAoKFdPUkQqKWJpb3MpW0N1ck9mc107CgkgIEN1ck9mcyArPSAyOwoJICBpZiAoQ3VyT2ZzID49IGJpb3MtPktiZEJ1ZmZlckVuZCkgQ3VyT2ZzID0gYmlvcy0+S2JkQnVmZmVyU3RhcnQ7CgkgIGJpb3MtPk5leHRLYmRDaGFyUHRyID0gQ3VyT2ZzOwoKCSAgaWYgKExPQllURShkYXRhKSA9PSAnXHInKSB7CgkgICAgLyogaXQncyB0aGUgcmV0dXJuIGtleSwgd2UncmUgZG9uZSAqLwoJICAgIGxpbmVidWZmZXJbbGVuKytdID0gTE9CWVRFKGRhdGEpOwoJICAgIGJyZWFrOwoJICB9CgkgIGVsc2UgaWYgKExPQllURShkYXRhKSA+PSAnICcpIHsKCSAgICAvKiBhIGNoYXJhY3RlciAqLwoJICAgIGlmICgobGVuKzEpPENPTl9CVUZGRVIpIHsKCSAgICAgIGxpbmVidWZmZXJbbGVuXSA9IExPQllURShkYXRhKTsKCSAgICAgIFdyaXRlRmlsZShHZXRTdGRIYW5kbGUoU1REX09VVFBVVF9IQU5ETEUpLCAmbGluZWJ1ZmZlcltsZW4rK10sIDEsIE5VTEwsIE5VTEwpOwoJICAgIH0KCSAgICAvKiBlbHNlIGJlZXAsIGJ1dCBJIGRvbid0IGxpa2Ugbm9pc2UgKi8KCSAgfQoJICBlbHNlIHN3aXRjaCAoTE9CWVRFKGRhdGEpKSB7CgkgIGNhc2UgJ1xiJzoKCSAgICBpZiAobGVuPjApIHsKCSAgICAgIGxlbi0tOwoJICAgICAgV3JpdGVGaWxlKEdldFN0ZEhhbmRsZShTVERfT1VUUFVUX0hBTkRMRSksICJcYiBcYiIsIDMsIE5VTEwsIE5VTEwpOwoJICAgIH0KCSAgICBicmVhazsKCSAgfQoJfQoJaWYgKGxlbiA+IGNvdW50KSB7CgkgIC8qIHNhdmUgcmVzdCBvZiBsaW5lIGZvciBsYXRlciAqLwoJICBsb2wtPm9mZnNfdW5yZWFkX0NPTiA9IGxpbmVidWZmZXIgLSAoQllURSopbG9sICsgY291bnQ7CgkgIGxlbiA9IGNvdW50OwoJfQoJbWVtY3B5KGJ1ZmZlciwgbGluZWJ1ZmZlciwgbGVuKTsKICAgICAgfQogICAgICBoZHItPnN0YXR1cyA9IFNUQVRfRE9ORTsKICAgICAgaW8tPmNvdW50ID0gbGVuOwogICAgfQogICAgYnJlYWs7CiAgY2FzZSBDTURfU0FGRUlOUFVUOgogICAgaWYgKGN1cmJ1ZmZlcikgewogICAgICAvKiBzb21lIGxpbmUgaW5wdXQgd2FpdGluZyAqLwogICAgICBoZHItPnN0YXR1cyA9IFNUQVRfRE9ORTsKICAgICAgKChSRVFfU0FGRUlOUFVUKiloZHIpLT5kYXRhID0gKmN1cmJ1ZmZlcjsKICAgIH0KICAgIGVsc2UgaWYgKGNvbi0+YXR0ciAmIEFUVFJfUkFXKSB7CiAgICAgIGlmIChDdXJPZnMgPT0gYmlvcy0+Rmlyc3RLYmRDaGFyUHRyKSB7CgkvKiBubyBpbnB1dCAqLwoJaGRyLT5zdGF0dXMgPSBTVEFUX0RPTkV8U1RBVF9CVVNZOwogICAgICB9IGVsc2UgewoJLyogc29tZSBrZXlib2FyZCBpbnB1dCB3YWl0aW5nICovCgloZHItPnN0YXR1cyA9IFNUQVRfRE9ORTsKCSgoUkVRX1NBRkVJTlBVVCopaGRyKS0+ZGF0YSA9ICgoQllURSopYmlvcylbQ3VyT2ZzXTsKICAgICAgfQogICAgfSBlbHNlIHsKICAgICAgLyogbm8gbGluZSBpbnB1dCAqLwogICAgICBoZHItPnN0YXR1cyA9IFNUQVRfRE9ORXxTVEFUX0JVU1k7CiAgICB9CiAgICBicmVhazsKICBjYXNlIENNRF9JTlNUQVRVUzoKICAgIGlmIChjdXJidWZmZXIpIHsKICAgICAgLyogd2UgaGF2ZSBkYXRhICovCiAgICAgIGhkci0+c3RhdHVzID0gU1RBVF9ET05FOwogICAgfQogICAgZWxzZSBpZiAoY29uLT5hdHRyICYgQVRUUl9SQVcpIHsKICAgICAgaWYgKEN1ck9mcyA9PSBiaW9zLT5GaXJzdEtiZENoYXJQdHIpIHsKCS8qIG5vIGlucHV0ICovCgloZHItPnN0YXR1cyA9IFNUQVRfRE9ORXxTVEFUX0JVU1k7CiAgICAgIH0gZWxzZSB7CgkvKiBzb21lIGtleWJvYXJkIGlucHV0IHdhaXRpbmcgKi8KCWhkci0+c3RhdHVzID0gU1RBVF9ET05FOwogICAgICB9CiAgICB9IGVsc2UgewogICAgICAvKiBubyBsaW5lIGlucHV0ICovCiAgICAgIGhkci0+c3RhdHVzID0gU1RBVF9ET05FfFNUQVRfQlVTWTsKICAgIH0KCiAgICBicmVhazsKICBjYXNlIENNRF9JTkZMVVNIOgogICAgLyogZmx1c2ggbGluZSBhbmQga2V5Ym9hcmQgcXVldWUgKi8KICAgIGxvbC0+b2Zmc191bnJlYWRfQ09OID0gMDsKICAgIGJpb3MtPk5leHRLYmRDaGFyUHRyID0gYmlvcy0+Rmlyc3RLYmRDaGFyUHRyOwogICAgYnJlYWs7CiAgY2FzZSBDTURfT1VUUFVUOgogIGNhc2UgQ01EX1NBRkVPVVRQVVQ6CiAgICB7CiAgICAgIFJFUV9JTyAqaW8gPSAoUkVRX0lPICopaGRyOwogICAgICBCWVRFICpidWZmZXIgPSBDVFhfU0VHX09GRl9UT19MSU4oY3R4LAoJCQkJCVNFTEVDVE9ST0YoaW8tPmJ1ZmZlciksCgkJCQkJKERXT1JEKU9GRlNFVE9GKGlvLT5idWZmZXIpKTsKICAgICAgRFdPUkQgcmVzdWx0ID0gMDsKICAgICAgV3JpdGVGaWxlKEdldFN0ZEhhbmRsZShTVERfT1VUUFVUX0hBTkRMRSksIGJ1ZmZlciwgaW8tPmNvdW50LCAmcmVzdWx0LCBOVUxMKTsKICAgICAgaW8tPmNvdW50ID0gcmVzdWx0OwogICAgICBoZHItPnN0YXR1cyA9IFNUQVRfRE9ORTsKICAgIH0KICAgIGJyZWFrOwogIGRlZmF1bHQ6CiAgICBoZHItPnN0YXR1cyA9IFNUQVRfRE9ORTsKICB9CiAgZG9fbHJldChjdHgpOwp9CgpzdGF0aWMgdm9pZCBJbml0TGlzdE9mTGlzdHMoRE9TX0xJU1RPRkxJU1RTICpET1NfTE9MKQp7Ci8qCk91dHB1dCBvZiBET1MgNi4yMjoKCjAxMzM6MDAyMCAgICAgICAgICAgICAgICAgICAgNkEgMTMtMzMgMDEgQ0MgMDAgMzMgMDEgNTkgMDAgICAgICAgICBqLjMuLi4zLlkuCjAxMzM6MDAzMCAgNzAgMDAgMDAgMDAgNzIgMDIgMDAgMDItNkQgMDAgMzMgMDEgMDAgMDAgMkUgMDUgICBwLi4uci4uLm0uMy4uLi4uCjAxMzM6MDA0MCAgMDAgMDAgRkMgMDQgMDAgMDAgMDMgMDgtOTIgMjEgMTEgRTAgMDQgODAgQzYgMEQgICAuLi4uLi4uLi4hLi4uLi4uCjAxMzM6MDA1MCAgQ0MgMEQgNEUgNTUgNEMgMjAgMjAgMjAtMjAgMjAgMDAgMDAgMDAgMDAgMDAgMDAgICAuLk5VTCAgICAgLi4uLi4uCjAxMzM6MDA2MCAgMDAgNEIgQkEgQzEgMDYgMTQgMDAgMDAtMDAgMDMgMDEgMDAgMDQgNzAgQ0UgRkYgICAuSy4uLi4uLi4uLi4ucC4uCjAxMzM6MDA3MCAgRkYgMDAgMDAgMDAgMDAgMDAgMDAgMDAtMDAgMDEgMDAgMDAgMEQgMDUgMDAgMDAgICAuLi4uLi4uLi4uLi4uLi4uCjAxMzM6MDA4MCAgMDAgRkYgRkYgMDAgMDAgMDAgMDAgRkUtMDAgMDAgRjggMDMgRkYgOUYgNzAgMDIgICAuLi4uLi4uLi4uLi4uLnAuCjAxMzM6MDA5MCAgRDAgNDQgQzggRkQgRDQgNDQgQzggRkQtRDQgNDQgQzggRkQgRDAgNDQgQzggRkQgICAuRC4uLkQuLi5ELi4uRC4uCjAxMzM6MDBBMCAgRDAgNDQgQzggRkQgRDAgNDQgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAuRC4uLkQKKi8KICBET1NfTE9MLT5DWF9JbnQyMV81ZTAxCQk9IDB4MDsKICBET1NfTE9MLT5MUlVfY291bnRfRkNCX2NhY2hlCT0gMHgwOwogIERPU19MT0wtPkxSVV9jb3VudF9GQ0Jfb3BlbgkJPSAweDA7CiAgRE9TX0xPTC0+T0VNX2Z1bmNfaGFuZGxlcgkJPSAtMTsgLyogbm90IGF2YWlsYWJsZSAqLwogIERPU19MT0wtPklOVDIxX29mZnNldAkJPSAweDA7CiAgRE9TX0xPTC0+c2hhcmluZ19yZXRyeV9jb3VudAk9IDM7CiAgRE9TX0xPTC0+c2hhcmluZ19yZXRyeV9kZWxheQk9IDE7CiAgRE9TX0xPTC0+cHRyX2Rpc2tfYnVmCQk9IDB4MDsKICBET1NfTE9MLT5vZmZzX3VucmVhZF9DT04JCT0gMHgwOwogIERPU19MT0wtPnNlZ19maXJzdF9NQ0IJCT0gMHgwOwogIERPU19MT0wtPnB0cl9maXJzdF9EUEIJCT0gMHgwOwogIERPU19MT0wtPnB0cl9maXJzdF9TeXNGaWxlVGFibGUJPSAweDA7CiAgRE9TX0xPTC0+cHRyX2Nsb2NrX2Rldl9oZHIJCT0gMHgwOwogIERPU19MT0wtPnB0cl9DT05fZGV2X2hkcgkJPSAweDA7CiAgRE9TX0xPTC0+bWF4X2J5dGVfcGVyX3NlYwkJPSA1MTI7CiAgRE9TX0xPTC0+cHRyX2Rpc2tfYnVmX2luZm8JCT0gMHgwOwogIERPU19MT0wtPnB0cl9hcnJheV9DRFMJCT0gMHgwOwogIERPU19MT0wtPnB0cl9zeXNfRkNCCQk9IDB4MDsKICBET1NfTE9MLT5ucl9wcm90ZWN0X0ZDQgkJPSAweDA7CiAgRE9TX0xPTC0+bnJfYmxvY2tfZGV2CQk9IDB4MDsKICBET1NfTE9MLT5ucl9hdmFpbF9kcml2ZV9sZXR0ZXJzCT0gMjY7IC8qIEEgLSBaICovCiAgRE9TX0xPTC0+bnJfZHJpdmVzX0pPSU5lZAkJPSAweDA7CiAgRE9TX0xPTC0+cHRyX3NwZWNfcHJnX25hbWVzCQk9IDB4MDsKICBET1NfTE9MLT5wdHJfU0VUVkVSX3ByZ19saXN0CT0gMHgwOyAvKiBubyBTRVRWRVIgbGlzdCAqLwogIERPU19MT0wtPkRPU19ISUdIX0EyMF9mdW5jX29mZnMJPSAweDA7CiAgRE9TX0xPTC0+UFNQX2xhc3RfZXhlYwkJPSAweDA7CiAgRE9TX0xPTC0+QlVGRkVSU192YWwJCT0gOTk7IC8qIG1heGltdW06IDk5ICovCiAgRE9TX0xPTC0+QlVGRkVSU19ucl9sb29rYWhlYWQJPSA4OyAvKiBtYXhpbXVtOiA4ICovCiAgRE9TX0xPTC0+Ym9vdF9kcml2ZQkJCT0gMzsgLyogQzogKi8KICBET1NfTE9MLT5mbGFnX0RXT1JEX21vdmVzCQk9IDB4MDE7IC8qIGkzODYrICovCiAgRE9TX0xPTC0+c2l6ZV9leHRlbmRlZF9tZW0JCT0gMHhmMDAwOyAvKiB2ZXJ5IGhpZ2ggdmFsdWUgKi8KfQoKdm9pZCBET1NERVZfSW5zdGFsbERPU0RldmljZXModm9pZCkKewogIERPU19EQVRBU0VHICpkYXRhc2VnOwogIFdPUkQgc2VnOwogIFdPUkQgc2VsZWN0b3I7CiAgdW5zaWduZWQgaW50IG47CgogIC8qIGFsbG9jYXRlIERPUyBkYXRhIHNlZ21lbnQgb3Igc29tZXRoaW5nICovCiAgZGF0YXNlZyA9IERPU1ZNX0FsbG9jRGF0YVVNQiggc2l6ZW9mKERPU19EQVRBU0VHKSwgJnNlZywgJnNlbGVjdG9yICk7CgogIERPU19MT0xTZWcgPSBNQUtFU0VHUFRSKCBzZWcsIDAgKTsKICBET1NNRU1fTE9MKCktPndpbmVfcm1fbG9sID0gCiAgICAgIE1BS0VTRUdQVFIoIHNlZywgRklFTERfT0ZGU0VUKERPU19MSVNUT0ZMSVNUUywgcHRyX2ZpcnN0X0RQQikgKTsKICBET1NNRU1fTE9MKCktPndpbmVfcG1fbG9sID0gCiAgICAgIE1BS0VTRUdQVFIoIHNlbGVjdG9yLCBGSUVMRF9PRkZTRVQoRE9TX0xJU1RPRkxJU1RTLCBwdHJfZmlyc3RfRFBCKSApOwoKICAvKiBpbml0aWFsaXplIHRoZSBtYWduaWZpY2VudCBMaXN0IE9mIExpc3RzICovCiAgSW5pdExpc3RPZkxpc3RzKCZkYXRhc2VnLT5sb2wpOwoKICAvKiBTZXQgdXAgZmlyc3QgZGV2aWNlIChOVUwpICovCiAgZGF0YXNlZy0+bG9sLk5VTF9kZXYubmV4dF9kZXYgID0gTUFLRVNFR1BUUihzZWcsIERPU19EQVRBU0VHX09GRihkZXZbMF0pKTsKICBkYXRhc2VnLT5sb2wuTlVMX2Rldi5hdHRyICAgICAgPSBkZXZzWzBdLmF0dHI7CiAgZGF0YXNlZy0+bG9sLk5VTF9kZXYuc3RyYXRlZ3kgID0gRE9TX0RBVEFTRUdfT0ZGKHRodW5rWzBdLmxqbXAxKTsKICBkYXRhc2VnLT5sb2wuTlVMX2Rldi5pbnRlcnJ1cHQgPSBET1NfREFUQVNFR19PRkYodGh1bmtbMF0ubGptcDIpOwogIG1lbWNweShkYXRhc2VnLT5sb2wuTlVMX2Rldi5uYW1lLCBkZXZzWzBdLm5hbWUsIDgpOwoKICAvKiBTZXQgdXAgdGhlIHJlbWFpbmluZyBkZXZpY2VzICovCiAgZm9yIChuID0gMTsgbiA8IE5SX0RFVlM7IG4rKykKICB7CiAgICBkYXRhc2VnLT5kZXZbbi0xXS5uZXh0X2RldiAgPSAobisxKSA9PSBOUl9ERVZTID8gTk9ORVhUIDoKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIE1BS0VTRUdQVFIoc2VnLCBET1NfREFUQVNFR19PRkYoZGV2W25dKSk7CiAgICBkYXRhc2VnLT5kZXZbbi0xXS5hdHRyICAgICAgPSBkZXZzW25dLmF0dHI7CiAgICBkYXRhc2VnLT5kZXZbbi0xXS5zdHJhdGVneSAgPSBET1NfREFUQVNFR19PRkYodGh1bmtbbl0ubGptcDEpOwogICAgZGF0YXNlZy0+ZGV2W24tMV0uaW50ZXJydXB0ID0gRE9TX0RBVEFTRUdfT0ZGKHRodW5rW25dLmxqbXAyKTsKICAgIG1lbWNweShkYXRhc2VnLT5kZXZbbi0xXS5uYW1lLCBkZXZzW25dLm5hbWUsIDgpOwogIH0KCiAgLyogU2V0IHVwIHRodW5rcyAqLwogIGZvciAobiA9IDA7IG4gPCBOUl9ERVZTOyBuKyspCiAgewogICAgZGF0YXNlZy0+dGh1bmtbbl0ubGptcDEgICAgID0gTEpNUDsKICAgIGRhdGFzZWctPnRodW5rW25dLnN0cmF0ZWd5ICA9IChSTUNCUFJPQylEUE1JX0FsbG9jSW50ZXJuYWxSTUNCKGRldnNbbl0uc3RyYXRlZ3kpOwogICAgZGF0YXNlZy0+dGh1bmtbbl0ubGptcDIgICAgID0gTEpNUDsKICAgIGRhdGFzZWctPnRodW5rW25dLmludGVycnVwdCA9IChSTUNCUFJPQylEUE1JX0FsbG9jSW50ZXJuYWxSTUNCKGRldnNbbl0uaW50ZXJydXB0KTsKICB9CgogIC8qIENPTiBpcyBkZXZpY2UgMSAqLwogIGRhdGFzZWctPmxvbC5wdHJfQ09OX2Rldl9oZHIgPSBNQUtFU0VHUFRSKHNlZywgRE9TX0RBVEFTRUdfT0ZGKGRldlswXSkpOwp9CgpEV09SRCBET1NERVZfQ29uc29sZSh2b2lkKQp7CiAgcmV0dXJuIERPU01FTV9MT0woKS0+cHRyX0NPTl9kZXZfaGRyOwp9CgpEV09SRCBET1NERVZfRmluZENoYXJEZXZpY2UoY2hhcipuYW1lKQp7CiAgU0VHUFRSIGN1cl9wdHIgPSBNQUtFU0VHUFRSKEhJV09SRChET1NfTE9MU2VnKSwgRklFTERfT0ZGU0VUKERPU19MSVNUT0ZMSVNUUyxOVUxfZGV2KSk7CiAgRE9TX0RFVklDRV9IRUFERVIgKmN1ciA9IFBUUl9SRUFMX1RPX0xJTihTRUxFQ1RPUk9GKGN1cl9wdHIpLE9GRlNFVE9GKGN1cl9wdHIpKTsKICBjaGFyIGRuYW1lWzhdOwogIGludCBjbnQ7CgogIC8qIGdldCBmaXJzdCA4IGNoYXJhY3RlcnMgKi8KICBzdHJuY3B5KGRuYW1lLG5hbWUsOCk7CiAgLyogaWYgbGVzcyB0aGFuIDggY2hhcmFjdGVycywgcGFkIHdpdGggc3BhY2VzICovCiAgZm9yIChjbnQ9MDsgY250PDg7IGNudCsrKQogICAgaWYgKCFkbmFtZVtjbnRdKSBkbmFtZVtjbnRdPScgJzsKCiAgLyogc2VhcmNoIGZvciBjaGFyIGRldmljZXMgd2l0aCB0aGUgcmlnaHQgbmFtZSAqLwogIHdoaWxlIChjdXIgJiYKCSAoKCEoY3VyLT5hdHRyICYgQVRUUl9DSEFSKSkgfHwKCSAgbWVtY21wKGN1ci0+bmFtZSxkbmFtZSw4KSkpIHsKICAgIGN1cl9wdHIgPSBjdXItPm5leHRfZGV2OwogICAgaWYgKGN1cl9wdHIgPT0gTk9ORVhUKSBjdXI9TlVMTDsKICAgIGVsc2UgY3VyID0gUFRSX1JFQUxfVE9fTElOKFNFTEVDVE9ST0YoY3VyX3B0ciksT0ZGU0VUT0YoY3VyX3B0cikpOwogIH0KICByZXR1cm4gY3VyX3B0cjsKfQoKc3RhdGljIHZvaWQgRE9TREVWX0RvUmVxKHZvaWQqcmVxLCBEV09SRCBkZXYpCnsKICBSRVFVRVNUX0hFQURFUiAqaGRyID0gKFJFUVVFU1RfSEVBREVSICopcmVxOwogIERPU19ERVZJQ0VfSEVBREVSICpkaGRyOwogIENPTlRFWFQ4NiBjdHg7CiAgY2hhciAqcGhkcjsKCiAgZGhkciA9IFBUUl9SRUFMX1RPX0xJTihTRUxFQ1RPUk9GKGRldiksT0ZGU0VUT0YoZGV2KSk7CiAgcGhkciA9ICgoY2hhciopRE9TTUVNX0xPTCgpKSArIERPU19EQVRBU0VHX09GRihyZXEpOwoKICAvKiBjb3B5IHJlcXVlc3QgdG8gcmVxdWVzdCBzY3JhdGNoIGFyZWEgKi8KICBtZW1jcHkocGhkciwgcmVxLCBoZHItPnNpemUpOwoKICAvKiBwcmVwYXJlIHRvIGNhbGwgZGV2aWNlIGRyaXZlciAqLwogIG1lbXNldCgmY3R4LCAwLCBzaXplb2YoY3R4KSk7CiAgY3R4LkVGbGFncyB8PSBWODZfRkxBRzsKCiAgLyogRVM6QlggcG9pbnRzIHRvIHJlcXVlc3QgZm9yIHN0cmF0ZWd5IHJvdXRpbmUgKi8KICBjdHguU2VnRXMgPSBISVdPUkQoRE9TX0xPTFNlZyk7CiAgY3R4LkVieCAgID0gRE9TX0RBVEFTRUdfT0ZGKHJlcSk7CgogIC8qIGNhbGwgc3RyYXRlZ3kgcm91dGluZSAqLwogIGN0eC5TZWdDcyA9IFNFTEVDVE9ST0YoZGV2KTsKICBjdHguRWlwICAgPSBkaGRyLT5zdHJhdGVneTsKICBEUE1JX0NhbGxSTVByb2MoJmN0eCwgMCwgMCwgMCk7CgogIC8qIGNhbGwgaW50ZXJydXB0IHJvdXRpbmUgKi8KICBjdHguU2VnQ3MgPSBTRUxFQ1RPUk9GKGRldik7CiAgY3R4LkVpcCAgID0gZGhkci0+aW50ZXJydXB0OwogIERQTUlfQ2FsbFJNUHJvYygmY3R4LCAwLCAwLCAwKTsKCiAgLyogY29tcGxldGVkLCBjb3B5IHJlcXVlc3QgYmFjayAqLwogIG1lbWNweShyZXEsIHBoZHIsIGhkci0+c2l6ZSk7CgogIGlmIChoZHItPnN0YXR1cyAmIFNUQVRfRVJST1IpIHsKICAgIHN3aXRjaCAoaGRyLT5zdGF0dXMgJiBTVEFUX01BU0spIHsKICAgIGNhc2UgMHgwRjogLyogaW52YWxpZCBkaXNrIGNoYW5nZSAqLwogICAgICAvKiB0aGlzIGVycm9yIHNlZW1zIHRvIGZpdCB0aGUgYmlsbCAqLwogICAgICBTZXRMYXN0RXJyb3IoRVJST1JfTk9UX1NBTUVfREVWSUNFKTsKICAgICAgYnJlYWs7CiAgICBkZWZhdWx0OgogICAgICBTZXRMYXN0RXJyb3IoKGhkci0+c3RhdHVzICYgU1RBVF9NQVNLKSArIDB4MTMpOwogICAgICBicmVhazsKICAgIH0KICB9Cn0KCnN0YXRpYyBpbnQgRE9TREVWX0lPKHVuc2lnbmVkIGNtZCwgRFdPUkQgZGV2LCBEV09SRCBidWYsIGludCBidWZsZW4pCnsKICBSRVFfSU8gcmVxOwoKICByZXEuaGRyLnNpemU9c2l6ZW9mKHJlcSk7CiAgcmVxLmhkci51bml0PTA7IC8qIG5vdCBkZWFsaW5nIHdpdGggYmxvY2sgZGV2aWNlcyB5ZXQgKi8KICByZXEuaGRyLmNvbW1hbmQ9Y21kOwogIHJlcS5oZHIuc3RhdHVzPVNUQVRfQlVTWTsKICByZXEubWVkaWE9MDsgLyogbm90IGRlYWxpbmcgd2l0aCBibG9jayBkZXZpY2VzIHlldCAqLwogIHJlcS5idWZmZXI9YnVmOwogIHJlcS5jb3VudD1idWZsZW47CiAgcmVxLnNlY3Rvcj0wOyAvKiBibG9jayBkZXZpY2VzICovCiAgcmVxLnZvbHVtZT0wOyAvKiBibG9jayBkZXZpY2VzICovCgogIERPU0RFVl9Eb1JlcSgmcmVxLCBkZXYpOwoKICByZXR1cm4gcmVxLmNvdW50Owp9CgppbnQgRE9TREVWX1BlZWsoRFdPUkQgZGV2LCBCWVRFKmRhdGEpCnsKICBSRVFfU0FGRUlOUFVUIHJlcTsKCiAgcmVxLmhkci5zaXplPXNpemVvZihyZXEpOwogIHJlcS5oZHIudW5pdD0wOyAvKiBub3QgZGVhbGluZyB3aXRoIGJsb2NrIGRldmljZXMgeWV0ICovCiAgcmVxLmhkci5jb21tYW5kPUNNRF9TQUZFSU5QVVQ7CiAgcmVxLmhkci5zdGF0dXM9U1RBVF9CVVNZOwogIHJlcS5kYXRhPTA7CgogIERPU0RFVl9Eb1JlcSgmcmVxLCBkZXYpOwoKICBpZiAocmVxLmhkci5zdGF0dXMgJiBTVEFUX0JVU1kpIHJldHVybiAwOwoKICAqZGF0YSA9IHJlcS5kYXRhOwogIHJldHVybiAxOwp9CgppbnQgRE9TREVWX1JlYWQoRFdPUkQgZGV2LCBEV09SRCBidWYsIGludCBidWZsZW4pCnsKICByZXR1cm4gRE9TREVWX0lPKENNRF9JTlBVVCwgZGV2LCBidWYsIGJ1Zmxlbik7Cn0KCmludCBET1NERVZfV3JpdGUoRFdPUkQgZGV2LCBEV09SRCBidWYsIGludCBidWZsZW4sIGludCB2ZXJpZnkpCnsKICByZXR1cm4gRE9TREVWX0lPKHZlcmlmeT9DTURfU0FGRU9VVFBVVDpDTURfT1VUUFVULCBkZXYsIGJ1ZiwgYnVmbGVuKTsKfQoKaW50IERPU0RFVl9Jb2N0bFJlYWQoRFdPUkQgZGV2LCBEV09SRCBidWYsIGludCBidWZsZW4pCnsKICByZXR1cm4gRE9TREVWX0lPKENNRF9JTklPQ1RMLCBkZXYsIGJ1ZiwgYnVmbGVuKTsKfQoKaW50IERPU0RFVl9Jb2N0bFdyaXRlKERXT1JEIGRldiwgRFdPUkQgYnVmLCBpbnQgYnVmbGVuKQp7CiAgcmV0dXJuIERPU0RFVl9JTyhDTURfT1VUSU9DVEwsIGRldiwgYnVmLCBidWZsZW4pOwp9Cgp2b2lkIERPU0RFVl9TZXRTaGFyaW5nUmV0cnkoV09SRCBkZWxheSwgV09SRCBjb3VudCkKewogICAgRE9TTUVNX0xPTCgpLT5zaGFyaW5nX3JldHJ5X2RlbGF5ID0gZGVsYXk7CiAgICBpZiAoY291bnQpIERPU01FTV9MT0woKS0+c2hhcmluZ19yZXRyeV9jb3VudCA9IGNvdW50Owp9CgpTRUdQVFIgRE9TREVWX0dldExPTChCT09MIHY4NikKewogICAgaWYgKHY4NikgcmV0dXJuIERPU01FTV9MT0woKS0+d2luZV9ybV9sb2w7CiAgICBlbHNlIHJldHVybiBET1NNRU1fTE9MKCktPndpbmVfcG1fbG9sOwp9Cg==