LyoKICBTaW1wbGUgRGlyZWN0TWVkaWEgTGF5ZXIKICBDb3B5cmlnaHQgKEMpIDE5OTctMjAxMyBTYW0gTGFudGluZ2EgPHNsb3VrZW5AbGlic2RsLm9yZz4KCiAgVGhpcyBzb2Z0d2FyZSBpcyBwcm92aWRlZCAnYXMtaXMnLCB3aXRob3V0IGFueSBleHByZXNzIG9yIGltcGxpZWQKICB3YXJyYW50eS4gIEluIG5vIGV2ZW50IHdpbGwgdGhlIGF1dGhvcnMgYmUgaGVsZCBsaWFibGUgZm9yIGFueSBkYW1hZ2VzCiAgYXJpc2luZyBmcm9tIHRoZSB1c2Ugb2YgdGhpcyBzb2Z0d2FyZS4KCiAgUGVybWlzc2lvbiBpcyBncmFudGVkIHRvIGFueW9uZSB0byB1c2UgdGhpcyBzb2Z0d2FyZSBmb3IgYW55IHB1cnBvc2UsCiAgaW5jbHVkaW5nIGNvbW1lcmNpYWwgYXBwbGljYXRpb25zLCBhbmQgdG8gYWx0ZXIgaXQgYW5kIHJlZGlzdHJpYnV0ZSBpdAogIGZyZWVseSwgc3ViamVjdCB0byB0aGUgZm9sbG93aW5nIHJlc3RyaWN0aW9uczoKCiAgMS4gVGhlIG9yaWdpbiBvZiB0aGlzIHNvZnR3YXJlIG11c3Qgbm90IGJlIG1pc3JlcHJlc2VudGVkOyB5b3UgbXVzdCBub3QKICAgICBjbGFpbSB0aGF0IHlvdSB3cm90ZSB0aGUgb3JpZ2luYWwgc29mdHdhcmUuIElmIHlvdSB1c2UgdGhpcyBzb2Z0d2FyZQogICAgIGluIGEgcHJvZHVjdCwgYW4gYWNrbm93bGVkZ21lbnQgaW4gdGhlIHByb2R1Y3QgZG9jdW1lbnRhdGlvbiB3b3VsZCBiZQogICAgIGFwcHJlY2lhdGVkIGJ1dCBpcyBub3QgcmVxdWlyZWQuCiAgMi4gQWx0ZXJlZCBzb3VyY2UgdmVyc2lvbnMgbXVzdCBiZSBwbGFpbmx5IG1hcmtlZCBhcyBzdWNoLCBhbmQgbXVzdCBub3QgYmUKICAgICBtaXNyZXByZXNlbnRlZCBhcyBiZWluZyB0aGUgb3JpZ2luYWwgc29mdHdhcmUuCiAgMy4gVGhpcyBub3RpY2UgbWF5IG5vdCBiZSByZW1vdmVkIG9yIGFsdGVyZWQgZnJvbSBhbnkgc291cmNlIGRpc3RyaWJ1dGlvbi4KKi8KI2luY2x1ZGUgIlNETF9jb25maWcuaCIKCiNpZiBTRExfQVVESU9fRFJJVkVSX1NVTkFVRElPCgovKiBBbGxvdyBhY2Nlc3MgdG8gYSByYXcgbWl4aW5nIGJ1ZmZlciAqLwoKI2luY2x1ZGUgPGZjbnRsLmg+CiNpbmNsdWRlIDxlcnJuby5oPgojaWZkZWYgX19ORVRCU0RfXwojaW5jbHVkZSA8c3lzL2lvY3RsLmg+CiNpbmNsdWRlIDxzeXMvYXVkaW9pby5oPgojZW5kaWYKI2lmZGVmIF9fU1ZSNAojaW5jbHVkZSA8c3lzL2F1ZGlvaW8uaD4KI2Vsc2UKI2luY2x1ZGUgPHN5cy90aW1lLmg+CiNpbmNsdWRlIDxzeXMvdHlwZXMuaD4KI2VuZGlmCiNpbmNsdWRlIDx1bmlzdGQuaD4KCiNpbmNsdWRlICJTRExfdGltZXIuaCIKI2luY2x1ZGUgIlNETF9hdWRpby5oIgojaW5jbHVkZSAiLi4vU0RMX2F1ZGlvbWVtLmgiCiNpbmNsdWRlICIuLi9TRExfYXVkaW9fYy5oIgojaW5jbHVkZSAiLi4vU0RMX2F1ZGlvZGV2X2MuaCIKI2luY2x1ZGUgIlNETF9zdW5hdWRpby5oIgoKLyogT3BlbiB0aGUgYXVkaW8gZGV2aWNlIGZvciBwbGF5YmFjaywgYW5kIGRvbid0IGJsb2NrIGlmIGJ1c3kgKi8KCiNpZiBkZWZpbmVkKEFVRElPX0dFVElORk8pICYmICFkZWZpbmVkKEFVRElPX0dFVEJVRklORk8pCiNkZWZpbmUgQVVESU9fR0VUQlVGSU5GTyBBVURJT19HRVRJTkZPCiNlbmRpZgoKLyogQXVkaW8gZHJpdmVyIGZ1bmN0aW9ucyAqLwpzdGF0aWMgVWludDggc25kMmF1KGludCBzYW1wbGUpOwoKLyogQXVkaW8gZHJpdmVyIGJvb3RzdHJhcCBmdW5jdGlvbnMgKi8Kc3RhdGljIHZvaWQKU1VOQVVESU9fRGV0ZWN0RGV2aWNlcyhpbnQgaXNjYXB0dXJlLCBTRExfQWRkQXVkaW9EZXZpY2UgYWRkZm4pCnsKICAgIFNETF9FbnVtVW5peEF1ZGlvRGV2aWNlcyhpc2NhcHR1cmUsIDEsIChpbnQgKCopKGludCBmZCkpIE5VTEwsIGFkZGZuKTsKfQoKI2lmZGVmIERFQlVHX0FVRElPCnZvaWQKQ2hlY2tVbmRlcmZsb3coX1RISVMpCnsKI2lmZGVmIEFVRElPX0dFVEJVRklORk8KICAgIGF1ZGlvX2luZm9fdCBpbmZvOwogICAgaW50IGxlZnQ7CgogICAgaW9jdGwodGhpcy0+aGlkZGVuLT5hdWRpb19mZCwgQVVESU9fR0VUQlVGSU5GTywgJmluZm8pOwogICAgbGVmdCA9ICh0aGlzLT5oaWRkZW4tPndyaXR0ZW4gLSBpbmZvLnBsYXkuc2FtcGxlcyk7CiAgICBpZiAodGhpcy0+aGlkZGVuLT53cml0dGVuICYmIChsZWZ0ID09IDApKSB7CiAgICAgICAgZnByaW50ZihzdGRlcnIsICJhdWRpbyB1bmRlcmZsb3chXG4iKTsKICAgIH0KI2VuZGlmCn0KI2VuZGlmCgpzdGF0aWMgdm9pZApTVU5BVURJT19XYWl0RGV2aWNlKF9USElTKQp7CiNpZmRlZiBBVURJT19HRVRCVUZJTkZPCiNkZWZpbmUgU0xFRVBfRlVER0UgMTAgICAgICAvKiAxMCBtcyBzY2hlZHVsaW5nIGZ1ZGdlIGZhY3RvciAqLwogICAgYXVkaW9faW5mb190IGluZm87CiAgICBTaW50MzIgbGVmdDsKCiAgICBpb2N0bCh0aGlzLT5oaWRkZW4tPmF1ZGlvX2ZkLCBBVURJT19HRVRCVUZJTkZPLCAmaW5mbyk7CiAgICBsZWZ0ID0gKHRoaXMtPmhpZGRlbi0+d3JpdHRlbiAtIGluZm8ucGxheS5zYW1wbGVzKTsKICAgIGlmIChsZWZ0ID4gdGhpcy0+aGlkZGVuLT5mcmFnc2l6ZSkgewogICAgICAgIFNpbnQzMiBzbGVlcHk7CgogICAgICAgIHNsZWVweSA9ICgobGVmdCAtIHRoaXMtPmhpZGRlbi0+ZnJhZ3NpemUpIC8gdGhpcy0+aGlkZGVuLT5mcmVxdWVuY3kpOwogICAgICAgIHNsZWVweSAtPSBTTEVFUF9GVURHRTsKICAgICAgICBpZiAoc2xlZXB5ID4gMCkgewogICAgICAgICAgICBTRExfRGVsYXkoc2xlZXB5KTsKICAgICAgICB9CiAgICB9CiNlbHNlCiAgICBmZF9zZXQgZmRzZXQ7CgogICAgRkRfWkVSTygmZmRzZXQpOwogICAgRkRfU0VUKHRoaXMtPmhpZGRlbi0+YXVkaW9fZmQsICZmZHNldCk7CiAgICBzZWxlY3QodGhpcy0+aGlkZGVuLT5hdWRpb19mZCArIDEsIE5VTEwsICZmZHNldCwgTlVMTCwgTlVMTCk7CiNlbmRpZgp9CgpzdGF0aWMgdm9pZApTVU5BVURJT19QbGF5RGV2aWNlKF9USElTKQp7CiAgICAvKiBXcml0ZSB0aGUgYXVkaW8gZGF0YSAqLwogICAgaWYgKHRoaXMtPmhpZGRlbi0+dWxhd19vbmx5KSB7CiAgICAgICAgLyogQXNzdW1pbmcgdGhhdCB0aGlzLT5zcGVjLmZyZXEgPj0gODAwMCBIeiAqLwogICAgICAgIGludCBhY2N1bSwgaW5jciwgcG9zOwogICAgICAgIFVpbnQ4ICphdWJ1ZjsKCiAgICAgICAgYWNjdW0gPSAwOwogICAgICAgIGluY3IgPSB0aGlzLT5zcGVjLmZyZXEgLyA4OwogICAgICAgIGF1YnVmID0gdGhpcy0+aGlkZGVuLT51bGF3X2J1ZjsKICAgICAgICBzd2l0Y2ggKHRoaXMtPmhpZGRlbi0+YXVkaW9fZm10ICYgMHhGRikgewogICAgICAgIGNhc2UgODoKICAgICAgICAgICAgewogICAgICAgICAgICAgICAgVWludDggKnNuZGJ1ZjsKCiAgICAgICAgICAgICAgICBzbmRidWYgPSB0aGlzLT5oaWRkZW4tPm1peGJ1ZjsKICAgICAgICAgICAgICAgIGZvciAocG9zID0gMDsgcG9zIDwgdGhpcy0+aGlkZGVuLT5mcmFnc2l6ZTsgKytwb3MpIHsKICAgICAgICAgICAgICAgICAgICAqYXVidWYgPSBzbmQyYXUoKDB4ODAgLSAqc25kYnVmKSAqIDY0KTsKICAgICAgICAgICAgICAgICAgICBhY2N1bSArPSBpbmNyOwogICAgICAgICAgICAgICAgICAgIHdoaWxlIChhY2N1bSA+IDApIHsKICAgICAgICAgICAgICAgICAgICAgICAgYWNjdW0gLT0gMTAwMDsKICAgICAgICAgICAgICAgICAgICAgICAgc25kYnVmICs9IDE7CiAgICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgICAgIGF1YnVmICs9IDE7CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgIH0KICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgY2FzZSAxNjoKICAgICAgICAgICAgewogICAgICAgICAgICAgICAgU2ludDE2ICpzbmRidWY7CgogICAgICAgICAgICAgICAgc25kYnVmID0gKFNpbnQxNiAqKSB0aGlzLT5oaWRkZW4tPm1peGJ1ZjsKICAgICAgICAgICAgICAgIGZvciAocG9zID0gMDsgcG9zIDwgdGhpcy0+aGlkZGVuLT5mcmFnc2l6ZTsgKytwb3MpIHsKICAgICAgICAgICAgICAgICAgICAqYXVidWYgPSBzbmQyYXUoKnNuZGJ1ZiAvIDQpOwogICAgICAgICAgICAgICAgICAgIGFjY3VtICs9IGluY3I7CiAgICAgICAgICAgICAgICAgICAgd2hpbGUgKGFjY3VtID4gMCkgewogICAgICAgICAgICAgICAgICAgICAgICBhY2N1bSAtPSAxMDAwOwogICAgICAgICAgICAgICAgICAgICAgICBzbmRidWYgKz0gMTsKICAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICAgICAgYXVidWYgKz0gMTsKICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgfQogICAgICAgICAgICBicmVhazsKICAgICAgICB9CiNpZmRlZiBERUJVR19BVURJTwogICAgICAgIENoZWNrVW5kZXJmbG93KHRoaXMpOwojZW5kaWYKICAgICAgICBpZiAod3JpdGUodGhpcy0+aGlkZGVuLT5hdWRpb19mZCwgdGhpcy0+aGlkZGVuLT51bGF3X2J1ZiwKICAgICAgICAgICAgdGhpcy0+aGlkZGVuLT5mcmFnc2l6ZSkgPCAwKSB7CiAgICAgICAgICAgIC8qIEFzc3VtZSBmYXRhbCBlcnJvciwgZm9yIG5vdyAqLwogICAgICAgICAgICB0aGlzLT5lbmFibGVkID0gMDsKICAgICAgICB9CiAgICAgICAgdGhpcy0+aGlkZGVuLT53cml0dGVuICs9IHRoaXMtPmhpZGRlbi0+ZnJhZ3NpemU7CiAgICB9IGVsc2UgewojaWZkZWYgREVCVUdfQVVESU8KICAgICAgICBDaGVja1VuZGVyZmxvdyh0aGlzKTsKI2VuZGlmCiAgICAgICAgaWYgKHdyaXRlKHRoaXMtPmhpZGRlbi0+YXVkaW9fZmQsIHRoaXMtPmhpZGRlbi0+bWl4YnVmLAogICAgICAgICAgICB0aGlzLT5zcGVjLnNpemUpIDwgMCkgewogICAgICAgICAgICAvKiBBc3N1bWUgZmF0YWwgZXJyb3IsIGZvciBub3cgKi8KICAgICAgICAgICAgdGhpcy0+ZW5hYmxlZCA9IDA7CiAgICAgICAgfQogICAgICAgIHRoaXMtPmhpZGRlbi0+d3JpdHRlbiArPSB0aGlzLT5oaWRkZW4tPmZyYWdzaXplOwogICAgfQp9CgpzdGF0aWMgVWludDggKgpTVU5BVURJT19HZXREZXZpY2VCdWYoX1RISVMpCnsKICAgIHJldHVybiAodGhpcy0+aGlkZGVuLT5taXhidWYpOwp9CgpzdGF0aWMgdm9pZApTVU5BVURJT19DbG9zZURldmljZShfVEhJUykKewogICAgaWYgKHRoaXMtPmhpZGRlbiAhPSBOVUxMKSB7CiAgICAgICAgaWYgKHRoaXMtPmhpZGRlbi0+bWl4YnVmICE9IE5VTEwpIHsKICAgICAgICAgICAgU0RMX0ZyZWVBdWRpb01lbSh0aGlzLT5oaWRkZW4tPm1peGJ1Zik7CiAgICAgICAgICAgIHRoaXMtPmhpZGRlbi0+bWl4YnVmID0gTlVMTDsKICAgICAgICB9CiAgICAgICAgaWYgKHRoaXMtPmhpZGRlbi0+dWxhd19idWYgIT0gTlVMTCkgewogICAgICAgICAgICBTRExfZnJlZSh0aGlzLT5oaWRkZW4tPnVsYXdfYnVmKTsKICAgICAgICAgICAgdGhpcy0+aGlkZGVuLT51bGF3X2J1ZiA9IE5VTEw7CiAgICAgICAgfQogICAgICAgIGlmICh0aGlzLT5oaWRkZW4tPmF1ZGlvX2ZkID49IDApIHsKICAgICAgICAgICAgY2xvc2UodGhpcy0+aGlkZGVuLT5hdWRpb19mZCk7CiAgICAgICAgICAgIHRoaXMtPmhpZGRlbi0+YXVkaW9fZmQgPSAtMTsKICAgICAgICB9CiAgICAgICAgU0RMX2ZyZWUodGhpcy0+aGlkZGVuKTsKICAgICAgICB0aGlzLT5oaWRkZW4gPSBOVUxMOwogICAgfQp9CgpzdGF0aWMgaW50ClNVTkFVRElPX09wZW5EZXZpY2UoX1RISVMsIGNvbnN0IGNoYXIgKmRldm5hbWUsIGludCBpc2NhcHR1cmUpCnsKICAgIGNvbnN0IGludCBmbGFncyA9ICgoaXNjYXB0dXJlKSA/IE9QRU5fRkxBR1NfSU5QVVQgOiBPUEVOX0ZMQUdTX09VVFBVVCk7CiAgICBTRExfQXVkaW9Gb3JtYXQgZm9ybWF0ID0gMDsKICAgIGF1ZGlvX2luZm9fdCBpbmZvOwoKICAgIC8qIFdlIGRvbid0IGNhcmUgd2hhdCB0aGUgZGV2bmFtZSBpcy4uLndlJ2xsIHRyeSB0byBvcGVuIGFueXRoaW5nLiAqLwogICAgLyogIC4uLmJ1dCBkZWZhdWx0IHRvIGZpcnN0IG5hbWUgaW4gdGhlIGxpc3QuLi4gKi8KICAgIGlmIChkZXZuYW1lID09IE5VTEwpIHsKICAgICAgICBkZXZuYW1lID0gU0RMX0dldEF1ZGlvRGV2aWNlTmFtZSgwLCBpc2NhcHR1cmUpOwogICAgICAgIGlmIChkZXZuYW1lID09IE5VTEwpIHsKICAgICAgICAgICAgcmV0dXJuIFNETF9TZXRFcnJvcigiTm8gc3VjaCBhdWRpbyBkZXZpY2UiKTsKICAgICAgICB9CiAgICB9CgogICAgLyogSW5pdGlhbGl6ZSBhbGwgdmFyaWFibGVzIHRoYXQgd2UgY2xlYW4gb24gc2h1dGRvd24gKi8KICAgIHRoaXMtPmhpZGRlbiA9IChzdHJ1Y3QgU0RMX1ByaXZhdGVBdWRpb0RhdGEgKikKICAgICAgICBTRExfbWFsbG9jKChzaXplb2YgKnRoaXMtPmhpZGRlbikpOwogICAgaWYgKHRoaXMtPmhpZGRlbiA9PSBOVUxMKSB7CiAgICAgICAgcmV0dXJuIFNETF9PdXRPZk1lbW9yeSgpOwogICAgfQogICAgU0RMX21lbXNldCh0aGlzLT5oaWRkZW4sIDAsIChzaXplb2YgKnRoaXMtPmhpZGRlbikpOwoKICAgIC8qIE9wZW4gdGhlIGF1ZGlvIGRldmljZSAqLwogICAgdGhpcy0+aGlkZGVuLT5hdWRpb19mZCA9IG9wZW4oZGV2bmFtZSwgZmxhZ3MsIDApOwogICAgaWYgKHRoaXMtPmhpZGRlbi0+YXVkaW9fZmQgPCAwKSB7CiAgICAgICAgcmV0dXJuIFNETF9TZXRFcnJvcigiQ291bGRuJ3Qgb3BlbiAlczogJXMiLCBkZXZuYW1lLCBzdHJlcnJvcihlcnJubykpOwogICAgfQoKI2lmZGVmIEFVRElPX1NFVElORk8KICAgIGludCBlbmM7CiNlbmRpZgogICAgaW50IGRlc2lyZWRfZnJlcSA9IHRoaXMtPnNwZWMuZnJlcTsKCiAgICAvKiBEZXRlcm1pbmUgdGhlIGF1ZGlvIHBhcmFtZXRlcnMgZnJvbSB0aGUgQXVkaW9TcGVjICovCiAgICBzd2l0Y2ggKFNETF9BVURJT19CSVRTSVpFKHRoaXMtPnNwZWMuZm9ybWF0KSkgewoKICAgIGNhc2UgODoKICAgICAgICB7ICAgICAgICAgICAgICAgICAgICAgICAvKiBVbnNpZ25lZCA4IGJpdCBhdWRpbyBkYXRhICovCiAgICAgICAgICAgIHRoaXMtPnNwZWMuZm9ybWF0ID0gQVVESU9fVTg7CiNpZmRlZiBBVURJT19TRVRJTkZPCiAgICAgICAgICAgIGVuYyA9IEFVRElPX0VOQ09ESU5HX0xJTkVBUjg7CiNlbmRpZgogICAgICAgIH0KICAgICAgICBicmVhazsKCiAgICBjYXNlIDE2OgogICAgICAgIHsgICAgICAgICAgICAgICAgICAgICAgIC8qIFNpZ25lZCAxNiBiaXQgYXVkaW8gZGF0YSAqLwogICAgICAgICAgICB0aGlzLT5zcGVjLmZvcm1hdCA9IEFVRElPX1MxNlNZUzsKI2lmZGVmIEFVRElPX1NFVElORk8KICAgICAgICAgICAgZW5jID0gQVVESU9fRU5DT0RJTkdfTElORUFSOwojZW5kaWYKICAgICAgICB9CiAgICAgICAgYnJlYWs7CgogICAgZGVmYXVsdDoKICAgICAgICB7CiAgICAgICAgICAgIC8qICEhISBGSVhNRTogZmFsbGJhY2sgdG8gY29udmVyc2lvbiBvbiB1bnN1cHBvcnRlZCB0eXBlcyEgKi8KICAgICAgICAgICAgcmV0dXJuIFNETF9TZXRFcnJvcigiVW5zdXBwb3J0ZWQgYXVkaW8gZm9ybWF0Iik7CiAgICAgICAgfQogICAgfQogICAgdGhpcy0+aGlkZGVuLT5hdWRpb19mbXQgPSB0aGlzLT5zcGVjLmZvcm1hdDsKCiAgICB0aGlzLT5oaWRkZW4tPnVsYXdfb25seSA9IDA7ICAgIC8qIG1vZGVybiBTdW5zIGRvIHN1cHBvcnQgbGluZWFyIGF1ZGlvICovCiNpZmRlZiBBVURJT19TRVRJTkZPCiAgICBmb3IgKDs7KSB7CiAgICAgICAgYXVkaW9faW5mb190IGluZm87CiAgICAgICAgQVVESU9fSU5JVElORk8oJmluZm8pOyAgLyogaW5pdCBhbGwgZmllbGRzIHRvICJubyBjaGFuZ2UiICovCgogICAgICAgIC8qIFRyeSB0byBzZXQgdGhlIHJlcXVlc3RlZCBzZXR0aW5ncyAqLwogICAgICAgIGluZm8ucGxheS5zYW1wbGVfcmF0ZSA9IHRoaXMtPnNwZWMuZnJlcTsKICAgICAgICBpbmZvLnBsYXkuY2hhbm5lbHMgPSB0aGlzLT5zcGVjLmNoYW5uZWxzOwogICAgICAgIGluZm8ucGxheS5wcmVjaXNpb24gPSAoZW5jID09IEFVRElPX0VOQ09ESU5HX1VMQVcpCiAgICAgICAgICAgID8gOCA6IHRoaXMtPnNwZWMuZm9ybWF0ICYgMHhmZjsKICAgICAgICBpbmZvLnBsYXkuZW5jb2RpbmcgPSBlbmM7CiAgICAgICAgaWYgKGlvY3RsKHRoaXMtPmhpZGRlbi0+YXVkaW9fZmQsIEFVRElPX1NFVElORk8sICZpbmZvKSA9PSAwKSB7CgogICAgICAgICAgICAvKiBDaGVjayB0byBiZSBzdXJlIHdlIGdvdCB3aGF0IHdlIHdhbnRlZCAqLwogICAgICAgICAgICBpZiAoaW9jdGwodGhpcy0+aGlkZGVuLT5hdWRpb19mZCwgQVVESU9fR0VUSU5GTywgJmluZm8pIDwgMCkgewogICAgICAgICAgICAgICAgcmV0dXJuIFNETF9TZXRFcnJvcigiRXJyb3IgZ2V0dGluZyBhdWRpbyBwYXJhbWV0ZXJzOiAlcyIsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHN0cmVycm9yKGVycm5vKSk7CiAgICAgICAgICAgIH0KICAgICAgICAgICAgaWYgKGluZm8ucGxheS5lbmNvZGluZyA9PSBlbmMKICAgICAgICAgICAgICAgICYmIGluZm8ucGxheS5wcmVjaXNpb24gPT0gKHRoaXMtPnNwZWMuZm9ybWF0ICYgMHhmZikKICAgICAgICAgICAgICAgICYmIGluZm8ucGxheS5jaGFubmVscyA9PSB0aGlzLT5zcGVjLmNoYW5uZWxzKSB7CiAgICAgICAgICAgICAgICAvKiBZb3chIEFsbCBzZWVtcyB0byBiZSB3ZWxsISAqLwogICAgICAgICAgICAgICAgdGhpcy0+c3BlYy5mcmVxID0gaW5mby5wbGF5LnNhbXBsZV9yYXRlOwogICAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICAgIH0KICAgICAgICB9CgogICAgICAgIHN3aXRjaCAoZW5jKSB7CiAgICAgICAgY2FzZSBBVURJT19FTkNPRElOR19MSU5FQVI4OgogICAgICAgICAgICAvKiB1bnNpZ25lZCA4Yml0IGFwcGFyZW50bHkgbm90IHN1cHBvcnRlZCBoZXJlICovCiAgICAgICAgICAgIGVuYyA9IEFVRElPX0VOQ09ESU5HX0xJTkVBUjsKICAgICAgICAgICAgdGhpcy0+c3BlYy5mb3JtYXQgPSBBVURJT19TMTZTWVM7CiAgICAgICAgICAgIGJyZWFrOyAgICAgICAgICAgICAgLyogdHJ5IGFnYWluICovCgogICAgICAgIGNhc2UgQVVESU9fRU5DT0RJTkdfTElORUFSOgogICAgICAgICAgICAvKiBsaW5lYXIgMTZiaXQgZGlkbid0IHdvcmsgZWl0aGVyLCByZXNvcnQgdG8gtS1sYXcgKi8KICAgICAgICAgICAgZW5jID0gQVVESU9fRU5DT0RJTkdfVUxBVzsKICAgICAgICAgICAgdGhpcy0+c3BlYy5jaGFubmVscyA9IDE7CiAgICAgICAgICAgIHRoaXMtPnNwZWMuZnJlcSA9IDgwMDA7CiAgICAgICAgICAgIHRoaXMtPnNwZWMuZm9ybWF0ID0gQVVESU9fVTg7CiAgICAgICAgICAgIHRoaXMtPmhpZGRlbi0+dWxhd19vbmx5ID0gMTsKICAgICAgICAgICAgYnJlYWs7CgogICAgICAgIGRlZmF1bHQ6CiAgICAgICAgICAgIC8qIG9oIHdlbGwuLi4gKi8KICAgICAgICAgICAgcmV0dXJuIFNETF9TZXRFcnJvcigiRXJyb3Igc2V0dGluZyBhdWRpbyBwYXJhbWV0ZXJzOiAlcyIsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgc3RyZXJyb3IoZXJybm8pKTsKICAgICAgICB9CiAgICB9CiNlbmRpZiAvKiBBVURJT19TRVRJTkZPICovCiAgICB0aGlzLT5oaWRkZW4tPndyaXR0ZW4gPSAwOwoKICAgIC8qIFdlIGNhbiBhY3R1YWxseSBjb252ZXJ0IG9uLXRoZS1mbHkgdG8gVS1MYXcgKi8KICAgIGlmICh0aGlzLT5oaWRkZW4tPnVsYXdfb25seSkgewogICAgICAgIHRoaXMtPnNwZWMuZnJlcSA9IGRlc2lyZWRfZnJlcTsKICAgICAgICB0aGlzLT5oaWRkZW4tPmZyYWdzaXplID0gKHRoaXMtPnNwZWMuc2FtcGxlcyAqIDEwMDApIC8KICAgICAgICAgICAgKHRoaXMtPnNwZWMuZnJlcSAvIDgpOwogICAgICAgIHRoaXMtPmhpZGRlbi0+ZnJlcXVlbmN5ID0gODsKICAgICAgICB0aGlzLT5oaWRkZW4tPnVsYXdfYnVmID0gKFVpbnQ4ICopIFNETF9tYWxsb2ModGhpcy0+aGlkZGVuLT5mcmFnc2l6ZSk7CiAgICAgICAgaWYgKHRoaXMtPmhpZGRlbi0+dWxhd19idWYgPT0gTlVMTCkgewogICAgICAgICAgICByZXR1cm4gU0RMX091dE9mTWVtb3J5KCk7CiAgICAgICAgfQogICAgICAgIHRoaXMtPnNwZWMuY2hhbm5lbHMgPSAxOwogICAgfSBlbHNlIHsKICAgICAgICB0aGlzLT5oaWRkZW4tPmZyYWdzaXplID0gdGhpcy0+c3BlYy5zYW1wbGVzOwogICAgICAgIHRoaXMtPmhpZGRlbi0+ZnJlcXVlbmN5ID0gdGhpcy0+c3BlYy5mcmVxIC8gMTAwMDsKICAgIH0KI2lmZGVmIERFQlVHX0FVRElPCiAgICBmcHJpbnRmKHN0ZGVyciwgIkF1ZGlvIGRldmljZSAlcyBVLUxhdyBvbmx5XG4iLAogICAgICAgICAgICB0aGlzLT5oaWRkZW4tPnVsYXdfb25seSA/ICJpcyIgOiAiaXMgbm90Iik7CiAgICBmcHJpbnRmKHN0ZGVyciwgImZvcm1hdD0weCV4IGNoYW49JWQgZnJlcT0lZFxuIiwKICAgICAgICAgICAgdGhpcy0+c3BlYy5mb3JtYXQsIHRoaXMtPnNwZWMuY2hhbm5lbHMsIHRoaXMtPnNwZWMuZnJlcSk7CiNlbmRpZgoKICAgIC8qIFVwZGF0ZSB0aGUgZnJhZ21lbnQgc2l6ZSBhcyBzaXplIGluIGJ5dGVzICovCiAgICBTRExfQ2FsY3VsYXRlQXVkaW9TcGVjKCZ0aGlzLT5zcGVjKTsKCiAgICAvKiBBbGxvY2F0ZSBtaXhpbmcgYnVmZmVyICovCiAgICB0aGlzLT5oaWRkZW4tPm1peGJ1ZiA9IChVaW50OCAqKSBTRExfQWxsb2NBdWRpb01lbSh0aGlzLT5zcGVjLnNpemUpOwogICAgaWYgKHRoaXMtPmhpZGRlbi0+bWl4YnVmID09IE5VTEwpIHsKICAgICAgICByZXR1cm4gU0RMX091dE9mTWVtb3J5KCk7CiAgICB9CiAgICBTRExfbWVtc2V0KHRoaXMtPmhpZGRlbi0+bWl4YnVmLCB0aGlzLT5zcGVjLnNpbGVuY2UsIHRoaXMtPnNwZWMuc2l6ZSk7CgogICAgLyogV2UncmUgcmVhZHkgdG8gcm9jayBhbmQgcm9sbC4gOi0pICovCiAgICByZXR1cm4gMDsKfQoKLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKi8KLyogVGhpcyBmdW5jdGlvbiAoc25kMmF1KCkpIGNvcHlyaWdodGVkOiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgKi8KLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKi8KLyogICAgICBDb3B5cmlnaHQgMTk4OSBieSBSaWNoIEdvcHN0ZWluIGFuZCBIYXJyaXMgQ29ycG9yYXRpb24gICAgICAgICAgKi8KLyogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgKi8KLyogICAgICBQZXJtaXNzaW9uIHRvIHVzZSwgY29weSwgbW9kaWZ5LCBhbmQgZGlzdHJpYnV0ZSB0aGlzIHNvZnR3YXJlICAgKi8KLyogICAgICBhbmQgaXRzIGRvY3VtZW50YXRpb24gZm9yIGFueSBwdXJwb3NlIGFuZCB3aXRob3V0IGZlZSBpcyAgICAgICAgKi8KLyogICAgICBoZXJlYnkgZ3JhbnRlZCwgcHJvdmlkZWQgdGhhdCB0aGUgYWJvdmUgY29weXJpZ2h0IG5vdGljZSAgICAgICAgKi8KLyogICAgICBhcHBlYXJzIGluIGFsbCBjb3BpZXMgYW5kIHRoYXQgYm90aCB0aGF0IGNvcHlyaWdodCBub3RpY2UgYW5kICAgKi8KLyogICAgICB0aGlzIHBlcm1pc3Npb24gbm90aWNlIGFwcGVhciBpbiBzdXBwb3J0aW5nIGRvY3VtZW50YXRpb24sIGFuZCAgKi8KLyogICAgICB0aGF0IHRoZSBuYW1lIG9mIFJpY2ggR29wc3RlaW4gYW5kIEhhcnJpcyBDb3Jwb3JhdGlvbiBub3QgYmUgICAgKi8KLyogICAgICB1c2VkIGluIGFkdmVydGlzaW5nIG9yIHB1YmxpY2l0eSBwZXJ0YWluaW5nIHRvIGRpc3RyaWJ1dGlvbiAgICAgKi8KLyogICAgICBvZiB0aGUgc29mdHdhcmUgd2l0aG91dCBzcGVjaWZpYywgd3JpdHRlbiBwcmlvciBwZXJtaXNzaW9uLiAgICAgKi8KLyogICAgICBSaWNoIEdvcHN0ZWluIGFuZCBIYXJyaXMgQ29ycG9yYXRpb24gbWFrZSBubyByZXByZXNlbnRhdGlvbnMgICAgKi8KLyogICAgICBhYm91dCB0aGUgc3VpdGFiaWxpdHkgb2YgdGhpcyBzb2Z0d2FyZSBmb3IgYW55IHB1cnBvc2UuICBJdCAgICAgKi8KLyogICAgICBwcm92aWRlZCAiYXMgaXMiIHdpdGhvdXQgZXhwcmVzcyBvciBpbXBsaWVkIHdhcnJhbnR5LiAgICAgICAgICAgKi8KLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKi8KCnN0YXRpYyBVaW50OApzbmQyYXUoaW50IHNhbXBsZSkKewoKICAgIGludCBtYXNrOwoKICAgIGlmIChzYW1wbGUgPCAwKSB7CiAgICAgICAgc2FtcGxlID0gLXNhbXBsZTsKICAgICAgICBtYXNrID0gMHg3ZjsKICAgIH0gZWxzZSB7CiAgICAgICAgbWFzayA9IDB4ZmY7CiAgICB9CgogICAgaWYgKHNhbXBsZSA8IDMyKSB7CiAgICAgICAgc2FtcGxlID0gMHhGMCB8ICgxNSAtIHNhbXBsZSAvIDIpOwogICAgfSBlbHNlIGlmIChzYW1wbGUgPCA5NikgewogICAgICAgIHNhbXBsZSA9IDB4RTAgfCAoMTUgLSAoc2FtcGxlIC0gMzIpIC8gNCk7CiAgICB9IGVsc2UgaWYgKHNhbXBsZSA8IDIyNCkgewogICAgICAgIHNhbXBsZSA9IDB4RDAgfCAoMTUgLSAoc2FtcGxlIC0gOTYpIC8gOCk7CiAgICB9IGVsc2UgaWYgKHNhbXBsZSA8IDQ4MCkgewogICAgICAgIHNhbXBsZSA9IDB4QzAgfCAoMTUgLSAoc2FtcGxlIC0gMjI0KSAvIDE2KTsKICAgIH0gZWxzZSBpZiAoc2FtcGxlIDwgOTkyKSB7CiAgICAgICAgc2FtcGxlID0gMHhCMCB8ICgxNSAtIChzYW1wbGUgLSA0ODApIC8gMzIpOwogICAgfSBlbHNlIGlmIChzYW1wbGUgPCAyMDE2KSB7CiAgICAgICAgc2FtcGxlID0gMHhBMCB8ICgxNSAtIChzYW1wbGUgLSA5OTIpIC8gNjQpOwogICAgfSBlbHNlIGlmIChzYW1wbGUgPCA0MDY0KSB7CiAgICAgICAgc2FtcGxlID0gMHg5MCB8ICgxNSAtIChzYW1wbGUgLSAyMDE2KSAvIDEyOCk7CiAgICB9IGVsc2UgaWYgKHNhbXBsZSA8IDgxNjApIHsKICAgICAgICBzYW1wbGUgPSAweDgwIHwgKDE1IC0gKHNhbXBsZSAtIDQwNjQpIC8gMjU2KTsKICAgIH0gZWxzZSB7CiAgICAgICAgc2FtcGxlID0gMHg4MDsKICAgIH0KICAgIHJldHVybiAobWFzayAmIHNhbXBsZSk7Cn0KCnN0YXRpYyBpbnQKU1VOQVVESU9fSW5pdChTRExfQXVkaW9Ecml2ZXJJbXBsICogaW1wbCkKewogICAgLyogU2V0IHRoZSBmdW5jdGlvbiBwb2ludGVycyAqLwogICAgaW1wbC0+RGV0ZWN0RGV2aWNlcyA9IFNVTkFVRElPX0RldGVjdERldmljZXM7CiAgICBpbXBsLT5PcGVuRGV2aWNlID0gU1VOQVVESU9fT3BlbkRldmljZTsKICAgIGltcGwtPlBsYXlEZXZpY2UgPSBTVU5BVURJT19QbGF5RGV2aWNlOwogICAgaW1wbC0+V2FpdERldmljZSA9IFNVTkFVRElPX1dhaXREZXZpY2U7CiAgICBpbXBsLT5HZXREZXZpY2VCdWYgPSBTVU5BVURJT19HZXREZXZpY2VCdWY7CiAgICBpbXBsLT5DbG9zZURldmljZSA9IFNVTkFVRElPX0Nsb3NlRGV2aWNlOwoKICAgIHJldHVybiAxOyAvKiB0aGlzIGF1ZGlvIHRhcmdldCBpcyBhdmFpbGFibGUuICovCn0KCkF1ZGlvQm9vdFN0cmFwIFNVTkFVRElPX2Jvb3RzdHJhcCA9IHsKICAgICJhdWRpbyIsICJVTklYIC9kZXYvYXVkaW8gaW50ZXJmYWNlIiwgU1VOQVVESU9fSW5pdCwgMAp9OwoKI2VuZGlmIC8qIFNETF9BVURJT19EUklWRVJfU1VOQVVESU8gKi8KCi8qIHZpOiBzZXQgdHM9NCBzdz00IGV4cGFuZHRhYjogKi8K