LyoKICogRGVyaXZlZCBmcm9tIHRoZSB1dGlsLWxpbnV4L21vdW50L21vdW50X2J5X2xhYmVsLmMgc291cmNlLAogKiBjdXJyZW50bHkgbWFpbnRhaW5lZCBieSBBbmRyaWVzIEJyb3V3ZXIgPGFlYkBjd2kubmw+LgogKgogKiAxOTk5LTAyLTIyIEFya2FkaXVzeiBNabZraWV3aWN6IDxtaXNpZWtAbWlzaWVrLmV1Lm9yZz4KICogLSBhZGRlZCBOYXRpdmUgTGFuZ3VhZ2UgU3VwcG9ydAogKiAyMDAwLTAxLTIwIEphbWVzIEFudGlsbCA8amFtZXNAYW5kLm9yZz4KICogLSBBZGRlZCBlcnJvciBtZXNzYWdlIGlmIC9wcm9jL3BhcnRpdGlvbnMgY2Fubm90IGJlIG9wZW5lZAogKiAyMDAwLTA1LTA5IEVyaWsgVHJvYW4gPGV3dEByZWRoYXQuY29tPgogKiAtIEFkZGVkIGNhY2hlIGZvciBVVUlEIGFuZCBkaXNrIGxhYmVscwogKiAyMDAwLTExLTA3IE5hdGhhbiBTY290dCA8bmF0aGFuc0BzZ2kuY29tPgogKiAtIEFkZGVkIFhGUyBzdXBwb3J0CiAqLwoKI2luY2x1ZGUgImNvbmZpZy5oIgoKI2luY2x1ZGUgPHN0ZGlvLmg+CiNpbmNsdWRlIDxzeXMvcGFyYW0uaD4KI2luY2x1ZGUgPHN0cmluZy5oPgojaW5jbHVkZSA8Y3R5cGUuaD4KI2luY2x1ZGUgPGZjbnRsLmg+CiNpbmNsdWRlIDx1bmlzdGQuaD4KI2luY2x1ZGUgPHN0ZGludC5oPgoKI2luY2x1ZGUgImJ5bGFiZWwuaCIKI2luY2x1ZGUgImNvbW1vbi5oIgojaW5jbHVkZSAicG90LmgiCgojZGVmaW5lIFBST0NfUEFSVElUSU9OUyAiL3Byb2MvcGFydGl0aW9ucyIKI2RlZmluZSBERVZMQUJFTERJUgkiL2RldiIKCnN0YXRpYyBzdHJ1Y3QgdXVpZENhY2hlX3MgewoJc3RydWN0IHV1aWRDYWNoZV9zICpuZXh0OwoJY2hhciB1dWlkWzE2XTsKCWNoYXIgKmxhYmVsOwoJY2hhciAqZGV2aWNlOwp9ICp1dWlkQ2FjaGUgPSBOVUxMOwoKI2RlZmluZSBFWFQyX1NVUEVSX01BR0lDCTB4RUY1MwpzdHJ1Y3QgZXh0Ml9zdXBlcl9ibG9jayB7Cgl1aW50OF90IHNfZHVtbXkxWzU2XTsKCXVpbnQ4X3Qgc19tYWdpY1syXTsKCXVpbnQ4X3Qgc19kdW1teTJbNDZdOwoJdWludDhfdCBzX3V1aWRbMTZdOwoJdWludDhfdCBzX3ZvbHVtZV9uYW1lWzE2XTsKfTsKCiNkZWZpbmUgZXh0Mm1hZ2ljKHMpCSgodWludDMyX3QpIHMuc19tYWdpY1swXSArICgoKHVpbnQzMl90KSBzLnNfbWFnaWNbMV0pIDw8IDgpKQoKI2RlZmluZSBYRlNfU1VQRVJfTUFHSUMgIlhGU0IiCiNkZWZpbmUgWEZTX1NVUEVSX01BR0lDMiAiQlNGWCIKI2RlZmluZSBFWEZTX1NVUEVSX01BR0lDICJFWEZTIgpzdHJ1Y3QgeGZzX3N1cGVyX2Jsb2NrIHsKCXVpbnQ4X3Qgc19tYWdpY1s0XTsKCXVpbnQ4X3Qgc19kdW1teVsyOF07Cgl1aW50OF90IHNfdXVpZFsxNl07Cgl1aW50OF90IHNfZHVtbXkyWzYwXTsKCXVpbnQ4X3Qgc19mc25hbWVbMTJdOwp9OwoKI2RlZmluZSBSRUlTRVJfU1VQRVJfTUFHSUMJIlJlSXNFcjJGcyIKc3RydWN0IHJlaXNlcmZzX3N1cGVyX2Jsb2NrIHsKCXVpbnQ4X3Qgc19kdW1teTFbNTJdOwoJdWludDhfdCBzX21hZ2ljWzEwXTsKCXVpbnQ4X3Qgc19kdW1teTJbMjJdOwoJdWludDhfdCBzX3V1aWRbMTZdOwoJdWludDhfdCBzX3ZvbHVtZV9uYW1lWzE2XTsKfTsKCiNkZWZpbmUgRjJGU19TVVBFUl9NQUdJQwkiMHhGMkY1MjAxMCIKc3RydWN0IGYyZnNfc3VwZXJfYmxvY2sgewoJdWludDhfdCBzX21hZ2ljWzhdOwoJdWludDhfdCBzX2R1bW15WzE0NF07Cgl1aW50OF90IHNfdXVpZFsxNl07Cgl1aW50OF90IHNfdm9sdW1lX25hbWVbNTEyXTsKfTsKCnN0YXRpYyBpbmxpbmUgdW5zaWduZWQgc2hvcnQgc3dhcHBlZCh1bnNpZ25lZCBzaG9ydCBhKQp7CglyZXR1cm4gKGEgPj4gOCkgfCAoYSA8PCA4KTsKfQoKLyogZm9yIG5vdywgb25seSBleHQyIGFuZCB4ZnMgYXJlIHN1cHBvcnRlZCAqLwpzdGF0aWMgaW50IGdldF9sYWJlbF91dWlkKGNvbnN0IGNoYXIgKmRldmljZSwgY2hhciAqKmxhYmVsLCBjaGFyICp1dWlkKQp7CgoJLyogc3RhcnQgd2l0aCBleHQyIGFuZCB4ZnMgdGVzdHMsIHRha2VuIGZyb20gbW91bnRfZ3Vlc3NfZnN0eXBlICovCgkvKiBzaG91bGQgbWVyZ2UgdGhlc2UgbGF0ZXIgKi8KCWludCBmZCwgcnYgPSAxOwoJc2l6ZV90IG5hbWVzaXplOwoJc3RydWN0IGV4dDJfc3VwZXJfYmxvY2sgZTJzYjsKCXN0cnVjdCB4ZnNfc3VwZXJfYmxvY2sgeGZzYjsKCXN0cnVjdCByZWlzZXJmc19zdXBlcl9ibG9jayByZWlzZXJzYjsKCXN0cnVjdCBmMmZzX3N1cGVyX2Jsb2NrIGYyZnNzYjsKCglmZCA9IG9wZW4oZGV2aWNlLCBPX1JET05MWSk7CglpZiAoZmQgPCAwKQoJCXJldHVybiBydjsKCglpZiAobHNlZWsoZmQsIDEwMjQsIFNFRUtfU0VUKSA9PSAxMDI0CgkgICAgJiYgcmVhZChmZCwgKGNoYXIgKikmZTJzYiwgc2l6ZW9mKGUyc2IpKSA9PSBzaXplb2YoZTJzYikKCSAgICAmJiBleHQybWFnaWMoZTJzYikgPT0gRVhUMl9TVVBFUl9NQUdJQykgewoJCW1lbWNweSh1dWlkLCBlMnNiLnNfdXVpZCwgc2l6ZW9mKGUyc2Iuc191dWlkKSk7CgkJbmFtZXNpemUgPSBzaXplb2YoZTJzYi5zX3ZvbHVtZV9uYW1lKTsKCQkqbGFiZWwgPSBzbWFsbG9jKG5hbWVzaXplICsgMSk7CgkJc3N0cm5jcHkoKmxhYmVsLCAoY2hhciAqKWUyc2Iuc192b2x1bWVfbmFtZSwgbmFtZXNpemUpOwoJCXJ2ID0gMDsKCX0KCWVsc2UgaWYgKGxzZWVrKGZkLCAwLCBTRUVLX1NFVCkgPT0gMAoJCSAmJiByZWFkKGZkLCAoY2hhciAqKSZ4ZnNiLCBzaXplb2YoeGZzYikpID09IHNpemVvZih4ZnNiKQoJCSAmJiAoc3RybmNtcCgoY2hhciAqKSZ4ZnNiLnNfbWFnaWMsIFhGU19TVVBFUl9NQUdJQywgNCkgPT0gMCB8fAoJCSAgICAgc3RybmNtcCgoY2hhciAqKSZ4ZnNiLnNfbWFnaWMsIFhGU19TVVBFUl9NQUdJQzIsIDQpID09IDAgfHwKCQkgICAgIHN0cm5jbXAoKGNoYXIgKikmeGZzYi5zX21hZ2ljLCBFWEZTX1NVUEVSX01BR0lDLCA0KSA9PSAwKSkgewoJCW1lbWNweSh1dWlkLCB4ZnNiLnNfdXVpZCwgc2l6ZW9mKHhmc2Iuc191dWlkKSk7CgkJbmFtZXNpemUgPSBzaXplb2YoeGZzYi5zX2ZzbmFtZSk7CgkJKmxhYmVsID0gc21hbGxvYyhuYW1lc2l6ZSArIDEpOwoJCXNzdHJuY3B5KCpsYWJlbCwgKGNoYXIgKil4ZnNiLnNfZnNuYW1lLCBuYW1lc2l6ZSk7CgkJcnYgPSAwOwoJfQoJZWxzZSBpZiAobHNlZWsoZmQsIDY1NTM2LCBTRUVLX1NFVCkgPT0gNjU1MzYKCQkmJiByZWFkKGZkLCAoY2hhciAqKSZyZWlzZXJzYiwgc2l6ZW9mKHJlaXNlcnNiKSkgPT0gc2l6ZW9mKHJlaXNlcnNiKQoJCSYmICFzdHJuY21wKChjaGFyICopJnJlaXNlcnNiLnNfbWFnaWMsIFJFSVNFUl9TVVBFUl9NQUdJQywgOSkpIHsKCQltZW1jcHkodXVpZCwgcmVpc2Vyc2Iuc191dWlkLCBzaXplb2YocmVpc2Vyc2Iuc191dWlkKSk7CgkJbmFtZXNpemUgPSBzaXplb2YocmVpc2Vyc2Iuc192b2x1bWVfbmFtZSk7CgkJKmxhYmVsID0gc21hbGxvYyhuYW1lc2l6ZSArIDEpOwoJCXNzdHJuY3B5KCpsYWJlbCwgKGNoYXIgKilyZWlzZXJzYi5zX3ZvbHVtZV9uYW1lLCBuYW1lc2l6ZSk7CgkJcnYgPSAwOwoJfQoJZWxzZSBpZiAobHNlZWsoZmQsIDY1NTM2LCBTRUVLX1NFVCkgPT0gNjU1MzYKCQkmJiByZWFkKGZkLCAoY2hhciAqKSZmMmZzc2IsIHNpemVvZihmMmZzc2IpKSA9PSBzaXplb2YoZjJmc3NiKQoJCSYmICFzdHJuY21wKChjaGFyICopJmYyZnNzYi5zX21hZ2ljLCBGMkZTX1NVUEVSX01BR0lDLCA4KSkgewoJCW1lbWNweSh1dWlkLCBmMmZzc2Iuc191dWlkLCBzaXplb2YoZjJmc3NiLnNfdXVpZCkpOwoJCW5hbWVzaXplID0gc2l6ZW9mKGYyZnNzYi5zX3ZvbHVtZV9uYW1lKTsKCQkqbGFiZWwgPSBzbWFsbG9jKG5hbWVzaXplICsgMSk7CgkJc3N0cm5jcHkoKmxhYmVsLCAoY2hhciAqKWYyZnNzYi5zX3ZvbHVtZV9uYW1lLCBuYW1lc2l6ZSk7CgkJcnYgPSAwOwoJfQoJY2xvc2UoZmQpOwoJcmV0dXJuIHJ2Owp9CgpzdGF0aWMgdm9pZCB1dWlkY2FjaGVfYWRkZW50cnkoY2hhciAqZGV2aWNlLCBjaGFyICpsYWJlbCwgY2hhciAqdXVpZCkKewoJc3RydWN0IHV1aWRDYWNoZV9zICpsYXN0OwoKCWlmICghdXVpZENhY2hlKSB7CgkJbGFzdCA9IHV1aWRDYWNoZSA9IHNtYWxsb2Moc2l6ZW9mKCp1dWlkQ2FjaGUpKTsKCX0KCWVsc2UgewoJCWZvciAobGFzdCA9IHV1aWRDYWNoZTsgbGFzdC0+bmV4dDsgbGFzdCA9IGxhc3QtPm5leHQpOwoJCWxhc3QtPm5leHQgPSBzbWFsbG9jKHNpemVvZigqdXVpZENhY2hlKSk7CgkJbGFzdCA9IGxhc3QtPm5leHQ7Cgl9CglsYXN0LT5uZXh0ID0gTlVMTDsKCWxhc3QtPmRldmljZSA9IGRldmljZTsKCWxhc3QtPmxhYmVsID0gbGFiZWw7CgltZW1jcHkobGFzdC0+dXVpZCwgdXVpZCwgc2l6ZW9mKGxhc3QtPnV1aWQpKTsKfQoKc3RhdGljIHZvaWQgdXVpZGNhY2hlX2luaXQodm9pZCkKewoJY2hhciBsaW5lWzEwMF07CgljaGFyICpzOwoJaW50IG1hLCBtaSwgc3o7CglzdGF0aWMgY2hhciBwdG5hbWVbMTAwXTsKCUZJTEUgKnByb2NwdDsKCWNoYXIgdXVpZFsxNl0sICpsYWJlbDsKCWNoYXIgZGV2aWNlWzExMF07CglpbnQgZmlyc3RQYXNzOwoJaW50IGhhbmRsZU9uRmlyc3Q7CgoJaWYgKHV1aWRDYWNoZSkKCQlyZXR1cm47CgoJcHJvY3B0ID0gZm9wZW4oUFJPQ19QQVJUSVRJT05TLCAiciIpOwoJaWYgKCFwcm9jcHQpCgkJcmV0dXJuOwoKCWZvciAoZmlyc3RQYXNzID0gMTsgZmlyc3RQYXNzID49IDA7IGZpcnN0UGFzcy0tKSB7CgkJZnNlZWsocHJvY3B0LCAwLCBTRUVLX1NFVCk7CgoJCXdoaWxlIChmZ2V0cyhsaW5lLCBzaXplb2YobGluZSksIHByb2NwdCkpIHsKCQkJaWYgKHNzY2FuZihsaW5lLCAiICVkICVkICVkICVbXlxuIF0iLCAmbWEsICZtaSwgJnN6LCBwdG5hbWUpICE9IDQpCgkJCQljb250aW51ZTsKCgkJCS8qIHNraXAgZXh0ZW5kZWQgcGFydGl0aW9ucyAoaGV1cmlzdGljOiBzaXplIDEpICovCgkJCWlmIChzeiA9PSAxKQoJCQkJY29udGludWU7CgoJCQkvKiBsb29rIG9ubHkgYXQgbWQgZGV2aWNlcyBvbiBmaXJzdCBwYXNzICovCgkJCWhhbmRsZU9uRmlyc3QgPSAhc3RybmNtcChwdG5hbWUsICJtZCIsIDIpOwoJCQlpZiAoZmlyc3RQYXNzICE9IGhhbmRsZU9uRmlyc3QpCgkJCQljb250aW51ZTsKCgkJCS8qIHNraXAgZW50aXJlIGRpc2sgKG1pbm9yIDAsIDY0LCAuLi4gb24gaWRlOwoJCQkgICAwLCAxNiwgLi4uIG9uIHNkKSAqLwoJCQkvKiBoZXVyaXN0aWM6IHBhcnRpdGlvbiBuYW1lIGVuZHMgaW4gYSBkaWdpdCAqLwoKCQkJZm9yIChzID0gcHRuYW1lOyAqczsgcysrKTsKCQkJaWYgKGlzZGlnaXQoc1stMV0pKSB7CgkJCQkvKgoJCQkJICogTm90ZTogdGhpcyBpcyBhIGhldXJpc3RpYyBvbmx5IC0gdGhlcmUgaXMgbm8gcmVhc29uCgkJCQkgKiB3aHkgdGhlc2UgZGV2aWNlcyBzaG91bGQgbGl2ZSBpbiAvZGV2LgoJCQkJICogUGVyaGFwcyB0aGlzIGRpcmVjdG9yeSBzaG91bGQgYmUgc3BlY2lmaWFibGUgYnkgb3B0aW9uLgoJCQkJICogT25lIG1pZ2h0IGZvciBleGFtcGxlIGhhdmUgL2RldmxhYmVsIHdpdGggbGlua3MgdG8gL2RldgoJCQkJICogZm9yIHRoZSBkZXZpY2VzIHRoYXQgbWF5IGJlIGFjY2Vzc2VkIGluIHRoaXMgd2F5LgoJCQkJICogKFRoaXMgaXMgdXNlZnVsLCBpZiB0aGUgY2Ryb20gb24gL2Rldi9oZGMgbXVzdCBub3QKCQkJCSAqIGJlIGFjY2Vzc2VkLikKCQkJCSAqLwoJCQkJc25wcmludGYoZGV2aWNlLCBzaXplb2YoZGV2aWNlKSwgIiVzLyVzIiwgREVWTEFCRUxESVIsIHB0bmFtZSk7CgkJCQlpZiAoIWdldF9sYWJlbF91dWlkKGRldmljZSwgJmxhYmVsLCB1dWlkKSkKCQkJCQl1dWlkY2FjaGVfYWRkZW50cnkoc3N0cmR1cChkZXZpY2UpLCBsYWJlbCwgdXVpZCk7CgkJCX0KCQl9Cgl9CgoJZmNsb3NlKHByb2NwdCk7Cn0KCiNkZWZpbmUgVVVJRCAgIDEKI2RlZmluZSBWT0wgICAgMgoKc3RhdGljIGNoYXIgKmdldF9zcGVjX2J5X3goaW50IG4sIGNvbnN0IGNoYXIgKnQpCnsKCXN0cnVjdCB1dWlkQ2FjaGVfcyAqdWM7CgoJdXVpZGNhY2hlX2luaXQoKTsKCXVjID0gdXVpZENhY2hlOwoKCXdoaWxlICh1YykgewoJCXN3aXRjaCAobikgewoJCSAgY2FzZSBVVUlEOgoJCQkgIGlmICghbWVtY21wKHQsIHVjLT51dWlkLCBzaXplb2YodWMtPnV1aWQpKSkKCQkJCSAgcmV0dXJuIHNzdHJkdXAodWMtPmRldmljZSk7CgkJCSAgYnJlYWs7CgkJICBjYXNlIFZPTDoKCQkJICBpZiAoIXN0cmNtcCh0LCB1Yy0+bGFiZWwpKQoJCQkJICByZXR1cm4gc3N0cmR1cCh1Yy0+ZGV2aWNlKTsKCQkJICBicmVhazsKCQl9CgkJdWMgPSB1Yy0+bmV4dDsKCX0KCXJldHVybiBOVUxMOwp9CgpzdGF0aWMgdWludDhfdCBmcm9taGV4KGNoYXIgYykKewoJaWYgKGlzZGlnaXQoYykpCgkJcmV0dXJuIChjIC0gJzAnKTsKCWVsc2UgaWYgKGlzbG93ZXIoYykpCgkJcmV0dXJuIChjIC0gJ2EnICsgMTApOwoJZWxzZQoJCXJldHVybiAoYyAtICdBJyArIDEwKTsKfQoKc3RhdGljIGNoYXIgKmdldF9zcGVjX2J5X3V1aWQoY29uc3QgY2hhciAqcykKewoJdWludDhfdCB1dWlkWzE2XTsKCWludCBpOwoKCWlmIChzdHJsZW4ocykgIT0gMzYgfHwgc1s4XSAhPSAnLScgfHwgc1sxM10gIT0gJy0nIHx8IHNbMThdICE9ICctJyB8fCBzWzIzXSAhPSAnLScpCgkJZ290byBiYWRfdXVpZDsKCWZvciAoaSA9IDA7IGkgPCAxNjsgaSsrKSB7CgkJaWYgKCpzID09ICctJykKCQkJcysrOwoJCWlmICghaXN4ZGlnaXQoc1swXSkgfHwgIWlzeGRpZ2l0KHNbMV0pKQoJCQlnb3RvIGJhZF91dWlkOwoJCXV1aWRbaV0gPSAoKGZyb21oZXgoc1swXSkgPDwgNCkgfCBmcm9taGV4KHNbMV0pKTsKCQlzICs9IDI7Cgl9CglyZXR1cm4gZ2V0X3NwZWNfYnlfeChVVUlELCAoY2hhciAqKXV1aWQpOwoKICAgICAgYmFkX3V1aWQ6CgllcnJzdHIoXygiRm91bmQgYW4gaW52YWxpZCBVVUlEOiAlc1xuIiksIHMpOwoJcmV0dXJuIE5VTEw7Cn0KCnN0YXRpYyBjaGFyICpnZXRfc3BlY19ieV92b2x1bWVfbGFiZWwoY29uc3QgY2hhciAqcykKewoJcmV0dXJuIGdldF9zcGVjX2J5X3goVk9MLCBzKTsKfQoKY29uc3QgY2hhciAqZ2V0X2RldmljZV9uYW1lKGNvbnN0IGNoYXIgKml0ZW0pCnsKCWNvbnN0IGNoYXIgKnJjOwoKCWlmICghc3RybmNtcChpdGVtLCAiVVVJRD0iLCA1KSkKCQlyYyA9IGdldF9zcGVjX2J5X3V1aWQoaXRlbSArIDUpOwoJZWxzZSBpZiAoIXN0cm5jbXAoaXRlbSwgIkxBQkVMPSIsIDYpKQoJCXJjID0gZ2V0X3NwZWNfYnlfdm9sdW1lX2xhYmVsKGl0ZW0gKyA2KTsKCWVsc2UKCQlyYyA9IHNzdHJkdXAoaXRlbSk7CglpZiAoIXJjKQoJCWVycnN0cihfKCJFcnJvciBjaGVja2luZyBkZXZpY2UgbmFtZTogJXNcbiIpLCBpdGVtKTsKCXJldHVybiByYzsKfQo=