LyoKICogbGludXgvYXJjaC9hcm0vbWFjaC1vbWFwL2lycS5jCiAqCiAqIEludGVycnVwdCBoYW5kbGVyIGZvciBhbGwgT01BUCBib2FyZHMKICoKICogQ29weXJpZ2h0IChDKSAyMDA0IE5va2lhIENvcnBvcmF0aW9uCiAqIFdyaXR0ZW4gYnkgVG9ueSBMaW5kZ3JlbiA8dG9ueUBhdG9taWRlLmNvbT4KICogTWFqb3IgY2xlYW51cHMgYnkgSnVoYSBZcmr2bOQgPGp1aGEueXJqb2xhQG5va2lhLmNvbT4KICoKICogQ29tcGxldGVseSByZS13cml0dGVuIHRvIHN1cHBvcnQgdmFyaW91cyBPTUFQIGNoaXBzIHdpdGggYmFuayBzcGVjaWZpYwogKiBpbnRlcnJ1cHQgaGFuZGxlcnMuCiAqCiAqIFNvbWUgc25pcHBldHMgb2YgdGhlIGNvZGUgdGFrZW4gZnJvbSB0aGUgb2xkZXIgT01BUCBpbnRlcnJ1cHQgaGFuZGxlcgogKiBDb3B5cmlnaHQgKEMpIDIwMDEgUmlkZ2VSdW4sIEluYy4gR3JlZyBMb25ub24gPGdsb25ub25AcmlkZ2VydW4uY29tPgogKgogKiBHUElPIGludGVycnVwdCBoYW5kbGVyIG1vdmVkIHRvIGdwaW8uYyBieSBKdWhhIFlyam9sYQogKgogKiBUaGlzIHByb2dyYW0gaXMgZnJlZSBzb2Z0d2FyZTsgeW91IGNhbiByZWRpc3RyaWJ1dGUgaXQgYW5kL29yIG1vZGlmeSBpdAogKiB1bmRlciB0aGUgdGVybXMgb2YgdGhlIEdOVSBHZW5lcmFsIFB1YmxpYyBMaWNlbnNlIGFzIHB1Ymxpc2hlZCBieSB0aGUKICogRnJlZSBTb2Z0d2FyZSBGb3VuZGF0aW9uOyBlaXRoZXIgdmVyc2lvbiAyIG9mIHRoZSBMaWNlbnNlLCBvciAoYXQgeW91cgogKiBvcHRpb24pIGFueSBsYXRlciB2ZXJzaW9uLgogKgogKiBUSElTIFNPRlRXQVJFIElTIFBST1ZJREVEIGBgQVMgSVMnJyBBTkQgQU5ZIEVYUFJFU1MgT1IgSU1QTElFRAogKiBXQVJSQU5USUVTLCBJTkNMVURJTkcsIEJVVCBOT1QgTElNSVRFRCBUTywgVEhFIElNUExJRUQgV0FSUkFOVElFUyBPRgogKiBNRVJDSEFOVEFCSUxJVFkgQU5EIEZJVE5FU1MgRk9SIEEgUEFSVElDVUxBUiBQVVJQT1NFIEFSRSBESVNDTEFJTUVELiBJTgogKiBOTyBFVkVOVCBTSEFMTCBUSEUgQVVUSE9SIEJFIExJQUJMRSBGT1IgQU5ZIERJUkVDVCwgSU5ESVJFQ1QsCiAqIElOQ0lERU5UQUwsIFNQRUNJQUwsIEVYRU1QTEFSWSwgT1IgQ09OU0VRVUVOVElBTCBEQU1BR0VTIChJTkNMVURJTkcsIEJVVAogKiBOT1QgTElNSVRFRCBUTywgUFJPQ1VSRU1FTlQgT0YgU1VCU1RJVFVURSBHT09EUyBPUiBTRVJWSUNFUzsgTE9TUyBPRgogKiBVU0UsIERBVEEsIE9SIFBST0ZJVFM7IE9SIEJVU0lORVNTIElOVEVSUlVQVElPTikgSE9XRVZFUiBDQVVTRUQgQU5EIE9OCiAqIEFOWSBUSEVPUlkgT0YgTElBQklMSVRZLCBXSEVUSEVSIElOIENPTlRSQUNULCBTVFJJQ1QgTElBQklMSVRZLCBPUiBUT1JUCiAqIChJTkNMVURJTkcgTkVHTElHRU5DRSBPUiBPVEhFUldJU0UpIEFSSVNJTkcgSU4gQU5ZIFdBWSBPVVQgT0YgVEhFIFVTRSBPRgogKiBUSElTIFNPRlRXQVJFLCBFVkVOIElGIEFEVklTRUQgT0YgVEhFIFBPU1NJQklMSVRZIE9GIFNVQ0ggREFNQUdFLgogKgogKiBZb3Ugc2hvdWxkIGhhdmUgcmVjZWl2ZWQgYSBjb3B5IG9mIHRoZSAgR05VIEdlbmVyYWwgUHVibGljIExpY2Vuc2UgYWxvbmcKICogd2l0aCB0aGlzIHByb2dyYW07IGlmIG5vdCwgd3JpdGUgIHRvIHRoZSBGcmVlIFNvZnR3YXJlIEZvdW5kYXRpb24sIEluYy4sCiAqIDY3NSBNYXNzIEF2ZSwgQ2FtYnJpZGdlLCBNQSAwMjEzOSwgVVNBLgogKi8KCiNpbmNsdWRlIDxsaW51eC9jb25maWcuaD4KI2luY2x1ZGUgPGxpbnV4L2luaXQuaD4KI2luY2x1ZGUgPGxpbnV4L21vZHVsZS5oPgojaW5jbHVkZSA8bGludXgvc2NoZWQuaD4KI2luY2x1ZGUgPGxpbnV4L2ludGVycnVwdC5oPgojaW5jbHVkZSA8bGludXgvcHRyYWNlLmg+CgojaW5jbHVkZSA8YXNtL2hhcmR3YXJlLmg+CiNpbmNsdWRlIDxhc20vaXJxLmg+CiNpbmNsdWRlIDxhc20vbWFjaC9pcnEuaD4KI2luY2x1ZGUgPGFzbS9hcmNoL2dwaW8uaD4KCiNpbmNsdWRlIDxhc20vaW8uaD4KCiNkZWZpbmUgSVJRX0JBTksoaXJxKSAoKGlycSkgPj4gNSkKI2RlZmluZSBJUlFfQklUKGlycSkgICgoaXJxKSAmIDB4MWYpCgpzdHJ1Y3Qgb21hcF9pcnFfYmFuayB7Cgl1bnNpZ25lZCBsb25nIGJhc2VfcmVnOwoJdW5zaWduZWQgbG9uZyB0cmlnZ2VyX21hcDsKfTsKCnN0YXRpYyB1bnNpZ25lZCBpbnQgaXJxX2JhbmtfY291bnQgPSAwOwpzdGF0aWMgc3RydWN0IG9tYXBfaXJxX2JhbmsgKmlycV9iYW5rczsKCnN0YXRpYyBpbmxpbmUgdW5zaWduZWQgaW50IGlycV9iYW5rX3JlYWRsKGludCBiYW5rLCBpbnQgb2Zmc2V0KQp7CglyZXR1cm4gb21hcF9yZWFkbChpcnFfYmFua3NbYmFua10uYmFzZV9yZWcgKyBvZmZzZXQpOwp9CgpzdGF0aWMgaW5saW5lIHZvaWQgaXJxX2Jhbmtfd3JpdGVsKHVuc2lnbmVkIGxvbmcgdmFsdWUsIGludCBiYW5rLCBpbnQgb2Zmc2V0KQp7CglvbWFwX3dyaXRlbCh2YWx1ZSwgaXJxX2JhbmtzW2JhbmtdLmJhc2VfcmVnICsgb2Zmc2V0KTsKfQoKc3RhdGljIHZvaWQgb21hcF9hY2tfaXJxKHVuc2lnbmVkIGludCBpcnEpCnsKCWlmIChpcnEgPiAzMSkKCQlvbWFwX3dyaXRlbCgweDEsIE9NQVBfSUgyX0JBU0UgKyBJUlFfQ09OVFJPTF9SRUdfT0ZGU0VUKTsKCglvbWFwX3dyaXRlbCgweDEsIE9NQVBfSUgxX0JBU0UgKyBJUlFfQ09OVFJPTF9SRUdfT0ZGU0VUKTsKfQoKc3RhdGljIHZvaWQgb21hcF9tYXNrX2lycSh1bnNpZ25lZCBpbnQgaXJxKQp7CglpbnQgYmFuayA9IElSUV9CQU5LKGlycSk7Cgl1MzIgbDsKCglsID0gb21hcF9yZWFkbChpcnFfYmFua3NbYmFua10uYmFzZV9yZWcgKyBJUlFfTUlSX1JFR19PRkZTRVQpOwoJbCB8PSAxIDw8IElSUV9CSVQoaXJxKTsKCW9tYXBfd3JpdGVsKGwsIGlycV9iYW5rc1tiYW5rXS5iYXNlX3JlZyArIElSUV9NSVJfUkVHX09GRlNFVCk7Cn0KCnN0YXRpYyB2b2lkIG9tYXBfdW5tYXNrX2lycSh1bnNpZ25lZCBpbnQgaXJxKQp7CglpbnQgYmFuayA9IElSUV9CQU5LKGlycSk7Cgl1MzIgbDsKCglsID0gb21hcF9yZWFkbChpcnFfYmFua3NbYmFua10uYmFzZV9yZWcgKyBJUlFfTUlSX1JFR19PRkZTRVQpOwoJbCAmPSB+KDEgPDwgSVJRX0JJVChpcnEpKTsKCW9tYXBfd3JpdGVsKGwsIGlycV9iYW5rc1tiYW5rXS5iYXNlX3JlZyArIElSUV9NSVJfUkVHX09GRlNFVCk7Cn0KCnN0YXRpYyB2b2lkIG9tYXBfbWFza19hY2tfaXJxKHVuc2lnbmVkIGludCBpcnEpCnsKCW9tYXBfbWFza19pcnEoaXJxKTsKCW9tYXBfYWNrX2lycShpcnEpOwp9CgovKgogKiBBbGxvd3MgdHVuaW5nIHRoZSBJUlEgdHlwZSBhbmQgcHJpb3JpdHkKICoKICogTk9URTogVGhlcmUgaXMgY3VycmVudGx5IG5vIE9NQVAgZmlxIGhhbmRsZXIgZm9yIExpbnV4LiBSZWFkIHRoZQogKgkgbWFpbGluZyBsaXN0IHRocmVhZHMgb24gRklRIGhhbmRsZXJzIGlmIHlvdSBhcmUgcGxhbm5pbmcgdG8KICoJIGFkZCBhIEZJUSBoYW5kbGVyIGZvciBPTUFQLgogKi8Kc3RhdGljIHZvaWQgb21hcF9pcnFfc2V0X2NmZyhpbnQgaXJxLCBpbnQgZmlxLCBpbnQgcHJpb3JpdHksIGludCB0cmlnZ2VyKQp7CglzaWduZWQgaW50IGJhbms7Cgl1bnNpZ25lZCBsb25nIHZhbCwgb2Zmc2V0OwoKCWJhbmsgPSBJUlFfQkFOSyhpcnEpOwoJLyogRklRIGlzIG9ubHkgYXZhaWxhYmxlIG9uIGJhbmsgMCBpbnRlcnJ1cHRzICovCglmaXEgPSBiYW5rID8gMCA6IChmaXEgJiAweDEpOwoJdmFsID0gZmlxIHwgKChwcmlvcml0eSAmIDB4MWYpIDw8IDIpIHwgKCh0cmlnZ2VyICYgMHgxKSA8PCAxKTsKCW9mZnNldCA9IElSUV9JTFIwX1JFR19PRkZTRVQgKyBJUlFfQklUKGlycSkgKiAweDQ7CglpcnFfYmFua193cml0ZWwodmFsLCBiYW5rLCBvZmZzZXQpOwp9CgojaWZkZWYgQ09ORklHX0FSQ0hfT01BUDczMApzdGF0aWMgc3RydWN0IG9tYXBfaXJxX2Jhbmsgb21hcDczMF9pcnFfYmFua3NbXSA9IHsKCXsgLmJhc2VfcmVnID0gT01BUF9JSDFfQkFTRSwgCQkudHJpZ2dlcl9tYXAgPSAweGIzZjhlMjJmIH0sCgl7IC5iYXNlX3JlZyA9IE9NQVBfSUgyX0JBU0UsIAkJLnRyaWdnZXJfbWFwID0gMHhmZGI5YzFmMiB9LAoJeyAuYmFzZV9yZWcgPSBPTUFQX0lIMl9CQVNFICsgMHgxMDAsCS50cmlnZ2VyX21hcCA9IDB4ODAwMDQwZjMgfSwKfTsKI2VuZGlmCgojaWZkZWYgQ09ORklHX0FSQ0hfT01BUDE1MTAKc3RhdGljIHN0cnVjdCBvbWFwX2lycV9iYW5rIG9tYXAxNTEwX2lycV9iYW5rc1tdID0gewoJeyAuYmFzZV9yZWcgPSBPTUFQX0lIMV9CQVNFLCAJCS50cmlnZ2VyX21hcCA9IDB4YjNmZWJmZmYgfSwKCXsgLmJhc2VfcmVnID0gT01BUF9JSDJfQkFTRSwgCQkudHJpZ2dlcl9tYXAgPSAweGZmYmZmZmVkIH0sCn07CiNlbmRpZgoKI2lmIGRlZmluZWQoQ09ORklHX0FSQ0hfT01BUDE2WFgpCgpzdGF0aWMgc3RydWN0IG9tYXBfaXJxX2Jhbmsgb21hcDE2MTBfaXJxX2JhbmtzW10gPSB7Cgl7IC5iYXNlX3JlZyA9IE9NQVBfSUgxX0JBU0UsIAkJLnRyaWdnZXJfbWFwID0gMHhiM2ZlZmU4ZiB9LAoJeyAuYmFzZV9yZWcgPSBPTUFQX0lIMl9CQVNFLCAJCS50cmlnZ2VyX21hcCA9IDB4ZmRiN2MxZmQgfSwKCXsgLmJhc2VfcmVnID0gT01BUF9JSDJfQkFTRSArIDB4MTAwLAkudHJpZ2dlcl9tYXAgPSAweGZmZmZmN2ZmIH0sCgl7IC5iYXNlX3JlZyA9IE9NQVBfSUgyX0JBU0UgKyAweDIwMCwJLnRyaWdnZXJfbWFwID0gMHhmZmZmZmZmZiB9LAp9OwojZW5kaWYKCnN0YXRpYyBzdHJ1Y3QgaXJxY2hpcCBvbWFwX2lycV9jaGlwID0gewoJLmFjayAgICA9IG9tYXBfbWFza19hY2tfaXJxLAoJLm1hc2sgICA9IG9tYXBfbWFza19pcnEsCgkudW5tYXNrID0gb21hcF91bm1hc2tfaXJxLAp9OwoKdm9pZCBfX2luaXQgb21hcF9pbml0X2lycSh2b2lkKQp7CglpbnQgaSwgajsKCiNpZmRlZiBDT05GSUdfQVJDSF9PTUFQNzMwCglpZiAoY3B1X2lzX29tYXA3MzAoKSkgewoJCWlycV9iYW5rcyA9IG9tYXA3MzBfaXJxX2JhbmtzOwoJCWlycV9iYW5rX2NvdW50ID0gQVJSQVlfU0laRShvbWFwNzMwX2lycV9iYW5rcyk7Cgl9CiNlbmRpZgojaWZkZWYgQ09ORklHX0FSQ0hfT01BUDE1MTAKCWlmIChjcHVfaXNfb21hcDE1MTAoKSkgewoJCWlycV9iYW5rcyA9IG9tYXAxNTEwX2lycV9iYW5rczsKCQlpcnFfYmFua19jb3VudCA9IEFSUkFZX1NJWkUob21hcDE1MTBfaXJxX2JhbmtzKTsKCX0KI2VuZGlmCiNpZiBkZWZpbmVkKENPTkZJR19BUkNIX09NQVAxNlhYKQoJaWYgKGNwdV9pc19vbWFwMTZ4eCgpKSB7CgkJaXJxX2JhbmtzID0gb21hcDE2MTBfaXJxX2JhbmtzOwoJCWlycV9iYW5rX2NvdW50ID0gQVJSQVlfU0laRShvbWFwMTYxMF9pcnFfYmFua3MpOwoJfQojZW5kaWYKCXByaW50aygiVG90YWwgb2YgJWkgaW50ZXJydXB0cyBpbiAlaSBpbnRlcnJ1cHQgYmFua3NcbiIsCgkgICAgICAgaXJxX2JhbmtfY291bnQgKiAzMiwgaXJxX2JhbmtfY291bnQpOwoKCS8qIE1hc2sgYW5kIGNsZWFyIGFsbCBpbnRlcnJ1cHRzICovCglmb3IgKGkgPSAwOyBpIDwgaXJxX2JhbmtfY291bnQ7IGkrKykgewoJCWlycV9iYW5rX3dyaXRlbCh+MHgwLCBpLCBJUlFfTUlSX1JFR19PRkZTRVQpOwoJCWlycV9iYW5rX3dyaXRlbCgweDAsIGksIElSUV9JVFJfUkVHX09GRlNFVCk7Cgl9CgoJLyogQ2xlYXIgYW55IHBlbmRpbmcgaW50ZXJydXB0cyAqLwoJaXJxX2Jhbmtfd3JpdGVsKDB4MDMsIDAsIElSUV9DT05UUk9MX1JFR19PRkZTRVQpOwoJaXJxX2Jhbmtfd3JpdGVsKDB4MDMsIDEsIElSUV9DT05UUk9MX1JFR19PRkZTRVQpOwoKCS8qIEVuYWJsZSBpbnRlcnJ1cHRzIGluIGdsb2JhbCBtYXNrICovCglpZiAoY3B1X2lzX29tYXA3MzAoKSkgewoJCWlycV9iYW5rX3dyaXRlbCgweDAsIDAsIElSUV9HTVJfUkVHX09GRlNFVCk7Cgl9CgoJLyogSW5zdGFsbCB0aGUgaW50ZXJydXB0IGhhbmRsZXJzIGZvciBlYWNoIGJhbmsgKi8KCWZvciAoaSA9IDA7IGkgPCBpcnFfYmFua19jb3VudDsgaSsrKSB7CgkJZm9yIChqID0gaSAqIDMyOyBqIDwgKGkgKyAxKSAqIDMyOyBqKyspIHsKCQkJaW50IGlycV90cmlnZ2VyOwoKCQkJaXJxX3RyaWdnZXIgPSBpcnFfYmFua3NbaV0udHJpZ2dlcl9tYXAgPj4gSVJRX0JJVChqKTsKCQkJb21hcF9pcnFfc2V0X2NmZyhqLCAwLCAwLCBpcnFfdHJpZ2dlcik7CgoJCQlzZXRfaXJxX2NoaXAoaiwgJm9tYXBfaXJxX2NoaXApOwoJCQlzZXRfaXJxX2hhbmRsZXIoaiwgZG9fbGV2ZWxfSVJRKTsKCQkJc2V0X2lycV9mbGFncyhqLCBJUlFGX1ZBTElEKTsKCQl9Cgl9CgoJLyogVW5tYXNrIGxldmVsIDIgaGFuZGxlciAqLwoJaWYgKGNwdV9pc19vbWFwNzMwKCkpIHsKCQlvbWFwX3VubWFza19pcnEoSU5UXzczMF9JSDJfSVJRKTsKCX0gZWxzZSB7CgkJb21hcF91bm1hc2tfaXJxKElOVF9JSDJfSVJRKTsKCX0KfQo=