From mboxrd@z Thu Jan 1 00:00:00 1970 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: base64 Subject: [8/8] EDAC: Add driver for the Marvell Armada XP SDRAM and L2 cache ECC From: Gregory CLEMENT Message-Id: <87bmp1vfj9.fsf@free-electrons.com> Date: Mon, 03 Jul 2017 15:03:22 +0200 To: Jan Luebbe Cc: Chris Packham , linux-arm-kernel@lists.infradead.org, linux-edac@vger.kernel.org, kernel@pengutronix.de, Thomas Petazzoni List-ID: SGkgSmFuLAogCiBPbiB2ZW4uLCBqdWluIDMwIDIwMTcsIEphbiBMdWViYmUgPGpsdUBwZW5ndXRy b25peC5kZT4gd3JvdGU6Cgo+IEFkZCBzdXBwb3J0IGZvciB0aGUgRUNDIGZ1bmN0aW9uYWxpdHkg YXMgZm91bmQgaW4gdGhlIEREUiBSQU0gYW5kIEwyCj4gY2FjaGUgY29udHJvbGxlcnMgb24gdGhl IE1WNzgyMzAvTVY3OHg2MCBTb0NzLiBUaGlzIGRyaXZlciBoYXMgYmVlbgo+IHRlc3RlZCBvbiB0 aGUgTVY3ODQ2MCAob24gYSBjdXN0b20gYm9hcmQgd2l0aCBhIEREUjMgRUNDIERJTU0pLgo+Cj4g U2lnbmVkLW9mZi1ieTogSmFuIEx1ZWJiZSA8amx1QHBlbmd1dHJvbml4LmRlPgo+IC0tLQo+ICBN QUlOVEFJTkVSUyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB8ICAgNiArCj4g IGFyY2gvYXJtL2luY2x1ZGUvYXNtL2hhcmR3YXJlL2NhY2hlLWF1cm9yYS1sMi5oIHwgIDQ4ICsr Cgp5b3UgY291bGQgbWF5YmUgbW92ZSB0aGUgY2FjaGUtYXVyb3JhLWwyLmggY2hhbmdlIGluIGEg c2VwYXJhdGUgcGF0Y2ggYW5kCnB1dCBpdCBhdCB0aGUgYmVnaW5uaW5nIG9mIHRoZSBzZXJpZXMg anVzdCBhZnRlciB0aGUgMm5kIHBhdGNoLgoKR3JlZ29yeQoKPiAgZHJpdmVycy9lZGFjL0tjb25m aWcgICAgICAgICAgICAgICAgICAgICAgICAgICAgfCAgIDcgKwo+ICBkcml2ZXJzL2VkYWMvTWFr ZWZpbGUgICAgICAgICAgICAgICAgICAgICAgICAgICB8ICAgMSArCj4gIGRyaXZlcnMvZWRhYy9h cm1hZGFfeHBfZWRhYy5jICAgICAgICAgICAgICAgICAgIHwgNjM5ICsrKysrKysrKysrKysrKysr KysrKysrKwo+ICA1IGZpbGVzIGNoYW5nZWQsIDcwMSBpbnNlcnRpb25zKCspCj4gIGNyZWF0ZSBt b2RlIDEwMDY0NCBkcml2ZXJzL2VkYWMvYXJtYWRhX3hwX2VkYWMuYwo+Cj4gZGlmZiAtLWdpdCBh L01BSU5UQUlORVJTIGIvTUFJTlRBSU5FUlMKPiBpbmRleCA3NjdlOWQyMDJhZGYuLjc1OGNjZTlj MjMxNSAxMDA2NDQKPiAtLS0gYS9NQUlOVEFJTkVSUwo+ICsrKyBiL01BSU5UQUlORVJTCj4gQEAg LTQ3NjYsNiArNDc2NiwxMiBAQCBMOglsaW51eC1lZGFjQHZnZXIua2VybmVsLm9yZwo+ICBTOglN YWludGFpbmVkCj4gIEY6CWRyaXZlcnMvZWRhYy9hbWQ2NF9lZGFjKgo+ICAKPiArRURBQy1BUk1B REEKPiArTToJSmFuIEx1ZWJiZSA8amx1QHBlbmd1dHJvbml4LmRlPgo+ICtMOglsaW51eC1lZGFj QHZnZXIua2VybmVsLm9yZwo+ICtTOglNYWludGFpbmVkCj4gK0Y6CWRyaXZlcnMvZWRhYy9hcm1h ZGFfeHBfKgo+ICsKPiAgRURBQy1DQUxYRURBCj4gIE06CVJvYmVydCBSaWNodGVyIDxycmljQGtl cm5lbC5vcmc+Cj4gIEw6CWxpbnV4LWVkYWNAdmdlci5rZXJuZWwub3JnCj4gZGlmZiAtLWdpdCBh L2FyY2gvYXJtL2luY2x1ZGUvYXNtL2hhcmR3YXJlL2NhY2hlLWF1cm9yYS1sMi5oIGIvYXJjaC9h cm0vaW5jbHVkZS9hc20vaGFyZHdhcmUvY2FjaGUtYXVyb3JhLWwyLmgKPiBpbmRleCBkYzVjNDc5 ZWM0YzMuLmMzMmJlNjg5ZDFmNiAxMDA2NDQKPiAtLS0gYS9hcmNoL2FybS9pbmNsdWRlL2FzbS9o YXJkd2FyZS9jYWNoZS1hdXJvcmEtbDIuaAo+ICsrKyBiL2FyY2gvYXJtL2luY2x1ZGUvYXNtL2hh cmR3YXJlL2NhY2hlLWF1cm9yYS1sMi5oCj4gQEAgLTMxLDYgKzMxLDkgQEAKPiAgI2RlZmluZSBB VVJPUkFfQUNSX1JFUExBQ0VNRU5UX1RZUEVfU0VNSVBMUlUgXAo+ICAJKDMgPDwgQVVST1JBX0FD Ul9SRVBMQUNFTUVOVF9PRkZTRVQpCj4gIAo+ICsjZGVmaW5lIEFVUk9SQV9BQ1JfUEFSSVRZX0VO CSgxIDw8IDIxKQo+ICsjZGVmaW5lIEFVUk9SQV9BQ1JfRUNDX0VOCSgxIDw8IDIwKQo+ICsKPiAg I2RlZmluZSBBVVJPUkFfQUNSX0ZPUkNFX1dSSVRFX1BPTElDWV9PRkZTRVQJMAo+ICAjZGVmaW5l IEFVUk9SQV9BQ1JfRk9SQ0VfV1JJVEVfUE9MSUNZX01BU0sJXAo+ICAJKDB4MyA8PCBBVVJPUkFf QUNSX0ZPUkNFX1dSSVRFX1BPTElDWV9PRkZTRVQpCj4gQEAgLTQxLDYgKzQ0LDUxIEBACj4gICNk ZWZpbmUgQVVST1JBX0FDUl9GT1JDRV9XUklURV9USFJPX1BPTElDWQlcCj4gIAkoMiA8PCBBVVJP UkFfQUNSX0ZPUkNFX1dSSVRFX1BPTElDWV9PRkZTRVQpCj4gIAo+ICsjZGVmaW5lIEFVUk9SQV9F UlJfQ05UX1JFRyAgICAgICAgICAweDYwMAo+ICsjZGVmaW5lIEFVUk9SQV9FUlJfQVRUUl9DQVBf UkVHICAgICAweDYwOAo+ICsjZGVmaW5lIEFVUk9SQV9FUlJfQUREUl9DQVBfUkVHICAgICAweDYw Ywo+ICsjZGVmaW5lIEFVUk9SQV9FUlJfV0FZX0NBUF9SRUcgICAgICAweDYxMAo+ICsjZGVmaW5l IEFVUk9SQV9FUlJfSU5KRUNUX0NUTF9SRUcgICAweDYxNAo+ICsjZGVmaW5lIEFVUk9SQV9FUlJf SU5KRUNUX01BU0tfUkVHICAweDYxOAo+ICsKPiArI2RlZmluZSBBVVJPUkFfRVJSX0NOVF9DTFJf T0ZGU0VUICAgICAgICAgMzEKPiArI2RlZmluZSBBVVJPUkFfRVJSX0NOVF9DTFIJCSAgIFwKPiAr CSgweDEgPDwgQVVST1JBX0VSUl9DTlRfQ0xSX09GRlNFVCkKPiArI2RlZmluZSBBVVJPUkFfRVJS X0NOVF9VRV9PRkZTRVQgICAgICAgICAgMTYKPiArI2RlZmluZSBBVVJPUkFfRVJSX0NOVF9VRV9N QVNLICAgICAgICAgICAgIFwKPiArCSgweDdmZmYgPDwgQVVST1JBX0VSUl9DTlRfVUVfT0ZGU0VU KQo+ICsjZGVmaW5lIEFVUk9SQV9FUlJfQ05UX0NFX09GRlNFVCAgICAgICAgICAgIDAKPiArI2Rl ZmluZSBBVVJPUkFfRVJSX0NOVF9DRV9NQVNLICAgICAgICAgICAgICBcCj4gKwkoMHhmZmZmIDw8 IEFVUk9SQV9FUlJfQ05UX0NFX09GRlNFVCkKPiArCj4gKyNkZWZpbmUgQVVST1JBX0VSUl9BVFRS X0NBUF9FUlJfU09VUkNFX09GRlNFVCAgICAgICAxNgo+ICsjZGVmaW5lIEFVUk9SQV9FUlJfQVRU Ul9DQVBfRVJSX1NPVVJDRV9NQVNLICAgICAgICAgIFwKPiArCSgweDcgPDwgQVVST1JBX0VSUl9B VFRSX0NBUF9FUlJfU09VUkNFX09GRlNFVCkKPiArI2RlZmluZSBBVVJPUkFfRVJSX0FUVFJfQ0FQ X1RSQU5TX1RZUEVfT0ZGU0VUICAgICAgIDEyCj4gKyNkZWZpbmUgQVVST1JBX0VSUl9BVFRSX0NB UF9UUkFOU19UWVBFX01BU0sgICAgICAgICAgXAo+ICsJKDB4ZiA8PCBBVVJPUkFfRVJSX0FUVFJf Q0FQX1RSQU5TX1RZUEVfT0ZGU0VUKQo+ICsjZGVmaW5lIEFVUk9SQV9FUlJfQVRUUl9DQVBfRVJS X1RZUEVfT0ZGU0VUICAgICAgICAgIDgKPiArI2RlZmluZSBBVVJPUkFfRVJSX0FUVFJfQ0FQX0VS Ul9UWVBFX01BU0sgICAgICAgICAgICBcCj4gKwkoMHgzIDw8IEFVUk9SQV9FUlJfQVRUUl9DQVBf RVJSX1RZUEVfT0ZGU0VUKQo+ICsjZGVmaW5lIEFVUk9SQV9FUlJfQVRUUl9DQVBfVkFMSURfT0ZG U0VUICAgICAgICAgICAgIDAKPiArI2RlZmluZSBBVVJPUkFfRVJSX0FUVFJfQ0FQX1ZBTElEICAg ICAgICAgICAgICAgICAgICBcCj4gKwkoMHgxIDw8IEFVUk9SQV9FUlJfQVRUUl9DQVBfVkFMSURf T0ZGU0VUKQo+ICsKPiArI2RlZmluZSBBVVJPUkFfRVJSX0FERFJfQ0FQX0FERFJfTUFTSyAweGZm ZmZmZmUwCj4gKwo+ICsjZGVmaW5lIEFVUk9SQV9FUlJfV0FZX0NBUF9JTkRFWF9PRkZTRVQgICAg ICAgICAgOAo+ICsjZGVmaW5lIEFVUk9SQV9FUlJfV0FZX0NBUF9JTkRFWF9NQVNLICAgICAgICAg ICAgXAo+ICsJKDB4ZmZmIDw8IEFVUk9SQV9FUlJfV0FZX0NBUF9JTkRFWF9PRkZTRVQpCj4gKyNk ZWZpbmUgQVVST1JBX0VSUl9XQVlfQ0FQX1dBWV9PRkZTRVQgICAgICAgICAgMQo+ICsjZGVmaW5l IEFVUk9SQV9FUlJfV0FZX0NBUF9XQVlfTUFTSyAgICAgICAgICAgIFwKPiArCSgweGYgPDwgQVVS T1JBX0VSUl9XQVlfQ0FQX1dBWV9PRkZTRVQpCj4gKwo+ICsjZGVmaW5lIEFVUk9SQV9FUlJfSU5K RUNUX0NUTF9BRERSX01BU0sgMHhmZmZmZmZmMAo+ICsjZGVmaW5lIEFVUk9SQV9FUlJfQVRUUl9D QVBfVFJBTlNfVFlQRV9PRkZTRVQgICAxMgo+ICsjZGVmaW5lIEFVUk9SQV9FUlJfSU5KRUNUX0NU TF9FTl9NQVNLICAgICAgICAgIDB4Mwo+ICsjZGVmaW5lIEFVUk9SQV9FUlJfSU5KRUNUX0NUTF9F Tl9QQVJJVFkgICAgICAgIDB4Mgo+ICsjZGVmaW5lIEFVUk9SQV9FUlJfSU5KRUNUX0NUTF9FTl9F Q0MgICAgICAgICAgIDB4MQo+ICsKPiAgI2RlZmluZSBBVVJPUkFfTUFYX1JBTkdFX1NJWkUJMTAy NAo+ICAKPiAgI2RlZmluZSBBVVJPUkFfV0FZX1NJWkVfU0hJRlQJMgo+IGRpZmYgLS1naXQgYS9k cml2ZXJzL2VkYWMvS2NvbmZpZyBiL2RyaXZlcnMvZWRhYy9LY29uZmlnCj4gaW5kZXggOTZhZmIy YWVlZDE4Li40ZTEyM2VjOTRhNGEgMTAwNjQ0Cj4gLS0tIGEvZHJpdmVycy9lZGFjL0tjb25maWcK PiArKysgYi9kcml2ZXJzL2VkYWMvS2NvbmZpZwo+IEBAIC00NDMsNiArNDQzLDEzIEBAIGNvbmZp ZyBFREFDX0FMVEVSQV9TRE1NQwo+ICAJICBTdXBwb3J0IGZvciBlcnJvciBkZXRlY3Rpb24gYW5k IGNvcnJlY3Rpb24gb24gdGhlCj4gIAkgIEFsdGVyYSBTRE1NQyBGSUZPIE1lbW9yeSBmb3IgQWx0 ZXJhIFNvQ3MuCj4gIAo+ICtjb25maWcgRURBQ19BUk1BREFfWFAKPiArCWJvb2wgIk1hcnZlbGwg QXJtYWRhIFhQIEREUiBhbmQgTDIgQ2FjaGUgRUNDIgo+ICsJZGVwZW5kcyBvbiBBUkNIX01WRUJV Cj4gKwloZWxwCj4gKwkgIFN1cHBvcnQgZm9yIGVycm9yIGNvcnJlY3Rpb24gYW5kIGRldGVjdGlv biBvbiB0aGUgTWFydmVsbCBBcmFtYWRhIFhQCj4gKwkgIEREUiBSQU0gYW5kIEwyIGNhY2hlIGNv bnRyb2xsZXJzLgo+ICsKPiAgY29uZmlnIEVEQUNfU1lOT1BTWVMKPiAgCXRyaXN0YXRlICJTeW5v cHN5cyBERFIgTWVtb3J5IENvbnRyb2xsZXIiCj4gIAlkZXBlbmRzIG9uIEFSQ0hfWllOUQo+IGRp ZmYgLS1naXQgYS9kcml2ZXJzL2VkYWMvTWFrZWZpbGUgYi9kcml2ZXJzL2VkYWMvTWFrZWZpbGUK PiBpbmRleCAwZmQ5ZmZhNjMyOTkuLjcwYTA5M2NjOTc2ZSAxMDA2NDQKPiAtLS0gYS9kcml2ZXJz L2VkYWMvTWFrZWZpbGUKPiArKysgYi9kcml2ZXJzL2VkYWMvTWFrZWZpbGUKPiBAQCAtNzYsNSAr NzYsNiBAQCBvYmotJChDT05GSUdfRURBQ19PQ1RFT05fUENJKQkJKz0gb2N0ZW9uX2VkYWMtcGNp Lm8KPiAgb2JqLSQoQ09ORklHX0VEQUNfVEhVTkRFUlgpCQkrPSB0aHVuZGVyeF9lZGFjLm8KPiAg Cj4gIG9iai0kKENPTkZJR19FREFDX0FMVEVSQSkJCSs9IGFsdGVyYV9lZGFjLm8KPiArb2JqLSQo Q09ORklHX0VEQUNfQVJNQURBX1hQKQkJKz0gYXJtYWRhX3hwX2VkYWMubwo+ICBvYmotJChDT05G SUdfRURBQ19TWU5PUFNZUykJCSs9IHN5bm9wc3lzX2VkYWMubwo+ICBvYmotJChDT05GSUdfRURB Q19YR0VORSkJCSs9IHhnZW5lX2VkYWMubwo+IGRpZmYgLS1naXQgYS9kcml2ZXJzL2VkYWMvYXJt YWRhX3hwX2VkYWMuYyBiL2RyaXZlcnMvZWRhYy9hcm1hZGFfeHBfZWRhYy5jCj4gbmV3IGZpbGUg bW9kZSAxMDA2NDQKPiBpbmRleCAwMDAwMDAwMDAwMDAuLjY4ZTg4YjE4MDkyOAo+IC0tLSAvZGV2 L251bGwKPiArKysgYi9kcml2ZXJzL2VkYWMvYXJtYWRhX3hwX2VkYWMuYwo+IEBAIC0wLDAgKzEs NjM5IEBACj4gKy8qCj4gKyAqIENvcHlyaWdodCAoQykgMjAxNyBQZW5ndXRyb25peCwgSmFuIEx1 ZWJiZSA8a2VybmVsQHBlbmd1dHJvbml4LmRlPgo+ICsgKgo+ICsgKiBUaGlzIHByb2dyYW0gaXMg ZnJlZSBzb2Z0d2FyZTsgeW91IGNhbiByZWRpc3RyaWJ1dGUgaXQgYW5kL29yCj4gKyAqIG1vZGlm eSBpdCB1bmRlciB0aGUgdGVybXMgb2YgdGhlIEdOVSBHZW5lcmFsIFB1YmxpYyBMaWNlbnNlCj4g KyAqIHZlcnNpb24gMiwgYXMgcHVibGlzaGVkIGJ5IHRoZSBGcmVlIFNvZnR3YXJlIEZvdW5kYXRp b24uCj4gKyAqCj4gKyAqIFRoaXMgcHJvZ3JhbSBpcyBkaXN0cmlidXRlZCBpbiB0aGUgaG9wZSB0 aGF0IGl0IHdpbGwgYmUgdXNlZnVsLAo+ICsgKiBidXQgV0lUSE9VVCBBTlkgV0FSUkFOVFk7IHdp dGhvdXQgZXZlbiB0aGUgaW1wbGllZCB3YXJyYW50eSBvZgo+ICsgKiBNRVJDSEFOVEFCSUxJVFkg b3IgRklUTkVTUyBGT1IgQSBQQVJUSUNVTEFSIFBVUlBPU0UuICBTZWUgdGhlCj4gKyAqIEdOVSBH ZW5lcmFsIFB1YmxpYyBMaWNlbnNlIGZvciBtb3JlIGRldGFpbHMuCj4gKyAqCj4gKyAqLwo+ICsK PiArI2luY2x1ZGUgPGxpbnV4L2tlcm5lbC5oPgo+ICsjaW5jbHVkZSA8bGludXgvZWRhYy5oPgo+ ICsjaW5jbHVkZSA8bGludXgvb2ZfcGxhdGZvcm0uaD4KPiArCj4gKyNpbmNsdWRlIDxhc20vaGFy ZHdhcmUvY2FjaGUtbDJ4MC5oPgo+ICsjaW5jbHVkZSA8YXNtL2hhcmR3YXJlL2NhY2hlLWF1cm9y YS1sMi5oPgo+ICsKPiArI2luY2x1ZGUgImVkYWNfbWMuaCIKPiArI2luY2x1ZGUgImVkYWNfZGV2 aWNlLmgiCj4gKyNpbmNsdWRlICJlZGFjX21vZHVsZS5oIgo+ICsKPiArLyoqKioqKioqKioqKioq KioqKioqKioqKiBFREFDIE1DIChERFIgUkFNKSAqKioqKioqKioqKioqKioqKioqKioqKioqKioq KioqKi8KPiArCj4gKyNkZWZpbmUgU0RSQU1fTlVNX0NTIDQKPiArCj4gKyNkZWZpbmUgU0RSQU1f Q09ORklHX1JFRyAweDAKPiArI2RlZmluZSBTRFJBTV9DT05GSUdfRUNDX01BU0sgICAgICAgIEJJ VCgxOCkKPiArI2RlZmluZSBTRFJBTV9DT05GSUdfUkVHSVNURVJFRF9NQVNLIEJJVCgxNykKPiAr I2RlZmluZSBTRFJBTV9DT05GSUdfQlVTX1dJRFRIX01BU0sgIEJJVCgxNSkKPiArCj4gKyNkZWZp bmUgU0RSQU1fQUREUl9DVFJMX1JFRyAweDEwCj4gKyNkZWZpbmUgU0RSQU1fQUREUl9DVFJMX1NJ WkVfSElHSF9PRkZTRVQoY3MpICAgKDIwK2NzKQo+ICsjZGVmaW5lIFNEUkFNX0FERFJfQ1RSTF9T SVpFX0hJR0hfTUFTSyhjcykgICAgICAgICAgIFwKPiArCSgweDEgPDwgU0RSQU1fQUREUl9DVFJM X1NJWkVfSElHSF9PRkZTRVQoY3MpKQo+ICsjZGVmaW5lIFNEUkFNX0FERFJfQ1RSTF9BRERSX1NF TF9NQVNLKGNzKSAgIEJJVCgxNitjcykKPiArI2RlZmluZSBTRFJBTV9BRERSX0NUUkxfU0laRV9M T1dfT0ZGU0VUKGNzKSAgIChjcyo0KzIpCj4gKyNkZWZpbmUgU0RSQU1fQUREUl9DVFJMX1NJWkVf TE9XX01BU0soY3MpICAgICAgICAgICAgXAo+ICsJKDB4MyA8PCBTRFJBTV9BRERSX0NUUkxfU0la RV9MT1dfT0ZGU0VUKGNzKSkKPiArI2RlZmluZSBTRFJBTV9BRERSX0NUUkxfU1RSVUNUX09GRlNF VChjcykgICAgICAgKGNzKjQpCj4gKyNkZWZpbmUgU0RSQU1fQUREUl9DVFJMX1NUUlVDVF9NQVNL KGNzKSAgICAgICAgICAgICAgXAo+ICsJKDB4MyA8PCBTRFJBTV9BRERSX0NUUkxfU1RSVUNUX09G RlNFVChjcykpCj4gKwo+ICsjZGVmaW5lIFNEUkFNX0VSUl9EQVRBX0hfUkVHIDB4NDAKPiArI2Rl ZmluZSBTRFJBTV9FUlJfREFUQV9MX1JFRyAweDQ0Cj4gKwo+ICsjZGVmaW5lIFNEUkFNX0VSUl9S RUNWX0VDQ19SRUcgMHg0OAo+ICsjZGVmaW5lIFNEUkFNX0VSUl9SRUNWX0VDQ19WQUxVRV9NQVNL IDB4ZmYKPiArCj4gKyNkZWZpbmUgU0RSQU1fRVJSX0NBTENfRUNDX1JFRyAweDRjCj4gKyNkZWZp bmUgU0RSQU1fRVJSX0NBTENfRUNDX1JPV19PRkZTRVQgICAgICAgICAgICAgOAo+ICsjZGVmaW5l IFNEUkFNX0VSUl9DQUxDX0VDQ19ST1dfTUFTSyAgICAgICAgICAgICAgIFwKPiArCSgweGZmZmYg PDwgU0RSQU1fRVJSX0NBTENfRUNDX1JPV19PRkZTRVQpCj4gKyNkZWZpbmUgU0RSQU1fRVJSX0NB TENfRUNDX1ZBTFVFX01BU0sgICAgICAgICAgMHhmZgo+ICsKPiArI2RlZmluZSBTRFJBTV9FUlJf QUREUl9SRUcgMHg1MAo+ICsjZGVmaW5lIFNEUkFNX0VSUl9BRERSX0JBTktfT0ZGU0VUICAgICAg ICAgICAyMwo+ICsjZGVmaW5lIFNEUkFNX0VSUl9BRERSX0JBTktfTUFTSyAgICAgICAgICAgICAg XAo+ICsJKDB4NyA8PCBTRFJBTV9FUlJfQUREUl9CQU5LX09GRlNFVCkKPiArI2RlZmluZSBTRFJB TV9FUlJfQUREUl9DT0xfT0ZGU0VUICAgICAgICAgICAgIDgKPiArI2RlZmluZSBTRFJBTV9FUlJf QUREUl9DT0xfTUFTSyAgICAgICAgICAgICAgIFwKPiArCSgweDdmZmYgPDwgU0RSQU1fRVJSX0FE RFJfQ09MX09GRlNFVCkKPiArI2RlZmluZSBTRFJBTV9FUlJfQUREUl9DU19PRkZTRVQgICAgICAg ICAgICAgIDEKPiArI2RlZmluZSBTRFJBTV9FUlJfQUREUl9DU19NQVNLICAgICAgICAgICAgICAg IFwKPiArCSgweDMgPDwgU0RSQU1fRVJSX0FERFJfQ1NfT0ZGU0VUKQo+ICsjZGVmaW5lIFNEUkFN X0VSUl9BRERSX1RZUEVfTUFTSyAgICAgICAgIEJJVCgwKQo+ICsKPiArI2RlZmluZSBTRFJBTV9F UlJfQ1RSTF9SRUcgMHg1NAo+ICsjZGVmaW5lIFNEUkFNX0VSUl9DVFJMX0VSUl9USFJfT0ZGU0VU ICAgICAgICAgIDE2Cj4gKyNkZWZpbmUgU0RSQU1fRVJSX0NUUkxfRVJSX1RIUl9NQVNLICAgICAg ICAgICAgIFwKPiArCSgweGZmIDw8IFNEUkFNX0VSUl9DVFJMX0VSUl9USFJfT0ZGU0VUKQo+ICsj ZGVmaW5lIFNEUkFNX0VSUl9DVFJMX0VSUl9QUk9QX01BU0sgICAgICAgQklUKDkpCj4gKwo+ICsj ZGVmaW5lIFNEUkFNX0VSUl9TQkVfQ09VTlRfUkVHIDB4NTgKPiArI2RlZmluZSBTRFJBTV9FUlJf REJFX0NPVU5UX1JFRyAweDVjCj4gKwo+ICsjZGVmaW5lIFNEUkFNX0VSUl9DQVVTRV9FUlJfUkVH IDB4ZDAKPiArI2RlZmluZSBTRFJBTV9FUlJfQ0FVU0VfTVNHX1JFRyAweGQ4Cj4gKyNkZWZpbmUg U0RSQU1fRVJSX0NBVVNFX0RCRV9NQVNLIEJJVCgxKQo+ICsjZGVmaW5lIFNEUkFNX0VSUl9DQVVT RV9TQkVfTUFTSyBCSVQoMCkKPiArCj4gKyNkZWZpbmUgU0RSQU1fUkFOS19DVFJMX1JFRyAweDFl MAo+ICsjZGVmaW5lIFNEUkFNX1JBTktfQ1RSTF9FWElTVF9NQVNLKGNzKSBCSVQoY3MpCj4gKwo+ ICtzdHJ1Y3QgYXJtYWRhX3hwX21jX2VkYWNfZHJ2ZGF0YSB7Cj4gKwl2b2lkIF9faW9tZW0gKmJh c2U7Cj4gKwo+ICsJdW5zaWduZWQgaW50IHdpZHRoOyAvKiB3aWR0aCBpbiBieXRlcyAqLwo+ICsJ Ym9vbCBjc19hZGRyX3NlbFtTRFJBTV9OVU1fQ1NdOyAvKiBiYW5rIGludGVybGVhdmluZyAqLwo+ ICsKPiArCWNoYXIgbXNnWzEyOF07Cj4gK307Cj4gKwo+ICsvKiBkZXJpdmVkIGZyb20gIkRSQU0g QWRkcmVzcyBNdWx0aXBsZXhpbmciIGluIHRoZSBBUkFNREEgWFAgRnVuY3Rpb25hbCBTcGVjICov Cj4gK3N0YXRpYyB1aW50MzJfdCBhcm1hZGFfeHBfbWNfZWRhY19jYWxjX2FkZHJlc3Moc3RydWN0 IGFybWFkYV94cF9tY19lZGFjX2RydmRhdGEKPiArCQkJCQkgICAgICAgKmRydmRhdGEsIHVpbnQ4 X3QgY3MsCj4gKwkJCQkJICAgICAgIHVpbnQ4X3QgYmFuaywgdWludDE2X3Qgcm93LAo+ICsJCQkJ CSAgICAgICB1aW50MTZfdCBjb2wpCj4gK3sKPiArCWlmIChkcnZkYXRhLT53aWR0aCA9PSA0KSB7 IC8qIDY0IGJpdCAqLwo+ICsJCWlmIChkcnZkYXRhLT5jc19hZGRyX3NlbFtjc10pIC8qIGJhbmsg aW50ZXJsZWF2ZWQgKi8KPiArCQkJcmV0dXJuICgoKHJvdyAmIDB4ZmZmOCkgPDwgMTYpIHwKPiAr CQkJCSgoYmFuayAmIDB4NykgPDwgMTYpIHwKPiArCQkJCSgocm93ICYgMHg3KSA8PCAxMykgfAo+ ICsJCQkJKChjb2wgJiAweDNmZikgPDwgMykpOwo+ICsJCWVsc2UKPiArCQkJcmV0dXJuICgoKHJv dyAmIDB4ZmZmZiA8PCAxNikgfAo+ICsJCQkJICgoYmFuayAmIDB4NykgPDwgMTMpIHwKPiArCQkJ CSAoKGNvbCAmIDB4M2ZmKSkgPDwgMykpOwo+ICsJfSBlbHNlIGlmIChkcnZkYXRhLT53aWR0aCA9 PSAyKSB7IC8qIDMyIGJpdCAqLwo+ICsJCWlmIChkcnZkYXRhLT5jc19hZGRyX3NlbFtjc10pIC8q IGJhbmsgaW50ZXJsZWF2ZWQgKi8KPiArCQkJcmV0dXJuICgoKHJvdyAmIDB4ZmZmMCkgPDwgMTUp IHwKPiArCQkJCSgoYmFuayAmIDB4NykgPDwgMTYpIHwKPiArCQkJCSgocm93ICYgMHhmKSA8PCAx MikgfAo+ICsJCQkJKChjb2wgJiAweDNmZikgPDwgMikpOwo+ICsJCWVsc2UKPiArCQkJcmV0dXJu ICgoKHJvdyAmIDB4ZmZmZiA8PCAxNSkgfAo+ICsJCQkJICgoYmFuayAmIDB4NykgPDwgMTIpIHwK PiArCQkJCSAoKGNvbCAmIDB4M2ZmKSkgPDwgMikpOwo+ICsJfSBlbHNlIHsgLyogMTYgYml0ICov Cj4gKwkJaWYgKGRydmRhdGEtPmNzX2FkZHJfc2VsW2NzXSkgLyogYmFuayBpbnRlcmxlYXZlZCAq Lwo+ICsJCQlyZXR1cm4gKCgocm93ICYgMHhmZmUwKSA8PCAxNCkgfAo+ICsJCQkJKChiYW5rICYg MHg3KSA8PCAxNikgfAo+ICsJCQkJKChyb3cgJiAweDFmKSA8PCAxMSkgfAo+ICsJCQkJKChjb2wg JiAweDNmZikgPDwgMSkpOwo+ICsJCWVsc2UKPiArCQkJcmV0dXJuICgoKHJvdyAmIDB4ZmZmZiA8 PCAxNCkgfAo+ICsJCQkJICgoYmFuayAmIDB4NykgPDwgMTEpIHwKPiArCQkJCSAoKGNvbCAmIDB4 M2ZmKSkgPDwgMSkpOwo+ICsJfQo+ICt9Cj4gKwo+ICtzdGF0aWMgdm9pZCBhcm1hZGFfeHBfbWNf ZWRhY19jaGVjayhzdHJ1Y3QgbWVtX2N0bF9pbmZvICptY2kpCj4gK3sKPiArCXN0cnVjdCBhcm1h ZGFfeHBfbWNfZWRhY19kcnZkYXRhICpkcnZkYXRhID0gbWNpLT5wdnRfaW5mbzsKPiArCXVpbnQz Ml90IGRhdGFfaCwgZGF0YV9sLCByZWN2X2VjYywgY2FsY19lY2MsIGFkZHI7Cj4gKwl1aW50MzJf dCBjbnRfc2JlLCBjbnRfZGJlLCBjYXVzZV9lcnIsIGNhdXNlX21zZzsKPiArCXVpbnQzMl90IHJv d192YWwsIGNvbF92YWwsIGJhbmtfdmFsLCBhZGRyX3ZhbDsKPiArCXVpbnQ4X3Qgc3luZHJvbWVf dmFsLCBjc192YWw7Cj4gKwljaGFyICptc2cgPSBkcnZkYXRhLT5tc2c7Cj4gKwo+ICsJZGF0YV9o ID0gcmVhZGwoZHJ2ZGF0YS0+YmFzZSArIFNEUkFNX0VSUl9EQVRBX0hfUkVHKTsKPiArCWRhdGFf bCA9IHJlYWRsKGRydmRhdGEtPmJhc2UgKyBTRFJBTV9FUlJfREFUQV9MX1JFRyk7Cj4gKwlyZWN2 X2VjYyA9IHJlYWRsKGRydmRhdGEtPmJhc2UgKyBTRFJBTV9FUlJfUkVDVl9FQ0NfUkVHKTsKPiAr CWNhbGNfZWNjID0gcmVhZGwoZHJ2ZGF0YS0+YmFzZSArIFNEUkFNX0VSUl9DQUxDX0VDQ19SRUcp Owo+ICsJYWRkciA9IHJlYWRsKGRydmRhdGEtPmJhc2UgKyBTRFJBTV9FUlJfQUREUl9SRUcpOwo+ ICsJY250X3NiZSA9IHJlYWRsKGRydmRhdGEtPmJhc2UgKyBTRFJBTV9FUlJfU0JFX0NPVU5UX1JF Ryk7Cj4gKwljbnRfZGJlID0gcmVhZGwoZHJ2ZGF0YS0+YmFzZSArIFNEUkFNX0VSUl9EQkVfQ09V TlRfUkVHKTsKPiArCWNhdXNlX2VyciA9IHJlYWRsKGRydmRhdGEtPmJhc2UgKyBTRFJBTV9FUlJf Q0FVU0VfRVJSX1JFRyk7Cj4gKwljYXVzZV9tc2cgPSByZWFkbChkcnZkYXRhLT5iYXNlICsgU0RS QU1fRVJSX0NBVVNFX01TR19SRUcpOwo+ICsKPiArCS8qIGNsZWFyIGNhdXNlIHJlZ2lzdGVycyAq Lwo+ICsJd3JpdGVsKH4oU0RSQU1fRVJSX0NBVVNFX0RCRV9NQVNLIHwgU0RSQU1fRVJSX0NBVVNF X1NCRV9NQVNLKSwKPiArCSAgICAgICBkcnZkYXRhLT5iYXNlICsgU0RSQU1fRVJSX0NBVVNFX0VS Ul9SRUcpOwo+ICsJd3JpdGVsKH4oU0RSQU1fRVJSX0NBVVNFX0RCRV9NQVNLIHwgU0RSQU1fRVJS X0NBVVNFX1NCRV9NQVNLKSwKPiArCSAgICAgICBkcnZkYXRhLT5iYXNlICsgU0RSQU1fRVJSX0NB VVNFX01TR19SRUcpOwo+ICsKPiArCS8qIGNsZWFyIGVycm9yIGNvdW50ZXIgcmVnaXN0ZXJzICov Cj4gKwlpZiAoY250X3NiZSkKPiArCQl3cml0ZWwoMCwgZHJ2ZGF0YS0+YmFzZSArIFNEUkFNX0VS Ul9TQkVfQ09VTlRfUkVHKTsKPiArCWlmIChjbnRfZGJlKQo+ICsJCXdyaXRlbCgwLCBkcnZkYXRh LT5iYXNlICsgU0RSQU1fRVJSX0RCRV9DT1VOVF9SRUcpOwo+ICsKPiArCWlmICghY250X3NiZSAm JiAhY250X2RiZSkKPiArCQlyZXR1cm47Cj4gKwo+ICsJaWYgKChhZGRyICYgU0RSQU1fRVJSX0FE RFJfVFlQRV9NQVNLKSA9PSAwKSB7Cj4gKwkJaWYgKGNudF9zYmUpCj4gKwkJCWNudF9zYmUtLTsK PiArCQllbHNlCj4gKwkJCWRldl93YXJuKG1jaS0+cGRldiwgImluY29uc2lzdGVudCBTQkUgY291 bnQgZGV0ZWN0ZWQiKTsKPiArCX0gZWxzZSB7Cj4gKwkJaWYgKGNudF9kYmUpCj4gKwkJCWNudF9k YmUtLTsKPiArCQllbHNlCj4gKwkJCWRldl93YXJuKG1jaS0+cGRldiwgImluY29uc2lzdGVudCBE QkUgY291bnQgZGV0ZWN0ZWQiKTsKPiArCX0KPiArCj4gKwkvKiByZXBvcnQgZWFybGllciBlcnJv cnMgKi8KPiArCWlmIChjbnRfc2JlKQo+ICsJCWVkYWNfbWNfaGFuZGxlX2Vycm9yKEhXX0VWRU5U X0VSUl9DT1JSRUNURUQsIG1jaSwKPiArCQkJCSAgICAgY250X3NiZSwgLyogZXJyb3IgY291bnQg Ki8KPiArCQkJCSAgICAgMCwgMCwgMCwgLyogcGZuLCBvZmZzZXQsIHN5bmRyb21lICovCj4gKwkJ CQkgICAgIC0xLCAtMSwgLTEsIC8qIHRvcCwgbWlkLCBsb3cgbGF5ZXIgKi8KPiArCQkJCSAgICAg bWNpLT5jdGxfbmFtZSwKPiArCQkJCSAgICAgImRldGFpbHMgdW5hdmFpbGFibGUgKG11bHRpcGxl IGVycm9ycykiKTsKPiArCWlmIChjbnRfZGJlKQo+ICsJCWVkYWNfbWNfaGFuZGxlX2Vycm9yKEhX X0VWRU5UX0VSUl9VTkNPUlJFQ1RFRCwgbWNpLAo+ICsJCQkJICAgICBjbnRfc2JlLCAvKiBlcnJv ciBjb3VudCAqLwo+ICsJCQkJICAgICAwLCAwLCAwLCAvKiBwZm4sIG9mZnNldCwgc3luZHJvbWUg Ki8KPiArCQkJCSAgICAgLTEsIC0xLCAtMSwgLyogdG9wLCBtaWQsIGxvdyBsYXllciAqLwo+ICsJ CQkJICAgICBtY2ktPmN0bF9uYW1lLAo+ICsJCQkJICAgICAiZGV0YWlscyB1bmF2YWlsYWJsZSAo bXVsdGlwbGUgZXJyb3JzKSIpOwo+ICsKPiArCS8qIHJlcG9ydCBkZXRhaWxzIGZvciBtb3N0IHJl Y2VudCBlcnJvciAqLwo+ICsJY3NfdmFsID0gKGFkZHIgJiBTRFJBTV9FUlJfQUREUl9DU19NQVNL KQo+ICsJICAgID4+IFNEUkFNX0VSUl9BRERSX0NTX09GRlNFVDsKPiArCWJhbmtfdmFsID0gKGFk ZHIgJiBTRFJBTV9FUlJfQUREUl9CQU5LX01BU0spCj4gKwkgICAgPj4gU0RSQU1fRVJSX0FERFJf QkFOS19PRkZTRVQ7Cj4gKwlyb3dfdmFsID0gKGNhbGNfZWNjICYgU0RSQU1fRVJSX0NBTENfRUND X1JPV19NQVNLKQo+ICsJICAgID4+IFNEUkFNX0VSUl9DQUxDX0VDQ19ST1dfT0ZGU0VUOwo+ICsJ Y29sX3ZhbCA9IChhZGRyICYgU0RSQU1fRVJSX0FERFJfQ09MX01BU0spCj4gKwkgICAgPj4gU0RS QU1fRVJSX0FERFJfQ09MX09GRlNFVDsKPiArCXN5bmRyb21lX3ZhbCA9IChyZWN2X2VjYyBeIGNh bGNfZWNjKSAmIDB4ZmY7Cj4gKwlhZGRyX3ZhbCA9IGFybWFkYV94cF9tY19lZGFjX2NhbGNfYWRk cmVzcyhkcnZkYXRhLCBjc192YWwsIGJhbmtfdmFsLAo+ICsJCQkJCQkgIHJvd192YWwsIGNvbF92 YWwpOwo+ICsJbXNnICs9IHNwcmludGYobXNnLCAicm93PTB4JTA0eCAiLCByb3dfdmFsKTsgLyog MTEgY2hhcnMgKi8KPiArCW1zZyArPSBzcHJpbnRmKG1zZywgImJhbms9MHgleCAiLCBiYW5rX3Zh bCk7IC8qICA5IGNoYXJzICovCj4gKwltc2cgKz0gc3ByaW50Zihtc2csICJjb2w9MHglMDR4ICIs IGNvbF92YWwpOyAvKiAxMSBjaGFycyAqLwo+ICsJbXNnICs9IHNwcmludGYobXNnLCAiY3M9JWQi LCBjc192YWwpOwkgICAgIC8qICA0IGNoYXJzICovCj4gKwo+ICsJaWYgKChhZGRyICYgU0RSQU1f RVJSX0FERFJfVFlQRV9NQVNLKSA9PSAwKSB7Cj4gKwkJZWRhY19tY19oYW5kbGVfZXJyb3IoSFdf RVZFTlRfRVJSX0NPUlJFQ1RFRCwgbWNpLAo+ICsJCQkJICAgICAxLAkvKiBlcnJvciBjb3VudCAq Lwo+ICsJCQkJICAgICBhZGRyX3ZhbCA+PiBQQUdFX1NISUZULAo+ICsJCQkJICAgICBhZGRyX3Zh bCAmIH5QQUdFX01BU0ssCj4gKwkJCQkgICAgIHN5bmRyb21lX3ZhbCwKPiArCQkJCSAgICAgY3Nf dmFsLCAtMSwgLTEsIC8qIHRvcCwgbWlkLCBsb3cgbGF5ZXIgKi8KPiArCQkJCSAgICAgbWNpLT5j dGxfbmFtZSwgZHJ2ZGF0YS0+bXNnKTsKPiArCX0gZWxzZSB7Cj4gKwkJZWRhY19tY19oYW5kbGVf ZXJyb3IoSFdfRVZFTlRfRVJSX1VOQ09SUkVDVEVELCBtY2ksCj4gKwkJCQkgICAgIDEsCS8qIGVy cm9yIGNvdW50ICovCj4gKwkJCQkgICAgIGFkZHJfdmFsID4+IFBBR0VfU0hJRlQsCj4gKwkJCQkg ICAgIGFkZHJfdmFsICYgflBBR0VfTUFTSywKPiArCQkJCSAgICAgc3luZHJvbWVfdmFsLAo+ICsJ CQkJICAgICBjc192YWwsIC0xLCAtMSwgLyogdG9wLCBtaWQsIGxvdyBsYXllciAqLwo+ICsJCQkJ ICAgICBtY2ktPmN0bF9uYW1lLCBkcnZkYXRhLT5tc2cpOwo+ICsJfQo+ICt9Cj4gKwo+ICtzdGF0 aWMgaW50IGFybWFkYV94cF9tY19lZGFjX3JlYWRfY29uZmlnKHN0cnVjdCBtZW1fY3RsX2luZm8g Km1jaSkKPiArewo+ICsJc3RydWN0IGFybWFkYV94cF9tY19lZGFjX2RydmRhdGEgKmRydmRhdGEg PSBtY2ktPnB2dF9pbmZvOwo+ICsJc3RydWN0IGRpbW1faW5mbyAqZGltbTsKPiArCXVuc2lnbmVk IGludCBpLCBjc19zdHJ1Y3QsIGNzX3NpemU7Cj4gKwl1aW50MzJfdCBjb25maWcsIGFkZHJfY3Ry bCwgcmFua19jdHJsOwo+ICsKPiArCWNvbmZpZyA9IHJlYWRsKGRydmRhdGEtPmJhc2UgKyBTRFJB TV9DT05GSUdfUkVHKTsKPiArCWlmICghKGNvbmZpZyAmIFNEUkFNX0NPTkZJR19FQ0NfTUFTSykp Cj4gKwkJZGV2X3dhcm4obWNpLT5wZGV2LCAiU0RSQU0gRUNDIGlzIG5vdCBlbmFibGVkIik7Cj4g Kwo+ICsJaWYgKG1jaS0+dG90X2RpbW1zICE9IFNEUkFNX05VTV9DUykgewo+ICsJCWRldl9lcnIo bWNpLT5wZGV2LCAiSW52YWlsZCBudW1iZXIgb2YgRElNTXMiKTsKPiArCQlyZXR1cm4gLUVJTlZB TDsKPiArCX0KPiArCj4gKwlpZiAoY29uZmlnICYgU0RSQU1fQ09ORklHX0JVU19XSURUSF9NQVNL KQo+ICsJCWRydmRhdGEtPndpZHRoID0gNDsgLyogNjQgYml0ICovCj4gKwllbHNlCj4gKwkJZHJ2 ZGF0YS0+d2lkdGggPSAyOyAvKiAzMiBiaXQgKi8KPiArCj4gKwlhZGRyX2N0cmwgPSByZWFkbChk cnZkYXRhLT5iYXNlICsgU0RSQU1fQUREUl9DVFJMX1JFRyk7Cj4gKwlyYW5rX2N0cmwgPSByZWFk bChkcnZkYXRhLT5iYXNlICsgU0RSQU1fUkFOS19DVFJMX1JFRyk7Cj4gKwlmb3IgKGkgPSAwOyBp IDwgU0RSQU1fTlVNX0NTOyBpKyspIHsKPiArCQlkaW1tID0gbWNpLT5kaW1tc1tpXTsKPiArCj4g KwkJaWYgKCEocmFua19jdHJsICYgU0RSQU1fUkFOS19DVFJMX0VYSVNUX01BU0soaSkpKQo+ICsJ CQljb250aW51ZTsKPiArCj4gKwkJZHJ2ZGF0YS0+Y3NfYWRkcl9zZWxbaV0gPQo+ICsJCQkhIShh ZGRyX2N0cmwgJiBTRFJBTV9BRERSX0NUUkxfQUREUl9TRUxfTUFTSyhpKSk7Cj4gKwo+ICsJCWNz X3N0cnVjdCA9IChhZGRyX2N0cmwgJiBTRFJBTV9BRERSX0NUUkxfU1RSVUNUX01BU0soaSkpID4+ Cj4gKwkJCVNEUkFNX0FERFJfQ1RSTF9TVFJVQ1RfT0ZGU0VUKGkpOwo+ICsJCWNzX3NpemUgPSAo KGFkZHJfY3RybCAmIFNEUkFNX0FERFJfQ1RSTF9TSVpFX0hJR0hfTUFTSyhpKSkgPj4KPiArCQkJ ICAgKFNEUkFNX0FERFJfQ1RSTF9TSVpFX0hJR0hfT0ZGU0VUKGkpIC0gMikgfAo+ICsJCQkgICAo KGFkZHJfY3RybCAmIFNEUkFNX0FERFJfQ1RSTF9TSVpFX0xPV19NQVNLKGkpKSA+Pgo+ICsJCQkg ICAgU0RSQU1fQUREUl9DVFJMX1NJWkVfTE9XX09GRlNFVChpKSkpOwo+ICsJCXN3aXRjaCAoY3Nf c2l6ZSkgewo+ICsJCWNhc2UgMDogLyogMkdCaXQgKi8KPiArCQkJZGltbS0+bnJfcGFnZXMgPSAo MHg4MDAwMDAwMFVMTCA+PiBQQUdFX1NISUZUKTsKPiArCQkJYnJlYWs7Cj4gKwkJY2FzZSAxOiAv KiAyNTZNQml0ICovCj4gKwkJCWRpbW0tPm5yX3BhZ2VzID0gKDB4MTAwMDAwMDBVTEwgPj4gUEFH RV9TSElGVCk7Cj4gKwkJCWJyZWFrOwo+ICsJCWNhc2UgMjogLyogNTEyTUJpdCAqLwo+ICsJCQlk aW1tLT5ucl9wYWdlcyA9ICgweDIwMDAwMDAwVUxMID4+IFBBR0VfU0hJRlQpOwo+ICsJCQlicmVh azsKPiArCQljYXNlIDM6IC8qIDFHQml0ICovCj4gKwkJCWRpbW0tPm5yX3BhZ2VzID0gKDB4NDAw MDAwMDBVTEwgPj4gUEFHRV9TSElGVCk7Cj4gKwkJCWJyZWFrOwo+ICsJCWNhc2UgNDogLyogNEdC aXQgKi8KPiArCQkJZGltbS0+bnJfcGFnZXMgPSAoMHgxMDAwMDAwMDBVTEwgPj4gUEFHRV9TSElG VCk7Cj4gKwkJCWJyZWFrOwo+ICsJCWNhc2UgNTogLyogOEdCaXQgKi8KPiArCQkJZGltbS0+bnJf cGFnZXMgPSAoMHgyMDAwMDAwMDBVTEwgPj4gUEFHRV9TSElGVCk7Cj4gKwkJCWJyZWFrOwo+ICsJ CX0KPiArCQlkaW1tLT5ncmFpbiA9IDg7Cj4gKwkJZGltbS0+ZHR5cGUgPSBjc19zdHJ1Y3QgPyBE RVZfWDE2IDogREVWX1g4Owo+ICsJCWRpbW0tPm10eXBlID0gKGNvbmZpZyAmIFNEUkFNX0NPTkZJ R19SRUdJU1RFUkVEX01BU0spID8KPiArCQkJTUVNX1JERFIzIDogTUVNX0REUjM7Cj4gKwkJZGlt bS0+ZWRhY19tb2RlID0gRURBQ19TRUNERUQ7Cj4gKwl9Cj4gKwo+ICsJcmV0dXJuIDA7Cj4gK30K PiArCj4gK3N0YXRpYyBjb25zdCBzdHJ1Y3Qgb2ZfZGV2aWNlX2lkIGFybWFkYV94cF9tY19lZGFj X29mX21hdGNoW10gPSB7Cj4gKwl7LmNvbXBhdGlibGUgPSAibWFydmVsbCxhcm1hZGEteHAtc2Ry YW0tY29udHJvbGxlciIsfSwKPiArCXt9LAo+ICt9Owo+ICtNT0RVTEVfREVWSUNFX1RBQkxFKG9m LCBhcm1hZGFfeHBfbWNfZWRhY19vZl9tYXRjaCk7Cj4gKwo+ICtzdGF0aWMgaW50IGFybWFkYV94 cF9tY19lZGFjX3Byb2JlKHN0cnVjdCBwbGF0Zm9ybV9kZXZpY2UgKnBkZXYpCj4gK3sKPiArCWNv bnN0IHN0cnVjdCBvZl9kZXZpY2VfaWQgKmlkOwo+ICsJc3RydWN0IG1lbV9jdGxfaW5mbyAqbWNp Owo+ICsJc3RydWN0IGVkYWNfbWNfbGF5ZXIgbGF5ZXJzWzFdOwo+ICsJc3RydWN0IGFybWFkYV94 cF9tY19lZGFjX2RydmRhdGEgKmRydmRhdGE7Cj4gKwlzdHJ1Y3QgcmVzb3VyY2UgKnI7Cj4gKwo+ ICsJbGF5ZXJzWzBdLnR5cGUgPSBFREFDX01DX0xBWUVSX0NISVBfU0VMRUNUOwo+ICsJbGF5ZXJz WzBdLnNpemUgPSBTRFJBTV9OVU1fQ1M7Cj4gKwlsYXllcnNbMF0uaXNfdmlydF9jc3JvdyA9IHRy dWU7Cj4gKwo+ICsJbWNpID0gZGV2bV9lZGFjX21jX2FsbG9jKCZwZGV2LT5kZXYsIDAsIEFSUkFZ X1NJWkUobGF5ZXJzKSwgbGF5ZXJzLAo+ICsJCQkJIHNpemVvZigqZHJ2ZGF0YSkpOwo+ICsJaWYg KCFtY2kpCj4gKwkJcmV0dXJuIC1FTk9NRU07Cj4gKwo+ICsJZHJ2ZGF0YSA9IG1jaS0+cHZ0X2lu Zm87Cj4gKwltY2ktPnBkZXYgPSAmcGRldi0+ZGV2Owo+ICsJcGxhdGZvcm1fc2V0X2RydmRhdGEo cGRldiwgbWNpKTsKPiArCj4gKwlyID0gcGxhdGZvcm1fZ2V0X3Jlc291cmNlKHBkZXYsIElPUkVT T1VSQ0VfTUVNLCAwKTsKPiArCWlmICghcikgewo+ICsJCWRldl9lcnIoJnBkZXYtPmRldiwgIlVu YWJsZSB0byBnZXQgbWVtIHJlc291cmNlXG4iKTsKPiArCQlyZXR1cm4gLUVOT0RFVjsKPiArCX0K PiArCj4gKwlkcnZkYXRhLT5iYXNlID0gZGV2bV9pb3JlbWFwX3Jlc291cmNlKCZwZGV2LT5kZXYs IHIpOwo+ICsJaWYgKElTX0VSUihkcnZkYXRhLT5iYXNlKSkgewo+ICsJCWRldl9lcnIoJnBkZXYt PmRldiwgIlVuYWJsZSB0byBtYXAgcmVnc1xuIik7Cj4gKwkJcmV0dXJuIFBUUl9FUlIoZHJ2ZGF0 YS0+YmFzZSk7Cj4gKwl9Cj4gKwo+ICsJaWQgPSBvZl9tYXRjaF9kZXZpY2UoYXJtYWRhX3hwX21j X2VkYWNfb2ZfbWF0Y2gsICZwZGV2LT5kZXYpOwo+ICsJbWNpLT5lZGFjX2NoZWNrID0gYXJtYWRh X3hwX21jX2VkYWNfY2hlY2s7Cj4gKwltY2ktPm10eXBlX2NhcCA9IE1FTV9GTEFHX0REUjM7Cj4g KwltY2ktPmVkYWNfY2FwID0gRURBQ19GTEFHX1NFQ0RFRDsKPiArCW1jaS0+bW9kX25hbWUgPSBw ZGV2LT5kZXYuZHJpdmVyLT5uYW1lOwo+ICsJbWNpLT5jdGxfbmFtZSA9IGlkID8gaWQtPmNvbXBh dGlibGUgOiAidW5rbm93biI7Cj4gKwltY2ktPmRldl9uYW1lID0gZGV2X25hbWUoJnBkZXYtPmRl dik7Cj4gKwltY2ktPnNjcnViX21vZGUgPSBTQ1JVQl9OT05FOwo+ICsKPiArCWlmIChhcm1hZGFf eHBfbWNfZWRhY19yZWFkX2NvbmZpZyhtY2kpKQo+ICsJCXJldHVybiAtRUlOVkFMOwo+ICsKPiAr CS8qIGNvbmZpZ3VyZSBTQkUgdGhyZXNob2xkICovCj4gKwkvKiBpdCBzZWVtcyB0aGF0IFNCRXMg YXJlIG5vdCBjYXB0dXJlZCBvdGhlcndpc2UgKi8KPiArCXdyaXRlbCgxIDw8IFNEUkFNX0VSUl9D VFJMX0VSUl9USFJfT0ZGU0VULAo+ICsJICAgICAgIGRydmRhdGEtPmJhc2UgKyBTRFJBTV9FUlJf Q1RSTF9SRUcpOwo+ICsKPiArCS8qIGNsZWFyIGNhdXNlIHJlZ2lzdGVycyAqLwo+ICsJd3JpdGVs KH4oU0RSQU1fRVJSX0NBVVNFX0RCRV9NQVNLIHwgU0RSQU1fRVJSX0NBVVNFX1NCRV9NQVNLKSwK PiArCSAgICAgICBkcnZkYXRhLT5iYXNlICsgU0RSQU1fRVJSX0NBVVNFX0VSUl9SRUcpOwo+ICsJ d3JpdGVsKH4oU0RSQU1fRVJSX0NBVVNFX0RCRV9NQVNLIHwgU0RSQU1fRVJSX0NBVVNFX1NCRV9N QVNLKSwKPiArCSAgICAgICBkcnZkYXRhLT5iYXNlICsgU0RSQU1fRVJSX0NBVVNFX01TR19SRUcp Owo+ICsKPiArCS8qIGNsZWFyIGNvdW50ZXIgcmVnaXN0ZXJzICovCj4gKwl3cml0ZWwoMCwgZHJ2 ZGF0YS0+YmFzZSArIFNEUkFNX0VSUl9TQkVfQ09VTlRfUkVHKTsKPiArCXdyaXRlbCgwLCBkcnZk YXRhLT5iYXNlICsgU0RSQU1fRVJSX0RCRV9DT1VOVF9SRUcpOwo+ICsKPiArCWlmIChkZXZtX2Vk YWNfbWNfYWRkX21jKCZwZGV2LT5kZXYsIG1jaSkpCj4gKwkJcmV0dXJuIC1FSU5WQUw7Cj4gKwll ZGFjX29wX3N0YXRlID0gRURBQ19PUFNUQVRFX1BPTEw7Cj4gKwo+ICsJcmV0dXJuIDA7Cj4gK30K PiArCj4gK3N0YXRpYyBzdHJ1Y3QgcGxhdGZvcm1fZHJpdmVyIGFybWFkYV94cF9tY19lZGFjX2Ry aXZlciA9IHsKPiArCS5wcm9iZSA9IGFybWFkYV94cF9tY19lZGFjX3Byb2JlLAo+ICsJLmRyaXZl ciA9IHsKPiArCQkubmFtZSA9ICJhcm1hZGFfeHBfbWNfZWRhYyIsCj4gKwkJLm9mX21hdGNoX3Rh YmxlID0gb2ZfbWF0Y2hfcHRyKGFybWFkYV94cF9tY19lZGFjX29mX21hdGNoKSwKPiArCX0sCj4g K307Cj4gKwo+ICsvKioqKioqKioqKioqKioqKioqKioqKioqIEVEQUMgRGV2aWNlIChMMiBDYWNo ZSkgKioqKioqKioqKioqKioqKioqKioqKioqKioqLwo+ICsKPiArc3RydWN0IGF1cm9yYV9sMl9l ZGFjX2RydmRhdGEgewo+ICsJdm9pZCBfX2lvbWVtICpiYXNlOwo+ICsKPiArCWNoYXIgbXNnWzEy OF07Cj4gKwo+ICsJLyogZXJyb3IgaW5qZWN0aW9uIHZpYSBkZWJ1Z2ZzICovCj4gKwl1aW50MzJf dCBpbmplY3RfYWRkcjsKPiArCXVpbnQzMl90IGluamVjdF9tYXNrOwo+ICsJdWludDhfdCBpbmpl Y3RfY3RsOwo+ICsKPiArCXN0cnVjdCBkZW50cnkgKmRlYnVnZnM7Cj4gK307Cj4gKwo+ICtzdGF0 aWMgdm9pZCBhdXJvcmFfbDJfZWRhY19pbmplY3Qoc3RydWN0IGF1cm9yYV9sMl9lZGFjX2RydmRh dGEgKmRydmRhdGEpCj4gK3sKPiArCWRydmRhdGEtPmluamVjdF9hZGRyICY9IEFVUk9SQV9FUlJf SU5KRUNUX0NUTF9BRERSX01BU0s7Cj4gKwlkcnZkYXRhLT5pbmplY3RfY3RsICY9IEFVUk9SQV9F UlJfSU5KRUNUX0NUTF9FTl9NQVNLOwo+ICsJd3JpdGVsKDAsIGRydmRhdGEtPmJhc2UgKyBBVVJP UkFfRVJSX0lOSkVDVF9DVExfUkVHKTsKPiArCXdyaXRlbChkcnZkYXRhLT5pbmplY3RfbWFzaywK PiArCSAgICAgICBkcnZkYXRhLT5iYXNlICsgQVVST1JBX0VSUl9JTkpFQ1RfTUFTS19SRUcpOwo+ ICsJd3JpdGVsKGRydmRhdGEtPmluamVjdF9hZGRyIHwgZHJ2ZGF0YS0+aW5qZWN0X2N0bCwKPiAr CSAgICAgICBkcnZkYXRhLT5iYXNlICsgQVVST1JBX0VSUl9JTkpFQ1RfQ1RMX1JFRyk7Cj4gK30K PiArCj4gK3N0YXRpYyB2b2lkIGF1cm9yYV9sMl9lZGFjX2NoZWNrKHN0cnVjdCBlZGFjX2Rldmlj ZV9jdGxfaW5mbyAqZGNpKQo+ICt7Cj4gKwlzdHJ1Y3QgYXVyb3JhX2wyX2VkYWNfZHJ2ZGF0YSAq ZHJ2ZGF0YSA9IGRjaS0+cHZ0X2luZm87Cj4gKwl1aW50MzJfdCBjbnQsIGF0dHJfY2FwLCBhZGRy X2NhcCwgd2F5X2NhcDsKPiArCXVuc2lnbmVkIGludCBjbnRfY2UsIGNudF91ZTsKPiArCj4gKwlj bnQgPSByZWFkbChkcnZkYXRhLT5iYXNlICsgQVVST1JBX0VSUl9DTlRfUkVHKTsKPiArCWF0dHJf Y2FwID0gcmVhZGwoZHJ2ZGF0YS0+YmFzZSArIEFVUk9SQV9FUlJfQVRUUl9DQVBfUkVHKTsKPiAr CWFkZHJfY2FwID0gcmVhZGwoZHJ2ZGF0YS0+YmFzZSArIEFVUk9SQV9FUlJfQUREUl9DQVBfUkVH KTsKPiArCXdheV9jYXAgPSByZWFkbChkcnZkYXRhLT5iYXNlICsgQVVST1JBX0VSUl9XQVlfQ0FQ X1JFRyk7Cj4gKwo+ICsJY250X2NlID0gKGNudCAmIEFVUk9SQV9FUlJfQ05UX0NFX01BU0spID4+ IEFVUk9SQV9FUlJfQ05UX0NFX09GRlNFVDsKPiArCWNudF91ZSA9IChjbnQgJiBBVVJPUkFfRVJS X0NOVF9VRV9NQVNLKSA+PiBBVVJPUkFfRVJSX0NOVF9VRV9PRkZTRVQ7Cj4gKwkvKiBjbGVhciBl cnJvciBjb3VudGVyIHJlZ2lzdGVycyAqLwo+ICsJaWYgKGNudF9jZSB8fCBjbnRfdWUpCj4gKwkJ d3JpdGVsKEFVUk9SQV9FUlJfQ05UX0NMUiwgZHJ2ZGF0YS0+YmFzZSArIEFVUk9SQV9FUlJfQ05U X1JFRyk7Cj4gKwo+ICsJaWYgKGF0dHJfY2FwICYgQVVST1JBX0VSUl9BVFRSX0NBUF9WQUxJRCkg ewo+ICsJCWNoYXIgKm1zZyA9IGRydmRhdGEtPm1zZzsKPiArCQlzaXplX3Qgc2l6ZSA9IHNpemVv ZihkcnZkYXRhLT5tc2cpOwo+ICsJCXNpemVfdCBsZW4gPSAwOwo+ICsKPiArCQlzd2l0Y2ggKChh dHRyX2NhcCAmIEFVUk9SQV9FUlJfQVRUUl9DQVBfRVJSX1NPVVJDRV9NQVNLKQo+ICsJCQk+PiBB VVJPUkFfRVJSX0FUVFJfQ0FQX0VSUl9TT1VSQ0VfT0ZGU0VUKSB7Cj4gKwkJY2FzZSAwOgo+ICsJ CQlsZW4gKz0gc25wcmludGYobXNnK2xlbiwgc2l6ZS1sZW4sICJzcmM9Q1BVMCAiKTsKPiArCQkJ YnJlYWs7Cj4gKwkJY2FzZSAxOgo+ICsJCQlsZW4gKz0gc25wcmludGYobXNnK2xlbiwgc2l6ZS1s ZW4sICJzcmM9Q1BVMSAiKTsKPiArCQkJYnJlYWs7Cj4gKwkJY2FzZSAyOgo+ICsJCQlsZW4gKz0g c25wcmludGYobXNnK2xlbiwgc2l6ZS1sZW4sICJzcmM9Q1BVMiAiKTsKPiArCQkJYnJlYWs7Cj4g KwkJY2FzZSAzOgo+ICsJCQlsZW4gKz0gc25wcmludGYobXNnK2xlbiwgc2l6ZS1sZW4sICJzcmM9 Q1BVMyAiKTsKPiArCQkJYnJlYWs7Cj4gKwkJY2FzZSA3Ogo+ICsJCQlsZW4gKz0gc25wcmludGYo bXNnK2xlbiwgc2l6ZS1sZW4sICJzcmM9SU8gIik7Cj4gKwkJCWJyZWFrOwo+ICsJCX0KPiArCQlz d2l0Y2ggKChhdHRyX2NhcCAmIEFVUk9SQV9FUlJfQVRUUl9DQVBfVFJBTlNfVFlQRV9NQVNLKQo+ ICsJCQk+PiBBVVJPUkFfRVJSX0FUVFJfQ0FQX1RSQU5TX1RZUEVfT0ZGU0VUKSB7Cj4gKwkJY2Fz ZSAwOgo+ICsJCQlsZW4gKz0gc25wcmludGYobXNnK2xlbiwgc2l6ZS1sZW4sICJ0eG49RGF0YS1S ZWFkICIpOwo+ICsJCQlicmVhazsKPiArCQljYXNlIDE6Cj4gKwkJCWxlbiArPSBzbnByaW50Ziht c2crbGVuLCBzaXplLWxlbiwgInR4bj1Jc24tUmVhZCAiKTsKPiArCQkJYnJlYWs7Cj4gKwkJY2Fz ZSAyOgo+ICsJCQlsZW4gKz0gc25wcmludGYobXNnK2xlbiwgc2l6ZS1sZW4sICJ0eG49Q2xlYW4t Rmx1c2ggIik7Cj4gKwkJCWJyZWFrOwo+ICsJCWNhc2UgMzoKPiArCQkJbGVuICs9IHNucHJpbnRm KG1zZytsZW4sIHNpemUtbGVuLCAidHhuPUV2aWN0aW9uICIpOwo+ICsJCQlicmVhazsKPiArCQlj YXNlIDQ6Cj4gKwkJCWxlbiArPSBzbnByaW50Zihtc2crbGVuLCBzaXplLWxlbiwKPiArCQkJCQki dHhuPVJlYWQtTW9kaWZ5LVdyaXRlICIpOwo+ICsJCQlicmVhazsKPiArCQl9Cj4gKwkJc3dpdGNo ICgoYXR0cl9jYXAgJiBBVVJPUkFfRVJSX0FUVFJfQ0FQX0VSUl9UWVBFX01BU0spCj4gKwkJCT4+ IEFVUk9SQV9FUlJfQVRUUl9DQVBfRVJSX1RZUEVfT0ZGU0VUKSB7Cj4gKwkJY2FzZSAwOgo+ICsJ CQlsZW4gKz0gc25wcmludGYobXNnK2xlbiwgc2l6ZS1sZW4sICJlcnI9Q29yckVDQyAiKTsKPiAr CQkJYnJlYWs7Cj4gKwkJY2FzZSAxOgo+ICsJCQlsZW4gKz0gc25wcmludGYobXNnK2xlbiwgc2l6 ZS1sZW4sICJlcnI9VW5Db3JyRUNDICIpOwo+ICsJCQlicmVhazsKPiArCQljYXNlIDI6Cj4gKwkJ CWxlbiArPSBzbnByaW50Zihtc2crbGVuLCBzaXplLWxlbiwgImVycj1UYWdQYXJpdHkgIik7Cj4g KwkJCWJyZWFrOwo+ICsJCX0KPiArCQlsZW4gKz0gc25wcmludGYobXNnK2xlbiwgc2l6ZS1sZW4s ICJhZGRyPTB4JXggIiwKPiArCQkJICAgIGFkZHJfY2FwICYgQVVST1JBX0VSUl9BRERSX0NBUF9B RERSX01BU0spOwo+ICsJCWxlbiArPSBzbnByaW50Zihtc2crbGVuLCBzaXplLWxlbiwgImluZGV4 PTB4JXggIiwKPiArCQkJICAgICh3YXlfY2FwICYgQVVST1JBX0VSUl9XQVlfQ0FQX0lOREVYX01B U0spCj4gKwkJCSAgICA+PiBBVVJPUkFfRVJSX1dBWV9DQVBfSU5ERVhfT0ZGU0VUKTsKPiArCQls ZW4gKz0gc25wcmludGYobXNnK2xlbiwgc2l6ZS1sZW4sICJ3YXk9MHgleCIsCj4gKwkJCSAgICAo d2F5X2NhcCAmIEFVUk9SQV9FUlJfV0FZX0NBUF9XQVlfTUFTSykKPiArCQkJICAgID4+IEFVUk9S QV9FUlJfV0FZX0NBUF9XQVlfT0ZGU0VUKTsKPiArCQkvKiBjbGVhciBlcnJvciBjYXB0dXJlIHJl Z2lzdGVycyAqLwo+ICsJCXdyaXRlbChBVVJPUkFfRVJSX0FUVFJfQ0FQX1ZBTElELAo+ICsJCSAg ICAgICBkcnZkYXRhLT5iYXNlICsgQVVST1JBX0VSUl9BVFRSX0NBUF9SRUcpOwo+ICsJCWlmICgo YXR0cl9jYXAgJiBBVVJPUkFfRVJSX0FUVFJfQ0FQX0VSUl9UWVBFX01BU0spCj4gKwkJICAgID4+ IEFVUk9SQV9FUlJfQVRUUl9DQVBfRVJSX1RZUEVfT0ZGU0VUKSB7Cj4gKwkJCS8qIFVuQ29yckVD QyBvciBUYWdQYXJpdHkgKi8KPiArCQkJaWYgKGNudF91ZSkKPiArCQkJCWNudF91ZS0tOwo+ICsJ CQllZGFjX2RldmljZV9oYW5kbGVfdWUoZGNpLCAwLCAwLCBkcnZkYXRhLT5tc2cpOwo+ICsJCX0g ZWxzZSB7Cj4gKwkJCWlmIChjbnRfY2UpCj4gKwkJCQljbnRfY2UtLTsKPiArCQkJZWRhY19kZXZp Y2VfaGFuZGxlX2NlKGRjaSwgMCwgMCwgZHJ2ZGF0YS0+bXNnKTsKPiArCQl9Cj4gKwl9Cj4gKwo+ ICsJLyogcmVwb3J0IHJlbWFpbmluZyBlcnJvcnMgKi8KPiArCXdoaWxlIChjbnRfdWUtLSkKPiAr CQllZGFjX2RldmljZV9oYW5kbGVfdWUoZGNpLCAwLCAwLAo+ICsJCQkJICAgICAgImRldGFpbHMg dW5hdmFpbGFibGUgKG11bHRpcGxlIGVycm9ycykiKTsKPiArCXdoaWxlIChjbnRfY2UtLSkKPiAr CQllZGFjX2RldmljZV9oYW5kbGVfdWUoZGNpLCAwLCAwLAo+ICsJCQkJICAgICAgImRldGFpbHMg dW5hdmFpbGFibGUgKG11bHRpcGxlIGVycm9ycykiKTsKPiArfQo+ICsKPiArc3RhdGljIHZvaWQg YXVyb3JhX2wyX2VkYWNfcG9sbChzdHJ1Y3QgZWRhY19kZXZpY2VfY3RsX2luZm8gKmRjaSkKPiAr ewo+ICsJc3RydWN0IGF1cm9yYV9sMl9lZGFjX2RydmRhdGEgKmRydmRhdGEgPSBkY2ktPnB2dF9p bmZvOwo+ICsKPiArCWF1cm9yYV9sMl9lZGFjX2NoZWNrKGRjaSk7Cj4gKwlhdXJvcmFfbDJfZWRh Y19pbmplY3QoZHJ2ZGF0YSk7Cj4gK30KPiArCj4gK3N0YXRpYyBjb25zdCBzdHJ1Y3Qgb2ZfZGV2 aWNlX2lkIGF1cm9yYV9sMl9lZGFjX29mX21hdGNoW10gPSB7Cj4gKwl7LmNvbXBhdGlibGUgPSAi bWFydmVsbCxhdXJvcmEtc3lzdGVtLWNhY2hlIix9LAo+ICsJe30sCj4gK307Cj4gK01PRFVMRV9E RVZJQ0VfVEFCTEUob2YsIGF1cm9yYV9sMl9lZGFjX29mX21hdGNoKTsKPiArCj4gK3N0YXRpYyBp bnQgYXVyb3JhX2wyX2VkYWNfcHJvYmUoc3RydWN0IHBsYXRmb3JtX2RldmljZSAqcGRldikKPiAr ewo+ICsJY29uc3Qgc3RydWN0IG9mX2RldmljZV9pZCAqaWQ7Cj4gKwlzdHJ1Y3QgZWRhY19kZXZp Y2VfY3RsX2luZm8gKmRjaTsKPiArCXN0cnVjdCBhdXJvcmFfbDJfZWRhY19kcnZkYXRhICpkcnZk YXRhOwo+ICsJc3RydWN0IHJlc291cmNlICpyOwo+ICsJdWludDMyX3QgbDJ4MF9hdXhfY3RybDsK PiArCj4gKwlkY2kgPSBkZXZtX2VkYWNfZGV2aWNlX2FsbG9jX2N0bF9pbmZvKCZwZGV2LT5kZXYs IHNpemVvZigqZHJ2ZGF0YSksCj4gKwkJCQkJICAgICAgImNwdSIsIDEsICJMIiwgMSwgMiwgTlVM TCwgMCwgMCk7Cj4gKwlpZiAoIWRjaSkKPiArCQlyZXR1cm4gLUVOT01FTTsKPiArCj4gKwlkcnZk YXRhID0gZGNpLT5wdnRfaW5mbzsKPiArCWRjaS0+ZGV2ID0gJnBkZXYtPmRldjsKPiArCXBsYXRm b3JtX3NldF9kcnZkYXRhKHBkZXYsIGRjaSk7Cj4gKwo+ICsJciA9IHBsYXRmb3JtX2dldF9yZXNv dXJjZShwZGV2LCBJT1JFU09VUkNFX01FTSwgMCk7Cj4gKwlpZiAoIXIpIHsKPiArCQlkZXZfZXJy KCZwZGV2LT5kZXYsICJVbmFibGUgdG8gZ2V0IG1lbSByZXNvdXJjZVxuIik7Cj4gKwkJcmV0dXJu IC1FTk9ERVY7Cj4gKwl9Cj4gKwo+ICsJZHJ2ZGF0YS0+YmFzZSA9IGRldm1faW9yZW1hcF9yZXNv dXJjZSgmcGRldi0+ZGV2LCByKTsKPiArCWlmIChJU19FUlIoZHJ2ZGF0YS0+YmFzZSkpIHsKPiAr CQlkZXZfZXJyKCZwZGV2LT5kZXYsICJVbmFibGUgdG8gbWFwIHJlZ3NcbiIpOwo+ICsJCXJldHVy biBQVFJfRVJSKGRydmRhdGEtPmJhc2UpOwo+ICsJfQo+ICsKPiArCWwyeDBfYXV4X2N0cmwgPSBy ZWFkbChkcnZkYXRhLT5iYXNlICsgTDJYMF9BVVhfQ1RSTCk7Cj4gKwlpZiAoIShsMngwX2F1eF9j dHJsICYgQVVST1JBX0FDUl9QQVJJVFlfRU4pKQo+ICsJCWRldl93YXJuKCZwZGV2LT5kZXYsICJ0 YWcgcGFyaXR5IGlzIG5vdCBlbmFibGVkIik7Cj4gKwlpZiAoIShsMngwX2F1eF9jdHJsICYgQVVS T1JBX0FDUl9FQ0NfRU4pKQo+ICsJCWRldl93YXJuKCZwZGV2LT5kZXYsICJkYXRhIEVDQyBpcyBu b3QgZW5hYmxlZCIpOwo+ICsKPiArCWlkID0gb2ZfbWF0Y2hfZGV2aWNlKGF1cm9yYV9sMl9lZGFj X29mX21hdGNoLCAmcGRldi0+ZGV2KTsKPiArCWRjaS0+ZWRhY19jaGVjayA9IGF1cm9yYV9sMl9l ZGFjX3BvbGw7Cj4gKwlkY2ktPm1vZF9uYW1lID0gcGRldi0+ZGV2LmRyaXZlci0+bmFtZTsKPiAr CWRjaS0+Y3RsX25hbWUgPSBpZCA/IGlkLT5jb21wYXRpYmxlIDogInVua25vd24iOwo+ICsJZGNp LT5kZXZfbmFtZSA9IGRldl9uYW1lKCZwZGV2LT5kZXYpOwo+ICsKPiArCS8qIGNsZWFyIHJlZ2lz dGVycyAqLwo+ICsJd3JpdGVsKEFVUk9SQV9FUlJfQ05UX0NMUiwgZHJ2ZGF0YS0+YmFzZSArIEFV Uk9SQV9FUlJfQ05UX1JFRyk7Cj4gKwl3cml0ZWwoQVVST1JBX0VSUl9BVFRSX0NBUF9WQUxJRCwK PiArCSAgICAgICBkcnZkYXRhLT5iYXNlICsgQVVST1JBX0VSUl9BVFRSX0NBUF9SRUcpOwo+ICsK PiArCWlmIChkZXZtX2VkYWNfZGV2aWNlX2FkZF9kZXZpY2UoJnBkZXYtPmRldiwgZGNpKSkKPiAr CQlyZXR1cm4gLUVJTlZBTDsKPiArCj4gKwlkcnZkYXRhLT5kZWJ1Z2ZzID0gZWRhY19kZWJ1Z2Zz X2NyZWF0ZV9kaXIoZGV2X25hbWUoJnBkZXYtPmRldikpOwo+ICsJaWYgKGRydmRhdGEtPmRlYnVn ZnMpIHsKPiArCQllZGFjX2RlYnVnZnNfY3JlYXRlX3gzMigiaW5qZWN0X2FkZHIiLCAwNjQ0LAo+ ICsJCQkJCWRydmRhdGEtPmRlYnVnZnMsCj4gKwkJCQkJJmRydmRhdGEtPmluamVjdF9hZGRyKTsK PiArCQllZGFjX2RlYnVnZnNfY3JlYXRlX3gzMigiaW5qZWN0X21hc2siLCAwNjQ0LAo+ICsJCQkJ CWRydmRhdGEtPmRlYnVnZnMsCj4gKwkJCQkJJmRydmRhdGEtPmluamVjdF9tYXNrKTsKPiArCQll ZGFjX2RlYnVnZnNfY3JlYXRlX3g4KCJpbmplY3RfY3RsIiwgMDY0NCwKPiArCQkJCSAgICAgICBk cnZkYXRhLT5kZWJ1Z2ZzLCAmZHJ2ZGF0YS0+aW5qZWN0X2N0bCk7Cj4gKwl9Cj4gKwo+ICsJcmV0 dXJuIDA7Cj4gK30KPiArCj4gK3N0YXRpYyBpbnQgYXVyb3JhX2wyX2VkYWNfcmVtb3ZlKHN0cnVj dCBwbGF0Zm9ybV9kZXZpY2UgKnBkZXYpCj4gK3sKPiArCXN0cnVjdCBlZGFjX2RldmljZV9jdGxf aW5mbyAqZGNpID0gcGxhdGZvcm1fZ2V0X2RydmRhdGEocGRldik7Cj4gKwlzdHJ1Y3QgYXVyb3Jh X2wyX2VkYWNfZHJ2ZGF0YSAqZHJ2ZGF0YSA9IGRjaS0+cHZ0X2luZm87Cj4gKwo+ICsJZWRhY19k ZWJ1Z2ZzX3JlbW92ZV9yZWN1cnNpdmUoZHJ2ZGF0YS0+ZGVidWdmcyk7Cj4gKwlyZXR1cm4gMDsK PiArfQo+ICsKPiArc3RhdGljIHN0cnVjdCBwbGF0Zm9ybV9kcml2ZXIgYXVyb3JhX2wyX2VkYWNf ZHJpdmVyID0gewo+ICsJLnByb2JlID0gYXVyb3JhX2wyX2VkYWNfcHJvYmUsCj4gKwkucmVtb3Zl ID0gYXVyb3JhX2wyX2VkYWNfcmVtb3ZlLAo+ICsJLmRyaXZlciA9IHsKPiArCQkubmFtZSA9ICJh dXJvcmFfbDJfZWRhYyIsCj4gKwkJLm9mX21hdGNoX3RhYmxlID0gb2ZfbWF0Y2hfcHRyKGF1cm9y YV9sMl9lZGFjX29mX21hdGNoKSwKPiArCX0sCj4gK307Cj4gKwo+ICsvKioqKioqKioqKioqKioq KioqKioqKioqIERyaXZlciByZWdpc3RyYXRpb24gKioqKioqKioqKioqKioqKioqKioqKioqKioq KioqLwo+ICsKPiArc3RhdGljIHN0cnVjdCBwbGF0Zm9ybV9kcml2ZXIgKiBjb25zdCBkcml2ZXJz W10gPSB7Cj4gKwkmYXJtYWRhX3hwX21jX2VkYWNfZHJpdmVyLAo+ICsJJmF1cm9yYV9sMl9lZGFj X2RyaXZlciwKPiArfTsKPiArCj4gK3N0YXRpYyBpbnQgX19pbml0IGFybWFkYV94cF9lZGFjX2lu aXQodm9pZCkKPiArewo+ICsJaW50IHJlcyA9IDA7Cj4gKwo+ICsJLyogb25seSBwb2xsaW5nIGlz IHN1cHBvcnRlZCAqLwo+ICsJZWRhY19vcF9zdGF0ZSA9IEVEQUNfT1BTVEFURV9QT0xMOwo+ICsK PiArCXJlcyA9IHBsYXRmb3JtX3JlZ2lzdGVyX2RyaXZlcnMoZHJpdmVycywgQVJSQVlfU0laRShk cml2ZXJzKSk7Cj4gKwlpZiAocmVzKQo+ICsJCXByX3dhcm4oIkFyYW1kYSBYUCBFREFDIGRyaXZl cnMgZmFpbCB0byByZWdpc3RlclxuIik7Cj4gKwo+ICsJcmV0dXJuIDA7Cj4gK30KPiArbW9kdWxl X2luaXQoYXJtYWRhX3hwX2VkYWNfaW5pdCk7Cj4gKwo+ICtzdGF0aWMgdm9pZCBfX2V4aXQgYXJt YWRhX3hwX2VkYWNfZXhpdCh2b2lkKQo+ICt7Cj4gKwlwbGF0Zm9ybV91bnJlZ2lzdGVyX2RyaXZl cnMoZHJpdmVycywgQVJSQVlfU0laRShkcml2ZXJzKSk7Cj4gK30KPiArbW9kdWxlX2V4aXQoYXJt YWRhX3hwX2VkYWNfZXhpdCk7Cj4gKwo+ICtNT0RVTEVfTElDRU5TRSgiR1BMIHYyIik7Cj4gK01P RFVMRV9BVVRIT1IoIlBlbmd1dHJvbml4Iik7Cj4gK01PRFVMRV9ERVNDUklQVElPTigiRURBQyBE cml2ZXJzIGZvciBNYXJ2ZWxsIEFybWFkYSBYUCBTRFJBTSBhbmQgTDIgQ2FjaGUgQ29udHJvbGxl ciIpOwo+IC0tIAo+IDIuMTEuMAo+Cg== From mboxrd@z Thu Jan 1 00:00:00 1970 From: gregory.clement@free-electrons.com (Gregory CLEMENT) Date: Mon, 03 Jul 2017 15:03:22 +0200 Subject: [PATCH 8/8] EDAC: Add driver for the Marvell Armada XP SDRAM and L2 cache ECC In-Reply-To: <20170630145106.29820-9-jlu@pengutronix.de> (Jan Luebbe's message of "Fri, 30 Jun 2017 16:51:06 +0200") References: <20170630145106.29820-1-jlu@pengutronix.de> <20170630145106.29820-9-jlu@pengutronix.de> Message-ID: <87bmp1vfj9.fsf@free-electrons.com> To: linux-arm-kernel@lists.infradead.org List-Id: linux-arm-kernel.lists.infradead.org Hi Jan, On ven., juin 30 2017, Jan Luebbe wrote: > Add support for the ECC functionality as found in the DDR RAM and L2 > cache controllers on the MV78230/MV78x60 SoCs. This driver has been > tested on the MV78460 (on a custom board with a DDR3 ECC DIMM). > > Signed-off-by: Jan Luebbe > --- > MAINTAINERS | 6 + > arch/arm/include/asm/hardware/cache-aurora-l2.h | 48 ++ you could maybe move the cache-aurora-l2.h change in a separate patch and put it at the beginning of the series just after the 2nd patch. Gregory > drivers/edac/Kconfig | 7 + > drivers/edac/Makefile | 1 + > drivers/edac/armada_xp_edac.c | 639 ++++++++++++++++++++++++ > 5 files changed, 701 insertions(+) > create mode 100644 drivers/edac/armada_xp_edac.c > > diff --git a/MAINTAINERS b/MAINTAINERS > index 767e9d202adf..758cce9c2315 100644 > --- a/MAINTAINERS > +++ b/MAINTAINERS > @@ -4766,6 +4766,12 @@ L: linux-edac at vger.kernel.org > S: Maintained > F: drivers/edac/amd64_edac* > > +EDAC-ARMADA > +M: Jan Luebbe > +L: linux-edac at vger.kernel.org > +S: Maintained > +F: drivers/edac/armada_xp_* > + > EDAC-CALXEDA > M: Robert Richter > L: linux-edac at vger.kernel.org > diff --git a/arch/arm/include/asm/hardware/cache-aurora-l2.h b/arch/arm/include/asm/hardware/cache-aurora-l2.h > index dc5c479ec4c3..c32be689d1f6 100644 > --- a/arch/arm/include/asm/hardware/cache-aurora-l2.h > +++ b/arch/arm/include/asm/hardware/cache-aurora-l2.h > @@ -31,6 +31,9 @@ > #define AURORA_ACR_REPLACEMENT_TYPE_SEMIPLRU \ > (3 << AURORA_ACR_REPLACEMENT_OFFSET) > > +#define AURORA_ACR_PARITY_EN (1 << 21) > +#define AURORA_ACR_ECC_EN (1 << 20) > + > #define AURORA_ACR_FORCE_WRITE_POLICY_OFFSET 0 > #define AURORA_ACR_FORCE_WRITE_POLICY_MASK \ > (0x3 << AURORA_ACR_FORCE_WRITE_POLICY_OFFSET) > @@ -41,6 +44,51 @@ > #define AURORA_ACR_FORCE_WRITE_THRO_POLICY \ > (2 << AURORA_ACR_FORCE_WRITE_POLICY_OFFSET) > > +#define AURORA_ERR_CNT_REG 0x600 > +#define AURORA_ERR_ATTR_CAP_REG 0x608 > +#define AURORA_ERR_ADDR_CAP_REG 0x60c > +#define AURORA_ERR_WAY_CAP_REG 0x610 > +#define AURORA_ERR_INJECT_CTL_REG 0x614 > +#define AURORA_ERR_INJECT_MASK_REG 0x618 > + > +#define AURORA_ERR_CNT_CLR_OFFSET 31 > +#define AURORA_ERR_CNT_CLR \ > + (0x1 << AURORA_ERR_CNT_CLR_OFFSET) > +#define AURORA_ERR_CNT_UE_OFFSET 16 > +#define AURORA_ERR_CNT_UE_MASK \ > + (0x7fff << AURORA_ERR_CNT_UE_OFFSET) > +#define AURORA_ERR_CNT_CE_OFFSET 0 > +#define AURORA_ERR_CNT_CE_MASK \ > + (0xffff << AURORA_ERR_CNT_CE_OFFSET) > + > +#define AURORA_ERR_ATTR_CAP_ERR_SOURCE_OFFSET 16 > +#define AURORA_ERR_ATTR_CAP_ERR_SOURCE_MASK \ > + (0x7 << AURORA_ERR_ATTR_CAP_ERR_SOURCE_OFFSET) > +#define AURORA_ERR_ATTR_CAP_TRANS_TYPE_OFFSET 12 > +#define AURORA_ERR_ATTR_CAP_TRANS_TYPE_MASK \ > + (0xf << AURORA_ERR_ATTR_CAP_TRANS_TYPE_OFFSET) > +#define AURORA_ERR_ATTR_CAP_ERR_TYPE_OFFSET 8 > +#define AURORA_ERR_ATTR_CAP_ERR_TYPE_MASK \ > + (0x3 << AURORA_ERR_ATTR_CAP_ERR_TYPE_OFFSET) > +#define AURORA_ERR_ATTR_CAP_VALID_OFFSET 0 > +#define AURORA_ERR_ATTR_CAP_VALID \ > + (0x1 << AURORA_ERR_ATTR_CAP_VALID_OFFSET) > + > +#define AURORA_ERR_ADDR_CAP_ADDR_MASK 0xffffffe0 > + > +#define AURORA_ERR_WAY_CAP_INDEX_OFFSET 8 > +#define AURORA_ERR_WAY_CAP_INDEX_MASK \ > + (0xfff << AURORA_ERR_WAY_CAP_INDEX_OFFSET) > +#define AURORA_ERR_WAY_CAP_WAY_OFFSET 1 > +#define AURORA_ERR_WAY_CAP_WAY_MASK \ > + (0xf << AURORA_ERR_WAY_CAP_WAY_OFFSET) > + > +#define AURORA_ERR_INJECT_CTL_ADDR_MASK 0xfffffff0 > +#define AURORA_ERR_ATTR_CAP_TRANS_TYPE_OFFSET 12 > +#define AURORA_ERR_INJECT_CTL_EN_MASK 0x3 > +#define AURORA_ERR_INJECT_CTL_EN_PARITY 0x2 > +#define AURORA_ERR_INJECT_CTL_EN_ECC 0x1 > + > #define AURORA_MAX_RANGE_SIZE 1024 > > #define AURORA_WAY_SIZE_SHIFT 2 > diff --git a/drivers/edac/Kconfig b/drivers/edac/Kconfig > index 96afb2aeed18..4e123ec94a4a 100644 > --- a/drivers/edac/Kconfig > +++ b/drivers/edac/Kconfig > @@ -443,6 +443,13 @@ config EDAC_ALTERA_SDMMC > Support for error detection and correction on the > Altera SDMMC FIFO Memory for Altera SoCs. > > +config EDAC_ARMADA_XP > + bool "Marvell Armada XP DDR and L2 Cache ECC" > + depends on ARCH_MVEBU > + help > + Support for error correction and detection on the Marvell Aramada XP > + DDR RAM and L2 cache controllers. > + > config EDAC_SYNOPSYS > tristate "Synopsys DDR Memory Controller" > depends on ARCH_ZYNQ > diff --git a/drivers/edac/Makefile b/drivers/edac/Makefile > index 0fd9ffa63299..70a093cc976e 100644 > --- a/drivers/edac/Makefile > +++ b/drivers/edac/Makefile > @@ -76,5 +76,6 @@ obj-$(CONFIG_EDAC_OCTEON_PCI) += octeon_edac-pci.o > obj-$(CONFIG_EDAC_THUNDERX) += thunderx_edac.o > > obj-$(CONFIG_EDAC_ALTERA) += altera_edac.o > +obj-$(CONFIG_EDAC_ARMADA_XP) += armada_xp_edac.o > obj-$(CONFIG_EDAC_SYNOPSYS) += synopsys_edac.o > obj-$(CONFIG_EDAC_XGENE) += xgene_edac.o > diff --git a/drivers/edac/armada_xp_edac.c b/drivers/edac/armada_xp_edac.c > new file mode 100644 > index 000000000000..68e88b180928 > --- /dev/null > +++ b/drivers/edac/armada_xp_edac.c > @@ -0,0 +1,639 @@ > +/* > + * Copyright (C) 2017 Pengutronix, Jan Luebbe > + * > + * This program is free software; you can redistribute it and/or > + * modify it under the terms of the GNU General Public License > + * version 2, as published by the Free Software Foundation. > + * > + * This program is distributed in the hope that it will be useful, > + * but WITHOUT ANY WARRANTY; without even the implied warranty of > + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the > + * GNU General Public License for more details. > + * > + */ > + > +#include > +#include > +#include > + > +#include > +#include > + > +#include "edac_mc.h" > +#include "edac_device.h" > +#include "edac_module.h" > + > +/************************ EDAC MC (DDR RAM) ********************************/ > + > +#define SDRAM_NUM_CS 4 > + > +#define SDRAM_CONFIG_REG 0x0 > +#define SDRAM_CONFIG_ECC_MASK BIT(18) > +#define SDRAM_CONFIG_REGISTERED_MASK BIT(17) > +#define SDRAM_CONFIG_BUS_WIDTH_MASK BIT(15) > + > +#define SDRAM_ADDR_CTRL_REG 0x10 > +#define SDRAM_ADDR_CTRL_SIZE_HIGH_OFFSET(cs) (20+cs) > +#define SDRAM_ADDR_CTRL_SIZE_HIGH_MASK(cs) \ > + (0x1 << SDRAM_ADDR_CTRL_SIZE_HIGH_OFFSET(cs)) > +#define SDRAM_ADDR_CTRL_ADDR_SEL_MASK(cs) BIT(16+cs) > +#define SDRAM_ADDR_CTRL_SIZE_LOW_OFFSET(cs) (cs*4+2) > +#define SDRAM_ADDR_CTRL_SIZE_LOW_MASK(cs) \ > + (0x3 << SDRAM_ADDR_CTRL_SIZE_LOW_OFFSET(cs)) > +#define SDRAM_ADDR_CTRL_STRUCT_OFFSET(cs) (cs*4) > +#define SDRAM_ADDR_CTRL_STRUCT_MASK(cs) \ > + (0x3 << SDRAM_ADDR_CTRL_STRUCT_OFFSET(cs)) > + > +#define SDRAM_ERR_DATA_H_REG 0x40 > +#define SDRAM_ERR_DATA_L_REG 0x44 > + > +#define SDRAM_ERR_RECV_ECC_REG 0x48 > +#define SDRAM_ERR_RECV_ECC_VALUE_MASK 0xff > + > +#define SDRAM_ERR_CALC_ECC_REG 0x4c > +#define SDRAM_ERR_CALC_ECC_ROW_OFFSET 8 > +#define SDRAM_ERR_CALC_ECC_ROW_MASK \ > + (0xffff << SDRAM_ERR_CALC_ECC_ROW_OFFSET) > +#define SDRAM_ERR_CALC_ECC_VALUE_MASK 0xff > + > +#define SDRAM_ERR_ADDR_REG 0x50 > +#define SDRAM_ERR_ADDR_BANK_OFFSET 23 > +#define SDRAM_ERR_ADDR_BANK_MASK \ > + (0x7 << SDRAM_ERR_ADDR_BANK_OFFSET) > +#define SDRAM_ERR_ADDR_COL_OFFSET 8 > +#define SDRAM_ERR_ADDR_COL_MASK \ > + (0x7fff << SDRAM_ERR_ADDR_COL_OFFSET) > +#define SDRAM_ERR_ADDR_CS_OFFSET 1 > +#define SDRAM_ERR_ADDR_CS_MASK \ > + (0x3 << SDRAM_ERR_ADDR_CS_OFFSET) > +#define SDRAM_ERR_ADDR_TYPE_MASK BIT(0) > + > +#define SDRAM_ERR_CTRL_REG 0x54 > +#define SDRAM_ERR_CTRL_ERR_THR_OFFSET 16 > +#define SDRAM_ERR_CTRL_ERR_THR_MASK \ > + (0xff << SDRAM_ERR_CTRL_ERR_THR_OFFSET) > +#define SDRAM_ERR_CTRL_ERR_PROP_MASK BIT(9) > + > +#define SDRAM_ERR_SBE_COUNT_REG 0x58 > +#define SDRAM_ERR_DBE_COUNT_REG 0x5c > + > +#define SDRAM_ERR_CAUSE_ERR_REG 0xd0 > +#define SDRAM_ERR_CAUSE_MSG_REG 0xd8 > +#define SDRAM_ERR_CAUSE_DBE_MASK BIT(1) > +#define SDRAM_ERR_CAUSE_SBE_MASK BIT(0) > + > +#define SDRAM_RANK_CTRL_REG 0x1e0 > +#define SDRAM_RANK_CTRL_EXIST_MASK(cs) BIT(cs) > + > +struct armada_xp_mc_edac_drvdata { > + void __iomem *base; > + > + unsigned int width; /* width in bytes */ > + bool cs_addr_sel[SDRAM_NUM_CS]; /* bank interleaving */ > + > + char msg[128]; > +}; > + > +/* derived from "DRAM Address Multiplexing" in the ARAMDA XP Functional Spec */ > +static uint32_t armada_xp_mc_edac_calc_address(struct armada_xp_mc_edac_drvdata > + *drvdata, uint8_t cs, > + uint8_t bank, uint16_t row, > + uint16_t col) > +{ > + if (drvdata->width == 4) { /* 64 bit */ > + if (drvdata->cs_addr_sel[cs]) /* bank interleaved */ > + return (((row & 0xfff8) << 16) | > + ((bank & 0x7) << 16) | > + ((row & 0x7) << 13) | > + ((col & 0x3ff) << 3)); > + else > + return (((row & 0xffff << 16) | > + ((bank & 0x7) << 13) | > + ((col & 0x3ff)) << 3)); > + } else if (drvdata->width == 2) { /* 32 bit */ > + if (drvdata->cs_addr_sel[cs]) /* bank interleaved */ > + return (((row & 0xfff0) << 15) | > + ((bank & 0x7) << 16) | > + ((row & 0xf) << 12) | > + ((col & 0x3ff) << 2)); > + else > + return (((row & 0xffff << 15) | > + ((bank & 0x7) << 12) | > + ((col & 0x3ff)) << 2)); > + } else { /* 16 bit */ > + if (drvdata->cs_addr_sel[cs]) /* bank interleaved */ > + return (((row & 0xffe0) << 14) | > + ((bank & 0x7) << 16) | > + ((row & 0x1f) << 11) | > + ((col & 0x3ff) << 1)); > + else > + return (((row & 0xffff << 14) | > + ((bank & 0x7) << 11) | > + ((col & 0x3ff)) << 1)); > + } > +} > + > +static void armada_xp_mc_edac_check(struct mem_ctl_info *mci) > +{ > + struct armada_xp_mc_edac_drvdata *drvdata = mci->pvt_info; > + uint32_t data_h, data_l, recv_ecc, calc_ecc, addr; > + uint32_t cnt_sbe, cnt_dbe, cause_err, cause_msg; > + uint32_t row_val, col_val, bank_val, addr_val; > + uint8_t syndrome_val, cs_val; > + char *msg = drvdata->msg; > + > + data_h = readl(drvdata->base + SDRAM_ERR_DATA_H_REG); > + data_l = readl(drvdata->base + SDRAM_ERR_DATA_L_REG); > + recv_ecc = readl(drvdata->base + SDRAM_ERR_RECV_ECC_REG); > + calc_ecc = readl(drvdata->base + SDRAM_ERR_CALC_ECC_REG); > + addr = readl(drvdata->base + SDRAM_ERR_ADDR_REG); > + cnt_sbe = readl(drvdata->base + SDRAM_ERR_SBE_COUNT_REG); > + cnt_dbe = readl(drvdata->base + SDRAM_ERR_DBE_COUNT_REG); > + cause_err = readl(drvdata->base + SDRAM_ERR_CAUSE_ERR_REG); > + cause_msg = readl(drvdata->base + SDRAM_ERR_CAUSE_MSG_REG); > + > + /* clear cause registers */ > + writel(~(SDRAM_ERR_CAUSE_DBE_MASK | SDRAM_ERR_CAUSE_SBE_MASK), > + drvdata->base + SDRAM_ERR_CAUSE_ERR_REG); > + writel(~(SDRAM_ERR_CAUSE_DBE_MASK | SDRAM_ERR_CAUSE_SBE_MASK), > + drvdata->base + SDRAM_ERR_CAUSE_MSG_REG); > + > + /* clear error counter registers */ > + if (cnt_sbe) > + writel(0, drvdata->base + SDRAM_ERR_SBE_COUNT_REG); > + if (cnt_dbe) > + writel(0, drvdata->base + SDRAM_ERR_DBE_COUNT_REG); > + > + if (!cnt_sbe && !cnt_dbe) > + return; > + > + if ((addr & SDRAM_ERR_ADDR_TYPE_MASK) == 0) { > + if (cnt_sbe) > + cnt_sbe--; > + else > + dev_warn(mci->pdev, "inconsistent SBE count detected"); > + } else { > + if (cnt_dbe) > + cnt_dbe--; > + else > + dev_warn(mci->pdev, "inconsistent DBE count detected"); > + } > + > + /* report earlier errors */ > + if (cnt_sbe) > + edac_mc_handle_error(HW_EVENT_ERR_CORRECTED, mci, > + cnt_sbe, /* error count */ > + 0, 0, 0, /* pfn, offset, syndrome */ > + -1, -1, -1, /* top, mid, low layer */ > + mci->ctl_name, > + "details unavailable (multiple errors)"); > + if (cnt_dbe) > + edac_mc_handle_error(HW_EVENT_ERR_UNCORRECTED, mci, > + cnt_sbe, /* error count */ > + 0, 0, 0, /* pfn, offset, syndrome */ > + -1, -1, -1, /* top, mid, low layer */ > + mci->ctl_name, > + "details unavailable (multiple errors)"); > + > + /* report details for most recent error */ > + cs_val = (addr & SDRAM_ERR_ADDR_CS_MASK) > + >> SDRAM_ERR_ADDR_CS_OFFSET; > + bank_val = (addr & SDRAM_ERR_ADDR_BANK_MASK) > + >> SDRAM_ERR_ADDR_BANK_OFFSET; > + row_val = (calc_ecc & SDRAM_ERR_CALC_ECC_ROW_MASK) > + >> SDRAM_ERR_CALC_ECC_ROW_OFFSET; > + col_val = (addr & SDRAM_ERR_ADDR_COL_MASK) > + >> SDRAM_ERR_ADDR_COL_OFFSET; > + syndrome_val = (recv_ecc ^ calc_ecc) & 0xff; > + addr_val = armada_xp_mc_edac_calc_address(drvdata, cs_val, bank_val, > + row_val, col_val); > + msg += sprintf(msg, "row=0x%04x ", row_val); /* 11 chars */ > + msg += sprintf(msg, "bank=0x%x ", bank_val); /* 9 chars */ > + msg += sprintf(msg, "col=0x%04x ", col_val); /* 11 chars */ > + msg += sprintf(msg, "cs=%d", cs_val); /* 4 chars */ > + > + if ((addr & SDRAM_ERR_ADDR_TYPE_MASK) == 0) { > + edac_mc_handle_error(HW_EVENT_ERR_CORRECTED, mci, > + 1, /* error count */ > + addr_val >> PAGE_SHIFT, > + addr_val & ~PAGE_MASK, > + syndrome_val, > + cs_val, -1, -1, /* top, mid, low layer */ > + mci->ctl_name, drvdata->msg); > + } else { > + edac_mc_handle_error(HW_EVENT_ERR_UNCORRECTED, mci, > + 1, /* error count */ > + addr_val >> PAGE_SHIFT, > + addr_val & ~PAGE_MASK, > + syndrome_val, > + cs_val, -1, -1, /* top, mid, low layer */ > + mci->ctl_name, drvdata->msg); > + } > +} > + > +static int armada_xp_mc_edac_read_config(struct mem_ctl_info *mci) > +{ > + struct armada_xp_mc_edac_drvdata *drvdata = mci->pvt_info; > + struct dimm_info *dimm; > + unsigned int i, cs_struct, cs_size; > + uint32_t config, addr_ctrl, rank_ctrl; > + > + config = readl(drvdata->base + SDRAM_CONFIG_REG); > + if (!(config & SDRAM_CONFIG_ECC_MASK)) > + dev_warn(mci->pdev, "SDRAM ECC is not enabled"); > + > + if (mci->tot_dimms != SDRAM_NUM_CS) { > + dev_err(mci->pdev, "Invaild number of DIMMs"); > + return -EINVAL; > + } > + > + if (config & SDRAM_CONFIG_BUS_WIDTH_MASK) > + drvdata->width = 4; /* 64 bit */ > + else > + drvdata->width = 2; /* 32 bit */ > + > + addr_ctrl = readl(drvdata->base + SDRAM_ADDR_CTRL_REG); > + rank_ctrl = readl(drvdata->base + SDRAM_RANK_CTRL_REG); > + for (i = 0; i < SDRAM_NUM_CS; i++) { > + dimm = mci->dimms[i]; > + > + if (!(rank_ctrl & SDRAM_RANK_CTRL_EXIST_MASK(i))) > + continue; > + > + drvdata->cs_addr_sel[i] = > + !!(addr_ctrl & SDRAM_ADDR_CTRL_ADDR_SEL_MASK(i)); > + > + cs_struct = (addr_ctrl & SDRAM_ADDR_CTRL_STRUCT_MASK(i)) >> > + SDRAM_ADDR_CTRL_STRUCT_OFFSET(i); > + cs_size = ((addr_ctrl & SDRAM_ADDR_CTRL_SIZE_HIGH_MASK(i)) >> > + (SDRAM_ADDR_CTRL_SIZE_HIGH_OFFSET(i) - 2) | > + ((addr_ctrl & SDRAM_ADDR_CTRL_SIZE_LOW_MASK(i)) >> > + SDRAM_ADDR_CTRL_SIZE_LOW_OFFSET(i))); > + switch (cs_size) { > + case 0: /* 2GBit */ > + dimm->nr_pages = (0x80000000ULL >> PAGE_SHIFT); > + break; > + case 1: /* 256MBit */ > + dimm->nr_pages = (0x10000000ULL >> PAGE_SHIFT); > + break; > + case 2: /* 512MBit */ > + dimm->nr_pages = (0x20000000ULL >> PAGE_SHIFT); > + break; > + case 3: /* 1GBit */ > + dimm->nr_pages = (0x40000000ULL >> PAGE_SHIFT); > + break; > + case 4: /* 4GBit */ > + dimm->nr_pages = (0x100000000ULL >> PAGE_SHIFT); > + break; > + case 5: /* 8GBit */ > + dimm->nr_pages = (0x200000000ULL >> PAGE_SHIFT); > + break; > + } > + dimm->grain = 8; > + dimm->dtype = cs_struct ? DEV_X16 : DEV_X8; > + dimm->mtype = (config & SDRAM_CONFIG_REGISTERED_MASK) ? > + MEM_RDDR3 : MEM_DDR3; > + dimm->edac_mode = EDAC_SECDED; > + } > + > + return 0; > +} > + > +static const struct of_device_id armada_xp_mc_edac_of_match[] = { > + {.compatible = "marvell,armada-xp-sdram-controller",}, > + {}, > +}; > +MODULE_DEVICE_TABLE(of, armada_xp_mc_edac_of_match); > + > +static int armada_xp_mc_edac_probe(struct platform_device *pdev) > +{ > + const struct of_device_id *id; > + struct mem_ctl_info *mci; > + struct edac_mc_layer layers[1]; > + struct armada_xp_mc_edac_drvdata *drvdata; > + struct resource *r; > + > + layers[0].type = EDAC_MC_LAYER_CHIP_SELECT; > + layers[0].size = SDRAM_NUM_CS; > + layers[0].is_virt_csrow = true; > + > + mci = devm_edac_mc_alloc(&pdev->dev, 0, ARRAY_SIZE(layers), layers, > + sizeof(*drvdata)); > + if (!mci) > + return -ENOMEM; > + > + drvdata = mci->pvt_info; > + mci->pdev = &pdev->dev; > + platform_set_drvdata(pdev, mci); > + > + r = platform_get_resource(pdev, IORESOURCE_MEM, 0); > + if (!r) { > + dev_err(&pdev->dev, "Unable to get mem resource\n"); > + return -ENODEV; > + } > + > + drvdata->base = devm_ioremap_resource(&pdev->dev, r); > + if (IS_ERR(drvdata->base)) { > + dev_err(&pdev->dev, "Unable to map regs\n"); > + return PTR_ERR(drvdata->base); > + } > + > + id = of_match_device(armada_xp_mc_edac_of_match, &pdev->dev); > + mci->edac_check = armada_xp_mc_edac_check; > + mci->mtype_cap = MEM_FLAG_DDR3; > + mci->edac_cap = EDAC_FLAG_SECDED; > + mci->mod_name = pdev->dev.driver->name; > + mci->ctl_name = id ? id->compatible : "unknown"; > + mci->dev_name = dev_name(&pdev->dev); > + mci->scrub_mode = SCRUB_NONE; > + > + if (armada_xp_mc_edac_read_config(mci)) > + return -EINVAL; > + > + /* configure SBE threshold */ > + /* it seems that SBEs are not captured otherwise */ > + writel(1 << SDRAM_ERR_CTRL_ERR_THR_OFFSET, > + drvdata->base + SDRAM_ERR_CTRL_REG); > + > + /* clear cause registers */ > + writel(~(SDRAM_ERR_CAUSE_DBE_MASK | SDRAM_ERR_CAUSE_SBE_MASK), > + drvdata->base + SDRAM_ERR_CAUSE_ERR_REG); > + writel(~(SDRAM_ERR_CAUSE_DBE_MASK | SDRAM_ERR_CAUSE_SBE_MASK), > + drvdata->base + SDRAM_ERR_CAUSE_MSG_REG); > + > + /* clear counter registers */ > + writel(0, drvdata->base + SDRAM_ERR_SBE_COUNT_REG); > + writel(0, drvdata->base + SDRAM_ERR_DBE_COUNT_REG); > + > + if (devm_edac_mc_add_mc(&pdev->dev, mci)) > + return -EINVAL; > + edac_op_state = EDAC_OPSTATE_POLL; > + > + return 0; > +} > + > +static struct platform_driver armada_xp_mc_edac_driver = { > + .probe = armada_xp_mc_edac_probe, > + .driver = { > + .name = "armada_xp_mc_edac", > + .of_match_table = of_match_ptr(armada_xp_mc_edac_of_match), > + }, > +}; > + > +/************************ EDAC Device (L2 Cache) ***************************/ > + > +struct aurora_l2_edac_drvdata { > + void __iomem *base; > + > + char msg[128]; > + > + /* error injection via debugfs */ > + uint32_t inject_addr; > + uint32_t inject_mask; > + uint8_t inject_ctl; > + > + struct dentry *debugfs; > +}; > + > +static void aurora_l2_edac_inject(struct aurora_l2_edac_drvdata *drvdata) > +{ > + drvdata->inject_addr &= AURORA_ERR_INJECT_CTL_ADDR_MASK; > + drvdata->inject_ctl &= AURORA_ERR_INJECT_CTL_EN_MASK; > + writel(0, drvdata->base + AURORA_ERR_INJECT_CTL_REG); > + writel(drvdata->inject_mask, > + drvdata->base + AURORA_ERR_INJECT_MASK_REG); > + writel(drvdata->inject_addr | drvdata->inject_ctl, > + drvdata->base + AURORA_ERR_INJECT_CTL_REG); > +} > + > +static void aurora_l2_edac_check(struct edac_device_ctl_info *dci) > +{ > + struct aurora_l2_edac_drvdata *drvdata = dci->pvt_info; > + uint32_t cnt, attr_cap, addr_cap, way_cap; > + unsigned int cnt_ce, cnt_ue; > + > + cnt = readl(drvdata->base + AURORA_ERR_CNT_REG); > + attr_cap = readl(drvdata->base + AURORA_ERR_ATTR_CAP_REG); > + addr_cap = readl(drvdata->base + AURORA_ERR_ADDR_CAP_REG); > + way_cap = readl(drvdata->base + AURORA_ERR_WAY_CAP_REG); > + > + cnt_ce = (cnt & AURORA_ERR_CNT_CE_MASK) >> AURORA_ERR_CNT_CE_OFFSET; > + cnt_ue = (cnt & AURORA_ERR_CNT_UE_MASK) >> AURORA_ERR_CNT_UE_OFFSET; > + /* clear error counter registers */ > + if (cnt_ce || cnt_ue) > + writel(AURORA_ERR_CNT_CLR, drvdata->base + AURORA_ERR_CNT_REG); > + > + if (attr_cap & AURORA_ERR_ATTR_CAP_VALID) { > + char *msg = drvdata->msg; > + size_t size = sizeof(drvdata->msg); > + size_t len = 0; > + > + switch ((attr_cap & AURORA_ERR_ATTR_CAP_ERR_SOURCE_MASK) > + >> AURORA_ERR_ATTR_CAP_ERR_SOURCE_OFFSET) { > + case 0: > + len += snprintf(msg+len, size-len, "src=CPU0 "); > + break; > + case 1: > + len += snprintf(msg+len, size-len, "src=CPU1 "); > + break; > + case 2: > + len += snprintf(msg+len, size-len, "src=CPU2 "); > + break; > + case 3: > + len += snprintf(msg+len, size-len, "src=CPU3 "); > + break; > + case 7: > + len += snprintf(msg+len, size-len, "src=IO "); > + break; > + } > + switch ((attr_cap & AURORA_ERR_ATTR_CAP_TRANS_TYPE_MASK) > + >> AURORA_ERR_ATTR_CAP_TRANS_TYPE_OFFSET) { > + case 0: > + len += snprintf(msg+len, size-len, "txn=Data-Read "); > + break; > + case 1: > + len += snprintf(msg+len, size-len, "txn=Isn-Read "); > + break; > + case 2: > + len += snprintf(msg+len, size-len, "txn=Clean-Flush "); > + break; > + case 3: > + len += snprintf(msg+len, size-len, "txn=Eviction "); > + break; > + case 4: > + len += snprintf(msg+len, size-len, > + "txn=Read-Modify-Write "); > + break; > + } > + switch ((attr_cap & AURORA_ERR_ATTR_CAP_ERR_TYPE_MASK) > + >> AURORA_ERR_ATTR_CAP_ERR_TYPE_OFFSET) { > + case 0: > + len += snprintf(msg+len, size-len, "err=CorrECC "); > + break; > + case 1: > + len += snprintf(msg+len, size-len, "err=UnCorrECC "); > + break; > + case 2: > + len += snprintf(msg+len, size-len, "err=TagParity "); > + break; > + } > + len += snprintf(msg+len, size-len, "addr=0x%x ", > + addr_cap & AURORA_ERR_ADDR_CAP_ADDR_MASK); > + len += snprintf(msg+len, size-len, "index=0x%x ", > + (way_cap & AURORA_ERR_WAY_CAP_INDEX_MASK) > + >> AURORA_ERR_WAY_CAP_INDEX_OFFSET); > + len += snprintf(msg+len, size-len, "way=0x%x", > + (way_cap & AURORA_ERR_WAY_CAP_WAY_MASK) > + >> AURORA_ERR_WAY_CAP_WAY_OFFSET); > + /* clear error capture registers */ > + writel(AURORA_ERR_ATTR_CAP_VALID, > + drvdata->base + AURORA_ERR_ATTR_CAP_REG); > + if ((attr_cap & AURORA_ERR_ATTR_CAP_ERR_TYPE_MASK) > + >> AURORA_ERR_ATTR_CAP_ERR_TYPE_OFFSET) { > + /* UnCorrECC or TagParity */ > + if (cnt_ue) > + cnt_ue--; > + edac_device_handle_ue(dci, 0, 0, drvdata->msg); > + } else { > + if (cnt_ce) > + cnt_ce--; > + edac_device_handle_ce(dci, 0, 0, drvdata->msg); > + } > + } > + > + /* report remaining errors */ > + while (cnt_ue--) > + edac_device_handle_ue(dci, 0, 0, > + "details unavailable (multiple errors)"); > + while (cnt_ce--) > + edac_device_handle_ue(dci, 0, 0, > + "details unavailable (multiple errors)"); > +} > + > +static void aurora_l2_edac_poll(struct edac_device_ctl_info *dci) > +{ > + struct aurora_l2_edac_drvdata *drvdata = dci->pvt_info; > + > + aurora_l2_edac_check(dci); > + aurora_l2_edac_inject(drvdata); > +} > + > +static const struct of_device_id aurora_l2_edac_of_match[] = { > + {.compatible = "marvell,aurora-system-cache",}, > + {}, > +}; > +MODULE_DEVICE_TABLE(of, aurora_l2_edac_of_match); > + > +static int aurora_l2_edac_probe(struct platform_device *pdev) > +{ > + const struct of_device_id *id; > + struct edac_device_ctl_info *dci; > + struct aurora_l2_edac_drvdata *drvdata; > + struct resource *r; > + uint32_t l2x0_aux_ctrl; > + > + dci = devm_edac_device_alloc_ctl_info(&pdev->dev, sizeof(*drvdata), > + "cpu", 1, "L", 1, 2, NULL, 0, 0); > + if (!dci) > + return -ENOMEM; > + > + drvdata = dci->pvt_info; > + dci->dev = &pdev->dev; > + platform_set_drvdata(pdev, dci); > + > + r = platform_get_resource(pdev, IORESOURCE_MEM, 0); > + if (!r) { > + dev_err(&pdev->dev, "Unable to get mem resource\n"); > + return -ENODEV; > + } > + > + drvdata->base = devm_ioremap_resource(&pdev->dev, r); > + if (IS_ERR(drvdata->base)) { > + dev_err(&pdev->dev, "Unable to map regs\n"); > + return PTR_ERR(drvdata->base); > + } > + > + l2x0_aux_ctrl = readl(drvdata->base + L2X0_AUX_CTRL); > + if (!(l2x0_aux_ctrl & AURORA_ACR_PARITY_EN)) > + dev_warn(&pdev->dev, "tag parity is not enabled"); > + if (!(l2x0_aux_ctrl & AURORA_ACR_ECC_EN)) > + dev_warn(&pdev->dev, "data ECC is not enabled"); > + > + id = of_match_device(aurora_l2_edac_of_match, &pdev->dev); > + dci->edac_check = aurora_l2_edac_poll; > + dci->mod_name = pdev->dev.driver->name; > + dci->ctl_name = id ? id->compatible : "unknown"; > + dci->dev_name = dev_name(&pdev->dev); > + > + /* clear registers */ > + writel(AURORA_ERR_CNT_CLR, drvdata->base + AURORA_ERR_CNT_REG); > + writel(AURORA_ERR_ATTR_CAP_VALID, > + drvdata->base + AURORA_ERR_ATTR_CAP_REG); > + > + if (devm_edac_device_add_device(&pdev->dev, dci)) > + return -EINVAL; > + > + drvdata->debugfs = edac_debugfs_create_dir(dev_name(&pdev->dev)); > + if (drvdata->debugfs) { > + edac_debugfs_create_x32("inject_addr", 0644, > + drvdata->debugfs, > + &drvdata->inject_addr); > + edac_debugfs_create_x32("inject_mask", 0644, > + drvdata->debugfs, > + &drvdata->inject_mask); > + edac_debugfs_create_x8("inject_ctl", 0644, > + drvdata->debugfs, &drvdata->inject_ctl); > + } > + > + return 0; > +} > + > +static int aurora_l2_edac_remove(struct platform_device *pdev) > +{ > + struct edac_device_ctl_info *dci = platform_get_drvdata(pdev); > + struct aurora_l2_edac_drvdata *drvdata = dci->pvt_info; > + > + edac_debugfs_remove_recursive(drvdata->debugfs); > + return 0; > +} > + > +static struct platform_driver aurora_l2_edac_driver = { > + .probe = aurora_l2_edac_probe, > + .remove = aurora_l2_edac_remove, > + .driver = { > + .name = "aurora_l2_edac", > + .of_match_table = of_match_ptr(aurora_l2_edac_of_match), > + }, > +}; > + > +/************************ Driver registration ******************************/ > + > +static struct platform_driver * const drivers[] = { > + &armada_xp_mc_edac_driver, > + &aurora_l2_edac_driver, > +}; > + > +static int __init armada_xp_edac_init(void) > +{ > + int res = 0; > + > + /* only polling is supported */ > + edac_op_state = EDAC_OPSTATE_POLL; > + > + res = platform_register_drivers(drivers, ARRAY_SIZE(drivers)); > + if (res) > + pr_warn("Aramda XP EDAC drivers fail to register\n"); > + > + return 0; > +} > +module_init(armada_xp_edac_init); > + > +static void __exit armada_xp_edac_exit(void) > +{ > + platform_unregister_drivers(drivers, ARRAY_SIZE(drivers)); > +} > +module_exit(armada_xp_edac_exit); > + > +MODULE_LICENSE("GPL v2"); > +MODULE_AUTHOR("Pengutronix"); > +MODULE_DESCRIPTION("EDAC Drivers for Marvell Armada XP SDRAM and L2 Cache Controller"); > -- > 2.11.0 > -- Gregory Clement, Free Electrons Kernel, drivers, real-time and embedded Linux development, consulting, training and support. http://free-electrons.com