LyoKICogQ29weXJpZ2h0IChDKSBNaWNoZWwgRORuemVyIDxtaWNoZGFlbkBpaWljLmV0aHouY2g+CiAqCiAqIEFQVVMgUENJIHJvdXRpbmVzLgogKgogKiBDdXJyZW50bHksIG9ubHkgQi9DVmlzaW9uUFBDIGNhcmRzIChQZXJtZWRpYTIpIGFyZSBzdXBwb3J0ZWQuCiAqCiAqIFRoYW5rcyB0byBHZWVydCBVeXR0ZXJob2V2ZW4gZm9yIHRoZSBpZGVhOgogKiBSZWFkIHZhbHVlcyBmcm9tIGdpdmVuIGNvbmZpZyBzcGFjZShzKSBmb3IgdGhlIGZpcnN0IGRldmljZXMsIC0xIG90aGVyd2lzZQogKgogKi8KCiNpbmNsdWRlIDxsaW51eC9jb25maWcuaD4KI2lmZGVmIENPTkZJR19BTUlHQQoKI2luY2x1ZGUgPGxpbnV4L2tlcm5lbC5oPgojaW5jbHVkZSA8bGludXgvcGNpLmg+CiNpbmNsdWRlIDxsaW51eC9kZWxheS5oPgojaW5jbHVkZSA8bGludXgvc3RyaW5nLmg+CiNpbmNsdWRlIDxsaW51eC9pbml0Lmg+CgojaW5jbHVkZSA8YXNtL2lvLmg+CiNpbmNsdWRlIDxhc20vcGNpLWJyaWRnZS5oPgojaW5jbHVkZSA8YXNtL21hY2hkZXAuaD4KCiNpbmNsdWRlICJhcHVzX3BjaS5oIgoKCi8qIFRoZXNlIGRlZmluaXRpb25zIGFyZSBtb3N0bHkgYWRhcHRlZCBmcm9tIHBtMmZiLmMgKi8KCiN1bmRlZiBBUFVTX1BDSV9NQVNURVJfREVCVUcKI2lmZGVmIEFQVVNfUENJX01BU1RFUl9ERUJVRwojZGVmaW5lIERQUklOVEsoYSxiLi4uKQlwcmludGsoS0VSTl9ERUJVRyAiYXB1c19wY2k6ICVzOiAiIGEsIF9fRlVOQ1RJT05fXyAsICMjIGIpCiNlbHNlCiNkZWZpbmUgRFBSSU5USyhhLGIuLi4pCiNlbmRpZgoKLyoKICogVGhlIF9ERUZJTklUSVZFXyBtZW1vcnkgbWFwcGluZy91bm1hcHBpbmcgZnVuY3Rpb25zLgogKiBUaGlzIGlzIGR1ZSB0byB0aGUgZmFjdCB0aGF0IHRoZXkncmUgY2hhbmdpbmcgc29vb28gb2Z0ZW4uLi4KICovCiNkZWZpbmUgREVGVygpCQl3bWIoKQojZGVmaW5lIERFRlIoKQkJcm1iKCkKI2RlZmluZSBERUZSVygpCQltYigpCgojZGVmaW5lIERFVk5PKGQpCSgoZCk+PjMpCiNkZWZpbmUgRk5OTyhkKQkJKChkKSY3KQoKCmV4dGVybiB1bnNpZ25lZCBsb25nIHBvd2VydXBfUENJX3ByZXNlbnQ7CgpzdGF0aWMgc3RydWN0IHBjaV9jb250cm9sbGVyICphcHVzX2hvc2U7CgoKdm9pZCAqcGNpX2lvX2Jhc2UodW5zaWduZWQgaW50IGJ1cykKewoJcmV0dXJuIDA7Cn0KCgppbnQKYXB1c19wY2liaW9zX3JlYWRfY29uZmlnKHN0cnVjdCBwY2lfYnVzICpidXMsIGludCBkZXZmbiwgaW50IG9mZnNldCwKCQkJIGludCBsZW4sIHUzMiAqdmFsKQp7CglpbnQgZm5ubyA9IEZOTk8oZGV2Zm4pOwoJaW50IGRldm5vID0gREVWTk8oZGV2Zm4pOwoJdm9sYXRpbGUgdW5zaWduZWQgY2hhciAqY2ZnX2RhdGE7CgoJaWYgKGJ1cy0+bnVtYmVyID4gMCB8fCBkZXZubyAhPSAxKSB7CgkJKnZhbCA9IH4wOwoJCXJldHVybiBQQ0lCSU9TX0RFVklDRV9OT1RfRk9VTkQ7Cgl9CgkvKiBiYXNlIGFkZHJlc3MgKyBmdW5jdGlvbiBvZmZzZXQgKyBvZmZzZXQgXiBlbmRpYW5uZXNzIGNvbnZlcnNpb24gKi8KCS8qIFhYWCB0aGUgZm5ubzw8NSBiaXQgc2VlbXMgd2Fja3kgIC0tIHBhdWx1cyAqLwoJY2ZnX2RhdGEgPSBhcHVzX2hvc2UtPmNmZ19kYXRhICsgKGZubm88PDUpICsgKG9mZnNldCBeIChsZW4gLSAxKSk7Cglzd2l0Y2ggKGxlbikgewoJY2FzZSAxOgoJCSp2YWwgPSByZWFkYihjZmdfZGF0YSk7CgkJYnJlYWs7CgljYXNlIDI6CgkJKnZhbCA9IHJlYWR3KGNmZ19kYXRhKTsKCQlicmVhazsKCWRlZmF1bHQ6CgkJKnZhbCA9IHJlYWRsKGNmZ19kYXRhKTsKCQlicmVhazsKCX0KCglEUFJJTlRLKCJyZWFkIGI6IDB4JXgsIGQ6IDB4JXgsIGY6IDB4JXgsIG86IDB4JXgsIGw6ICVkLCB2OiAweCV4XG4iLAoJCWJ1cy0+bnVtYmVyLCBkZXZmbj4+MywgZGV2Zm4mNywgb2Zmc2V0LCBsZW4sICp2YWwpOwoJcmV0dXJuIFBDSUJJT1NfU1VDQ0VTU0ZVTDsKfQoKaW50CmFwdXNfcGNpYmlvc193cml0ZV9jb25maWcoc3RydWN0IHBjaV9idXMgKmJ1cywgaW50IGRldmZuLCBpbnQgb2Zmc2V0LAoJCQkgIGludCBsZW4sIHUzMiAqdmFsKQp7CglpbnQgZm5ubyA9IEZOTk8oZGV2Zm4pOwoJaW50IGRldm5vID0gREVWTk8oZGV2Zm4pOwoJdm9sYXRpbGUgdW5zaWduZWQgY2hhciAqY2ZnX2RhdGE7CgoJaWYgKGJ1cy0+bnVtYmVyID4gMCB8fCBkZXZubyAhPSAxKSB7CgkJcmV0dXJuIFBDSUJJT1NfREVWSUNFX05PVF9GT1VORDsKCX0KCS8qIGJhc2UgYWRkcmVzcyArIGZ1bmN0aW9uIG9mZnNldCArIG9mZnNldCBeIGVuZGlhbm5lc3MgY29udmVyc2lvbiAqLwoJLyogWFhYIHRoZSBmbm5vPDw1IGJpdCBzZWVtcyB3YWNreSAgLS0gcGF1bHVzICovCgljZmdfZGF0YSA9IGFwdXNfaG9zZS0+Y2ZnX2RhdGEgKyAoZm5ubzw8NSkgKyAob2Zmc2V0IF4gKGxlbiAtIDEpKTsKCXN3aXRjaCAobGVuKSB7CgljYXNlIDE6CgkJd3JpdGViKHZhbCwgY2ZnX2RhdGEpOyBERUZXKCk7CgkJYnJlYWs7CgljYXNlIDI6CgkJd3JpdGV3KHZhbCwgY2ZnX2RhdGEpOyBERUZXKCk7CgkJYnJlYWs7CglkZWZhdWx0OgoJCXdyaXRlbCh2YWwsIGNmZ19kYXRhKTsgREVGVygpOwoJCWJyZWFrOwoJfQoKCURQUklOVEsoIndyaXRlIGI6IDB4JXgsIGQ6IDB4JXgsIGY6IDB4JXgsIG86IDB4JXgsIGw6ICVkLCB2OiAweCV4XG4iLAoJCWJ1cy0+bnVtYmVyLCBkZXZmbj4+MywgZGV2Zm4mNywgb2Zmc2V0LCBsZW4sIHZhbCk7CglyZXR1cm4gUENJQklPU19TVUNDRVNTRlVMOwp9CgpzdGF0aWMgc3RydWN0IHBjaV9vcHMgYXB1c19wY2lfb3BzID0gewoJYXB1c19wY2liaW9zX3JlYWRfY29uZmlnLAoJYXB1c19wY2liaW9zX3dyaXRlX2NvbmZpZwp9OwoKc3RhdGljIHN0cnVjdCByZXNvdXJjZSBwY2lfbWVtID0geyAiQi9DVmlzaW9uUFBDIFBDSSBtZW0iLCBDVlBQQ19GQl9BUEVSVFVSRV9PTkUsIENWUFBDX1BDSV9DT05GSUcsIElPUkVTT1VSQ0VfTUVNIH07Cgp2b2lkIF9faW5pdAphcHVzX3BjaWJpb3NfZml4dXAodm9pZCkKewovKglzdHJ1Y3QgcGNpX2RldiAqZGV2ID0gcGNpX2ZpbmRfc2xvdCgwLCAxPDwzKTsKCXVuc2lnbmVkIGludCByZWcsIHZhbCwgb2Zmc2V0OyovCgoJLyogRklYTUU6IGludGVycnVwdD8gKi8KCS8qZGV2LT5pbnRlcnJ1cHQgPSB4eHg7Ki8KCiAgICAgICAgcmVxdWVzdF9yZXNvdXJjZSgmaW9tZW1fcmVzb3VyY2UsICZwY2lfbWVtKTsKICAgIAlwcmludGsoIiVzOiBQQ0kgbWVtIHJlc291cmNlIHJlcXVlc3RlZFxuIiwgX19GVU5DVElPTl9fKTsKfQoKc3RhdGljIHZvaWQgX19pbml0IGFwdXNfcGNpYmlvc19maXh1cF9idXMoc3RydWN0IHBjaV9idXMgKmJ1cykKewogICAgICAgIGJ1cy0+cmVzb3VyY2VbMV0gPSAmcGNpX21lbTsKfQoKCi8qCiAqIFRoaXMgaXMgZnJvbSBwbTJmYi5jIGFnYWluCiAqCiAqIENoZWNrIGlmIFBDSSAoQi9DVmlzaW9uUFBDKSBpcyBhdmFpbGFibGUsIGluaXRpYWxpemUgaXQgYW5kIHNldCB1cAogKiB0aGUgcGNpYmlvc18qIHBvaW50ZXJzCiAqLwoKCnZvaWQgX19pbml0CmFwdXNfc2V0dXBfcGNpX3B0cnModm9pZCkKewoJaWYgKCFwb3dlcnVwX1BDSV9wcmVzZW50KSB7CgkJRFBSSU5USygibm8gUENJIGJyaWRnZSBkZXRlY3RlZFxuIik7CgkJcmV0dXJuOwoJfQoJRFBSSU5USygiUGhhc2U1IEIvQ1Zpc2lvblBQQyBQQ0kgYnJpZGdlIGRldGVjdGVkLlxuIik7CgoJYXB1c19ob3NlID0gcGNpYmlvc19hbGxvY19jb250cm9sbGVyKCk7CglpZiAoIWFwdXNfaG9zZSkgewoJCXByaW50aygiYXB1c19wY2k6IENhbid0IGFsbG9jYXRlIFBDSSBjb250cm9sbGVyIHN0cnVjdHVyZVxuIik7CgkJcmV0dXJuOwoJfQoKCWlmICghKGFwdXNfaG9zZS0+Y2ZnX2RhdGEgPSBpb3JlbWFwKENWUFBDX1BDSV9DT05GSUcsIDI1NikpKSB7CgkJcHJpbnRrKCJhcHVzX3BjaTogdW5hYmxlIHRvIG1hcCBQQ0kgY29uZmlnIHJlZ2lvblxuIik7CgkJcmV0dXJuOwoJfQoKCWlmICghKGFwdXNfaG9zZS0+Y2ZnX2FkZHIgPSBpb3JlbWFwKENTUFBDX1BDSV9CUklER0UsIDI1NikpKSB7CgkJcHJpbnRrKCJhcHVzX3BjaTogdW5hYmxlIHRvIG1hcCBQQ0kgYnJpZGdlXG4iKTsKCQlyZXR1cm47Cgl9CgoJd3JpdGVsKENTUFBDRl9CUklER0VfQklHX0VORElBTiwgYXB1c19ob3NlLT5jZmdfYWRkciArIENTUFBDX0JSSURHRV9FTkRJQU4pOwoJREVGVygpOwoKCXdyaXRlbChDVlBQQ19SRUdTX1JFR0lPTiwgIGFwdXNfaG9zZS0+Y2ZnX2RhdGErIFBDSV9CQVNFX0FERFJFU1NfMCk7CglERUZXKCk7Cgl3cml0ZWwoQ1ZQUENfRkJfQVBFUlRVUkVfT05FLCBhcHVzX2hvc2UtPmNmZ19kYXRhICsgUENJX0JBU0VfQUREUkVTU18xKTsKCURFRlcoKTsKCXdyaXRlbChDVlBQQ19GQl9BUEVSVFVSRV9UV08sIGFwdXNfaG9zZS0+Y2ZnX2RhdGEgKyBQQ0lfQkFTRV9BRERSRVNTXzIpOwoJREVGVygpOwoJd3JpdGVsKENWUFBDX1JPTV9BRERSRVNTLCBhcHVzX2hvc2UtPmNmZ19kYXRhICsgUENJX1JPTV9BRERSRVNTKTsKCURFRlcoKTsKCgl3cml0ZWwoMHhlZjAwMDAwMCB8IFBDSV9DT01NQU5EX0lPIHwgUENJX0NPTU1BTkRfTUVNT1JZIHwKCQlQQ0lfQ09NTUFORF9NQVNURVIsIGFwdXNfaG9zZS0+Y2ZnX2RhdGEgKyBQQ0lfQ09NTUFORCk7CglERUZXKCk7CgoJYXB1c19ob3NlLT5maXJzdF9idXNubyA9IDA7CglhcHVzX2hvc2UtPmxhc3RfYnVzbm8gPSAwOwoJYXB1c19ob3NlLT5vcHMgPSAmYXB1c19wY2lfb3BzOwoJcHBjX21kLnBjaWJpb3NfZml4dXAgPSBhcHVzX3BjaWJpb3NfZml4dXA7CglwcGNfbWQucGNpYmlvc19maXh1cF9idXMgPSBhcHVzX3BjaWJpb3NfZml4dXBfYnVzOwoKCXJldHVybjsKfQoKI2VuZGlmIC8qIENPTkZJR19BTUlHQSAqLwo=