LyoKICogRE9TIGRldmljZXMKICoKICogQ29weXJpZ2h0IDE5OTkgT3ZlIEvldmVuCiAqCiAqIFRoaXMgbGlicmFyeSBpcyBmcmVlIHNvZnR3YXJlOyB5b3UgY2FuIHJlZGlzdHJpYnV0ZSBpdCBhbmQvb3IKICogbW9kaWZ5IGl0IHVuZGVyIHRoZSB0ZXJtcyBvZiB0aGUgR05VIExlc3NlciBHZW5lcmFsIFB1YmxpYwogKiBMaWNlbnNlIGFzIHB1Ymxpc2hlZCBieSB0aGUgRnJlZSBTb2Z0d2FyZSBGb3VuZGF0aW9uOyBlaXRoZXIKICogdmVyc2lvbiAyLjEgb2YgdGhlIExpY2Vuc2UsIG9yIChhdCB5b3VyIG9wdGlvbikgYW55IGxhdGVyIHZlcnNpb24uCiAqCiAqIFRoaXMgbGlicmFyeSBpcyBkaXN0cmlidXRlZCBpbiB0aGUgaG9wZSB0aGF0IGl0IHdpbGwgYmUgdXNlZnVsLAogKiBidXQgV0lUSE9VVCBBTlkgV0FSUkFOVFk7IHdpdGhvdXQgZXZlbiB0aGUgaW1wbGllZCB3YXJyYW50eSBvZgogKiBNRVJDSEFOVEFCSUxJVFkgb3IgRklUTkVTUyBGT1IgQSBQQVJUSUNVTEFSIFBVUlBPU0UuICBTZWUgdGhlIEdOVQogKiBMZXNzZXIgR2VuZXJhbCBQdWJsaWMgTGljZW5zZSBmb3IgbW9yZSBkZXRhaWxzLgogKgogKiBZb3Ugc2hvdWxkIGhhdmUgcmVjZWl2ZWQgYSBjb3B5IG9mIHRoZSBHTlUgTGVzc2VyIEdlbmVyYWwgUHVibGljCiAqIExpY2Vuc2UgYWxvbmcgd2l0aCB0aGlzIGxpYnJhcnk7IGlmIG5vdCwgd3JpdGUgdG8gdGhlIEZyZWUgU29mdHdhcmUKICogRm91bmRhdGlvbiwgSW5jLiwgNTkgVGVtcGxlIFBsYWNlLCBTdWl0ZSAzMzAsIEJvc3RvbiwgTUEgIDAyMTExLTEzMDcgIFVTQQogKi8KCiNpbmNsdWRlIDxzdGRsaWIuaD4KI2luY2x1ZGUgPHN0cmluZy5oPgojaW5jbHVkZSAid2luZS93aW5iYXNlMTYuaCIKI2luY2x1ZGUgImRvc2V4ZS5oIgojaW5jbHVkZSAid2luZS9kZWJ1Zy5oIgoKI2luY2x1ZGUgInBzaHBhY2sxLmgiCgp0eXBlZGVmIHN0cnVjdCB7CiAgQllURSBsam1wMTsKICBSTUNCUFJPQyBzdHJhdGVneTsKICBCWVRFIGxqbXAyOwogIFJNQ0JQUk9DIGludGVycnVwdDsKfSBXSU5FREVWX1RIVU5LOwoKdHlwZWRlZiBzdHJ1Y3QgewogIEJZVEUgc2l6ZTsgLyogbGVuZ3RoIG9mIGhlYWRlciArIGRhdGEgKi8KICBCWVRFIHVuaXQ7IC8qIHVuaXQgKGJsb2NrIGRldmljZXMgb25seSkgKi8KICBCWVRFIGNvbW1hbmQ7CiAgV09SRCBzdGF0dXM7CiAgQllURSByZXNlcnZlZFs4XTsKfSBSRVFVRVNUX0hFQURFUjsKCnR5cGVkZWYgc3RydWN0IHsKICBSRVFVRVNUX0hFQURFUiBoZHI7CiAgQllURSBtZWRpYTsgLyogbWVkaWEgZGVzY3JpcHRvciBmcm9tIEJQQiAqLwogIFNFR1BUUiBidWZmZXI7CiAgV09SRCBjb3VudDsgLyogYnl0ZS9zZWN0b3IgY291bnQgKi8KICBXT1JEIHNlY3RvcjsgLyogc3RhcnRpbmcgc2VjdG9yIChibG9jayBkZXZpY2VzKSAqLwogIERXT1JEIHZvbHVtZTsgLyogdm9sdW1lIElEIChibG9jayBkZXZpY2VzKSAqLwp9IFJFUV9JTzsKCnR5cGVkZWYgc3RydWN0IHsKICBSRVFVRVNUX0hFQURFUiBoZHI7CiAgQllURSBkYXRhOwp9IFJFUV9TQUZFSU5QVVQ7Cgp0eXBlZGVmIHN0cnVjdAp7CiAgICBEV09SRCBuZXh0X2RldjsKICAgIFdPUkQgIGF0dHI7CiAgICBXT1JEICBzdHJhdGVneTsKICAgIFdPUkQgIGludGVycnVwdDsKICAgIGNoYXIgIG5hbWVbOF07Cn0gRE9TX0RFVklDRV9IRUFERVI7CgovKiBXYXJuaW5nOiBuZWVkIHRvIHJldHVybiBMT0wgcHRyIHcvIG9mZnNldCAwICgmcHRyX2ZpcnN0X0RQQikgdG8gcHJvZ3JhbXMgISAqLwp0eXBlZGVmIHN0cnVjdCBfRE9TX0xJU1RPRkxJU1RTCnsKICAgIFdPUkQgIENYX0ludDIxXzVlMDE7ICAgICAgICAvKiAtMjRkIGNvbnRlbnRzIG9mIENYIGZyb20gSU5UIDIxL0FYPTVFMDFoICovCiAgICBXT1JEICBMUlVfY291bnRfRkNCX2NhY2hlOyAgLyogLTIyZCAqLwogICAgV09SRCAgTFJVX2NvdW50X0ZDQl9vcGVuOyAgIC8qIC0yMGQgKi8KICAgIERXT1JEIE9FTV9mdW5jX2hhbmRsZXI7ICAgICAvKiAtMThkIE9FTSBmdW5jdGlvbiBvZiBJTlQgMjEvQUg9RjhoICovCiAgICBXT1JEICBJTlQyMV9vZmZzZXQ7ICAgICAgICAgLyogLTE0ZCBvZmZzZXQgaW4gRE9TIENTIG9mIGNvZGUgdG8gcmV0dXJuIGZyb20gSU5UIDIxIGNhbGwgKi8KICAgIFdPUkQgIHNoYXJpbmdfcmV0cnlfY291bnQ7ICAvKiAtMTJkICovCiAgICBXT1JEICBzaGFyaW5nX3JldHJ5X2RlbGF5OyAgLyogLTEwZCAqLwogICAgRFdPUkQgcHRyX2Rpc2tfYnVmOyAgICAgICAgIC8qIC04ZCBwdHIgdG8gY3VycmVudCBkaXNrIGJ1ZiAqLwogICAgV09SRCAgb2Zmc191bnJlYWRfQ09OOyAgICAgIC8qIC00ZCBwb2ludGVyIGluIERPUyBkYXRhIHNlZ21lbnQgb2YgdW5yZWFkIENPTiBpbnB1dCAqLwogICAgV09SRCAgc2VnX2ZpcnN0X01DQjsgICAgICAgIC8qIC0yZCAqLwogICAgRFdPUkQgcHRyX2ZpcnN0X0RQQjsgICAgICAgIC8qIDAwICovCiAgICBEV09SRCBwdHJfZmlyc3RfU3lzRmlsZVRhYmxlOyAvKiAwNCAqLwogICAgRFdPUkQgcHRyX2Nsb2NrX2Rldl9oZHI7ICAgIC8qIDA4ICovCiAgICBEV09SRCBwdHJfQ09OX2Rldl9oZHI7ICAgICAgLyogMEMgKi8KICAgIFdPUkQgIG1heF9ieXRlX3Blcl9zZWM7ICAgICAvKiAxMCBtYXhpbXVtIGJ5dGVzIHBlciBzZWN0b3Igb2YgYW55IGJsb2NrIGRldmljZSAqLwogICAgRFdPUkQgcHRyX2Rpc2tfYnVmX2luZm87ICAgIC8qIDEyICovCiAgICBEV09SRCBwdHJfYXJyYXlfQ0RTOyAgICAgICAgLyogMTYgY3VycmVudCBkaXJlY3Rvcnkgc3RydWN0dXJlICovCiAgICBEV09SRCBwdHJfc3lzX0ZDQjsgICAgICAgICAgLyogMUEgKi8KICAgIFdPUkQgIG5yX3Byb3RlY3RfRkNCOyAgICAgICAvKiAxRSAqLwogICAgQllURSAgbnJfYmxvY2tfZGV2OyAgICAgICAgIC8qIDIwICovCiAgICBCWVRFICBucl9hdmFpbF9kcml2ZV9sZXR0ZXJzOyAvKiAyMSAqLwogICAgRE9TX0RFVklDRV9IRUFERVIgTlVMX2RldjsgIC8qIDIyICovCiAgICBCWVRFICBucl9kcml2ZXNfSk9JTmVkOyAgICAgLyogMzQgKi8KICAgIFdPUkQgIHB0cl9zcGVjX3ByZ19uYW1lczsgICAvKiAzNSAqLwogICAgRFdPUkQgcHRyX1NFVFZFUl9wcmdfbGlzdDsgIC8qIDM3ICovCiAgICBXT1JEIERPU19ISUdIX0EyMF9mdW5jX29mZnM7LyogM0IgKi8KICAgIFdPUkQgUFNQX2xhc3RfZXhlYzsgICAgICAgICAvKiAzRCBpZiBET1MgaW4gSE1BOiBQU1Agb2YgcHJvZ3JhbSBleGVjdXRlZCBsYXN0OyBpZiBET1MgbG93OiAwMDAwaCAqLwogICAgV09SRCBCVUZGRVJTX3ZhbDsgICAgICAgICAgIC8qIDNGICovCiAgICBXT1JEIEJVRkZFUlNfbnJfbG9va2FoZWFkOyAgLyogNDEgKi8KICAgIEJZVEUgYm9vdF9kcml2ZTsgICAgICAgICAgICAvKiA0MyAqLwogICAgQllURSBmbGFnX0RXT1JEX21vdmVzOyAgICAgIC8qIDQ0IDAxaCBmb3IgMzg2KywgMDBoIG90aGVyd2lzZSAqLwogICAgV09SRCBzaXplX2V4dGVuZGVkX21lbTsgICAgIC8qIDQ1IHNpemUgb2YgZXh0ZW5kZWQgbWVtIGluIEtCICovCiAgICBTRUdQVFIgd2luZV9ybV9sb2w7ICAgICAgICAgLyogLS0gd2luZTogUmVhbCBtb2RlIHBvaW50ZXIgdG8gTE9MICovCiAgICBTRUdQVFIgd2luZV9wbV9sb2w7ICAgICAgICAgLyogLS0gd2luZTogUHJvdGVjdGVkIG1vZGUgcG9pbnRlciB0byBMT0wgKi8KfSBET1NfTElTVE9GTElTVFM7CgojaW5jbHVkZSAicG9wcGFjay5oIgoKI2RlZmluZSBDT05fQlVGRkVSIDEyOAoKZW51bSBzdHJhdGVneSB7IFNZU1RFTV9TVFJBVEVHWV9OVUwsIFNZU1RFTV9TVFJBVEVHWV9DT04sIE5CX1NZU1RFTV9TVFJBVEVHSUVTIH07CgpzdGF0aWMgdm9pZCAqc3RyYXRlZ3lfZGF0YVtOQl9TWVNURU1fU1RSQVRFR0lFU107CgojZGVmaW5lIE5PTkVYVCAoKERXT1JEKS0xKQoKI2RlZmluZSBBVFRSX1NURElOICAgICAweDAwMDEKI2RlZmluZSBBVFRSX1NURE9VVCAgICAweDAwMDIKI2RlZmluZSBBVFRSX05VTCAgICAgICAweDAwMDQKI2RlZmluZSBBVFRSX0NMT0NLICAgICAweDAwMDgKI2RlZmluZSBBVFRSX0ZBU1RDT04gICAweDAwMTAKI2RlZmluZSBBVFRSX1JBVyAgICAgICAweDAwMjAKI2RlZmluZSBBVFRSX05PVEVPRiAgICAweDAwNDAKI2RlZmluZSBBVFRSX0RFVklDRSAgICAweDAwODAKI2RlZmluZSBBVFRSX1JFTU9WQUJMRSAweDA4MDAKI2RlZmluZSBBVFRSX05PTklCTSAgICAweDIwMDAgLyogYmxvY2sgZGV2aWNlcyAqLwojZGVmaW5lIEFUVFJfVU5USUxCVVNZIDB4MjAwMCAvKiBjaGFyIGRldmljZXMgKi8KI2RlZmluZSBBVFRSX0lPQ1RMICAgICAweDQwMDAKI2RlZmluZSBBVFRSX0NIQVIgICAgICAweDgwMDAKCiNkZWZpbmUgQ01EX0lOSVQgICAgICAgMAojZGVmaW5lIENNRF9NRURJQUNIRUNLIDEgLyogYmxvY2sgZGV2aWNlcyAqLwojZGVmaW5lIENNRF9CVUlMREJQQiAgIDIgLyogYmxvY2sgZGV2aWNlcyAqLwojZGVmaW5lIENNRF9JTklPQ1RMICAgIDMKI2RlZmluZSBDTURfSU5QVVQgICAgICA0IC8qIHJlYWQgZGF0YSAqLwojZGVmaW5lIENNRF9TQUZFSU5QVVQgIDUgLyogIm5vbi1kZXN0cnVjdGl2ZSBpbnB1dCBubyB3YWl0IiwgY2hhciBkZXZpY2VzICovCiNkZWZpbmUgQ01EX0lOU1RBVFVTICAgNiAvKiBjaGFyIGRldmljZXMgKi8KI2RlZmluZSBDTURfSU5GTFVTSCAgICA3IC8qIGNoYXIgZGV2aWNlcyAqLwojZGVmaW5lIENNRF9PVVRQVVQgICAgIDggLyogd3JpdGUgZGF0YSAqLwojZGVmaW5lIENNRF9TQUZFT1VUUFVUIDkgLyogd3JpdGUgZGF0YSB3aXRoIHZlcmlmeSAqLwojZGVmaW5lIENNRF9PVVRTVEFUVVMgMTAgLyogY2hhciBkZXZpY2VzICovCiNkZWZpbmUgQ01EX09VVEZMVVNIICAxMSAvKiBjaGFyIGRldmljZXMgKi8KI2RlZmluZSBDTURfT1VUSU9DVEwgIDEyCiNkZWZpbmUgQ01EX0RFVk9QRU4gICAxMwojZGVmaW5lIENNRF9ERVZDTE9TRSAgMTQKI2RlZmluZSBDTURfUkVNT1ZBQkxFIDE1IC8qIGJsb2NrIGRldmljZXMgKi8KI2RlZmluZSBDTURfVU5USUxCVVNZIDE2IC8qIG91dHB1dCB1bnRpbCBidXN5ICovCgojZGVmaW5lIFNUQVRfTUFTSyAgMHgwMEZGCiNkZWZpbmUgU1RBVF9ET05FICAweDAxMDAKI2RlZmluZSBTVEFUX0JVU1kgIDB4MDIwMAojZGVmaW5lIFNUQVRfRVJST1IgMHg4MDAwCgojZGVmaW5lIExKTVAgMHhlYQoKCi8qIHByb3RvdHlwZXMgKi8Kc3RhdGljIHZvaWQgV0lOQVBJIG51bF9zdHJhdGVneShDT05URVhUODYqY3R4KTsKc3RhdGljIHZvaWQgV0lOQVBJIG51bF9pbnRlcnJ1cHQoQ09OVEVYVDg2KmN0eCk7CnN0YXRpYyB2b2lkIFdJTkFQSSBjb25fc3RyYXRlZ3koQ09OVEVYVDg2KmN0eCk7CnN0YXRpYyB2b2lkIFdJTkFQSSBjb25faW50ZXJydXB0KENPTlRFWFQ4NipjdHgpOwoKLyogZGV2aWNlcyAqLwp0eXBlZGVmIHN0cnVjdAp7CiAgICBjaGFyIG5hbWVbOF07CiAgICBXT1JEIGF0dHI7CiAgICBSTUNCUFJPQyBzdHJhdGVneTsKICAgIFJNQ0JQUk9DIGludGVycnVwdDsKfSBXSU5FREVWOwoKc3RhdGljIFdJTkVERVYgZGV2c1tdID0KewogIHsgIk5VTCAgICAgIiwKICAgIEFUVFJfQ0hBUnxBVFRSX05VTHxBVFRSX0RFVklDRSwKICAgIG51bF9zdHJhdGVneSwgbnVsX2ludGVycnVwdCB9LAoKICB7ICJDT04gICAgICIsCiAgICBBVFRSX0NIQVJ8QVRUUl9TVERJTnxBVFRSX1NURE9VVHxBVFRSX0ZBU1RDT058QVRUUl9OT1RFT0Z8QVRUUl9ERVZJQ0UsCiAgICBjb25fc3RyYXRlZ3ksIGNvbl9pbnRlcnJ1cHQgfQp9OwoKI2RlZmluZSBOUl9ERVZTIChzaXplb2YoZGV2cykvc2l6ZW9mKFdJTkVERVYpKQoKLyogRE9TIGRhdGEgc2VnbWVudCAqLwp0eXBlZGVmIHN0cnVjdAp7CiAgICBET1NfTElTVE9GTElTVFMgICAgbG9sOwogICAgRE9TX0RFVklDRV9IRUFERVIgIGRldltOUl9ERVZTLTFdOwogICAgV0lORURFVl9USFVOSyAgICAgIHRodW5rW05SX0RFVlNdOwogICAgUkVRX0lPICAgICAgICAgICAgIHJlcTsKICAgIEJZVEUgICAgICAgICAgICAgICBidWZmZXJbQ09OX0JVRkZFUl07Cgp9IERPU19EQVRBU0VHOwoKI2RlZmluZSBET1NfREFUQVNFR19PRkYoeHh4KSBGSUVMRF9PRkZTRVQoRE9TX0RBVEFTRUcsIHh4eCkKCkRXT1JEIERPU19MT0xTZWc7CgpzdGF0aWMgc3RydWN0IF9ET1NfTElTVE9GTElTVFMgKiBET1NNRU1fTE9MKHZvaWQpCnsKICAgIHJldHVybiBQVFJfUkVBTF9UT19MSU4oSElXT1JEKERPU19MT0xTZWcpLDApOwp9CgoKLyogdGhlIGRldmljZSBpbXBsZW1lbnRhdGlvbnMgKi8Kc3RhdGljIHZvaWQgZG9fbHJldChDT05URVhUODYqY3R4KQp7CiAgV09SRCAqc3RhY2sgPSBDVFhfU0VHX09GRl9UT19MSU4oY3R4LCBjdHgtPlNlZ1NzLCBjdHgtPkVzcCk7CgogIGN0eC0+RWlwICAgPSAqKHN0YWNrKyspOwogIGN0eC0+U2VnQ3MgPSAqKHN0YWNrKyspOwogIGN0eC0+RXNwICArPSAyKnNpemVvZihXT1JEKTsKfQoKc3RhdGljIHZvaWQgZG9fc3RyYXRlZ3koQ09OVEVYVDg2KmN0eCwgaW50IGlkLCBpbnQgZXh0cmEpCnsKICBSRVFVRVNUX0hFQURFUiAqaGRyID0gQ1RYX1NFR19PRkZfVE9fTElOKGN0eCwgY3R4LT5TZWdFcywgY3R4LT5FYngpOwogIHZvaWQgKipoZHJfcHRyID0gc3RyYXRlZ3lfZGF0YVtpZF07CgogIGlmICghaGRyX3B0cikgewogICAgaGRyX3B0ciA9IGNhbGxvYygxLHNpemVvZih2b2lkICopK2V4dHJhKTsKICAgIHN0cmF0ZWd5X2RhdGFbaWRdID0gaGRyX3B0cjsKICB9CiAgKmhkcl9wdHIgPSBoZHI7CiAgZG9fbHJldChjdHgpOwp9CgpzdGF0aWMgUkVRVUVTVF9IRUFERVIgKiBnZXRfaGRyKGludCBpZCwgdm9pZCoqZXh0cmEpCnsKICB2b2lkICoqaGRyX3B0ciA9IHN0cmF0ZWd5X2RhdGFbaWRdOwogIGlmIChleHRyYSkKICAgICpleHRyYSA9IGhkcl9wdHIgPyAodm9pZCopKGhkcl9wdHIrMSkgOiAodm9pZCAqKU5VTEw7CiAgcmV0dXJuIGhkcl9wdHIgPyAqaGRyX3B0ciA6ICh2b2lkICopTlVMTDsKfQoKc3RhdGljIHZvaWQgV0lOQVBJIG51bF9zdHJhdGVneShDT05URVhUODYqY3R4KQp7CiAgZG9fc3RyYXRlZ3koY3R4LCBTWVNURU1fU1RSQVRFR1lfTlVMLCAwKTsKfQoKc3RhdGljIHZvaWQgV0lOQVBJIG51bF9pbnRlcnJ1cHQoQ09OVEVYVDg2KmN0eCkKewogIFJFUVVFU1RfSEVBREVSICpoZHIgPSBnZXRfaGRyKFNZU1RFTV9TVFJBVEVHWV9OVUwsIE5VTEwpOwogIC8qIGVhdCBldmVyeXRoaW5nIGFuZCByZWN5Y2xlIG5vdGhpbmcgKi8KICBzd2l0Y2ggKGhkci0+Y29tbWFuZCkgewogIGNhc2UgQ01EX0lOUFVUOgogICAgKChSRVFfSU8qKWhkciktPmNvdW50ID0gMDsKICAgIGhkci0+c3RhdHVzID0gU1RBVF9ET05FOwogICAgYnJlYWs7CiAgY2FzZSBDTURfU0FGRUlOUFVUOgogICAgaGRyLT5zdGF0dXMgPSBTVEFUX0RPTkV8U1RBVF9CVVNZOwogICAgYnJlYWs7CiAgZGVmYXVsdDoKICAgIGhkci0+c3RhdHVzID0gU1RBVF9ET05FOwogIH0KICBkb19scmV0KGN0eCk7Cn0KCnN0YXRpYyB2b2lkIFdJTkFQSSBjb25fc3RyYXRlZ3koQ09OVEVYVDg2KmN0eCkKewogIGRvX3N0cmF0ZWd5KGN0eCwgU1lTVEVNX1NUUkFURUdZX0NPTiwgc2l6ZW9mKGludCkpOwp9CgpzdGF0aWMgdm9pZCBXSU5BUEkgY29uX2ludGVycnVwdChDT05URVhUODYqY3R4KQp7CiAgaW50ICpzY2FuOwogIFJFUVVFU1RfSEVBREVSICpoZHIgPSBnZXRfaGRyKFNZU1RFTV9TVFJBVEVHWV9DT04sKHZvaWQgKiopJnNjYW4pOwogIEJJT1NEQVRBICpiaW9zID0gRE9TVk1fQmlvc0RhdGEoKTsKICBXT1JEIEN1ck9mcyA9IGJpb3MtPk5leHRLYmRDaGFyUHRyOwogIERPU19MSVNUT0ZMSVNUUyAqbG9sID0gRE9TTUVNX0xPTCgpOwogIERPU19EQVRBU0VHICpkYXRhc2VnID0gKERPU19EQVRBU0VHICopbG9sOwogIEJZVEUgKmxpbmVidWZmZXIgPSBkYXRhc2VnLT5idWZmZXI7CiAgQllURSAqY3VyYnVmZmVyID0gKGxvbC0+b2Zmc191bnJlYWRfQ09OKSA/CiAgICAoKChCWVRFKilkYXRhc2VnKSArIGxvbC0+b2Zmc191bnJlYWRfQ09OKSA6IChCWVRFKilOVUxMOwogIERPU19ERVZJQ0VfSEVBREVSICpjb24gPSBkYXRhc2VnLT5kZXY7CiAgRFdPUkQgdzsKCiAgc3dpdGNoIChoZHItPmNvbW1hbmQpIHsKICBjYXNlIENNRF9JTlBVVDoKICAgIHsKICAgICAgUkVRX0lPICppbyA9IChSRVFfSU8gKiloZHI7CiAgICAgIFdPUkQgY291bnQgPSBpby0+Y291bnQsIGxlbiA9IDA7CiAgICAgIEJZVEUgKmJ1ZmZlciA9IENUWF9TRUdfT0ZGX1RPX0xJTihjdHgsCgkJCQkJU0VMRUNUT1JPRihpby0+YnVmZmVyKSwKCQkJCQkoRFdPUkQpT0ZGU0VUT0YoaW8tPmJ1ZmZlcikpOwoKICAgICAgaGRyLT5zdGF0dXMgPSBTVEFUX0JVU1k7CiAgICAgIC8qIGZpcnN0LCBjaGVjayB3aGV0aGVyIHdlIGFscmVhZHkgaGF2ZSBkYXRhIGluIGxpbmUgYnVmZmVyICovCiAgICAgIGlmIChjdXJidWZmZXIpIHsKCS8qIHllcCwgY29weSBhcyBtdWNoIGFzIHdlIGNhbiAqLwoJQllURSBkYXRhID0gMDsKCXdoaWxlICgobGVuPGNvdW50KSAmJiAoZGF0YSAhPSAnXHInKSkgewoJICBkYXRhID0gKmN1cmJ1ZmZlcisrOwoJICBidWZmZXJbbGVuKytdID0gZGF0YTsKCX0KCWlmIChkYXRhID09ICdccicpIHsKCSAgLyogbGluZSBidWZmZXIgZW1wdGllZCAqLwoJICBsb2wtPm9mZnNfdW5yZWFkX0NPTiA9IDA7CgkgIGN1cmJ1ZmZlciA9IE5VTEw7CgkgIC8qIGlmIHdlJ3JlIG5vdCBpbiByYXcgbW9kZSwgY2FsbCBpdCBhIGRheSAqLwoJICBpZiAoIShjb24tPmF0dHIgJiBBVFRSX1JBVykpIHsKCSAgICBoZHItPnN0YXR1cyA9IFNUQVRfRE9ORTsKCSAgICBpby0+Y291bnQgPSBsZW47CgkgICAgYnJlYWs7CgkgIH0KCX0gZWxzZSB7CgkgIC8qIHN0aWxsIHNvbWUgZGF0YSBsZWZ0ICovCgkgIGxvbC0+b2Zmc191bnJlYWRfQ09OID0gY3VyYnVmZmVyIC0gKEJZVEUqKWxvbDsKCSAgLyogYnV0IGJ1ZmZlciB3YXMgZmlsbGVkLCB3ZSdyZSBkb25lICovCgkgIGhkci0+c3RhdHVzID0gU1RBVF9ET05FOwoJICBpby0+Y291bnQgPSBsZW47CgkgIGJyZWFrOwoJfQogICAgICB9CgogICAgICAvKiBpZiB3ZSdyZSBpbiByYXcgbW9kZSwgd2UganVzdCBuZWVkIHRvIGZpbGwgdGhlIGJ1ZmZlciAqLwogICAgICBpZiAoY29uLT5hdHRyICYgQVRUUl9SQVcpIHsKCXdoaWxlIChsZW48Y291bnQpIHsKCSAgV09SRCBkYXRhOwoKCSAgLyogZG8gd2UgaGF2ZSBhIHdhaXRpbmcgc2NhbmNvZGU/ICovCgkgIGlmICgqc2NhbikgewoJICAgIC8qIHllcywgc3RvcmUgc2NhbmNvZGUgaW4gYnVmZmVyICovCgkgICAgYnVmZmVyW2xlbisrXSA9ICpzY2FuOwoJICAgICpzY2FuID0gMDsKCSAgICBpZiAobGVuPT1jb3VudCkgYnJlYWs7CgkgIH0KCgkgIC8qIGNoZWNrIGZvciBuZXcga2V5Ym9hcmQgaW5wdXQgKi8KCSAgd2hpbGUgKEN1ck9mcyA9PSBiaW9zLT5GaXJzdEtiZENoYXJQdHIpIHsKCSAgICAvKiBubyBpbnB1dCBhdmFpbGFibGUgeWV0LCBzbyB3YWl0Li4uICovCgkgICAgRE9TVk1fV2FpdCggY3R4ICk7CgkgIH0KCSAgLyogcmVhZCBmcm9tIGtleWJvYXJkIHF1ZXVlIChjYWxsIGludDE2PykgKi8KCSAgZGF0YSA9ICgoV09SRCopYmlvcylbQ3VyT2ZzXTsKCSAgQ3VyT2ZzICs9IDI7CgkgIGlmIChDdXJPZnMgPj0gYmlvcy0+S2JkQnVmZmVyRW5kKSBDdXJPZnMgPSBiaW9zLT5LYmRCdWZmZXJTdGFydDsKCSAgYmlvcy0+TmV4dEtiZENoYXJQdHIgPSBDdXJPZnM7CgkgIC8qIGlmIGl0J3MgYW4gZXh0ZW5kZWQga2V5LCBzYXZlIHNjYW5jb2RlICovCgkgIGlmIChMT0JZVEUoZGF0YSkgPT0gMCkgKnNjYW4gPSBISUJZVEUoZGF0YSk7CgkgIC8qIHN0b3JlIEFTQ0lJIGNoYXIgaW4gYnVmZmVyICovCgkgIGJ1ZmZlcltsZW4rK10gPSBMT0JZVEUoZGF0YSk7Cgl9CiAgICAgIH0gZWxzZSB7CgkvKiB3ZSdyZSBub3QgaW4gcmF3IG1vZGUsIHNvIHdlIG5lZWQgdG8gZG8gbGluZSBpbnB1dC4uLiAqLwoJd2hpbGUgKFRSVUUpIHsKCSAgV09SRCBkYXRhOwoJICAvKiBjaGVjayBmb3IgbmV3IGtleWJvYXJkIGlucHV0ICovCgkgIHdoaWxlIChDdXJPZnMgPT0gYmlvcy0+Rmlyc3RLYmRDaGFyUHRyKSB7CgkgICAgLyogbm8gaW5wdXQgYXZhaWxhYmxlIHlldCwgc28gd2FpdC4uLiAqLwoJICAgIERPU1ZNX1dhaXQoIGN0eCApOwoJICB9CgkgIC8qIHJlYWQgZnJvbSBrZXlib2FyZCBxdWV1ZSAoY2FsbCBpbnQxNj8pICovCgkgIGRhdGEgPSAoKFdPUkQqKWJpb3MpW0N1ck9mc107CgkgIEN1ck9mcyArPSAyOwoJICBpZiAoQ3VyT2ZzID49IGJpb3MtPktiZEJ1ZmZlckVuZCkgQ3VyT2ZzID0gYmlvcy0+S2JkQnVmZmVyU3RhcnQ7CgkgIGJpb3MtPk5leHRLYmRDaGFyUHRyID0gQ3VyT2ZzOwoKCSAgaWYgKExPQllURShkYXRhKSA9PSAnXHInKSB7CgkgICAgLyogaXQncyB0aGUgcmV0dXJuIGtleSwgd2UncmUgZG9uZSAqLwoJICAgIGxpbmVidWZmZXJbbGVuKytdID0gTE9CWVRFKGRhdGEpOwoJICAgIGJyZWFrOwoJICB9CgkgIGVsc2UgaWYgKExPQllURShkYXRhKSA+PSAnICcpIHsKCSAgICAvKiBhIGNoYXJhY3RlciAqLwoJICAgIGlmICgobGVuKzEpPENPTl9CVUZGRVIpIHsKCSAgICAgIGxpbmVidWZmZXJbbGVuXSA9IExPQllURShkYXRhKTsKCSAgICAgIFdyaXRlRmlsZShHZXRTdGRIYW5kbGUoU1REX09VVFBVVF9IQU5ETEUpLCAmbGluZWJ1ZmZlcltsZW4rK10sIDEsICZ3LCBOVUxMKTsKCSAgICB9CgkgICAgLyogZWxzZSBiZWVwLCBidXQgSSBkb24ndCBsaWtlIG5vaXNlICovCgkgIH0KCSAgZWxzZSBzd2l0Y2ggKExPQllURShkYXRhKSkgewoJICBjYXNlICdcYic6CgkgICAgaWYgKGxlbj4wKSB7CgkgICAgICBsZW4tLTsKCSAgICAgIFdyaXRlRmlsZShHZXRTdGRIYW5kbGUoU1REX09VVFBVVF9IQU5ETEUpLCAiXGIgXGIiLCAzLCAmdywgTlVMTCk7CgkgICAgfQoJICAgIGJyZWFrOwoJICB9Cgl9CglpZiAobGVuID4gY291bnQpIHsKCSAgLyogc2F2ZSByZXN0IG9mIGxpbmUgZm9yIGxhdGVyICovCgkgIGxvbC0+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+bG9sLnB0cl9DT05fZGV2X2hkciA9IE1BS0VTRUdQVFIoc2VnLCBET1NfREFUQVNFR19PRkYoZGV2WzBdKSk7Cn0KCkRXT1JEIERPU0RFVl9Db25zb2xlKHZvaWQpCnsKICByZXR1cm4gRE9TTUVNX0xPTCgpLT5wdHJfQ09OX2Rldl9oZHI7Cn0KCkRXT1JEIERPU0RFVl9GaW5kQ2hhckRldmljZShjaGFyKm5hbWUpCnsKICBTRUdQVFIgY3VyX3B0ciA9IE1BS0VTRUdQVFIoSElXT1JEKERPU19MT0xTZWcpLCBGSUVMRF9PRkZTRVQoRE9TX0xJU1RPRkxJU1RTLE5VTF9kZXYpKTsKICBET1NfREVWSUNFX0hFQURFUiAqY3VyID0gUFRSX1JFQUxfVE9fTElOKFNFTEVDVE9ST0YoY3VyX3B0ciksT0ZGU0VUT0YoY3VyX3B0cikpOwogIGNoYXIgZG5hbWVbOF07CiAgaW50IGNudDsKCiAgLyogZ2V0IGZpcnN0IDggY2hhcmFjdGVycyAqLwogIC8qIGlmIGxlc3MgdGhhbiA4IGNoYXJhY3RlcnMsIHBhZCB3aXRoIHNwYWNlcyAqLwogIGZvciAoY250PTA7IG5hbWVbY250XSAmJiBjbnQ8ODsgY250KyspCiAgICBkbmFtZVtjbnRdPW5hbWVbY250XTsKCiAgd2hpbGUoY250PDgpIGRuYW1lW2NudCsrXSA9ICcgJzsKCiAgLyogc2VhcmNoIGZvciBjaGFyIGRldmljZXMgd2l0aCB0aGUgcmlnaHQgbmFtZSAqLwogIHdoaWxlIChjdXIgJiYKCSAoKCEoY3VyLT5hdHRyICYgQVRUUl9DSEFSKSkgfHwKCSAgbWVtY21wKGN1ci0+bmFtZSxkbmFtZSw4KSkpIHsKICAgIGN1cl9wdHIgPSBjdXItPm5leHRfZGV2OwogICAgaWYgKGN1cl9wdHIgPT0gTk9ORVhUKSBjdXI9TlVMTDsKICAgIGVsc2UgY3VyID0gUFRSX1JFQUxfVE9fTElOKFNFTEVDVE9ST0YoY3VyX3B0ciksT0ZGU0VUT0YoY3VyX3B0cikpOwogIH0KICByZXR1cm4gY3VyX3B0cjsKfQoKc3RhdGljIHZvaWQgRE9TREVWX0RvUmVxKHZvaWQqcmVxLCBEV09SRCBkZXYpCnsKICBSRVFVRVNUX0hFQURFUiAqaGRyID0gKFJFUVVFU1RfSEVBREVSICopcmVxOwogIERPU19ERVZJQ0VfSEVBREVSICpkaGRyOwogIENPTlRFWFQ4NiBjdHg7CiAgY2hhciAqcGhkcjsKCiAgZGhkciA9IFBUUl9SRUFMX1RPX0xJTihTRUxFQ1RPUk9GKGRldiksT0ZGU0VUT0YoZGV2KSk7CiAgcGhkciA9ICgoY2hhciopRE9TTUVNX0xPTCgpKSArIERPU19EQVRBU0VHX09GRihyZXEpOwoKICAvKiBjb3B5IHJlcXVlc3QgdG8gcmVxdWVzdCBzY3JhdGNoIGFyZWEgKi8KICBtZW1jcHkocGhkciwgcmVxLCBoZHItPnNpemUpOwoKICAvKiBwcmVwYXJlIHRvIGNhbGwgZGV2aWNlIGRyaXZlciAqLwogIG1lbXNldCgmY3R4LCAwLCBzaXplb2YoY3R4KSk7CiAgY3R4LkVGbGFncyB8PSBWODZfRkxBRzsKCiAgLyogRVM6QlggcG9pbnRzIHRvIHJlcXVlc3QgZm9yIHN0cmF0ZWd5IHJvdXRpbmUgKi8KICBjdHguU2VnRXMgPSBISVdPUkQoRE9TX0xPTFNlZyk7CiAgY3R4LkVieCAgID0gRE9TX0RBVEFTRUdfT0ZGKHJlcSk7CgogIC8qIGNhbGwgc3RyYXRlZ3kgcm91dGluZSAqLwogIGN0eC5TZWdDcyA9IFNFTEVDVE9ST0YoZGV2KTsKICBjdHguRWlwICAgPSBkaGRyLT5zdHJhdGVneTsKICBEUE1JX0NhbGxSTVByb2MoJmN0eCwgMCwgMCwgMCk7CgogIC8qIGNhbGwgaW50ZXJydXB0IHJvdXRpbmUgKi8KICBjdHguU2VnQ3MgPSBTRUxFQ1RPUk9GKGRldik7CiAgY3R4LkVpcCAgID0gZGhkci0+aW50ZXJydXB0OwogIERQTUlfQ2FsbFJNUHJvYygmY3R4LCAwLCAwLCAwKTsKCiAgLyogY29tcGxldGVkLCBjb3B5IHJlcXVlc3QgYmFjayAqLwogIG1lbWNweShyZXEsIHBoZHIsIGhkci0+c2l6ZSk7CgogIGlmIChoZHItPnN0YXR1cyAmIFNUQVRfRVJST1IpIHsKICAgIHN3aXRjaCAoaGRyLT5zdGF0dXMgJiBTVEFUX01BU0spIHsKICAgIGNhc2UgMHgwRjogLyogaW52YWxpZCBkaXNrIGNoYW5nZSAqLwogICAgICAvKiB0aGlzIGVycm9yIHNlZW1zIHRvIGZpdCB0aGUgYmlsbCAqLwogICAgICBTZXRMYXN0RXJyb3IoRVJST1JfTk9UX1NBTUVfREVWSUNFKTsKICAgICAgYnJlYWs7CiAgICBkZWZhdWx0OgogICAgICBTZXRMYXN0RXJyb3IoKGhkci0+c3RhdHVzICYgU1RBVF9NQVNLKSArIDB4MTMpOwogICAgICBicmVhazsKICAgIH0KICB9Cn0KCnN0YXRpYyBpbnQgRE9TREVWX0lPKHVuc2lnbmVkIGNtZCwgRFdPUkQgZGV2LCBEV09SRCBidWYsIGludCBidWZsZW4pCnsKICBSRVFfSU8gcmVxOwoKICByZXEuaGRyLnNpemU9c2l6ZW9mKHJlcSk7CiAgcmVxLmhkci51bml0PTA7IC8qIG5vdCBkZWFsaW5nIHdpdGggYmxvY2sgZGV2aWNlcyB5ZXQgKi8KICByZXEuaGRyLmNvbW1hbmQ9Y21kOwogIHJlcS5oZHIuc3RhdHVzPVNUQVRfQlVTWTsKICByZXEubWVkaWE9MDsgLyogbm90IGRlYWxpbmcgd2l0aCBibG9jayBkZXZpY2VzIHlldCAqLwogIHJlcS5idWZmZXI9YnVmOwogIHJlcS5jb3VudD1idWZsZW47CiAgcmVxLnNlY3Rvcj0wOyAvKiBibG9jayBkZXZpY2VzICovCiAgcmVxLnZvbHVtZT0wOyAvKiBibG9jayBkZXZpY2VzICovCgogIERPU0RFVl9Eb1JlcSgmcmVxLCBkZXYpOwoKICByZXR1cm4gcmVxLmNvdW50Owp9CgppbnQgRE9TREVWX1BlZWsoRFdPUkQgZGV2LCBCWVRFKmRhdGEpCnsKICBSRVFfU0FGRUlOUFVUIHJlcTsKCiAgcmVxLmhkci5zaXplPXNpemVvZihyZXEpOwogIHJlcS5oZHIudW5pdD0wOyAvKiBub3QgZGVhbGluZyB3aXRoIGJsb2NrIGRldmljZXMgeWV0ICovCiAgcmVxLmhkci5jb21tYW5kPUNNRF9TQUZFSU5QVVQ7CiAgcmVxLmhkci5zdGF0dXM9U1RBVF9CVVNZOwogIHJlcS5kYXRhPTA7CgogIERPU0RFVl9Eb1JlcSgmcmVxLCBkZXYpOwoKICBpZiAocmVxLmhkci5zdGF0dXMgJiBTVEFUX0JVU1kpIHJldHVybiAwOwoKICAqZGF0YSA9IHJlcS5kYXRhOwogIHJldHVybiAxOwp9CgppbnQgRE9TREVWX1JlYWQoRFdPUkQgZGV2LCBEV09SRCBidWYsIGludCBidWZsZW4pCnsKICByZXR1cm4gRE9TREVWX0lPKENNRF9JTlBVVCwgZGV2LCBidWYsIGJ1Zmxlbik7Cn0KCmludCBET1NERVZfV3JpdGUoRFdPUkQgZGV2LCBEV09SRCBidWYsIGludCBidWZsZW4sIGludCB2ZXJpZnkpCnsKICByZXR1cm4gRE9TREVWX0lPKHZlcmlmeT9DTURfU0FGRU9VVFBVVDpDTURfT1VUUFVULCBkZXYsIGJ1ZiwgYnVmbGVuKTsKfQoKaW50IERPU0RFVl9Jb2N0bFJlYWQoRFdPUkQgZGV2LCBEV09SRCBidWYsIGludCBidWZsZW4pCnsKICByZXR1cm4gRE9TREVWX0lPKENNRF9JTklPQ1RMLCBkZXYsIGJ1ZiwgYnVmbGVuKTsKfQoKaW50IERPU0RFVl9Jb2N0bFdyaXRlKERXT1JEIGRldiwgRFdPUkQgYnVmLCBpbnQgYnVmbGVuKQp7CiAgcmV0dXJuIERPU0RFVl9JTyhDTURfT1VUSU9DVEwsIGRldiwgYnVmLCBidWZsZW4pOwp9Cgp2b2lkIERPU0RFVl9TZXRTaGFyaW5nUmV0cnkoV09SRCBkZWxheSwgV09SRCBjb3VudCkKewogICAgRE9TTUVNX0xPTCgpLT5zaGFyaW5nX3JldHJ5X2RlbGF5ID0gZGVsYXk7CiAgICBpZiAoY291bnQpIERPU01FTV9MT0woKS0+c2hhcmluZ19yZXRyeV9jb3VudCA9IGNvdW50Owp9CgpTRUdQVFIgRE9TREVWX0dldExPTChCT09MIHY4NikKewogICAgaWYgKHY4NikgcmV0dXJuIERPU01FTV9MT0woKS0+d2luZV9ybV9sb2w7CiAgICBlbHNlIHJldHVybiBET1NNRU1fTE9MKCktPndpbmVfcG1fbG9sOwp9Cg==