LyoKICoJaTYzMDBlc2I6CVdhdGNoZG9nIHRpbWVyIGRyaXZlciBmb3IgSW50ZWwgNjMwMEVTQiBjaGlwc2V0CiAqCiAqCShjKSBDb3B5cmlnaHQgMjAwNCBHb29nbGUgSW5jLgogKgkoYykgQ29weXJpZ2h0IDIwMDUgRGF2aWQgSORyZGVtYW4gPGRhdmlkQDJnZW4uY29tPgogKgogKglUaGlzIHByb2dyYW0gaXMgZnJlZSBzb2Z0d2FyZTsgeW91IGNhbiByZWRpc3RyaWJ1dGUgaXQgYW5kL29yCiAqCW1vZGlmeSBpdCB1bmRlciB0aGUgdGVybXMgb2YgdGhlIEdOVSBHZW5lcmFsIFB1YmxpYyBMaWNlbnNlCiAqCWFzIHB1Ymxpc2hlZCBieSB0aGUgRnJlZSBTb2Z0d2FyZSBGb3VuZGF0aW9uOyBlaXRoZXIgdmVyc2lvbgogKgkyIG9mIHRoZSBMaWNlbnNlLCBvciAoYXQgeW91ciBvcHRpb24pIGFueSBsYXRlciB2ZXJzaW9uLgogKgogKiAgICAgIGJhc2VkIG9uIGk4MTAtdGNvLmMgd2hpY2ggaXMgaW4gdHVybiBiYXNlZCBvbiBzb2Z0ZG9nLmMKICoKICogCVRoZSB0aW1lciBpcyBpbXBsZW1lbnRlZCBpbiB0aGUgZm9sbG93aW5nIEkvTyBjb250cm9sbGVyIGh1YnM6CiAqIAkoU2VlIHRoZSBpbnRlbCBkb2N1bWVudGF0aW9uIG9uIGh0dHA6Ly9kZXZlbG9wZXIuaW50ZWwuY29tLikKICogCTYzMDBFU0IgY2hpcCA6IGRvY3VtZW50IG51bWJlciAzMDA2NDEtMDAzCiAqCiAqICAyMDA0WVlaWiBSb3NzIEJpcm8KICoJSW5pdGlhbCB2ZXJzaW9uIDAuMDEKICogIDIwMDRZWVpaIFJvc3MgQmlybwogKiAgCVZlcnNpb24gMC4wMgogKiAgMjAwNTAyMTAgRGF2aWQgSORyZGVtYW4gPGRhdmlkQDJnZW4uY29tPgogKiAgICAgIFBvcnRlZCBkcml2ZXIgdG8ga2VybmVsIDIuNgogKi8KCi8qCiAqICAgICAgSW5jbHVkZXMsIGRlZmluZXMsIHZhcmlhYmxlcywgbW9kdWxlIHBhcmFtZXRlcnMsIC4uLgogKi8KCiNpbmNsdWRlIDxsaW51eC9tb2R1bGUuaD4KI2luY2x1ZGUgPGxpbnV4L3R5cGVzLmg+CiNpbmNsdWRlIDxsaW51eC9rZXJuZWwuaD4KI2luY2x1ZGUgPGxpbnV4L2ZzLmg+CiNpbmNsdWRlIDxsaW51eC9tbS5oPgojaW5jbHVkZSA8bGludXgvbWlzY2RldmljZS5oPgojaW5jbHVkZSA8bGludXgvd2F0Y2hkb2cuaD4KI2luY2x1ZGUgPGxpbnV4L3JlYm9vdC5oPgojaW5jbHVkZSA8bGludXgvaW5pdC5oPgojaW5jbHVkZSA8bGludXgvcGNpLmg+CiNpbmNsdWRlIDxsaW51eC9pb3BvcnQuaD4KCiNpbmNsdWRlIDxhc20vdWFjY2Vzcy5oPgojaW5jbHVkZSA8YXNtL2lvLmg+CgovKiBNb2R1bGUgYW5kIHZlcnNpb24gaW5mb3JtYXRpb24gKi8KI2RlZmluZSBFU0JfVkVSU0lPTiAiMC4wMyIKI2RlZmluZSBFU0JfTU9EVUxFX05BTUUgImk2MzAwRVNCIHRpbWVyIgojZGVmaW5lIEVTQl9EUklWRVJfTkFNRSBFU0JfTU9EVUxFX05BTUUgIiwgdiIgRVNCX1ZFUlNJT04KI2RlZmluZSBQRlggRVNCX01PRFVMRV9OQU1FICI6ICIKCi8qIFBDSSBjb25maWd1cmF0aW9uIHJlZ2lzdGVycyAqLwojZGVmaW5lIEVTQl9DT05GSUdfUkVHICAweDYwICAgICAgICAgICAgLyogQ29uZmlnIHJlZ2lzdGVyICAgICAgICAgICAgICAgICAgICovCiNkZWZpbmUgRVNCX0xPQ0tfUkVHICAgIDB4NjggICAgICAgICAgICAvKiBXRFQgbG9jayByZWdpc3RlciAgICAgICAgICAgICAgICAgKi8KCi8qIE1lbW9yeSBtYXBwZWQgcmVnaXN0ZXJzICovCiNkZWZpbmUgRVNCX1RJTUVSMV9SRUcgIEJBU0VBRERSICsgMHgwMCAvKiBUaW1lcjEgdmFsdWUgYWZ0ZXIgZWFjaCByZXNldCAgICAgKi8KI2RlZmluZSBFU0JfVElNRVIyX1JFRyAgQkFTRUFERFIgKyAweDA0IC8qIFRpbWVyMiB2YWx1ZSBhZnRlciBlYWNoIHJlc2V0ICAgICAqLwojZGVmaW5lIEVTQl9HSU5UU1JfUkVHICBCQVNFQUREUiArIDB4MDggLyogR2VuZXJhbCBJbnRlcnJ1cHQgU3RhdHVzIFJlZ2lzdGVyICovCiNkZWZpbmUgRVNCX1JFTE9BRF9SRUcgIEJBU0VBRERSICsgMHgwYyAvKiBSZWxvYWQgcmVnaXN0ZXIgICAgICAgICAgICAgICAgICAgKi8KCi8qIExvY2sgcmVnaXN0ZXIgYml0cyAqLwojZGVmaW5lIEVTQl9XRFRfRlVOQyAgICAoIDB4MDEgPDwgMiApICAgLyogV2F0Y2hkb2cgZnVuY3Rpb25hbGl0eSAgICAgICAgICAgICovCiNkZWZpbmUgRVNCX1dEVF9FTkFCTEUgICggMHgwMSA8PCAxICkgICAvKiBFbmFibGUgV0RUICAgICAgICAgICAgICAgICAgICAgICAgKi8KI2RlZmluZSBFU0JfV0RUX0xPQ0sgICAgKCAweDAxIDw8IDAgKSAgIC8qIExvY2sgKG5vd2F5b3V0KSAgICAgICAgICAgICAgICAgICAqLwoKLyogQ29uZmlnIHJlZ2lzdGVyIGJpdHMgKi8KI2RlZmluZSBFU0JfV0RUX1JFQk9PVCAgKCAweDAxIDw8IDUgKSAgIC8qIEVuYWJsZSByZWJvb3Qgb24gdGltZW91dCAgICAgICAgICAqLwojZGVmaW5lIEVTQl9XRFRfRlJFUSAgICAoIDB4MDEgPDwgMiApICAgLyogRGVjcmVtZW50IGZyZXF1ZW5jeSAgICAgICAgICAgICAgICovCiNkZWZpbmUgRVNCX1dEVF9JTlRUWVBFICggMHgxMSA8PCAwICkgICAvKiBJbnRlcnJ1cHQgdHlwZSBvbiB0aW1lcjEgdGltZW91dCAgKi8KCi8qIFJlbG9hZCByZWdpc3RlciBiaXRzICovCiNkZWZpbmUgRVNCX1dEVF9SRUxPQUQgKCAweDAxIDw8IDggKSAgICAvKiBwcmV2ZW50IHRpbWVvdXQgICAgICAgICAgICAgICAgICAgKi8KCi8qIE1hZ2ljIGNvbnN0YW50cyAqLwojZGVmaW5lIEVTQl9VTkxPQ0sxICAgICAweDgwICAgICAgICAgICAgLyogU3RlcCAxIHRvIHVubG9jayByZXNldCByZWdpc3RlcnMgICovCiNkZWZpbmUgRVNCX1VOTE9DSzIgICAgIDB4ODYgICAgICAgICAgICAvKiBTdGVwIDIgdG8gdW5sb2NrIHJlc2V0IHJlZ2lzdGVycyAgKi8KCi8qIGludGVybmFsIHZhcmlhYmxlcyAqLwpzdGF0aWMgdm9pZCBfX2lvbWVtICpCQVNFQUREUjsKc3RhdGljIHNwaW5sb2NrX3QgZXNiX2xvY2s7IC8qIEd1YXJkcyB0aGUgaGFyZHdhcmUgKi8Kc3RhdGljIHVuc2lnbmVkIGxvbmcgdGltZXJfYWxpdmU7CnN0YXRpYyBzdHJ1Y3QgcGNpX2RldiAqZXNiX3BjaTsKc3RhdGljIHVuc2lnbmVkIHNob3J0IHRyaWdnZXJlZDsgLyogVGhlIHN0YXR1cyBvZiB0aGUgd2F0Y2hkb2cgdXBvbiBib290ICovCnN0YXRpYyBjaGFyIGVzYl9leHBlY3RfY2xvc2U7CgovKiBtb2R1bGUgcGFyYW1ldGVycyAqLwojZGVmaW5lIFdBVENIRE9HX0hFQVJUQkVBVCAzMCAgIC8qIDMwIHNlYyBkZWZhdWx0IGhlYXJ0YmVhdCAoMTxoZWFydGJlYXQ8MioxMDIzKSAqLwpzdGF0aWMgaW50IGhlYXJ0YmVhdCA9IFdBVENIRE9HX0hFQVJUQkVBVDsgIC8qIGluIHNlY29uZHMgKi8KbW9kdWxlX3BhcmFtKGhlYXJ0YmVhdCwgaW50LCAwKTsKTU9EVUxFX1BBUk1fREVTQyhoZWFydGJlYXQsICJXYXRjaGRvZyBoZWFydGJlYXQgaW4gc2Vjb25kcy4gKDE8aGVhcnRiZWF0PDIwNDYsIGRlZmF1bHQ9IiBfX01PRFVMRV9TVFJJTkcoV0FUQ0hET0dfSEVBUlRCRUFUKSAiKSIpOwoKc3RhdGljIGludCBub3dheW91dCA9IFdBVENIRE9HX05PV0FZT1VUOwptb2R1bGVfcGFyYW0obm93YXlvdXQsIGludCwgMCk7Ck1PRFVMRV9QQVJNX0RFU0Mobm93YXlvdXQsICJXYXRjaGRvZyBjYW5ub3QgYmUgc3RvcHBlZCBvbmNlIHN0YXJ0ZWQgKGRlZmF1bHQ9IiBfX01PRFVMRV9TVFJJTkcoV0FUQ0hET0dfTk9XQVlPVVQpICIpIik7CgovKgogKiBTb21lIGk2MzAwRVNCIHNwZWNpZmljIGZ1bmN0aW9ucwogKi8KCi8qCiAqIFByZXBhcmUgZm9yIHJlbG9hZGluZyB0aGUgdGltZXIgYnkgdW5sb2NraW5nIHRoZSBwcm9wZXIgcmVnaXN0ZXJzLgogKiBUaGlzIGlzIHBlcmZvcm1lZCBieSBmaXJzdCB3cml0aW5nIDB4ODAgZm9sbG93ZWQgYnkgMHg4NiB0byB0aGUKICogcmVsb2FkIHJlZ2lzdGVyLiBBZnRlciB0aGlzIHRoZSBhcHByb3ByaWF0ZSByZWdpc3RlcnMgY2FuIGJlIHdyaXR0ZW4KICogdG8gb25jZSBiZWZvcmUgdGhleSBuZWVkIHRvIGJlIHVubG9ja2VkIGFnYWluLgogKi8Kc3RhdGljIGlubGluZSB2b2lkIGVzYl91bmxvY2tfcmVnaXN0ZXJzKHZvaWQpIHsKICAgICAgICB3cml0ZWIoRVNCX1VOTE9DSzEsIEVTQl9SRUxPQURfUkVHKTsKICAgICAgICB3cml0ZWIoRVNCX1VOTE9DSzIsIEVTQl9SRUxPQURfUkVHKTsKfQoKc3RhdGljIHZvaWQgZXNiX3RpbWVyX3N0YXJ0KHZvaWQpCnsKCXU4IHZhbDsKCgkvKiBFbmFibGUgb3IgRW5hYmxlICsgTG9jaz8gKi8KCXZhbCA9IDB4MDIgfCAobm93YXlvdXQgPyAweDAxIDogMHgwMCk7CgogICAgICAgIHBjaV93cml0ZV9jb25maWdfYnl0ZShlc2JfcGNpLCBFU0JfTE9DS19SRUcsIHZhbCk7Cn0KCnN0YXRpYyBpbnQgZXNiX3RpbWVyX3N0b3Aodm9pZCkKewoJdTggdmFsOwoKCXNwaW5fbG9jaygmZXNiX2xvY2spOwoJLyogRmlyc3QsIHJlc2V0IHRpbWVycyBhcyBzdWdnZXN0ZWQgYnkgdGhlIGRvY3MgKi8KCWVzYl91bmxvY2tfcmVnaXN0ZXJzKCk7Cgl3cml0ZXcoRVNCX1dEVF9SRUxPQUQsIEVTQl9SRUxPQURfUkVHKTsKCS8qIFRoZW4gZGlzYWJsZSB0aGUgV0RUICovCglwY2lfd3JpdGVfY29uZmlnX2J5dGUoZXNiX3BjaSwgRVNCX0xPQ0tfUkVHLCAweDApOwoJcGNpX3JlYWRfY29uZmlnX2J5dGUoZXNiX3BjaSwgRVNCX0xPQ0tfUkVHLCAmdmFsKTsKCXNwaW5fdW5sb2NrKCZlc2JfbG9jayk7CgoJLyogUmV0dXJucyAwIGlmIHRoZSB0aW1lciB3YXMgZGlzYWJsZWQsIG5vbi16ZXJvIG90aGVyd2lzZSAqLwoJcmV0dXJuICh2YWwgJiAweDAxKTsKfQoKc3RhdGljIHZvaWQgZXNiX3RpbWVyX2tlZXBhbGl2ZSh2b2lkKQp7CglzcGluX2xvY2soJmVzYl9sb2NrKTsKCWVzYl91bmxvY2tfcmVnaXN0ZXJzKCk7Cgl3cml0ZXcoRVNCX1dEVF9SRUxPQUQsIEVTQl9SRUxPQURfUkVHKTsKICAgICAgICAvKiBGSVhNRTogRG8gd2UgbmVlZCB0byBmbHVzaCBhbnl0aGluZyBoZXJlPyAqLwoJc3Bpbl91bmxvY2soJmVzYl9sb2NrKTsKfQoKc3RhdGljIGludCBlc2JfdGltZXJfc2V0X2hlYXJ0YmVhdChpbnQgdGltZSkKewoJdTMyIHZhbDsKCglpZiAodGltZSA8IDB4MSB8fCB0aW1lID4gKDIgKiAweDAzZmYpKQoJCXJldHVybiAtRUlOVkFMOwoKCXNwaW5fbG9jaygmZXNiX2xvY2spOwoKCS8qIFdlIHNoaWZ0IGJ5IDksIHNvIGlmIHdlIGFyZSBwYXNzZWQgYSB2YWx1ZSBvZiAxIHNlYywKCSAqIHZhbCB3aWxsIGJlIDEgPDwgOSA9IDUxMiwgdGhlbiB3cml0ZSB0aGF0IHRvIHR3bwoJICogdGltZXJzID0+IDIgKiA1MTIgPSAxMDI0ICh3aGljaCBpcyBkZWNyZW1lbnRlZCBhdCAxS0h6KQoJICovCgl2YWwgPSB0aW1lIDw8IDk7CgoJLyogV3JpdGUgdGltZXIgMSAqLwoJZXNiX3VubG9ja19yZWdpc3RlcnMoKTsKCXdyaXRlbCh2YWwsIEVTQl9USU1FUjFfUkVHKTsKCgkvKiBXcml0ZSB0aW1lciAyICovCgllc2JfdW5sb2NrX3JlZ2lzdGVycygpOwogICAgICAgIHdyaXRlbCh2YWwsIEVTQl9USU1FUjJfUkVHKTsKCiAgICAgICAgLyogUmVsb2FkICovCgllc2JfdW5sb2NrX3JlZ2lzdGVycygpOwoJd3JpdGV3KEVTQl9XRFRfUkVMT0FELCBFU0JfUkVMT0FEX1JFRyk7CgoJLyogRklYTUU6IERvIHdlIG5lZWQgdG8gZmx1c2ggZXZlcnl0aGluZyBvdXQ/ICovCgoJLyogRG9uZSAqLwoJaGVhcnRiZWF0ID0gdGltZTsKCXNwaW5fdW5sb2NrKCZlc2JfbG9jayk7CglyZXR1cm4gMDsKfQoKc3RhdGljIGludCBlc2JfdGltZXJfcmVhZCAodm9pZCkKewogICAgICAgCXUzMiBjb3VudDsKCgkvKiBUaGlzIGlzbid0IGRvY3VtZW50ZWQsIGFuZCBkb2Vzbid0IHRha2UgaW50bwogICAgICAgICAqIGFjb3VudCB3aGljaCBzdGFnZSBpcyBydW5uaW5nLCBidXQgaXQgbG9va3MKICAgICAgICAgKiBsaWtlIGEgMjAgYml0IGNvdW50IGRvd24sIHNvIHdlIG1pZ2h0IGFzIHdlbGwgcmVwb3J0IGl0LgogICAgICAgICAqLwogICAgICAgIHBjaV9yZWFkX2NvbmZpZ19kd29yZChlc2JfcGNpLCAweDY0LCAmY291bnQpOwogICAgICAgIHJldHVybiAoaW50KWNvdW50Owp9CgovKgogKiAJL2Rldi93YXRjaGRvZyBoYW5kbGluZwogKi8KCnN0YXRpYyBpbnQgZXNiX29wZW4gKHN0cnVjdCBpbm9kZSAqaW5vZGUsIHN0cnVjdCBmaWxlICpmaWxlKQp7CiAgICAgICAgLyogL2Rldi93YXRjaGRvZyBjYW4gb25seSBiZSBvcGVuZWQgb25jZSAqLwogICAgICAgIGlmICh0ZXN0X2FuZF9zZXRfYml0KDAsICZ0aW1lcl9hbGl2ZSkpCiAgICAgICAgICAgICAgICByZXR1cm4gLUVCVVNZOwoKICAgICAgICAvKiBSZWxvYWQgYW5kIGFjdGl2YXRlIHRpbWVyICovCiAgICAgICAgZXNiX3RpbWVyX2tlZXBhbGl2ZSAoKTsKICAgICAgICBlc2JfdGltZXJfc3RhcnQgKCk7CgoJcmV0dXJuIG5vbnNlZWthYmxlX29wZW4oaW5vZGUsIGZpbGUpOwp9CgpzdGF0aWMgaW50IGVzYl9yZWxlYXNlIChzdHJ1Y3QgaW5vZGUgKmlub2RlLCBzdHJ1Y3QgZmlsZSAqZmlsZSkKewogICAgICAgIC8qIFNodXQgb2ZmIHRoZSB0aW1lci4gKi8KICAgICAgICBpZiAoZXNiX2V4cGVjdF9jbG9zZSA9PSA0MikgewogICAgICAgICAgICAgICAgZXNiX3RpbWVyX3N0b3AgKCk7CiAgICAgICAgfSBlbHNlIHsKICAgICAgICAgICAgICAgIHByaW50ayhLRVJOX0NSSVQgUEZYICJVbmV4cGVjdGVkIGNsb3NlLCBub3Qgc3RvcHBpbmcgd2F0Y2hkb2chXG4iKTsKICAgICAgICAgICAgICAgIGVzYl90aW1lcl9rZWVwYWxpdmUgKCk7CiAgICAgICAgfQogICAgICAgIGNsZWFyX2JpdCgwLCAmdGltZXJfYWxpdmUpOwogICAgICAgIGVzYl9leHBlY3RfY2xvc2UgPSAwOwogICAgICAgIHJldHVybiAwOwp9CgpzdGF0aWMgc3NpemVfdCBlc2Jfd3JpdGUgKHN0cnVjdCBmaWxlICpmaWxlLCBjb25zdCBjaGFyIF9fdXNlciAqZGF0YSwKCQkJICBzaXplX3QgbGVuLCBsb2ZmX3QgKiBwcG9zKQp7CgkvKiBTZWUgaWYgd2UgZ290IHRoZSBtYWdpYyBjaGFyYWN0ZXIgJ1YnIGFuZCByZWxvYWQgdGhlIHRpbWVyICovCiAgICAgICAgaWYgKGxlbikgewoJCWlmICghbm93YXlvdXQpIHsKCQkJc2l6ZV90IGk7CgoJCQkvKiBub3RlOiBqdXN0IGluIGNhc2Ugc29tZW9uZSB3cm90ZSB0aGUgbWFnaWMgY2hhcmFjdGVyCgkJCSAqIGZpdmUgbW9udGhzIGFnby4uLiAqLwoJCQllc2JfZXhwZWN0X2Nsb3NlID0gMDsKCgkJCS8qIHNjYW4gdG8gc2VlIHdoZXRoZXIgb3Igbm90IHdlIGdvdCB0aGUgbWFnaWMgY2hhcmFjdGVyICovCgkJCWZvciAoaSA9IDA7IGkgIT0gbGVuOyBpKyspIHsKCQkJCWNoYXIgYzsKCQkJCWlmKGdldF91c2VyKGMsIGRhdGEraSkpCgkJCQkJcmV0dXJuIC1FRkFVTFQ7CgkJCQlpZiAoYyA9PSAnVicpCgkJCQkJZXNiX2V4cGVjdF9jbG9zZSA9IDQyOwoJCQl9CgkJfQoKCQkvKiBzb21lb25lIHdyb3RlIHRvIHVzLCB3ZSBzaG91bGQgcmVsb2FkIHRoZSB0aW1lciAqLwoJCWVzYl90aW1lcl9rZWVwYWxpdmUgKCk7Cgl9CglyZXR1cm4gbGVuOwp9CgpzdGF0aWMgaW50IGVzYl9pb2N0bCAoc3RydWN0IGlub2RlICppbm9kZSwgc3RydWN0IGZpbGUgKmZpbGUsCgkJICAgICAgdW5zaWduZWQgaW50IGNtZCwgdW5zaWduZWQgbG9uZyBhcmcpCnsKCWludCBuZXdfb3B0aW9ucywgcmV0dmFsID0gLUVJTlZBTDsKCWludCBuZXdfaGVhcnRiZWF0OwoJdm9pZCBfX3VzZXIgKmFyZ3AgPSAodm9pZCBfX3VzZXIgKilhcmc7CglpbnQgX191c2VyICpwID0gYXJncDsKCXN0YXRpYyBzdHJ1Y3Qgd2F0Y2hkb2dfaW5mbyBpZGVudCA9IHsKCQkub3B0aW9ucyA9ICAgICAgICAgICAgICBXRElPRl9TRVRUSU1FT1VUIHwKCQkJCQlXRElPRl9LRUVQQUxJVkVQSU5HIHwKCQkJCQlXRElPRl9NQUdJQ0NMT1NFLAoJCS5maXJtd2FyZV92ZXJzaW9uID0gICAgIDAsCgkJLmlkZW50aXR5ID0gICAgICAgICAgICAgRVNCX01PRFVMRV9OQU1FLAoJfTsKCglzd2l0Y2ggKGNtZCkgewoJCWNhc2UgV0RJT0NfR0VUU1VQUE9SVDoKCQkJcmV0dXJuIGNvcHlfdG9fdXNlcihhcmdwLCAmaWRlbnQsCgkJCQkJICAgIHNpemVvZiAoaWRlbnQpKSA/IC1FRkFVTFQgOiAwOwoKCQljYXNlIFdESU9DX0dFVFNUQVRVUzoKCQkJcmV0dXJuIHB1dF91c2VyIChlc2JfdGltZXJfcmVhZCgpLCBwKTsKCgkJY2FzZSBXRElPQ19HRVRCT09UU1RBVFVTOgoJCQlyZXR1cm4gcHV0X3VzZXIgKHRyaWdnZXJlZCwgcCk7CgogICAgICAgICAgICAgICAgY2FzZSBXRElPQ19LRUVQQUxJVkU6CiAgICAgICAgICAgICAgICAgICAgICAgIGVzYl90aW1lcl9rZWVwYWxpdmUgKCk7CiAgICAgICAgICAgICAgICAgICAgICAgIHJldHVybiAwOwoKICAgICAgICAgICAgICAgIGNhc2UgV0RJT0NfU0VUT1BUSU9OUzoKICAgICAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgICAgICAgICAgaWYgKGdldF91c2VyIChuZXdfb3B0aW9ucywgcCkpCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgcmV0dXJuIC1FRkFVTFQ7CgogICAgICAgICAgICAgICAgICAgICAgICBpZiAobmV3X29wdGlvbnMgJiBXRElPU19ESVNBQkxFQ0FSRCkgewogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGVzYl90aW1lcl9zdG9wICgpOwogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHJldHZhbCA9IDA7CiAgICAgICAgICAgICAgICAgICAgICAgIH0KCiAgICAgICAgICAgICAgICAgICAgICAgIGlmIChuZXdfb3B0aW9ucyAmIFdESU9TX0VOQUJMRUNBUkQpIHsKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBlc2JfdGltZXJfa2VlcGFsaXZlICgpOwogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGVzYl90aW1lcl9zdGFydCAoKTsKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICByZXR2YWwgPSAwOwogICAgICAgICAgICAgICAgICAgICAgICB9CgogICAgICAgICAgICAgICAgICAgICAgICByZXR1cm4gcmV0dmFsOwogICAgICAgICAgICAgICAgfQoKICAgICAgICAgICAgICAgIGNhc2UgV0RJT0NfU0VUVElNRU9VVDoKICAgICAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgICAgICAgICAgaWYgKGdldF91c2VyKG5ld19oZWFydGJlYXQsIHApKQogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHJldHVybiAtRUZBVUxUOwoKICAgICAgICAgICAgICAgICAgICAgICAgaWYgKGVzYl90aW1lcl9zZXRfaGVhcnRiZWF0KG5ld19oZWFydGJlYXQpKQogICAgICAgICAgICAgICAgICAgICAgICAgICAgcmV0dXJuIC1FSU5WQUw7CgogICAgICAgICAgICAgICAgICAgICAgICBlc2JfdGltZXJfa2VlcGFsaXZlICgpOwogICAgICAgICAgICAgICAgICAgICAgICAvKiBGYWxsICovCiAgICAgICAgICAgICAgICB9CgogICAgICAgICAgICAgICAgY2FzZSBXRElPQ19HRVRUSU1FT1VUOgogICAgICAgICAgICAgICAgICAgICAgICByZXR1cm4gcHV0X3VzZXIoaGVhcnRiZWF0LCBwKTsKCiAgICAgICAgICAgICAgICBkZWZhdWx0OgogICAgICAgICAgICAgICAgICAgICAgICByZXR1cm4gLUVOT1RUWTsKICAgICAgICB9Cn0KCi8qCiAqICAgICAgTm90aWZ5IHN5c3RlbQogKi8KCnN0YXRpYyBpbnQgZXNiX25vdGlmeV9zeXMgKHN0cnVjdCBub3RpZmllcl9ibG9jayAqdGhpcywgdW5zaWduZWQgbG9uZyBjb2RlLCB2b2lkICp1bnVzZWQpCnsKICAgICAgICBpZiAoY29kZT09U1lTX0RPV04gfHwgY29kZT09U1lTX0hBTFQpIHsKICAgICAgICAgICAgICAgIC8qIFR1cm4gdGhlIFdEVCBvZmYgKi8KICAgICAgICAgICAgICAgIGVzYl90aW1lcl9zdG9wICgpOwogICAgICAgIH0KCiAgICAgICAgcmV0dXJuIE5PVElGWV9ET05FOwp9CgovKgogKiAgICAgIEtlcm5lbCBJbnRlcmZhY2VzCiAqLwoKc3RhdGljIGNvbnN0IHN0cnVjdCBmaWxlX29wZXJhdGlvbnMgZXNiX2ZvcHMgPSB7CiAgICAgICAgLm93bmVyID0gICAgICAgIFRISVNfTU9EVUxFLAogICAgICAgIC5sbHNlZWsgPSAgICAgICBub19sbHNlZWssCiAgICAgICAgLndyaXRlID0gICAgICAgIGVzYl93cml0ZSwKICAgICAgICAuaW9jdGwgPSAgICAgICAgZXNiX2lvY3RsLAogICAgICAgIC5vcGVuID0gICAgICAgICBlc2Jfb3BlbiwKICAgICAgICAucmVsZWFzZSA9ICAgICAgZXNiX3JlbGVhc2UsCn07CgpzdGF0aWMgc3RydWN0IG1pc2NkZXZpY2UgZXNiX21pc2NkZXYgPSB7CiAgICAgICAgLm1pbm9yID0gICAgICAgIFdBVENIRE9HX01JTk9SLAogICAgICAgIC5uYW1lID0gICAgICAgICAid2F0Y2hkb2ciLAogICAgICAgIC5mb3BzID0gICAgICAgICAmZXNiX2ZvcHMsCn07CgpzdGF0aWMgc3RydWN0IG5vdGlmaWVyX2Jsb2NrIGVzYl9ub3RpZmllciA9IHsKICAgICAgICAubm90aWZpZXJfY2FsbCA9ICAgICAgICBlc2Jfbm90aWZ5X3N5cywKfTsKCi8qCiAqIERhdGEgZm9yIFBDSSBkcml2ZXIgaW50ZXJmYWNlCiAqCiAqIFRoaXMgZGF0YSBvbmx5IGV4aXN0cyBmb3IgZXhwb3J0aW5nIHRoZSBzdXBwb3J0ZWQKICogUENJIGlkcyB2aWEgTU9EVUxFX0RFVklDRV9UQUJMRS4gIFdlIGRvIG5vdCBhY3R1YWxseQogKiByZWdpc3RlciBhIHBjaV9kcml2ZXIsIGJlY2F1c2Ugc29tZW9uZSBlbHNlIG1pZ2h0IG9uZSBkYXkKICogd2FudCB0byByZWdpc3RlciBhbm90aGVyIGRyaXZlciBvbiB0aGUgc2FtZSBQQ0kgaWQuCiAqLwpzdGF0aWMgc3RydWN0IHBjaV9kZXZpY2VfaWQgZXNiX3BjaV90YmxbXSA9IHsKICAgICAgICB7IFBDSV9ERVZJQ0UoUENJX1ZFTkRPUl9JRF9JTlRFTCwgUENJX0RFVklDRV9JRF9JTlRFTF9FU0JfOSksIH0sCiAgICAgICAgeyAwLCB9LCAgICAgICAgICAgICAgICAgLyogRW5kIG9mIGxpc3QgKi8KfTsKTU9EVUxFX0RFVklDRV9UQUJMRSAocGNpLCBlc2JfcGNpX3RibCk7CgovKgogKiAgICAgIEluaXQgJiBleGl0IHJvdXRpbmVzCiAqLwoKc3RhdGljIHVuc2lnbmVkIGNoYXIgX19pbml0IGVzYl9nZXRkZXZpY2UgKHZvaWQpCnsKCXU4IHZhbDE7Cgl1bnNpZ25lZCBzaG9ydCB2YWwyOwoKICAgICAgICBzdHJ1Y3QgcGNpX2RldiAqZGV2ID0gTlVMTDsKICAgICAgICAvKgogICAgICAgICAqICAgICAgRmluZCB0aGUgUENJIGRldmljZQogICAgICAgICAqLwoKICAgICAgICBmb3JfZWFjaF9wY2lfZGV2KGRldikgewogICAgICAgICAgICAgICAgaWYgKHBjaV9tYXRjaF9pZChlc2JfcGNpX3RibCwgZGV2KSkgewogICAgICAgICAgICAgICAgICAgICAgICBlc2JfcGNpID0gZGV2OwogICAgICAgICAgICAgICAgICAgICAgICBicmVhazsKICAgICAgICAgICAgICAgIH0KCX0KCiAgICAgICAgaWYgKGVzYl9wY2kpIHsKICAgICAgICAJaWYgKHBjaV9lbmFibGVfZGV2aWNlKGVzYl9wY2kpKSB7CgkJCXByaW50ayAoS0VSTl9FUlIgUEZYICJmYWlsZWQgdG8gZW5hYmxlIGRldmljZVxuIik7CgkJCWdvdG8gZXJyX2RldnB1dDsKCQl9CgoJCWlmIChwY2lfcmVxdWVzdF9yZWdpb24oZXNiX3BjaSwgMCwgRVNCX01PRFVMRV9OQU1FKSkgewoJCQlwcmludGsgKEtFUk5fRVJSIFBGWCAiZmFpbGVkIHRvIHJlcXVlc3QgcmVnaW9uXG4iKTsKCQkJZ290byBlcnJfZGlzYWJsZTsKCQl9CgoJCUJBU0VBRERSID0gaW9yZW1hcChwY2lfcmVzb3VyY2Vfc3RhcnQoZXNiX3BjaSwgMCksCgkJCQkgICBwY2lfcmVzb3VyY2VfbGVuKGVzYl9wY2ksIDApKTsKCQlpZiAoQkFTRUFERFIgPT0gTlVMTCkgewogICAgICAgICAgICAgICAgCS8qIFNvbWV0aGluZydzIHdyb25nIGhlcmUsIEJBU0VBRERSIGhhcyB0byBiZSBzZXQgKi8KCQkJcHJpbnRrIChLRVJOX0VSUiBQRlggImZhaWxlZCB0byBnZXQgQkFTRUFERFJcbiIpOwogICAgICAgICAgICAgICAgICAgICAgICBnb3RvIGVycl9yZWxlYXNlOwogICAgICAgICAgICAgICAgfQoKCQkvKgoJCSAqIFRoZSB3YXRjaGRvZyBoYXMgdHdvIHRpbWVycywgaXQgY2FuIGJlIHNldHVwIHNvIHRoYXQgdGhlCgkJICogZXhwaXJ5IG9mIHRpbWVyMSByZXN1bHRzIGluIGFuIGludGVycnVwdCBhbmQgdGhlIGV4cGlyeSBvZgoJCSAqIHRpbWVyMiByZXN1bHRzIGluIGEgcmVib290LiBXZSBzZXQgaXQgdG8gbm90IGdlbmVyYXRlCgkJICogYW55IGludGVycnVwdHMgYXMgdGhlcmUgaXMgbm90IG11Y2ggd2UgY2FuIGRvIHdpdGggaXQKCQkgKiByaWdodCBub3cuCgkJICoKCQkgKiBXZSBhbHNvIGVuYWJsZSByZWJvb3RzIGFuZCBzZXQgdGhlIHRpbWVyIGZyZXF1ZW5jeSB0bwoJCSAqIHRoZSBQQ0kgY2xvY2sgZGl2aWRlZCBieSAyXjE1IChhcHByb3ggMUtIeikuCgkJICovCgkJcGNpX3dyaXRlX2NvbmZpZ193b3JkKGVzYl9wY2ksIEVTQl9DT05GSUdfUkVHLCAweDAwMDMpOwoKCQkvKiBDaGVjayB0aGF0IHRoZSBXRFQgaXNuJ3QgYWxyZWFkeSBsb2NrZWQgKi8KCQlwY2lfcmVhZF9jb25maWdfYnl0ZShlc2JfcGNpLCBFU0JfTE9DS19SRUcsICZ2YWwxKTsKCQlpZiAodmFsMSAmIEVTQl9XRFRfTE9DSykKCQkJcHJpbnRrIChLRVJOX1dBUk5JTkcgUEZYICJub3dheW91dCBhbHJlYWR5IHNldFxuIik7CgoJCS8qIFNldCB0aGUgdGltZXIgdG8gd2F0Y2hkb2cgbW9kZSBhbmQgZGlzYWJsZSBpdCBmb3Igbm93ICovCgkJcGNpX3dyaXRlX2NvbmZpZ19ieXRlKGVzYl9wY2ksIEVTQl9MT0NLX1JFRywgMHgwMCk7CgoJCS8qIENoZWNrIGlmIHRoZSB3YXRjaGRvZyB3YXMgcHJldmlvdXNseSB0cmlnZ2VyZWQgKi8KCQllc2JfdW5sb2NrX3JlZ2lzdGVycygpOwoJCXZhbDIgPSByZWFkdyhFU0JfUkVMT0FEX1JFRyk7CgkJdHJpZ2dlcmVkID0gKHZhbDIgJiAoMHgwMSA8PCA5KSA+PiA5KTsKCgkJLyogUmVzZXQgdHJpZ2dlciBmbGFnIGFuZCB0aW1lcnMgKi8KCQllc2JfdW5sb2NrX3JlZ2lzdGVycygpOwoJCXdyaXRldygoMHgxMSA8PCA4KSwgRVNCX1JFTE9BRF9SRUcpOwoKCQkvKiBEb25lICovCgkJcmV0dXJuIDE7CgplcnJfcmVsZWFzZToKCQlwY2lfcmVsZWFzZV9yZWdpb24oZXNiX3BjaSwgMCk7CmVycl9kaXNhYmxlOgoJCXBjaV9kaXNhYmxlX2RldmljZShlc2JfcGNpKTsKZXJyX2RldnB1dDoKCQlwY2lfZGV2X3B1dChlc2JfcGNpKTsKCX0KCXJldHVybiAwOwp9CgpzdGF0aWMgaW50IF9faW5pdCB3YXRjaGRvZ19pbml0ICh2b2lkKQp7CiAgICAgICAgaW50IHJldDsKCiAgICAgICAgc3Bpbl9sb2NrX2luaXQoJmVzYl9sb2NrKTsKCiAgICAgICAgLyogQ2hlY2sgd2hldGhlciBvciBub3QgdGhlIGhhcmR3YXJlIHdhdGNoZG9nIGlzIHRoZXJlICovCiAgICAgICAgaWYgKCFlc2JfZ2V0ZGV2aWNlICgpIHx8IGVzYl9wY2kgPT0gTlVMTCkKICAgICAgICAgICAgICAgIHJldHVybiAtRU5PREVWOwoKICAgICAgICAvKiBDaGVjayB0aGF0IHRoZSBoZWFydGJlYXQgdmFsdWUgaXMgd2l0aGluIGl0J3MgcmFuZ2UgOyBpZiBub3QgcmVzZXQgdG8gdGhlIGRlZmF1bHQgKi8KICAgICAgICBpZiAoZXNiX3RpbWVyX3NldF9oZWFydGJlYXQgKGhlYXJ0YmVhdCkpIHsKICAgICAgICAgICAgICAgIGVzYl90aW1lcl9zZXRfaGVhcnRiZWF0IChXQVRDSERPR19IRUFSVEJFQVQpOwogICAgICAgICAgICAgICAgcHJpbnRrKEtFUk5fSU5GTyBQRlggImhlYXJ0YmVhdCB2YWx1ZSBtdXN0IGJlIDE8aGVhcnRiZWF0PDIwNDYsIHVzaW5nICVkXG4iLAoJCSAgICAgICBoZWFydGJlYXQpOwogICAgICAgIH0KCiAgICAgICAgcmV0ID0gcmVnaXN0ZXJfcmVib290X25vdGlmaWVyKCZlc2Jfbm90aWZpZXIpOwogICAgICAgIGlmIChyZXQgIT0gMCkgewogICAgICAgICAgICAgICAgcHJpbnRrKEtFUk5fRVJSIFBGWCAiY2Fubm90IHJlZ2lzdGVyIHJlYm9vdCBub3RpZmllciAoZXJyPSVkKVxuIiwKICAgICAgICAgICAgICAgICAgICAgICAgcmV0KTsKICAgICAgICAgICAgICAgIGdvdG8gZXJyX3VubWFwOwogICAgICAgIH0KCiAgICAgICAgcmV0ID0gbWlzY19yZWdpc3RlcigmZXNiX21pc2NkZXYpOwogICAgICAgIGlmIChyZXQgIT0gMCkgewogICAgICAgICAgICAgICAgcHJpbnRrKEtFUk5fRVJSIFBGWCAiY2Fubm90IHJlZ2lzdGVyIG1pc2NkZXYgb24gbWlub3I9JWQgKGVycj0lZClcbiIsCiAgICAgICAgICAgICAgICAgICAgICAgIFdBVENIRE9HX01JTk9SLCByZXQpOwogICAgICAgICAgICAgICAgZ290byBlcnJfbm90aWZpZXI7CiAgICAgICAgfQoKICAgICAgICBlc2JfdGltZXJfc3RvcCAoKTsKCiAgICAgICAgcHJpbnRrIChLRVJOX0lORk8gUEZYICJpbml0aWFsaXplZCAoMHglcCkuIGhlYXJ0YmVhdD0lZCBzZWMgKG5vd2F5b3V0PSVkKVxuIiwKICAgICAgICAgICAgICAgIEJBU0VBRERSLCBoZWFydGJlYXQsIG5vd2F5b3V0KTsKCiAgICAgICAgcmV0dXJuIDA7CgplcnJfbm90aWZpZXI6CiAgICAgICAgdW5yZWdpc3Rlcl9yZWJvb3Rfbm90aWZpZXIoJmVzYl9ub3RpZmllcik7CmVycl91bm1hcDoKCWlvdW5tYXAoQkFTRUFERFIpOwovKiBlcnJfcmVsZWFzZTogKi8KCXBjaV9yZWxlYXNlX3JlZ2lvbihlc2JfcGNpLCAwKTsKLyogZXJyX2Rpc2FibGU6ICovCglwY2lfZGlzYWJsZV9kZXZpY2UoZXNiX3BjaSk7Ci8qIGVycl9kZXZwdXQ6ICovCglwY2lfZGV2X3B1dChlc2JfcGNpKTsKICAgICAgICByZXR1cm4gcmV0Owp9CgpzdGF0aWMgdm9pZCBfX2V4aXQgd2F0Y2hkb2dfY2xlYW51cCAodm9pZCkKewoJLyogU3RvcCB0aGUgdGltZXIgYmVmb3JlIHdlIGxlYXZlICovCglpZiAoIW5vd2F5b3V0KQoJCWVzYl90aW1lcl9zdG9wICgpOwoKCS8qIERlcmVnaXN0ZXIgKi8KCW1pc2NfZGVyZWdpc3RlcigmZXNiX21pc2NkZXYpOwogICAgICAgIHVucmVnaXN0ZXJfcmVib290X25vdGlmaWVyKCZlc2Jfbm90aWZpZXIpOwoJaW91bm1hcChCQVNFQUREUik7CglwY2lfcmVsZWFzZV9yZWdpb24oZXNiX3BjaSwgMCk7CglwY2lfZGlzYWJsZV9kZXZpY2UoZXNiX3BjaSk7CglwY2lfZGV2X3B1dChlc2JfcGNpKTsKfQoKbW9kdWxlX2luaXQod2F0Y2hkb2dfaW5pdCk7Cm1vZHVsZV9leGl0KHdhdGNoZG9nX2NsZWFudXApOwoKTU9EVUxFX0FVVEhPUigiUm9zcyBCaXJvIGFuZCBEYXZpZCBI5HJkZW1hbiIpOwpNT0RVTEVfREVTQ1JJUFRJT04oIldhdGNoZG9nIGRyaXZlciBmb3IgSW50ZWwgNjMwMEVTQiBjaGlwc2V0cyIpOwpNT0RVTEVfTElDRU5TRSgiR1BMIik7Ck1PRFVMRV9BTElBU19NSVNDREVWKFdBVENIRE9HX01JTk9SKTsK