LyoKICogQWdlcmUgU3lzdGVtcyBJbmMuCiAqIDEwLzEwMC8xMDAwIEJhc2UtVCBFdGhlcm5ldCBEcml2ZXIgZm9yIHRoZSBFVDEzMDEgYW5kIEVUMTMxeCBzZXJpZXMgTUFDcwogKgogKiBDb3B5cmlnaHQgqSAyMDA1IEFnZXJlIFN5c3RlbXMgSW5jLgogKiBBbGwgcmlnaHRzIHJlc2VydmVkLgogKiAgIGh0dHA6Ly93d3cuYWdlcmUuY29tCiAqCiAqLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tCiAqCiAqIGV0MTMxMF9wbS5jIC0gQWxsIHBvd2VyIG1hbmFnZW1lbnQgcmVsYXRlZCBjb2RlIChub3QgY29tcGxldGVseSBpbXBsZW1lbnRlZCkKICoKICotLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0KICoKICogU09GVFdBUkUgTElDRU5TRQogKgogKiBUaGlzIHNvZnR3YXJlIGlzIHByb3ZpZGVkIHN1YmplY3QgdG8gdGhlIGZvbGxvd2luZyB0ZXJtcyBhbmQgY29uZGl0aW9ucywKICogd2hpY2ggeW91IHNob3VsZCByZWFkIGNhcmVmdWxseSBiZWZvcmUgdXNpbmcgdGhlIHNvZnR3YXJlLiAgVXNpbmcgdGhpcwogKiBzb2Z0d2FyZSBpbmRpY2F0ZXMgeW91ciBhY2NlcHRhbmNlIG9mIHRoZXNlIHRlcm1zIGFuZCBjb25kaXRpb25zLiAgSWYgeW91IGRvCiAqIG5vdCBhZ3JlZSB3aXRoIHRoZXNlIHRlcm1zIGFuZCBjb25kaXRpb25zLCBkbyBub3QgdXNlIHRoZSBzb2Z0d2FyZS4KICoKICogQ29weXJpZ2h0IKkgMjAwNSBBZ2VyZSBTeXN0ZW1zIEluYy4KICogQWxsIHJpZ2h0cyByZXNlcnZlZC4KICoKICogUmVkaXN0cmlidXRpb24gYW5kIHVzZSBpbiBzb3VyY2Ugb3IgYmluYXJ5IGZvcm1zLCB3aXRoIG9yIHdpdGhvdXQKICogbW9kaWZpY2F0aW9ucywgYXJlIHBlcm1pdHRlZCBwcm92aWRlZCB0aGF0IHRoZSBmb2xsb3dpbmcgY29uZGl0aW9ucyBhcmUgbWV0OgogKgogKiAuIFJlZGlzdHJpYnV0aW9ucyBvZiBzb3VyY2UgY29kZSBtdXN0IHJldGFpbiB0aGUgYWJvdmUgY29weXJpZ2h0IG5vdGljZSwgdGhpcwogKiAgICBsaXN0IG9mIGNvbmRpdGlvbnMgYW5kIHRoZSBmb2xsb3dpbmcgRGlzY2xhaW1lciBhcyBjb21tZW50cyBpbiB0aGUgY29kZSBhcwogKiAgICB3ZWxsIGFzIGluIHRoZSBkb2N1bWVudGF0aW9uIGFuZC9vciBvdGhlciBtYXRlcmlhbHMgcHJvdmlkZWQgd2l0aCB0aGUKICogICAgZGlzdHJpYnV0aW9uLgogKgogKiAuIFJlZGlzdHJpYnV0aW9ucyBpbiBiaW5hcnkgZm9ybSBtdXN0IHJlcHJvZHVjZSB0aGUgYWJvdmUgY29weXJpZ2h0IG5vdGljZSwKICogICAgdGhpcyBsaXN0IG9mIGNvbmRpdGlvbnMgYW5kIHRoZSBmb2xsb3dpbmcgRGlzY2xhaW1lciBpbiB0aGUgZG9jdW1lbnRhdGlvbgogKiAgICBhbmQvb3Igb3RoZXIgbWF0ZXJpYWxzIHByb3ZpZGVkIHdpdGggdGhlIGRpc3RyaWJ1dGlvbi4KICoKICogLiBOZWl0aGVyIHRoZSBuYW1lIG9mIEFnZXJlIFN5c3RlbXMgSW5jLiBub3IgdGhlIG5hbWVzIG9mIHRoZSBjb250cmlidXRvcnMKICogICAgbWF5IGJlIHVzZWQgdG8gZW5kb3JzZSBvciBwcm9tb3RlIHByb2R1Y3RzIGRlcml2ZWQgZnJvbSB0aGlzIHNvZnR3YXJlCiAqICAgIHdpdGhvdXQgc3BlY2lmaWMgcHJpb3Igd3JpdHRlbiBwZXJtaXNzaW9uLgogKgogKiBEaXNjbGFpbWVyCiAqCiAqIFRISVMgU09GVFdBUkUgSVMgUFJPVklERUQgk0FTIElTlCBBTkQgQU5ZIEVYUFJFU1MgT1IgSU1QTElFRCBXQVJSQU5USUVTLAogKiBJTkNMVURJTkcsIEJVVCBOT1QgTElNSVRFRCBUTywgSU5GUklOR0VNRU5UIEFORCBUSEUgSU1QTElFRCBXQVJSQU5USUVTIE9GCiAqIE1FUkNIQU5UQUJJTElUWSBBTkQgRklUTkVTUyBGT1IgQSBQQVJUSUNVTEFSIFBVUlBPU0UgQVJFIERJU0NMQUlNRUQuICBBTlkKICogVVNFLCBNT0RJRklDQVRJT04gT1IgRElTVFJJQlVUSU9OIE9GIFRISVMgU09GVFdBUkUgSVMgU09MRUxZIEFUIFRIRSBVU0VSUyBPV04KICogUklTSy4gSU4gTk8gRVZFTlQgU0hBTEwgQUdFUkUgU1lTVEVNUyBJTkMuIE9SIENPTlRSSUJVVE9SUyBCRSBMSUFCTEUgRk9SIEFOWQogKiBESVJFQ1QsIElORElSRUNULCBJTkNJREVOVEFMLCBTUEVDSUFMLCBFWEVNUExBUlksIE9SIENPTlNFUVVFTlRJQUwgREFNQUdFUwogKiAoSU5DTFVESU5HLCBCVVQgTk9UIExJTUlURUQgVE8sIFBST0NVUkVNRU5UIE9GIFNVQlNUSVRVVEUgR09PRFMgT1IgU0VSVklDRVM7CiAqIExPU1MgT0YgVVNFLCBEQVRBLCBPUiBQUk9GSVRTOyBPUiBCVVNJTkVTUyBJTlRFUlJVUFRJT04pIEhPV0VWRVIgQ0FVU0VEIEFORAogKiBPTiBBTlkgVEhFT1JZIE9GIExJQUJJTElUWSwgSU5DTFVESU5HLCBCVVQgTk9UIExJTUlURUQgVE8sIENPTlRSQUNULCBTVFJJQ1QKICogTElBQklMSVRZLCBPUiBUT1JUIChJTkNMVURJTkcgTkVHTElHRU5DRSBPUiBPVEhFUldJU0UpIEFSSVNJTkcgSU4gQU5ZIFdBWSBPVVQKICogT0YgVEhFIFVTRSBPRiBUSElTIFNPRlRXQVJFLCBFVkVOIElGIEFEVklTRUQgT0YgVEhFIFBPU1NJQklMSVRZIE9GIFNVQ0gKICogREFNQUdFLgogKgogKi8KCiNpbmNsdWRlICJldDEzMXhfdmVyc2lvbi5oIgojaW5jbHVkZSAiZXQxMzF4X2RlYnVnLmgiCiNpbmNsdWRlICJldDEzMXhfZGVmcy5oIgoKI2luY2x1ZGUgPGxpbnV4L2luaXQuaD4KI2luY2x1ZGUgPGxpbnV4L21vZHVsZS5oPgojaW5jbHVkZSA8bGludXgvdHlwZXMuaD4KI2luY2x1ZGUgPGxpbnV4L2tlcm5lbC5oPgoKI2luY2x1ZGUgPGxpbnV4L3NjaGVkLmg+CiNpbmNsdWRlIDxsaW51eC9wdHJhY2UuaD4KI2luY2x1ZGUgPGxpbnV4L3NsYWIuaD4KI2luY2x1ZGUgPGxpbnV4L2N0eXBlLmg+CiNpbmNsdWRlIDxsaW51eC9zdHJpbmcuaD4KI2luY2x1ZGUgPGxpbnV4L3RpbWVyLmg+CiNpbmNsdWRlIDxsaW51eC9pbnRlcnJ1cHQuaD4KI2luY2x1ZGUgPGxpbnV4L2luLmg+CiNpbmNsdWRlIDxsaW51eC9kZWxheS5oPgojaW5jbHVkZSA8YXNtL2lvLmg+CiNpbmNsdWRlIDxhc20vc3lzdGVtLmg+CiNpbmNsdWRlIDxhc20vYml0b3BzLmg+CgojaW5jbHVkZSA8bGludXgvbmV0ZGV2aWNlLmg+CiNpbmNsdWRlIDxsaW51eC9ldGhlcmRldmljZS5oPgojaW5jbHVkZSA8bGludXgvc2tidWZmLmg+CiNpbmNsdWRlIDxsaW51eC9pZl9hcnAuaD4KI2luY2x1ZGUgPGxpbnV4L2lvcG9ydC5oPgoKI2luY2x1ZGUgImV0MTMxMF9waHkuaCIKI2luY2x1ZGUgImV0MTMxMF9wbS5oIgojaW5jbHVkZSAiZXQxMzEwX2phZ2NvcmUuaCIKI2luY2x1ZGUgImV0MTMxMF9tYWMuaCIKI2luY2x1ZGUgImV0MTMxMF9yeC5oIgoKI2luY2x1ZGUgImV0MTMxeF9hZGFwdGVyLmgiCiNpbmNsdWRlICJldDEzMXhfaW5pdHBjaS5oIgoKLyogRGF0YSBmb3IgZGVidWdnaW5nIGZhY2lsaXRpZXMgKi8KI2lmZGVmIENPTkZJR19FVDEzMVhfREVCVUcKZXh0ZXJuIGRiZ19pbmZvX3QgKmV0MTMxeF9kYmdpbmZvOwojZW5kaWYgLyogQ09ORklHX0VUMTMxWF9ERUJVRyAqLwoKLyoqCiAqIEVuYWJsZVBoeUNvbWEgLSBjYWxsZWQgd2hlbiBuZXR3b3JrIGNhYmxlIGlzIHVucGx1Z2dlZAogKiBAcEFkYXB0ZXI6IHBvaW50ZXIgdG8gb3VyIGFkYXB0ZXIgc3RydWN0dXJlCiAqCiAqIGRyaXZlciByZWNlaXZlIGFuIHBoeSBzdGF0dXMgY2hhbmdlIGludGVycnVwdCB3aGlsZSBpbiBEMCBhbmQgY2hlY2sgdGhhdAogKiBwaHlfc3RhdHVzIGlzIGRvd24uCiAqCiAqICAgICAgICAgIC0tIGdhdGUgb2ZmIEpBR0NvcmU7CiAqICAgICAgICAgIC0tIHNldCBnaWdFIFBIWSBpbiBDb21hIG1vZGUKICogICAgICAgICAgLS0gd2FrZSBvbiBwaHlfaW50ZXJydXB0OyBQZXJmb3JtIHNvZnR3YXJlIHJlc2V0IEpBR0NvcmUsCiAqICAgICAgICAgICAgIHJlLWluaXRpYWxpemUgamFnY29yZSBhbmQgZ2lnRSBQSFkKICoKICogICAgICBBZGQgRDAtQVNQTS1QaHlMaW5rRG93biBTdXBwb3J0OgogKiAgICAgICAgICAtLSB3aGlsZSBpbiBEMCwgd2hlbiB0aGVyZSBpcyBhIHBoeV9pbnRlcnJ1cHQgaW5kaWNhdGluZyBwaHkgbGluawogKiAgICAgICAgICAgICBkb3duIHN0YXR1cywgY2FsbCB0aGUgTVBTZXRQaHlDb21hIHJvdXRpbmUgdG8gZW50ZXIgdGhpcyBhY3RpdmUKICogICAgICAgICAgICAgc3RhdGUgcG93ZXIgc2F2aW5nIG1vZGUKICogICAgICAgICAgLS0gd2hpbGUgaW4gRDAtQVNQTS1QaHlMaW5rRG93biBtb2RlLCB3aGVuIHRoZXJlIGlzIGEgcGh5X2ludGVycnVwdAogKiAgICAgICBpbmRpY2F0aW5nIGxpbmt1cCBzdGF0dXMsIGNhbGwgdGhlIE1QRGlzYWJsZVBoeUNvbWEgcm91dGluZSB0bwogKiAgICAgICAgICAgICByZXN0b3JlIEpBR0NvcmUgYW5kIGdpZ0UgUEhZCiAqLwp2b2lkIEVuYWJsZVBoeUNvbWEoc3RydWN0IGV0MTMxeF9hZGFwdGVyICpwQWRhcHRlcikKewoJdW5zaWduZWQgbG9uZyBsb2NrZmxhZ3M7CglQTV9DU1JfdCBHbG9iYWxQbUNTUjsKCWludDMyX3QgTG9vcENvdW50ZXIgPSAxMDsKCglEQkdfRU5URVIoZXQxMzF4X2RiZ2luZm8pOwoKCUdsb2JhbFBtQ1NSLnZhbHVlID0gcmVhZGwoJnBBZGFwdGVyLT5DU1JBZGRyZXNzLT5nbG9iYWwucG1fY3NyLnZhbHVlKTsKCgkvKiBTYXZlIHRoZSBHYkUgUEhZIHNwZWVkIGFuZCBkdXBsZXggbW9kZXMuIE5lZWQgdG8gcmVzdG9yZSB0aGlzCgkgKiB3aGVuIGNhYmxlIGlzIHBsdWdnZWQgYmFjayBpbgoJICovCglwQWRhcHRlci0+UG9NZ210LlBvd2VyRG93blNwZWVkID0gcEFkYXB0ZXItPkFpRm9yY2VTcGVlZDsKCXBBZGFwdGVyLT5Qb01nbXQuUG93ZXJEb3duRHVwbGV4ID0gcEFkYXB0ZXItPkFpRm9yY2VEcHg7CgoJLyogU3RvcCBzZW5kaW5nIHBhY2tldHMuICovCglzcGluX2xvY2tfaXJxc2F2ZSgmcEFkYXB0ZXItPlNlbmRIV0xvY2ssIGxvY2tmbGFncyk7CglNUF9TRVRfRkxBRyhwQWRhcHRlciwgZk1QX0FEQVBURVJfTE9XRVJfUE9XRVIpOwoJc3Bpbl91bmxvY2tfaXJxcmVzdG9yZSgmcEFkYXB0ZXItPlNlbmRIV0xvY2ssIGxvY2tmbGFncyk7CgoJLyogV2FpdCBmb3Igb3V0c3RhbmRpbmcgUmVjZWl2ZSBwYWNrZXRzICovCgl3aGlsZSAoKE1QX0dFVF9SQ1ZfUkVGKHBBZGFwdGVyKSAhPSAwKSAmJiAoTG9vcENvdW50ZXItLSA+IDApKSB7CgkJbWRlbGF5KDIpOwoJfQoKCS8qIEdhdGUgb2ZmIEpBR0NvcmUgMyBjbG9jayBkb21haW5zICovCglHbG9iYWxQbUNTUi5iaXRzLnBtX3N5c2Nsa19nYXRlID0gMDsKCUdsb2JhbFBtQ1NSLmJpdHMucG1fdHhjbGtfZ2F0ZSA9IDA7CglHbG9iYWxQbUNTUi5iaXRzLnBtX3J4Y2xrX2dhdGUgPSAwOwoJd3JpdGVsKEdsb2JhbFBtQ1NSLnZhbHVlLCAmcEFkYXB0ZXItPkNTUkFkZHJlc3MtPmdsb2JhbC5wbV9jc3IudmFsdWUpOwoKCS8qIFByb2dyYW0gZ2lnRSBQSFkgaW4gdG8gQ29tYSBtb2RlICovCglHbG9iYWxQbUNTUi5iaXRzLnBtX3BoeV9zd19jb21hID0gMTsKCXdyaXRlbChHbG9iYWxQbUNTUi52YWx1ZSwgJnBBZGFwdGVyLT5DU1JBZGRyZXNzLT5nbG9iYWwucG1fY3NyLnZhbHVlKTsKCglEQkdfTEVBVkUoZXQxMzF4X2RiZ2luZm8pOwp9CgovKioKICogRGlzYWJsZVBoeUNvbWEgLSBEaXNhYmxlIHRoZSBQaHkgQ29tYSBNb2RlCiAqIEBwQWRhcHRlcjogcG9pbnRlciB0byBvdXIgYWRhcHRlciBzdHJ1Y3R1cmUKICovCnZvaWQgRGlzYWJsZVBoeUNvbWEoc3RydWN0IGV0MTMxeF9hZGFwdGVyICpwQWRhcHRlcikKewoJUE1fQ1NSX3QgR2xvYmFsUG1DU1I7CgoJREJHX0VOVEVSKGV0MTMxeF9kYmdpbmZvKTsKCglHbG9iYWxQbUNTUi52YWx1ZSA9IHJlYWRsKCZwQWRhcHRlci0+Q1NSQWRkcmVzcy0+Z2xvYmFsLnBtX2Nzci52YWx1ZSk7CgoJLyogRGlzYWJsZSBwaHlfc3dfY29tYSByZWdpc3RlciBhbmQgcmUtZW5hYmxlIEpBR0NvcmUgY2xvY2tzICovCglHbG9iYWxQbUNTUi5iaXRzLnBtX3N5c2Nsa19nYXRlID0gMTsKCUdsb2JhbFBtQ1NSLmJpdHMucG1fdHhjbGtfZ2F0ZSA9IDE7CglHbG9iYWxQbUNTUi5iaXRzLnBtX3J4Y2xrX2dhdGUgPSAxOwoJR2xvYmFsUG1DU1IuYml0cy5wbV9waHlfc3dfY29tYSA9IDA7Cgl3cml0ZWwoR2xvYmFsUG1DU1IudmFsdWUsICZwQWRhcHRlci0+Q1NSQWRkcmVzcy0+Z2xvYmFsLnBtX2Nzci52YWx1ZSk7CgoJLyogUmVzdG9yZSB0aGUgR2JFIFBIWSBzcGVlZCBhbmQgZHVwbGV4IG1vZGVzOwoJICogUmVzZXQgSkFHQ29yZTsgcmUtY29uZmlndXJlIGFuZCBpbml0aWFsaXplIEpBR0NvcmUgYW5kIGdpZ0UgUEhZCgkgKi8KCXBBZGFwdGVyLT5BaUZvcmNlU3BlZWQgPSBwQWRhcHRlci0+UG9NZ210LlBvd2VyRG93blNwZWVkOwoJcEFkYXB0ZXItPkFpRm9yY2VEcHggPSBwQWRhcHRlci0+UG9NZ210LlBvd2VyRG93bkR1cGxleDsKCgkvKiBSZS1pbml0aWFsaXplIHRoZSBzZW5kIHN0cnVjdHVyZXMgKi8KCWV0MTMxeF9pbml0X3NlbmQocEFkYXB0ZXIpOwoKCS8qIFJlc2V0IHRoZSBSRkQgbGlzdCBhbmQgcmUtc3RhcnQgUlUgICovCglldDEzMXhfcmVzZXRfcmVjdihwQWRhcHRlcik7CgoJLyogQnJpbmcgdGhlIGRldmljZSBiYWNrIHRvIHRoZSBzdGF0ZSBpdCB3YXMgZHVyaW5nIGluaXQgcHJpb3IgdG8KICAgICAgICAgKiBhdXRvbmVnb3RpYXRpb24gYmVpbmcgY29tcGxldGUuICBUaGlzIHdheSwgd2hlbiB3ZSBnZXQgdGhlIGF1dG8tbmVnCiAgICAgICAgICogY29tcGxldGUgaW50ZXJydXB0LCB3ZSBjYW4gY29tcGxldGUgaW5pdCBieSBjYWxsaW5nIENvbmZpZ01hY1JFR1MyLgogICAgICAgICAqLwoJZXQxMzF4X3NvZnRfcmVzZXQocEFkYXB0ZXIpOwoKCS8qIHNldHVwIGV0MTMxMCBhcyBwZXIgdGhlIGRvY3VtZW50YXRpb24gPz8gKi8KCWV0MTMxeF9hZGFwdGVyX3NldHVwKHBBZGFwdGVyKTsKCgkvKiBBbGxvdyBUeCB0byByZXN0YXJ0ICovCglNUF9DTEVBUl9GTEFHKHBBZGFwdGVyLCBmTVBfQURBUFRFUl9MT1dFUl9QT1dFUik7CgoJLyogTmVlZCB0byByZS1lbmFibGUgUnguICovCglldDEzMXhfcnhfZG1hX2VuYWJsZShwQWRhcHRlcik7CgoJREJHX0xFQVZFKGV0MTMxeF9kYmdpbmZvKTsKfQoK