LyoKICogQWdlcmUgU3lzdGVtcyBJbmMuCiAqIDEwLzEwMC8xMDAwIEJhc2UtVCBFdGhlcm5ldCBEcml2ZXIgZm9yIHRoZSBFVDEzMDEgYW5kIEVUMTMxeCBzZXJpZXMgTUFDcwogKgogKiBDb3B5cmlnaHQgqSAyMDA1IEFnZXJlIFN5c3RlbXMgSW5jLgogKiBBbGwgcmlnaHRzIHJlc2VydmVkLgogKiAgIGh0dHA6Ly93d3cuYWdlcmUuY29tCiAqCiAqLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tCiAqCiAqIGV0MTMxeF9pc3IuYyAtIEZpbGUgd2hpY2ggY29udGFpbnMgdGhlIElTUiwgSVNSIGhhbmRsZXIsIGFuZCByZWxhdGVkIHJvdXRpbmVzCiAqICAgICAgICAgICAgICAgIGZvciBwcm9jZXNzaW5nIGludGVycnVwdHMgZnJvbSB0aGUgZGV2aWNlLgogKgogKi0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLQogKgogKiBTT0ZUV0FSRSBMSUNFTlNFCiAqCiAqIFRoaXMgc29mdHdhcmUgaXMgcHJvdmlkZWQgc3ViamVjdCB0byB0aGUgZm9sbG93aW5nIHRlcm1zIGFuZCBjb25kaXRpb25zLAogKiB3aGljaCB5b3Ugc2hvdWxkIHJlYWQgY2FyZWZ1bGx5IGJlZm9yZSB1c2luZyB0aGUgc29mdHdhcmUuICBVc2luZyB0aGlzCiAqIHNvZnR3YXJlIGluZGljYXRlcyB5b3VyIGFjY2VwdGFuY2Ugb2YgdGhlc2UgdGVybXMgYW5kIGNvbmRpdGlvbnMuICBJZiB5b3UgZG8KICogbm90IGFncmVlIHdpdGggdGhlc2UgdGVybXMgYW5kIGNvbmRpdGlvbnMsIGRvIG5vdCB1c2UgdGhlIHNvZnR3YXJlLgogKgogKiBDb3B5cmlnaHQgqSAyMDA1IEFnZXJlIFN5c3RlbXMgSW5jLgogKiBBbGwgcmlnaHRzIHJlc2VydmVkLgogKgogKiBSZWRpc3RyaWJ1dGlvbiBhbmQgdXNlIGluIHNvdXJjZSBvciBiaW5hcnkgZm9ybXMsIHdpdGggb3Igd2l0aG91dAogKiBtb2RpZmljYXRpb25zLCBhcmUgcGVybWl0dGVkIHByb3ZpZGVkIHRoYXQgdGhlIGZvbGxvd2luZyBjb25kaXRpb25zIGFyZSBtZXQ6CiAqCiAqIC4gUmVkaXN0cmlidXRpb25zIG9mIHNvdXJjZSBjb2RlIG11c3QgcmV0YWluIHRoZSBhYm92ZSBjb3B5cmlnaHQgbm90aWNlLCB0aGlzCiAqICAgIGxpc3Qgb2YgY29uZGl0aW9ucyBhbmQgdGhlIGZvbGxvd2luZyBEaXNjbGFpbWVyIGFzIGNvbW1lbnRzIGluIHRoZSBjb2RlIGFzCiAqICAgIHdlbGwgYXMgaW4gdGhlIGRvY3VtZW50YXRpb24gYW5kL29yIG90aGVyIG1hdGVyaWFscyBwcm92aWRlZCB3aXRoIHRoZQogKiAgICBkaXN0cmlidXRpb24uCiAqCiAqIC4gUmVkaXN0cmlidXRpb25zIGluIGJpbmFyeSBmb3JtIG11c3QgcmVwcm9kdWNlIHRoZSBhYm92ZSBjb3B5cmlnaHQgbm90aWNlLAogKiAgICB0aGlzIGxpc3Qgb2YgY29uZGl0aW9ucyBhbmQgdGhlIGZvbGxvd2luZyBEaXNjbGFpbWVyIGluIHRoZSBkb2N1bWVudGF0aW9uCiAqICAgIGFuZC9vciBvdGhlciBtYXRlcmlhbHMgcHJvdmlkZWQgd2l0aCB0aGUgZGlzdHJpYnV0aW9uLgogKgogKiAuIE5laXRoZXIgdGhlIG5hbWUgb2YgQWdlcmUgU3lzdGVtcyBJbmMuIG5vciB0aGUgbmFtZXMgb2YgdGhlIGNvbnRyaWJ1dG9ycwogKiAgICBtYXkgYmUgdXNlZCB0byBlbmRvcnNlIG9yIHByb21vdGUgcHJvZHVjdHMgZGVyaXZlZCBmcm9tIHRoaXMgc29mdHdhcmUKICogICAgd2l0aG91dCBzcGVjaWZpYyBwcmlvciB3cml0dGVuIHBlcm1pc3Npb24uCiAqCiAqIERpc2NsYWltZXIKICoKICogVEhJUyBTT0ZUV0FSRSBJUyBQUk9WSURFRCCTQVMgSVOUIEFORCBBTlkgRVhQUkVTUyBPUiBJTVBMSUVEIFdBUlJBTlRJRVMsCiAqIElOQ0xVRElORywgQlVUIE5PVCBMSU1JVEVEIFRPLCBJTkZSSU5HRU1FTlQgQU5EIFRIRSBJTVBMSUVEIFdBUlJBTlRJRVMgT0YKICogTUVSQ0hBTlRBQklMSVRZIEFORCBGSVRORVNTIEZPUiBBIFBBUlRJQ1VMQVIgUFVSUE9TRSBBUkUgRElTQ0xBSU1FRC4gIEFOWQogKiBVU0UsIE1PRElGSUNBVElPTiBPUiBESVNUUklCVVRJT04gT0YgVEhJUyBTT0ZUV0FSRSBJUyBTT0xFTFkgQVQgVEhFIFVTRVJTIE9XTgogKiBSSVNLLiBJTiBOTyBFVkVOVCBTSEFMTCBBR0VSRSBTWVNURU1TIElOQy4gT1IgQ09OVFJJQlVUT1JTIEJFIExJQUJMRSBGT1IgQU5ZCiAqIERJUkVDVCwgSU5ESVJFQ1QsIElOQ0lERU5UQUwsIFNQRUNJQUwsIEVYRU1QTEFSWSwgT1IgQ09OU0VRVUVOVElBTCBEQU1BR0VTCiAqIChJTkNMVURJTkcsIEJVVCBOT1QgTElNSVRFRCBUTywgUFJPQ1VSRU1FTlQgT0YgU1VCU1RJVFVURSBHT09EUyBPUiBTRVJWSUNFUzsKICogTE9TUyBPRiBVU0UsIERBVEEsIE9SIFBST0ZJVFM7IE9SIEJVU0lORVNTIElOVEVSUlVQVElPTikgSE9XRVZFUiBDQVVTRUQgQU5ECiAqIE9OIEFOWSBUSEVPUlkgT0YgTElBQklMSVRZLCBJTkNMVURJTkcsIEJVVCBOT1QgTElNSVRFRCBUTywgQ09OVFJBQ1QsIFNUUklDVAogKiBMSUFCSUxJVFksIE9SIFRPUlQgKElOQ0xVRElORyBORUdMSUdFTkNFIE9SIE9USEVSV0lTRSkgQVJJU0lORyBJTiBBTlkgV0FZIE9VVAogKiBPRiBUSEUgVVNFIE9GIFRISVMgU09GVFdBUkUsIEVWRU4gSUYgQURWSVNFRCBPRiBUSEUgUE9TU0lCSUxJVFkgT0YgU1VDSAogKiBEQU1BR0UuCiAqCiAqLwoKI2luY2x1ZGUgImV0MTMxeF92ZXJzaW9uLmgiCiNpbmNsdWRlICJldDEzMXhfZGVidWcuaCIKI2luY2x1ZGUgImV0MTMxeF9kZWZzLmgiCgojaW5jbHVkZSA8bGludXgvaW5pdC5oPgojaW5jbHVkZSA8bGludXgvbW9kdWxlLmg+CiNpbmNsdWRlIDxsaW51eC90eXBlcy5oPgojaW5jbHVkZSA8bGludXgva2VybmVsLmg+CgojaW5jbHVkZSA8bGludXgvc2NoZWQuaD4KI2luY2x1ZGUgPGxpbnV4L3B0cmFjZS5oPgojaW5jbHVkZSA8bGludXgvc2xhYi5oPgojaW5jbHVkZSA8bGludXgvY3R5cGUuaD4KI2luY2x1ZGUgPGxpbnV4L3N0cmluZy5oPgojaW5jbHVkZSA8bGludXgvdGltZXIuaD4KI2luY2x1ZGUgPGxpbnV4L2ludGVycnVwdC5oPgojaW5jbHVkZSA8bGludXgvaW4uaD4KI2luY2x1ZGUgPGxpbnV4L2RlbGF5Lmg+CiNpbmNsdWRlIDxhc20vaW8uaD4KI2luY2x1ZGUgPGFzbS9zeXN0ZW0uaD4KI2luY2x1ZGUgPGFzbS9iaXRvcHMuaD4KCiNpbmNsdWRlIDxsaW51eC9uZXRkZXZpY2UuaD4KI2luY2x1ZGUgPGxpbnV4L2V0aGVyZGV2aWNlLmg+CiNpbmNsdWRlIDxsaW51eC9za2J1ZmYuaD4KI2luY2x1ZGUgPGxpbnV4L2lmX2FycC5oPgojaW5jbHVkZSA8bGludXgvaW9wb3J0Lmg+CgojaW5jbHVkZSAiZXQxMzEwX3BoeS5oIgojaW5jbHVkZSAiZXQxMzEwX3BtLmgiCiNpbmNsdWRlICJldDEzMTBfamFnY29yZS5oIgojaW5jbHVkZSAiZXQxMzEwX21hYy5oIgoKI2luY2x1ZGUgImV0MTMxeF9hZGFwdGVyLmgiCgovKiBEYXRhIGZvciBkZWJ1Z2dpbmcgZmFjaWxpdGllcyAqLwojaWZkZWYgQ09ORklHX0VUMTMxWF9ERUJVRwpleHRlcm4gZGJnX2luZm9fdCAqZXQxMzF4X2RiZ2luZm87CiNlbmRpZiAvKiBDT05GSUdfRVQxMzFYX0RFQlVHICovCgovKioKICogZXQxMzF4X2lzciAtIFRoZSBJbnRlcnJ1cHQgU2VydmljZSBSb3V0aW5lIGZvciB0aGUgZHJpdmVyLgogKiBAaXJxOiB0aGUgSVJRIG9uIHdoaWNoIHRoZSBpbnRlcnJ1cHQgd2FzIHJlY2VpdmVkLgogKiBAZGV2X2lkOiBkZXZpY2Utc3BlY2lmaWMgaW5mbyAoaGVyZSBhIHBvaW50ZXIgdG8gYSBuZXRfZGV2aWNlIHN0cnVjdCkKICoKICogUmV0dXJucyBhIHZhbHVlIGluZGljYXRpbmcgaWYgdGhlIGludGVycnVwdCB3YXMgaGFuZGxlZC4KICovCmlycXJldHVybl90IGV0MTMxeF9pc3IoaW50IGlycSwgdm9pZCAqZGV2X2lkKQp7Cglib29sIGhhbmRsZWQgPSB0cnVlOwoJc3RydWN0IG5ldF9kZXZpY2UgKm5ldGRldiA9IChzdHJ1Y3QgbmV0X2RldmljZSAqKWRldl9pZDsKCXN0cnVjdCBldDEzMXhfYWRhcHRlciAqYWRhcHRlciA9IE5VTEw7CglJTlRFUlJVUFRfdCBzdGF0dXM7CgoJaWYgKG5ldGRldiA9PSBOVUxMIHx8ICFuZXRpZl9kZXZpY2VfcHJlc2VudChuZXRkZXYpKSB7CgkJREJHX1dBUk5JTkcoZXQxMzF4X2RiZ2luZm8sCgkJCSAgICAiTm8gbmV0X2RldmljZSBzdHJ1Y3Qgb3IgZGV2aWNlIG5vdCBwcmVzZW50XG4iKTsKCQloYW5kbGVkID0gZmFsc2U7CgkJZ290byBvdXQ7Cgl9CgoJYWRhcHRlciA9IG5ldGRldl9wcml2KG5ldGRldik7CgoJLyogSWYgdGhlIGFkYXB0ZXIgaXMgaW4gbG93IHBvd2VyIHN0YXRlLCB0aGVuIGl0IHNob3VsZCBub3QKCSAqIHJlY29nbml6ZSBhbnkgaW50ZXJydXB0CgkgKi8KCgkvKiBEaXNhYmxlIERldmljZSBJbnRlcnJ1cHRzICovCglldDEzMXhfZGlzYWJsZV9pbnRlcnJ1cHRzKGFkYXB0ZXIpOwoKCS8qIEdldCBhIGNvcHkgb2YgdGhlIHZhbHVlIGluIHRoZSBpbnRlcnJ1cHQgc3RhdHVzIHJlZ2lzdGVyCgkgKiBzbyB3ZSBjYW4gcHJvY2VzcyB0aGUgaW50ZXJydXB0aW5nIHNlY3Rpb24KCSAqLwoJc3RhdHVzLnZhbHVlID0gcmVhZGwoJmFkYXB0ZXItPkNTUkFkZHJlc3MtPmdsb2JhbC5pbnRfc3RhdHVzLnZhbHVlKTsKCglpZiAoYWRhcHRlci0+Rmxvd0NvbnRyb2wgPT0gVHhPbmx5IHx8CgkgICAgYWRhcHRlci0+Rmxvd0NvbnRyb2wgPT0gQm90aCkgewoJCXN0YXR1cy52YWx1ZSAmPSB+SU5UX01BU0tfRU5BQkxFOwoJfSBlbHNlIHsKCQlzdGF0dXMudmFsdWUgJj0gfklOVF9NQVNLX0VOQUJMRV9OT19GTE9XOwoJfQoKCS8qIE1ha2Ugc3VyZSB0aGlzIGlzIG91ciBpbnRlcnJ1cHQgKi8KCWlmICghc3RhdHVzLnZhbHVlKSB7CiNpZmRlZiBDT05GSUdfRVQxMzFYX0RFQlVHCgkJYWRhcHRlci0+U3RhdHMuVW5oYW5kbGVkSW50ZXJydXB0c1BlclNlYysrOwojZW5kaWYKCQloYW5kbGVkID0gZmFsc2U7CgkJREJHX1ZFUkJPU0UoZXQxMzF4X2RiZ2luZm8sICJOT1QgT1VSIElOVEVSUlVQVFxuIik7CgkJZXQxMzF4X2VuYWJsZV9pbnRlcnJ1cHRzKGFkYXB0ZXIpOwoJCWdvdG8gb3V0OwoJfQoKCS8qIFRoaXMgaXMgb3VyIGludGVycnVwdCwgc28gcHJvY2VzcyBhY2NvcmRpbmdseSAqLwojaWZkZWYgQ09ORklHX0VUMTMxWF9ERUJVRwoJaWYgKHN0YXR1cy5iaXRzLnJ4ZG1hX3hmcl9kb25lKSB7CgkJYWRhcHRlci0+U3RhdHMuUnhEbWFJbnRlcnJ1cHRzUGVyU2VjKys7Cgl9CgoJaWYgKHN0YXR1cy5iaXRzLnR4ZG1hX2lzcikgewoJCWFkYXB0ZXItPlN0YXRzLlR4RG1hSW50ZXJydXB0c1BlclNlYysrOwoJfQojZW5kaWYKCglpZiAoc3RhdHVzLmJpdHMud2F0Y2hkb2dfaW50ZXJydXB0KSB7CgkJUE1QX1RDQiBwTXBUY2IgPSBhZGFwdGVyLT5UeFJpbmcuQ3VyclNlbmRIZWFkOwoKCQlpZiAocE1wVGNiKSB7CgkJCWlmICgrK3BNcFRjYi0+UGFja2V0U3RhbGVDb3VudCA+IDEpIHsKCQkJCXN0YXR1cy5iaXRzLnR4ZG1hX2lzciA9IDE7CgkJCX0KCQl9CgoJCWlmIChhZGFwdGVyLT5SeFJpbmcuVW5maW5pc2hlZFJlY2VpdmVzKSB7CgkJCXN0YXR1cy5iaXRzLnJ4ZG1hX3hmcl9kb25lID0gMTsKCQl9IGVsc2UgaWYgKHBNcFRjYiA9PSBOVUxMKSB7CgkJCXdyaXRlbCgwLCAmYWRhcHRlci0+Q1NSQWRkcmVzcy0+Z2xvYmFsLndhdGNoZG9nX3RpbWVyKTsKCQl9CgoJCXN0YXR1cy5iaXRzLndhdGNoZG9nX2ludGVycnVwdCA9IDA7CiNpZmRlZiBDT05GSUdfRVQxMzFYX0RFQlVHCgkJYWRhcHRlci0+U3RhdHMuV2F0Y2hEb2dJbnRlcnJ1cHRzUGVyU2VjKys7CiNlbmRpZgoJfQoKCWlmIChzdGF0dXMudmFsdWUgPT0gMCkgewoJCS8qIFRoaXMgaW50ZXJydXB0IGhhcyBpbiBzb21lIHdheSBiZWVuICJoYW5kbGVkIiBieQoJCSAqIHRoZSBJU1IuIEVpdGhlciBpdCB3YXMgYSBzcHVyaW91cyBSeCBpbnRlcnJ1cHQsIG9yCgkJICogaXQgd2FzIGEgVHggaW50ZXJydXB0IHRoYXQgaGFzIGJlZW4gZmlsdGVyZWQgYnkKCQkgKiB0aGUgSVNSLgoJCSAqLwoJCWV0MTMxeF9lbmFibGVfaW50ZXJydXB0cyhhZGFwdGVyKTsKCQlnb3RvIG91dDsKCX0KCgkvKiBXZSBuZWVkIHRvIHNhdmUgdGhlIGludGVycnVwdCBzdGF0dXMgdmFsdWUgZm9yIHVzZSBpbiBvdXIKCSAqIERQQy4gV2Ugd2lsbCBjbGVhciB0aGUgc29mdHdhcmUgY29weSBvZiB0aGF0IGluIHRoYXQKCSAqIHJvdXRpbmUuCgkgKi8KCWFkYXB0ZXItPlN0YXRzLkludGVycnVwdFN0YXR1cyA9IHN0YXR1czsKCgkvKiBTY2hlZHVsZSB0aGUgSVNSIGhhbmRsZXIgYXMgYSBib3R0b20taGFsZiB0YXNrIGluIHRoZQoJICoga2VybmVsJ3MgdHFfaW1tZWRpYXRlIHF1ZXVlLCBhbmQgbWFyayB0aGUgcXVldWUgZm9yCgkgKiBleGVjdXRpb24KCSAqLwoJc2NoZWR1bGVfd29yaygmYWRhcHRlci0+dGFzayk7CgpvdXQ6CglyZXR1cm4gSVJRX1JFVFZBTChoYW5kbGVkKTsKfQoKLyoqCiAqIGV0MTMxeF9pc3JfaGFuZGxlciAtIFRoZSBJU1IgaGFuZGxlcgogKiBAcF9hZGFwdGVyLCBhIHBvaW50ZXIgdG8gdGhlIGRldmljZSdzIHByaXZhdGUgYWRhcHRlciBzdHJ1Y3R1cmUKICoKICogc2NoZWR1bGVkIHRvIHJ1biBpbiBhIGRlZmVycmVkIGNvbnRleHQgYnkgdGhlIElTUi4gVGhpcyBpcyB3aGVyZSB0aGUgSVNSJ3MKICogd29yayBhY3R1YWxseSBnZXRzIGRvbmUuCiAqLwp2b2lkIGV0MTMxeF9pc3JfaGFuZGxlcihzdHJ1Y3Qgd29ya19zdHJ1Y3QgKndvcmspCnsKCXN0cnVjdCBldDEzMXhfYWRhcHRlciAqcEFkYXB0ZXIgPQoJCWNvbnRhaW5lcl9vZih3b3JrLCBzdHJ1Y3QgZXQxMzF4X2FkYXB0ZXIsIHRhc2spOwoJSU5URVJSVVBUX3QgR2xvYlN0YXR1cyA9IHBBZGFwdGVyLT5TdGF0cy5JbnRlcnJ1cHRTdGF0dXM7CglBRERSRVNTX01BUF90IF9faW9tZW0gKmlvbWVtID0gcEFkYXB0ZXItPkNTUkFkZHJlc3M7CgoJLyoKCSAqIFRoZXNlIGZpcnN0IHR3byBhcmUgYnkgZmFyIHRoZSBtb3N0IGNvbW1vbi4gIE9uY2UgaGFuZGxlZCwgd2UgY2xlYXIKCSAqIHRoZWlyIHR3byBiaXRzIGluIHRoZSBzdGF0dXMgd29yZC4gIElmIHRoZSB3b3JkIGlzIG5vdyB6ZXJvLCB3ZQoJICogZXhpdC4KCSAqLwoJLyogSGFuZGxlIGFsbCB0aGUgY29tcGxldGVkIFRyYW5zbWl0IGludGVycnVwdHMgKi8KCWlmIChHbG9iU3RhdHVzLmJpdHMudHhkbWFfaXNyKSB7CgkJREJHX1RYKGV0MTMxeF9kYmdpbmZvLCAiVFhETUFfSVNSIGludGVycnVwdFxuIik7CgkJZXQxMzF4X2hhbmRsZV9zZW5kX2ludGVycnVwdChwQWRhcHRlcik7Cgl9CgoJLyogSGFuZGxlIGFsbCB0aGUgY29tcGxldGVkIFJlY2VpdmVzIGludGVycnVwdHMgKi8KCWlmIChHbG9iU3RhdHVzLmJpdHMucnhkbWFfeGZyX2RvbmUpIHsKCQlEQkdfUlgoZXQxMzF4X2RiZ2luZm8sICJSWERNQV9YRlJfRE9ORSBpbnRlcnJ1cHRcbiIpOwoJCWV0MTMxeF9oYW5kbGVfcmVjdl9pbnRlcnJ1cHQocEFkYXB0ZXIpOwoJfQoKCUdsb2JTdGF0dXMudmFsdWUgJj0gMHhmZmZmZmZkNzsKCglpZiAoR2xvYlN0YXR1cy52YWx1ZSkgewoJCS8qIEhhbmRsZSB0aGUgVFhETUEgRXJyb3IgaW50ZXJydXB0ICovCgkJaWYgKEdsb2JTdGF0dXMuYml0cy50eGRtYV9lcnIpIHsKCQkJVFhETUFfRVJST1JfdCBUeERtYUVycjsKCgkJCS8qIEZvbGxvd2luZyByZWFkIGFsc28gY2xlYXJzIHRoZSByZWdpc3RlciAoQ09SKSAqLwoJCQlUeERtYUVyci52YWx1ZSA9IHJlYWRsKCZpb21lbS0+dHhkbWEuVHhEbWFFcnJvci52YWx1ZSk7CgoJCQlEQkdfV0FSTklORyhldDEzMXhfZGJnaW5mbywKCQkJCSAgICAiVFhETUFfRVJSIGludGVycnVwdCwgZXJyb3IgPSAlZFxuIiwKCQkJCSAgICBUeERtYUVyci52YWx1ZSk7CgkJfQoKCQkvKiBIYW5kbGUgRnJlZSBCdWZmZXIgUmluZyAwIGFuZCAxIExvdyBpbnRlcnJ1cHQgKi8KCQlpZiAoR2xvYlN0YXR1cy5iaXRzLnJ4ZG1hX2ZiX3JpbmcwX2xvdyB8fAoJCSAgICBHbG9iU3RhdHVzLmJpdHMucnhkbWFfZmJfcmluZzFfbG93KSB7CgkJCS8qCgkJCSAqIFRoaXMgaW5kaWNhdGVzIHRoZSBudW1iZXIgb2YgdW51c2VkIGJ1ZmZlcnMgaW4KCQkJICogUlhETUEgZnJlZSBidWZmZXIgcmluZyAwIGlzIDw9IHRoZSBsaW1pdCB5b3UKCQkJICogcHJvZ3JhbW1lZC4gRnJlZSBidWZmZXIgcmVzb3VyY2VzIG5lZWQgdG8gYmUKCQkJICogcmV0dXJuZWQuICBGcmVlIGJ1ZmZlcnMgYXJlIGNvbnN1bWVkIGFzIHBhY2tldHMKCQkJICogYXJlIHBhc3NlZCBmcm9tIHRoZSBuZXR3b3JrIHRvIHRoZSBob3N0LiBUaGUgaG9zdAoJCQkgKiBiZWNvbWVzIGF3YXJlIG9mIHRoZSBwYWNrZXRzIGZyb20gdGhlIGNvbnRlbnRzIG9mCgkJCSAqIHRoZSBwYWNrZXQgc3RhdHVzIHJpbmcuIFRoaXMgcmluZyBpcyBxdWVyaWVkIHdoZW4KCQkJICogdGhlIHBhY2tldCBkb25lIGludGVycnVwdCBvY2N1cnMuIFBhY2tldHMgYXJlIHRoZW4KCQkJICogcGFzc2VkIHRvIHRoZSBPUy4gV2hlbiB0aGUgT1MgaXMgZG9uZSB3aXRoIHRoZQoJCQkgKiBwYWNrZXRzIHRoZSByZXNvdXJjZXMgY2FuIGJlIHJldHVybmVkIHRvIHRoZQoJCQkgKiBFVDEzMTAgZm9yIHJlLXVzZS4gVGhpcyBpbnRlcnJ1cHQgaXMgb25lIG1ldGhvZCBvZgoJCQkgKiByZXR1cm5pbmcgcmVzb3VyY2VzLgoJCQkgKi8KCQkJREJHX1dBUk5JTkcoZXQxMzF4X2RiZ2luZm8sCgkJCQkgICAgIlJYRE1BX0ZCX1JJTkcwX0xPVyBvciAiCgkJCQkgICAgIlJYRE1BX0ZCX1JJTkcxX0xPVyBpbnRlcnJ1cHRcbiIpOwoKCQkJLyogSWYgdGhlIHVzZXIgaGFzIGZsb3cgY29udHJvbCBvbiwgdGhlbiB3ZSB3aWxsCgkJCSAqIHNlbmQgYSBwYXVzZSBwYWNrZXQsIG90aGVyd2lzZSBqdXN0IGV4aXQKCQkJICovCgkJCWlmIChwQWRhcHRlci0+Rmxvd0NvbnRyb2wgPT0gVHhPbmx5IHx8CgkJCSAgICBwQWRhcHRlci0+Rmxvd0NvbnRyb2wgPT0gQm90aCkgewoJCQkJUE1fQ1NSX3QgcG1fY3NyOwoKCQkJCS8qIFRlbGwgdGhlIGRldmljZSB0byBzZW5kIGEgcGF1c2UgcGFja2V0IHZpYQoJCQkJICogdGhlIGJhY2sgcHJlc3N1cmUgcmVnaXN0ZXIKCQkJCSAqLwoJCQkJcG1fY3NyLnZhbHVlID0gcmVhZGwoJmlvbWVtLT5nbG9iYWwucG1fY3NyLnZhbHVlKTsKCQkJCWlmIChwbV9jc3IuYml0cy5wbV9waHlfc3dfY29tYSA9PSAwKSB7CgkJCQkJVFhNQUNfQlBfQ1RSTF90IGJwX2N0cmwgPSB7IDAgfTsKCgkJCQkJYnBfY3RybC5iaXRzLmJwX3JlcSA9IDE7CgkJCQkJYnBfY3RybC5iaXRzLmJwX3hvbnhvZmYgPSAxOwoJCQkJCXdyaXRlbChicF9jdHJsLnZhbHVlLAoJCQkJCSAgICAgICAmaW9tZW0tPnR4bWFjLmJwX2N0cmwudmFsdWUpOwoJCQkJfQoJCQl9CgkJfQoKCQkvKiBIYW5kbGUgUGFja2V0IFN0YXR1cyBSaW5nIExvdyBJbnRlcnJ1cHQgKi8KCQlpZiAoR2xvYlN0YXR1cy5iaXRzLnJ4ZG1hX3BrdF9zdGF0X3JpbmdfbG93KSB7CgkJCURCR19XQVJOSU5HKGV0MTMxeF9kYmdpbmZvLAoJCQkJICAgICJSWERNQV9QS1RfU1RBVF9SSU5HX0xPVyBpbnRlcnJ1cHRcbiIpOwoKCQkJLyoKCQkJICogU2FtZSBpZGVhIGFzIHdpdGggdGhlIHR3byBGcmVlIEJ1ZmZlciBSaW5ncy4KCQkJICogUGFja2V0cyBnb2luZyBmcm9tIHRoZSBuZXR3b3JrIHRvIHRoZSBob3N0IGVhY2gKCQkJICogY29uc3VtZSBhIGZyZWUgYnVmZmVyIHJlc291cmNlIGFuZCBhIHBhY2tldCBzdGF0dXMKCQkJICogcmVzb3VyY2UuICBUaGVzZSByZXNvdXJlcyBhcmUgcGFzc2VkIHRvIHRoZSBPUy4KCQkJICogV2hlbiB0aGUgT1MgaXMgZG9uZSB3aXRoIHRoZSByZXNvdXJjZXMsIHRoZXkgbmVlZAoJCQkgKiB0byBiZSByZXR1cm5lZCB0byB0aGUgRVQxMzEwLiBUaGlzIGlzIG9uZSBtZXRob2QKCQkJICogb2YgcmV0dXJuaW5nIHRoZSByZXNvdXJjZXMuCgkJCSAqLwoJCX0KCgkJLyogSGFuZGxlIFJYRE1BIEVycm9yIEludGVycnVwdCAqLwoJCWlmIChHbG9iU3RhdHVzLmJpdHMucnhkbWFfZXJyKSB7CgkJCS8qCgkJCSAqIFRoZSByeGRtYV9lcnJvciBpbnRlcnJ1cHQgaXMgc2VudCB3aGVuIGEgdGltZS1vdXQKCQkJICogb24gYSByZXF1ZXN0IGlzc3VlZCBieSB0aGUgSkFHQ29yZSBoYXMgb2NjdXJyZWQgb3IKCQkJICogYSBjb21wbGV0aW9uIGlzIHJldHVybmVkIHdpdGggYW4gdW4tc3VjY2Vzc2Z1bAoJCQkgKiBzdGF0dXMuICBJbiBib3RoIGNhc2VzIHRoZSByZXF1ZXN0IGlzIGNvbnNpZGVyZWQKCQkJICogY29tcGxldGUuIFRoZSBKQUdDb3JlIHdpbGwgYXV0b21hdGljYWxseSByZS10cnkgdGhlCgkJCSAqIHJlcXVlc3QgaW4gcXVlc3Rpb24uIE5vcm1hbGx5IGluZm9ybWF0aW9uIG9uIGV2ZW50cwoJCQkgKiBsaWtlIHRoZXNlIGFyZSBzZW50IHRvIHRoZSBob3N0IHVzaW5nIHRoZSAiQWR2YW5jZWQKCQkJICogRXJyb3IgUmVwb3J0aW5nIiBjYXBhYmlsaXR5LiBUaGlzIGludGVycnVwdCBpcwoJCQkgKiBhbm90aGVyIHdheSBvZiBnZXR0aW5nIHNpbWlsYXIgaW5mb3JtYXRpb24uIFRoZQoJCQkgKiBvbmx5IHRoaW5nIHJlcXVpcmVkIGlzIHRvIGNsZWFyIHRoZSBpbnRlcnJ1cHQgYnkKCQkJICogcmVhZGluZyB0aGUgSVNSIGluIHRoZSBnbG9iYWwgcmVzb3VyY2VzLiBUaGUKCQkJICogSkFHQ29yZSB3aWxsIGRvIGEgcmUtdHJ5IG9uIHRoZSByZXF1ZXN0LiAgTm9ybWFsbHkKCQkJICogeW91IHNob3VsZCBuZXZlciBzZWUgdGhpcyBpbnRlcnJ1cHQuIElmIHlvdSBzdGFydAoJCQkgKiB0byBzZWUgdGhpcyBpbnRlcnJ1cHQgb2NjdXJyaW5nIGZyZXF1ZW50bHkgdGhlbgoJCQkgKiBzb21ldGhpbmcgYmFkIGhhcyBvY2N1cnJlZC4gQSByZXNldCBtaWdodCBiZSB0aGUKCQkJICogdGhpbmcgdG8gZG8uCgkJCSAqLwoJCQkvLyBUUkFQKCk7CgoJCQlwQWRhcHRlci0+VHhNYWNUZXN0LnZhbHVlID0KCQkJCXJlYWRsKCZpb21lbS0+dHhtYWMudHhfdGVzdC52YWx1ZSk7CgkJCURCR19XQVJOSU5HKGV0MTMxeF9kYmdpbmZvLAoJCQkJICAgICJSeERNQV9FUlIgaW50ZXJydXB0LCBlcnJvciAleFxuIiwKCQkJCSAgICBwQWRhcHRlci0+VHhNYWNUZXN0LnZhbHVlKTsKCQl9CgoJCS8qIEhhbmRsZSB0aGUgV2FrZSBvbiBMQU4gRXZlbnQgKi8KCQlpZiAoR2xvYlN0YXR1cy5iaXRzLndha2Vfb25fbGFuKSB7CgkJCS8qCgkJCSAqIFRoaXMgaXMgYSBzZWNvbmRhcnkgaW50ZXJydXB0IGZvciB3YWtlIG9uIExBTi4KCQkJICogVGhlIGRyaXZlciBzaG91bGQgbmV2ZXIgc2VlIHRoaXMsIGlmIGl0IGRvZXMsCgkJCSAqIHNvbWV0aGluZyBzZXJpb3VzIGlzIHdyb25nLiBXZSB3aWxsIFRSQVAgdGhlCgkJCSAqIG1lc3NhZ2Ugd2hlbiB3ZSBhcmUgaW4gREJHIG1vZGUsIG90aGVyd2lzZSB3ZQoJCQkgKiB3aWxsIGlnbm9yZSBpdC4KCQkJICovCgkJCURCR19FUlJPUihldDEzMXhfZGJnaW5mbywgIldBS0VfT05fTEFOIGludGVycnVwdFxuIik7CgkJfQoKCQkvKiBIYW5kbGUgdGhlIFBIWSBpbnRlcnJ1cHQgKi8KCQlpZiAoR2xvYlN0YXR1cy5iaXRzLnBoeV9pbnRlcnJ1cHQpIHsKCQkJUE1fQ1NSX3QgcG1fY3NyOwoJCQlNSV9CTVNSX3QgQm1zckludHMsIEJtc3JEYXRhOwoJCQlNSV9JU1JfdCBteUlzcjsKCgkJCURCR19WRVJCT1NFKGV0MTMxeF9kYmdpbmZvLCAiUEhZIGludGVycnVwdFxuIik7CgoJCQkvKiBJZiB3ZSBhcmUgaW4gY29tYSBtb2RlIHdoZW4gd2UgZ2V0IHRoaXMgaW50ZXJydXB0LAoJCQkgKiB3ZSBuZWVkIHRvIGRpc2FibGUgaXQuCgkJCSAqLwoJCQlwbV9jc3IudmFsdWUgPSByZWFkbCgmaW9tZW0tPmdsb2JhbC5wbV9jc3IudmFsdWUpOwoJCQlpZiAocG1fY3NyLmJpdHMucG1fcGh5X3N3X2NvbWEgPT0gMSkgewoJCQkJLyoKCQkJCSAqIENoZWNrIHRvIHNlZSBpZiB3ZSBhcmUgaW4gY29tYSBtb2RlIGFuZCBpZgoJCQkJICogc28sIGRpc2FibGUgaXQgYmVjYXVzZSB3ZSB3aWxsIG5vdCBiZSBhYmxlCgkJCQkgKiB0byByZWFkIFBIWSB2YWx1ZXMgdW50aWwgd2UgYXJlIG91dC4KCQkJCSAqLwoJCQkJREJHX1ZFUkJPU0UoZXQxMzF4X2RiZ2luZm8sCgkJCQkJICAgICJEZXZpY2UgaXMgaW4gQ09NQSBtb2RlLCAiCgkJCQkJICAgICJuZWVkIHRvIHdha2UgdXBcbiIpOwoJCQkJRGlzYWJsZVBoeUNvbWEocEFkYXB0ZXIpOwoJCQl9CgoJCQkvKiBSZWFkIHRoZSBQSFkgSVNSIHRvIGNsZWFyIHRoZSByZWFzb24gZm9yIHRoZQoJCQkgKiBpbnRlcnJ1cHQuCgkJCSAqLwoJCQlNaVJlYWQocEFkYXB0ZXIsICh1aW50OF90KSBvZmZzZXRvZihNSV9SRUdTX3QsIGlzciksCgkJCSAgICAgICAmbXlJc3IudmFsdWUpOwoKCQkJaWYgKCFwQWRhcHRlci0+UmVwbGljYVBoeUxvb3BiaykgewoJCQkJTWlSZWFkKHBBZGFwdGVyLAoJCQkJICAgICAgICh1aW50OF90KSBvZmZzZXRvZihNSV9SRUdTX3QsIGJtc3IpLAoJCQkJICAgICAgICZCbXNyRGF0YS52YWx1ZSk7CgoJCQkJQm1zckludHMudmFsdWUgPQoJCQkJICAgIHBBZGFwdGVyLT5CbXNyLnZhbHVlIF4gQm1zckRhdGEudmFsdWU7CgkJCQlwQWRhcHRlci0+Qm1zci52YWx1ZSA9IEJtc3JEYXRhLnZhbHVlOwoKCQkJCURCR19WRVJCT1NFKGV0MTMxeF9kYmdpbmZvLAoJCQkJCSAgICAiQm1zci52YWx1ZSA9IDB4JTA0eCwiCgkJCQkJICAgICJCbXNyX2ludHMudmFsdWUgPSAweCUwNHhcbiIsCgkJCQkJICAgIEJtc3JEYXRhLnZhbHVlLCBCbXNySW50cy52YWx1ZSk7CgoJCQkJLyogRG8gYWxsIHRoZSBjYWJsZSBpbiAvIGNhYmxlIG91dCBzdHVmZiAqLwoJCQkJZXQxMzF4X01paV9jaGVjayhwQWRhcHRlciwgQm1zckRhdGEsIEJtc3JJbnRzKTsKCQkJfQoJCX0KCgkJLyogTGV0J3MgbW92ZSBvbiB0byB0aGUgVHhNYWMgKi8KCQlpZiAoR2xvYlN0YXR1cy5iaXRzLnR4bWFjX2ludGVycnVwdCkgewoJCQlwQWRhcHRlci0+VHhSaW5nLlR4TWFjRXJyLnZhbHVlID0KCQkJCXJlYWRsKCZpb21lbS0+dHhtYWMuZXJyLnZhbHVlKTsKCgkJCS8qCgkJCSAqIFdoZW4gYW55IG9mIHRoZSBlcnJvcnMgb2NjdXIgYW5kIFRYTUFDIGdlbmVyYXRlcwoJCQkgKiBhbiBpbnRlcnJ1cHQgdG8gcmVwb3J0IHRoZXNlIGVycm9ycywgaXQgdXN1YWxseQoJCQkgKiBtZWFucyB0aGF0IFRYTUFDIGhhcyBkZXRlY3RlZCBhbiBlcnJvciBpbiB0aGUgZGF0YQoJCQkgKiBzdHJlYW0gcmV0cmlldmVkIGZyb20gdGhlIG9uLWNoaXAgVHggUS4gQWxsIG9mCgkJCSAqIHRoZXNlIGVycm9ycyBhcmUgY2F0YXN0cm9waGljIGFuZCBUWE1BQyB3b24ndCBiZQoJCQkgKiBhYmxlIHRvIHJlY292ZXIgZGF0YSB3aGVuIHRoZXNlIGVycm9ycyBvY2N1ci4gIEluCgkJCSAqIGEgbnV0c2hlbGwsIHRoZSB3aG9sZSBUeCBwYXRoIHdpbGwgaGF2ZSB0byBiZSByZXNldAoJCQkgKiBhbmQgcmUtY29uZmlndXJlZCBhZnRlcndhcmRzLgoJCQkgKi8KCQkJREJHX1dBUk5JTkcoZXQxMzF4X2RiZ2luZm8sCgkJCQkgICAgIlRYTUFDIGludGVycnVwdCwgZXJyb3IgMHglMDh4XG4iLAoJCQkJICAgIHBBZGFwdGVyLT5UeFJpbmcuVHhNYWNFcnIudmFsdWUpOwoKCQkJLyogSWYgd2UgYXJlIGRlYnVnZ2luZywgd2Ugd2FudCB0byBzZWUgdGhpcyBlcnJvciwKCQkJICogb3RoZXJ3aXNlIHdlIGp1c3Qgd2FudCB0aGUgZGV2aWNlIHRvIGJlIHJlc2V0IGFuZAoJCQkgKiBjb250aW51ZQoJCQkgKi8KCQkJLy9EQkdfVFJBUCgpOwoJCX0KCgkJLyogSGFuZGxlIFJYTUFDIEludGVycnVwdCAqLwoJCWlmIChHbG9iU3RhdHVzLmJpdHMucnhtYWNfaW50ZXJydXB0KSB7CgkJCS8qCgkJCSAqIFRoZXNlIGludGVycnVwdHMgYXJlIGNhdGFzdHJvcGhpYyB0byB0aGUgZGV2aWNlLAoJCQkgKiB3aGF0IHdlIG5lZWQgdG8gZG8gaXMgZGlzYWJsZSB0aGUgaW50ZXJydXB0cyBhbmQKCQkJICogc2V0IHRoZSBmbGFnIHRvIGNhdXNlIHVzIHRvIHJlc2V0IHNvIHdlIGNhbiBzb2x2ZQoJCQkgKiB0aGlzIGlzc3VlLgoJCQkgKi8KCQkJLy8gTVBfU0VUX0ZMQUcoIHBBZGFwdGVyLCBmTVBfQURBUFRFUl9IQVJEV0FSRV9FUlJPUiApOwoKCQkJREJHX1dBUk5JTkcoZXQxMzF4X2RiZ2luZm8sCgkJCQkgICAgIlJYTUFDIGludGVycnVwdCwgZXJyb3IgMHglMDh4LiAgUmVxdWVzdGluZyByZXNldFxuIiwKCQkJCSAgICByZWFkbCgmaW9tZW0tPnJ4bWFjLmVycl9yZWcudmFsdWUpKTsKCgkJCURCR19XQVJOSU5HKGV0MTMxeF9kYmdpbmZvLAoJCQkJICAgICJFbmFibGUgMHglMDh4LCBEaWFnIDB4JTA4eFxuIiwKCQkJCSAgICByZWFkbCgmaW9tZW0tPnJ4bWFjLmN0cmwudmFsdWUpLAoJCQkJICAgIHJlYWRsKCZpb21lbS0+cnhtYWMucnhxX2RpYWcudmFsdWUpKTsKCgkJCS8qCgkJCSAqIElmIHdlIGFyZSBkZWJ1Z2dpbmcsIHdlIHdhbnQgdG8gc2VlIHRoaXMgZXJyb3IsCgkJCSAqIG90aGVyd2lzZSB3ZSBqdXN0IHdhbnQgdGhlIGRldmljZSB0byBiZSByZXNldCBhbmQKCQkJICogY29udGludWUKCQkJICovCgkJCS8vIFRSQVAoKTsKCQl9CgoJCS8qIEhhbmRsZSBNQUNfU1RBVCBJbnRlcnJ1cHQgKi8KCQlpZiAoR2xvYlN0YXR1cy5iaXRzLm1hY19zdGF0X2ludGVycnVwdCkgewoJCQkvKgoJCQkgKiBUaGlzIG1lYW5zIGF0IGxlYXN0IG9uZSBvZiB0aGUgdW4tbWFza2VkIGNvdW50ZXJzCgkJCSAqIGluIHRoZSBNQUNfU1RBVCBibG9jayBoYXMgcm9sbGVkIG92ZXIuICBVc2UgdGhpcwoJCQkgKiB0byBtYWludGFpbiB0aGUgdG9wLCBzb2Z0d2FyZSBtYW5hZ2VkIGJpdHMgb2YgdGhlCgkJCSAqIGNvdW50ZXIocykuCgkJCSAqLwoJCQlEQkdfVkVSQk9TRShldDEzMXhfZGJnaW5mbywgIk1BQ19TVEFUIGludGVycnVwdFxuIik7CgkJCUhhbmRsZU1hY1N0YXRJbnRlcnJ1cHQocEFkYXB0ZXIpOwoJCX0KCgkJLyogSGFuZGxlIFNMViBUaW1lb3V0IEludGVycnVwdCAqLwoJCWlmIChHbG9iU3RhdHVzLmJpdHMuc2x2X3RpbWVvdXQpIHsKCQkJLyoKCQkJICogVGhpcyBtZWFucyBhIHRpbWVvdXQgaGFzIG9jY3VyZWQgb24gYSByZWFkIG9yCgkJCSAqIHdyaXRlIHJlcXVlc3QgdG8gb25lIG9mIHRoZSBKQUdDb3JlIHJlZ2lzdGVycy4gVGhlCgkJCSAqIEdsb2JhbCBSZXNvdXJjZXMgYmxvY2sgaGFzIHRlcm1pbmF0ZWQgdGhlIHJlcXVlc3QKCQkJICogYW5kIG9uIGEgcmVhZCByZXF1ZXN0LCByZXR1cm5lZCBhICJmYWtlIiB2YWx1ZS4KCQkJICogVGhlIG1vc3QgbGlrZWx5IHJlYXNvbnMgYXJlOiBCYWQgQWRkcmVzcyBvciB0aGUKCQkJICogYWRkcmVzc2VkIG1vZHVsZSBpcyBpbiBhIHBvd2VyLWRvd24gc3RhdGUgYW5kCgkJCSAqIGNhbid0IHJlc3BvbmQuCgkJCSAqLwoJCQlEQkdfVkVSQk9TRShldDEzMXhfZGJnaW5mbywgIlNMVl9USU1FT1VUIGludGVycnVwdFxuIik7CgkJfQoJfQoKCWlmIChwQWRhcHRlci0+UG9NZ210LlBvd2VyU3RhdGUgPT0gTmRpc0RldmljZVN0YXRlRDApIHsKCQlldDEzMXhfZW5hYmxlX2ludGVycnVwdHMocEFkYXB0ZXIpOwoJfQp9Cg==