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: [v1] EDAC, armv8: Add Cache Error Reporting driver for ARMv8 processors From: Kyle Yan Message-Id: <1515804626-21254-1-git-send-email-kyan@codeaurora.org> Date: Fri, 12 Jan 2018 16:50:26 -0800 To: bp@alien8.de, mchehab@kernel.org Cc: linux-arm-kernel@lists.infradead.org, linux-edac@vger.kernel.org, Kyle Yan List-ID: SW50ZXJydXB0IGJhc2VkIEVEQUMgZHJpdmVyIGZvciBBUk12OCBwcm9jZXNzb3JzIHRoYXQgaW1w bGVtZW50ClJBUyBmb3IgZXJyb3IgZGV0ZWN0aW9uIG9mIENQVSBjYWNoZXMgYW5kIGxzbyBhbGxv d3Mgb3B0aW9uYWwgcG9sbGluZwpvZiBlcnJvciBzeW5kcm9tZSByZWdpc3RlcnMgaWYgaW50ZXJy dXB0cyBhcmUgbm90IHN1cHBvcnRlZC4KClNpZ25lZC1vZmYtYnk6IEt5bGUgWWFuIDxreWFuQGNv ZGVhdXJvcmEub3JnPgotLS0KIGRyaXZlcnMvZWRhYy9LY29uZmlnICAgICAgfCAgMjEgKysKIGRy aXZlcnMvZWRhYy9NYWtlZmlsZSAgICAgfCAgIDEgKwogZHJpdmVycy9lZGFjL2FybXY4X2VkYWMu YyB8IDQ4OSArKysrKysrKysrKysrKysrKysrKysrKysrKysrKysrKysrKysrKysrKysrKysrCiAz IGZpbGVzIGNoYW5nZWQsIDUxMSBpbnNlcnRpb25zKCspCiBjcmVhdGUgbW9kZSAxMDA2NDQgZHJp dmVycy9lZGFjL2FybXY4X2VkYWMuYwoKZGlmZiAtLWdpdCBhL2RyaXZlcnMvZWRhYy9LY29uZmln IGIvZHJpdmVycy9lZGFjL0tjb25maWcKaW5kZXggOTZhZmIyYS4uNDdhNjhlMyAxMDA2NDQKLS0t IGEvZHJpdmVycy9lZGFjL0tjb25maWcKKysrIGIvZHJpdmVycy9lZGFjL0tjb25maWcKQEAgLTQ1 Nyw0ICs0NTcsMjUgQEAgY29uZmlnIEVEQUNfWEdFTkUKIAkgIFN1cHBvcnQgZm9yIGVycm9yIGRl dGVjdGlvbiBhbmQgY29ycmVjdGlvbiBvbiB0aGUKIAkgIEFQTSBYLUdlbmUgZmFtaWx5IG9mIFNP Q3MuCiAKK2NvbmZpZyBFREFDX0FSTVY4CisJZGVwZW5kcyBvbiAoQVJNIHx8IEFSTTY0KQorCXRy aXN0YXRlICJBUk12OCBMMS9MMi9MMy9TQ1UgQ2FjaGVzIEVDQyIKKwloZWxwCisJICAgU3VwcG9y dCBmb3IgZXJyb3IgZGV0ZWN0aW9uIGFuZCBjb3JyZWN0aW9uIG9uIEFSTXY4IGNvcmVzCisJICAg c3VwcG9ydGluZyBSQVMgZmVhdHVyZXMuIFJlcG9ydHMgZXJyb3JzIGNhdWdodCBieSBBUk12OAor CSAgIEVDQyBtZWNoYW5pc20uCisJICAgRm9yIGRlYnVnZ2luZyBpc3N1ZXMgaGF2aW5nIHRvIGRv IHdpdGggc3RhYmlsaXR5IGFuZCBvdmVyYWxsIHN5c3RlbQorCSAgIGhlYWx0aCwgeW91IHNob3Vs ZCBwcm9iYWJseSBzYXkgJ1knIGhlcmUuCisKK2NvbmZpZyBFREFDX0FSTVY4X1BPTEwKKwlkZXBl bmRzIG9uIEVEQUNfQVJNVjgKKwlib29sICJQb2xsIG9uIEFSTXY4IEVDQyByZWdpc3RlcnMiCisJ aGVscAorCSAgIFRoaXMgb3B0aW9uIGNob29zZXMgd2hldGhlciBvciBub3QgeW91IHdhbnQgdG8g cG9sbCBvbiB0aGUgS3J5bzN4eAorCSAgIEVDQyByZWdpc3RlcnMuIFdoZW4gdGhpcyBpcyBlbmFi bGVkLCB0aGUgcG9sbGluZyByYXRlIGNhbiBiZSBzZXQgYXMKKwkgICBhIG1vZHVsZSBwYXJhbWV0 ZXIuIEJ5IGRlZmF1bHQsIGl0IHdpbGwgY2FsbCB0aGUgcG9sbGluZyBmdW5jdGlvbgorCSAgIGV2 ZXJ5IHNlY29uZC4KKwkgICBUaGlzIG9wdGlvbiBzaG91bGQgb25seSBiZSB1c2VkIGlmIHRoZSBh c3NvY2lhdGVkIGludGVycnVwdCBsaW5lcworCSAgIGFyZSBub3QgZW5hYmxlZC4KKwogZW5kaWYg IyBFREFDCmRpZmYgLS1naXQgYS9kcml2ZXJzL2VkYWMvTWFrZWZpbGUgYi9kcml2ZXJzL2VkYWMv TWFrZWZpbGUKaW5kZXggMGZkOWZmYS4uNTcxMTNiYSAxMDA2NDQKLS0tIGEvZHJpdmVycy9lZGFj L01ha2VmaWxlCisrKyBiL2RyaXZlcnMvZWRhYy9NYWtlZmlsZQpAQCAtNDMsNiArNDMsNyBAQCBv YmotJChDT05GSUdfRURBQ19JRTMxMjAwKQkJKz0gaWUzMTIwMF9lZGFjLm8KIG9iai0kKENPTkZJ R19FREFDX1gzOCkJCQkrPSB4MzhfZWRhYy5vCiBvYmotJChDT05GSUdfRURBQ19JODI4NjApCQkr PSBpODI4NjBfZWRhYy5vCiBvYmotJChDT05GSUdfRURBQ19SODI2MDApCQkrPSByODI2MDBfZWRh Yy5vCitvYmotJChDT05GSUdfRURBQ19BUk1WOCkJCSs9IGFybXY4X2VkYWMubwogCiBhbWQ2NF9l ZGFjX21vZC15IDo9IGFtZDY0X2VkYWMubwogYW1kNjRfZWRhY19tb2QtJChDT05GSUdfRURBQ19E RUJVRykgKz0gYW1kNjRfZWRhY19kYmcubwpkaWZmIC0tZ2l0IGEvZHJpdmVycy9lZGFjL2FybXY4 X2VkYWMuYyBiL2RyaXZlcnMvZWRhYy9hcm12OF9lZGFjLmMKbmV3IGZpbGUgbW9kZSAxMDA2NDQK aW5kZXggMDAwMDAwMC4uZDk4NmM0NwotLS0gL2Rldi9udWxsCisrKyBiL2RyaXZlcnMvZWRhYy9h cm12OF9lZGFjLmMKQEAgLTAsMCArMSw0ODkgQEAKKy8qIENvcHlyaWdodCAoYykgMjAxNi0yMDE4 LCBUaGUgTGludXggRm91bmRhdGlvbi4gQWxsIHJpZ2h0cyByZXNlcnZlZC4KKyAqCisgKiBUaGlz IHByb2dyYW0gaXMgZnJlZSBzb2Z0d2FyZTsgeW91IGNhbiByZWRpc3RyaWJ1dGUgaXQgYW5kL29y IG1vZGlmeQorICogaXQgdW5kZXIgdGhlIHRlcm1zIG9mIHRoZSBHTlUgR2VuZXJhbCBQdWJsaWMg TGljZW5zZSB2ZXJzaW9uIDIgYW5kCisgKiBvbmx5IHZlcnNpb24gMiBhcyBwdWJsaXNoZWQgYnkg dGhlIEZyZWUgU29mdHdhcmUgRm91bmRhdGlvbi4KKyAqCisgKiBUaGlzIHByb2dyYW0gaXMgZGlz dHJpYnV0ZWQgaW4gdGhlIGhvcGUgdGhhdCBpdCB3aWxsIGJlIHVzZWZ1bCwKKyAqIGJ1dCBXSVRI T1VUIEFOWSBXQVJSQU5UWTsgd2l0aG91dCBldmVuIHRoZSBpbXBsaWVkIHdhcnJhbnR5IG9mCisg KiBNRVJDSEFOVEFCSUxJVFkgb3IgRklUTkVTUyBGT1IgQSBQQVJUSUNVTEFSIFBVUlBPU0UuICBT ZWUgdGhlCisgKiBHTlUgR2VuZXJhbCBQdWJsaWMgTGljZW5zZSBmb3IgbW9yZSBkZXRhaWxzLgor ICovCisKKyNpbmNsdWRlIDxsaW51eC9rZXJuZWwuaD4KKyNpbmNsdWRlIDxsaW51eC9lZGFjLmg+ CisjaW5jbHVkZSA8bGludXgvb2ZfZGV2aWNlLmg+CisjaW5jbHVkZSA8bGludXgvcGxhdGZvcm1f ZGV2aWNlLmg+CisjaW5jbHVkZSA8bGludXgvc21wLmg+CisjaW5jbHVkZSA8bGludXgvY3B1Lmg+ CisjaW5jbHVkZSA8bGludXgvY3B1X3BtLmg+CisjaW5jbHVkZSA8bGludXgvaW50ZXJydXB0Lmg+ CisjaW5jbHVkZSA8bGludXgvb2ZfaXJxLmg+CisKKyNpbmNsdWRlICJlZGFjX21jLmgiCisjaW5j bHVkZSAiZWRhY19kZXZpY2UuaCIKKworc3RhdGljIGludCBwb2xsX21zZWMgPSAxMDAwOworbW9k dWxlX3BhcmFtKHBvbGxfbXNlYywgaW50LCAwNDQ0KTsKKworc3RhdGljIGJvb2wgcGFuaWNfb25f dWUgPSAwOworbW9kdWxlX3BhcmFtX25hbWVkKHBhbmljX29uX3VlLCBwYW5pY19vbl91ZSwgYm9v bCwgMDY2NCk7CisKKyNkZWZpbmUgTDEgMHgwCisjZGVmaW5lIEwyIDB4MQorI2RlZmluZSBMMyAw eDIKKworI2RlZmluZSBFREFDX0NQVQkiYXJtdjhfZWRhYyIKKworI2RlZmluZSBFUlJYU1RBVFVT X1ZBTElEKGEpCSgoYSA+PiAzMCkgJiAweDEpCisjZGVmaW5lIEVSUlhTVEFUVVNfVUUoYSkJKChh ID4+IDI5KSAmIDB4MSkKKyNkZWZpbmUgRVJSWFNUQVRVU19TRVJSKGEpCShhICYgMHhGRikKKwor I2RlZmluZSBFUlJYTUlTQ19MVkwoYSkJCSgoYSA+PiAxKSAmIDB4NykKKyNkZWZpbmUgRVJSWE1J U0NfV0FZKGEpCQkoKGEgPj4gMjgpICYgMHhGKQorCisjZGVmaW5lIEVSUlhDVExSX0VOQUJMRQkJ MHgxMGYKKyNkZWZpbmUgRVJSWE1JU0NfT1ZFUkZMT1cJMHg3RjdGMDAwMDAwMDBVTEwKKworc3Rh dGljIGlubGluZSB2b2lkIHNldF9lcnJ4Y3Rscl9lbDEodm9pZCkKK3sKKwlhc20gdm9sYXRpbGUo Im1zciBzM18wX2M1X2M0XzEsICUwIiA6IDogInIiIChFUlJYQ1RMUl9FTkFCTEUpKTsKK30KKwor c3RhdGljIGlubGluZSB2b2lkIHNldF9lcnJ4bWlzY19vdmVyZmxvdyh2b2lkKQoreworCWFzbSB2 b2xhdGlsZSgibXNyIHMzXzBfYzVfYzVfMCwgJTAiIDogOiAiciIgKEVSUlhNSVNDX09WRVJGTE9X KSk7Cit9CisKK3N0YXRpYyBpbmxpbmUgdm9pZCB3cml0ZV9lcnJzZWxyX2VsMSh1NjQgdmFsKQor eworCWFzbSB2b2xhdGlsZSgibXNyIHMzXzBfYzVfYzNfMSwgJTAiIDogOiAiciIgKHZhbCkpOwor fQorCitzdGF0aWMgaW5saW5lIHU2NCByZWFkX2VycnhzdGF0dXNfZWwxKHZvaWQpCit7CisJdTY0 IHZhbDsKKworCWFzbSB2b2xhdGlsZSgibXJzICUwLCBzM18wX2M1X2M0XzIiIDogIj1yIiAodmFs KSk7CisJcmV0dXJuIHZhbDsKK30KKworc3RhdGljIGlubGluZSB1NjQgcmVhZF9lcnJ4bWlzY19l bDEodm9pZCkKK3sKKwl1NjQgdmFsOworCisJYXNtIHZvbGF0aWxlKCJtcnMgJTAsIHMzXzBfYzVf YzVfMCIgOiAiPXIiICh2YWwpKTsKKwlyZXR1cm4gdmFsOworfQorCitzdGF0aWMgaW5saW5lIHZv aWQgY2xlYXJfZXJyeHN0YXR1c192YWxpZCh1NjQgdmFsKQoreworCWFzbSB2b2xhdGlsZSgibXNy IHMzXzBfYzVfYzRfMiwgJTAiIDogOiAiciIgKHZhbCkpOworfQorCitzdHJ1Y3QgZXJyb3JzX2Vk YWMgeworCWNvbnN0IGNoYXIgKiBjb25zdCBtc2c7CisJdm9pZCAoKmZ1bmMpKHN0cnVjdCBlZGFj X2RldmljZV9jdGxfaW5mbyAqZWRhY19kZXYsCisJCQlpbnQgaW5zdF9uciwgaW50IGJsb2NrX25y LCBjb25zdCBjaGFyICptc2cpOworfTsKKworc3RhdGljIGNvbnN0IHN0cnVjdCBlcnJvcnNfZWRh YyBlcnJvcnNbXSA9IHsKKwl7ICJMMSBDb3JyZWN0YWJsZSBFcnJvciIsIGVkYWNfZGV2aWNlX2hh bmRsZV9jZSB9LAorCXsgIkwxIFVuY29ycmVjdGFibGUgRXJyb3IiLCBlZGFjX2RldmljZV9oYW5k bGVfdWUgfSwKKwl7ICJMMiBDb3JyZWN0YWJsZSBFcnJvciIsIGVkYWNfZGV2aWNlX2hhbmRsZV9j ZSB9LAorCXsgIkwyIFVuY29ycmVjdGFibGUgRXJyb3IiLCBlZGFjX2RldmljZV9oYW5kbGVfdWUg fSwKKwl7ICJMMyBDb3JyZWN0YWJsZSBFcnJvciIsIGVkYWNfZGV2aWNlX2hhbmRsZV9jZSB9LAor CXsgIkwzIFVuY29ycmVjdGFibGUgRXJyb3IiLCBlZGFjX2RldmljZV9oYW5kbGVfdWUgfSwKK307 CisKKyNkZWZpbmUgTDFfQ0UgMAorI2RlZmluZSBMMV9VRSAxCisjZGVmaW5lIEwyX0NFIDIKKyNk ZWZpbmUgTDJfVUUgMworI2RlZmluZSBMM19DRSA0CisjZGVmaW5lIEwzX1VFIDUKKworI2RlZmlu ZSBEQVRBX0JVRl9FUlIJCTB4MgorI2RlZmluZSBDQUNIRV9EQVRBX0VSUgkJMHg2CisjZGVmaW5l IENBQ0hFX1RBR19ESVJUWV9FUlIJMHg3CisjZGVmaW5lIFRMQl9QQVJJVFlfRVJSX0RBVEEJMHg4 CisjZGVmaW5lIFRMQl9QQVJJVFlfRVJSX1RBRwkweDkKKyNkZWZpbmUgQlVTX0VSUk9SCQkweDEy CisKK3N0cnVjdCBlcnBfZHJ2ZGF0YSB7CisJc3RydWN0IGVkYWNfZGV2aWNlX2N0bF9pbmZvICpl ZGV2X2N0bDsKKwlzdHJ1Y3QgZXJwX2RydmRhdGEgX19wZXJjcHUgKiplcnBfY3B1X2RydmRhdGE7 CisJc3RydWN0IG5vdGlmaWVyX2Jsb2NrIG5iX3BtOworCWludCBwcGk7Cit9OworCitzdGF0aWMg c3RydWN0IGVycF9kcnZkYXRhICpwYW5pY19oYW5kbGVyX2RydmRhdGE7CisKK3N0YXRpYyBERUZJ TkVfU1BJTkxPQ0soYXJtdjhfZWRhY19sb2NrKTsKKworc3RhdGljIHZvaWQgbDFfbDJfaXJxX2Vu YWJsZSh2b2lkICppbmZvKQoreworCWludCBpcnEgPSAqKGludCAqKWluZm87CisKKwllbmFibGVf cGVyY3B1X2lycShpcnEsIElSUV9UWVBFX0xFVkVMX0hJR0gpOworfQorCitzdGF0aWMgaW50IHJl cXVlc3RfZXJwX2lycShzdHJ1Y3QgcGxhdGZvcm1fZGV2aWNlICpwZGV2LCBjb25zdCBjaGFyICpw cm9wbmFtZSwKKwkJCWNvbnN0IGNoYXIgKmRlc2MsIGlycV9oYW5kbGVyX3QgaGFuZGxlciwKKwkJ CXZvaWQgKmVkLCBpbnQgcGVyY3B1KQoreworCWludCByYzsKKwlzdHJ1Y3QgcmVzb3VyY2UgKnI7 CisJc3RydWN0IGVycF9kcnZkYXRhICpkcnYgPSBlZDsKKworCXIgPSBwbGF0Zm9ybV9nZXRfcmVz b3VyY2VfYnluYW1lKHBkZXYsIElPUkVTT1VSQ0VfSVJRLCBwcm9wbmFtZSk7CisKKwlpZiAoIXIp IHsKKwkJcHJfZXJyKCJBUk12OCBDUFUgRVJQOiBDb3VsZCBub3QgZmluZCA8JXM+IElSUSBwcm9w ZXJ0eS4gUHJvY2VlZGluZyBhbnl3YXkuXG4iLAorCQkJcHJvcG5hbWUpOworCQlnb3RvIG91dDsK Kwl9CisKKwlpZiAoIXBlcmNwdSkgeworCQlyYyA9IGRldm1fcmVxdWVzdF90aHJlYWRlZF9pcnEo JnBkZXYtPmRldiwgci0+c3RhcnQsIE5VTEwsCisJCQkJCSAgICAgICBoYW5kbGVyLAorCQkJCQkg ICAgICAgSVJRRl9PTkVTSE9UIHwgSVJRRl9UUklHR0VSX0hJR0gsCisJCQkJCSAgICAgICBkZXNj LAorCQkJCQkgICAgICAgZWQpOworCisJCWlmIChyYykgeworCQkJcHJfZXJyKCJBUk12OCBDUFUg RVJQOiBGYWlsZWQgdG8gcmVxdWVzdCBJUlEgJWQ6ICVkICglcyAvICVzKS4gUHJvY2VlZGluZyBh bnl3YXkuXG4iLAorCQkJICAgICAgIChpbnQpIHItPnN0YXJ0LCByYywgcHJvcG5hbWUsIGRlc2Mp OworCQkJZ290byBvdXQ7CisJCX0KKworCX0gZWxzZSB7CisJCWRydi0+ZXJwX2NwdV9kcnZkYXRh ID0gYWxsb2NfcGVyY3B1KHN0cnVjdCBlcnBfZHJ2ZGF0YSAqKTsKKwkJaWYgKCFkcnYtPmVycF9j cHVfZHJ2ZGF0YSkgeworCQkJcHJfZXJyKCJGYWlsZWQgdG8gYWxsb2NhdGUgcGVyY3B1IGVycCBk YXRhXG4iKTsKKwkJCWdvdG8gb3V0OworCQl9CisKKwkJKnJhd19jcHVfcHRyKGRydi0+ZXJwX2Nw dV9kcnZkYXRhKSA9IGRydjsKKwkJcmMgPSByZXF1ZXN0X3BlcmNwdV9pcnEoci0+c3RhcnQsIGhh bmRsZXIsIGRlc2MsCisJCQkJZHJ2LT5lcnBfY3B1X2RydmRhdGEpOworCisJCWlmIChyYykgewor CQkJcHJfZXJyKCJBUk12OCBDUFUgRVJQOiBGYWlsZWQgdG8gcmVxdWVzdCBJUlEgJWQ6ICVkICgl cyAvICVzKS4gUHJvY2VlZGluZyBhbnl3YXkuXG4iLAorCQkJICAgICAgIChpbnQpIHItPnN0YXJ0 LCByYywgcHJvcG5hbWUsIGRlc2MpOworCQkJZ290byBvdXRfZnJlZTsKKwkJfQorCisJCWRydi0+ cHBpID0gci0+c3RhcnQ7CisJCW9uX2VhY2hfY3B1KGwxX2wyX2lycV9lbmFibGUsICYoci0+c3Rh cnQpLCAxKTsKKwl9CisKKwlyZXR1cm4gMDsKKworb3V0X2ZyZWU6CisJZnJlZV9wZXJjcHUoZHJ2 LT5lcnBfY3B1X2RydmRhdGEpOworCWRydi0+ZXJwX2NwdV9kcnZkYXRhID0gTlVMTDsKK291dDoK KwlyZXR1cm4gMTsKK30KKworc3RhdGljIHZvaWQgZHVtcF9lcnJfcmVnKGludCBlcnJvcmNvZGUs IGludCBsZXZlbCwgdTY0IGVycnhzdGF0dXMsIHU2NCBlcnJ4bWlzYywKKwlzdHJ1Y3QgZWRhY19k ZXZpY2VfY3RsX2luZm8gKmVkZXZfY3RsKQoreworCWVkYWNfcHJpbnRrKEtFUk5fQ1JJVCwgRURB Q19DUFUsICJFUlJYU1RBVFVTX0VMMTogJWxseFxuIiwgZXJyeHN0YXR1cyk7CisJZWRhY19wcmlu dGsoS0VSTl9DUklULCBFREFDX0NQVSwgIkVSUlhNSVNDX0VMMTogJWxseFxuIiwgZXJyeG1pc2Mp OworCWVkYWNfcHJpbnRrKEtFUk5fQ1JJVCwgRURBQ19DUFUsICJDYWNoZSBsZXZlbDogTCVkXG4i LCBsZXZlbCsxKTsKKworCXN3aXRjaCAoRVJSWFNUQVRVU19TRVJSKGVycnhzdGF0dXMpKSB7CisJ Y2FzZSBEQVRBX0JVRl9FUlI6CisJCWVkYWNfcHJpbnRrKEtFUk5fQ1JJVCwgRURBQ19DUFUsICJF Q0MgRXJyb3IgZnJvbSBpbnRlcm5hbCBkYXRhIGJ1ZmZlclxuIik7CisJCWJyZWFrOworCisJY2Fz ZSBDQUNIRV9EQVRBX0VSUjoKKwkJZWRhY19wcmludGsoS0VSTl9DUklULCBFREFDX0NQVSwgIkVD QyBFcnJvciBmcm9tIGNhY2hlIGRhdGEgUkFNXG4iKTsKKwkJYnJlYWs7CisKKwljYXNlIENBQ0hF X1RBR19ESVJUWV9FUlI6CisJCWVkYWNfcHJpbnRrKEtFUk5fQ1JJVCwgRURBQ19DUFUsICJFQ0Mg RXJyb3IgZnJvbSBjYWNoZSB0YWcgb3IgZGlydHkgUkFNXG4iKTsKKwkJYnJlYWs7CisKKwljYXNl IFRMQl9QQVJJVFlfRVJSX0RBVEE6CisJCWVkYWNfcHJpbnRrKEtFUk5fQ1JJVCwgRURBQ19DUFUs ICJQYXJpdHkgZXJyb3Igb24gVExCIERBVEEgUkFNXG4iKTsKKwkJYnJlYWs7CisKKwljYXNlIFRM Ql9QQVJJVFlfRVJSX1RBRzoKKwkJZWRhY19wcmludGsoS0VSTl9DUklULCBFREFDX0NQVSwgIlBh cml0eSBlcnJvciBvbiBUTEIgVEFHIFJBTVxuIik7CisJCWJyZWFrOworCisJY2FzZSBCVVNfRVJS T1I6CisJCWVkYWNfcHJpbnRrKEtFUk5fQ1JJVCwgRURBQ19DUFUsICJCdXMgRXJyb3JcbiIpOwor CQlicmVhazsKKwl9CisKKwlpZiAobGV2ZWwgPT0gTDMpCisJCWVkYWNfcHJpbnRrKEtFUk5fQ1JJ VCwgRURBQ19DUFUsCisJCQkiV2F5OiAlZFxuIiwgKGludCkgRVJSWE1JU0NfV0FZKGVycnhtaXNj KSk7CisJZWxzZQorCQllZGFjX3ByaW50ayhLRVJOX0NSSVQsIEVEQUNfQ1BVLAorCQkJIldheTog JWRcbiIsIChpbnQpIEVSUlhNSVNDX1dBWShlcnJ4bWlzYykgPj4gMik7CisKKwllZGV2X2N0bC0+ cGFuaWNfb25fdWUgPSBwYW5pY19vbl91ZTsKKwllcnJvcnNbZXJyb3Jjb2RlXS5mdW5jKGVkZXZf Y3RsLCBzbXBfcHJvY2Vzc29yX2lkKCksCisJCQkJbGV2ZWwsIGVycm9yc1tlcnJvcmNvZGVdLm1z Zyk7Cit9CisKK3N0YXRpYyB2b2lkIGFybXY4X3BhcnNlX2wxX2wyX2NhY2hlX2Vycm9yKHU2NCBl cnJ4c3RhdHVzLCB1NjQgZXJyeG1pc2MsCisJc3RydWN0IGVkYWNfZGV2aWNlX2N0bF9pbmZvICpl ZGV2X2N0bCkKK3sKKwlzd2l0Y2ggKEVSUlhNSVNDX0xWTChlcnJ4bWlzYykpIHsKKwljYXNlIEwx OgorCQlpZiAoRVJSWFNUQVRVU19VRShlcnJ4c3RhdHVzKSkKKwkJCWR1bXBfZXJyX3JlZyhMMV9V RSwgTDEsIGVycnhzdGF0dXMsIGVycnhtaXNjLAorCQkJCQllZGV2X2N0bCk7CisJCWVsc2UKKwkJ CWR1bXBfZXJyX3JlZyhMMV9DRSwgTDEsIGVycnhzdGF0dXMsIGVycnhtaXNjLAorCQkJCQllZGV2 X2N0bCk7CisJCWJyZWFrOworCWNhc2UgTDI6CisJCWlmIChFUlJYU1RBVFVTX1VFKGVycnhzdGF0 dXMpKQorCQkJZHVtcF9lcnJfcmVnKEwyX1VFLCBMMiwgZXJyeHN0YXR1cywgZXJyeG1pc2MsCisJ CQkJCWVkZXZfY3RsKTsKKwkJZWxzZQorCQkJZHVtcF9lcnJfcmVnKEwyX0NFLCBMMiwgZXJyeHN0 YXR1cywgZXJyeG1pc2MsCisJCQkJCWVkZXZfY3RsKTsKKwkJYnJlYWs7CisJZGVmYXVsdDoKKwkJ ZWRhY19wcmludGsoS0VSTl9DUklULCBFREFDX0NQVSwgIlVua25vd24gRVJSWE1JU0NfTFZMIHZh bHVlXG4iKTsKKwl9Cit9CisKK3N0YXRpYyBib29sIGFybXY4X2NoZWNrX2wxX2wyX2VjYyh2b2lk ICppbmZvKQoreworCXN0cnVjdCBlZGFjX2RldmljZV9jdGxfaW5mbyAqZWRldl9jdGwgPSBpbmZv OworCXU2NCBlcnJ4c3RhdHVzOworCXU2NCBlcnJ4bWlzYzsKKwl1bnNpZ25lZCBsb25nIGZsYWdz OworCisJc3Bpbl9sb2NrX2lycXNhdmUoJmFybXY4X2VkYWNfbG9jaywgZmxhZ3MpOworCXdyaXRl X2VycnNlbHJfZWwxKDApOworCWVycnhzdGF0dXMgPSByZWFkX2VycnhzdGF0dXNfZWwxKCk7CisK KwlpZiAoRVJSWFNUQVRVU19WQUxJRChlcnJ4c3RhdHVzKSkgeworCQllcnJ4bWlzYyA9IHJlYWRf ZXJyeG1pc2NfZWwxKCk7CisJCWVkYWNfcHJpbnRrKEtFUk5fQ1JJVCwgRURBQ19DUFUsCisJCSJD UFUlZCBkZXRlY3RlZCBhIEwxL0wyIGNhY2hlIGVycm9yXG4iLAorCQlzbXBfcHJvY2Vzc29yX2lk KCkpOworCisJCWFybXY4X3BhcnNlX2wxX2wyX2NhY2hlX2Vycm9yKGVycnhzdGF0dXMsIGVycnht aXNjLCBlZGV2X2N0bCk7CisJCWNsZWFyX2VycnhzdGF0dXNfdmFsaWQoZXJyeHN0YXR1cyk7CisJ CXNwaW5fdW5sb2NrX2lycXJlc3RvcmUoJmFybXY4X2VkYWNfbG9jaywgZmxhZ3MpOworCQlyZXR1 cm4gdHJ1ZTsKKwl9CisJc3Bpbl91bmxvY2tfaXJxcmVzdG9yZSgmYXJtdjhfZWRhY19sb2NrLCBm bGFncyk7CisJcmV0dXJuIGZhbHNlOworfQorCitzdGF0aWMgYm9vbCBhcm12OF9jaGVja19sM19z Y3VfZXJyb3Ioc3RydWN0IGVkYWNfZGV2aWNlX2N0bF9pbmZvICplZGV2X2N0bCkKK3sKKwl1NjQg ZXJyeHN0YXR1cyA9IDA7CisJdTY0IGVycnhtaXNjID0gMDsKKwl1bnNpZ25lZCBsb25nIGZsYWdz OworCisJc3Bpbl9sb2NrX2lycXNhdmUoJmFybXY4X2VkYWNfbG9jaywgZmxhZ3MpOworCXdyaXRl X2VycnNlbHJfZWwxKDEpOworCWVycnhzdGF0dXMgPSByZWFkX2VycnhzdGF0dXNfZWwxKCk7CisJ ZXJyeG1pc2MgPSByZWFkX2VycnhtaXNjX2VsMSgpOworCisJaWYgKEVSUlhTVEFUVVNfVkFMSUQo ZXJyeHN0YXR1cykgJiYKKwkJRVJSWE1JU0NfTFZMKGVycnhtaXNjKSA9PSBMMykgeworCQlpZiAo RVJSWFNUQVRVU19VRShlcnJ4c3RhdHVzKSkgeworCQkJZWRhY19wcmludGsoS0VSTl9DUklULCBF REFDX0NQVSwgIkRldGVjdGVkIEwzIHVuY29ycmVjdGFibGUgZXJyb3JcbiIpOworCQkJZHVtcF9l cnJfcmVnKEwzX1VFLCBMMywgZXJyeHN0YXR1cywgZXJyeG1pc2MsCisJCQkJZWRldl9jdGwpOwor CQl9IGVsc2UgeworCQkJZWRhY19wcmludGsoS0VSTl9DUklULCBFREFDX0NQVSwgIkRldGVjdGVk IEwzIGNvcnJlY3RhYmxlIGVycm9yXG4iKTsKKwkJCWR1bXBfZXJyX3JlZyhMM19DRSwgTDMsIGVy cnhzdGF0dXMsIGVycnhtaXNjLAorCQkJCWVkZXZfY3RsKTsKKwkJfQorCisJCWNsZWFyX2Vycnhz dGF0dXNfdmFsaWQoZXJyeHN0YXR1cyk7CisJCXNwaW5fdW5sb2NrX2lycXJlc3RvcmUoJmFybXY4 X2VkYWNfbG9jaywgZmxhZ3MpOworCQlyZXR1cm4gdHJ1ZTsKKwl9CisJc3Bpbl91bmxvY2tfaXJx cmVzdG9yZSgmYXJtdjhfZWRhY19sb2NrLCBmbGFncyk7CisJcmV0dXJuIGZhbHNlOworfQorCitz dGF0aWMgdm9pZCBhcm12OF9jaGVja19sMV9sMl9lY2NfaGVscGVyKHZvaWQgKmluZm8pCit7CisJ YXJtdjhfY2hlY2tfbDFfbDJfZWNjKGluZm8pOworfQorCit2b2lkIGFybXY4X3BvbGxfY2FjaGVf ZXJyb3JzKHN0cnVjdCBlZGFjX2RldmljZV9jdGxfaW5mbyAqZWRldl9jdGwpCit7CisJaW50IGNw dTsKKworCWlmICghZWRldl9jdGwpCisJCWVkZXZfY3RsID0gcGFuaWNfaGFuZGxlcl9kcnZkYXRh LT5lZGV2X2N0bDsKKworCWFybXY4X2NoZWNrX2wzX3NjdV9lcnJvcihlZGV2X2N0bCk7CisJZm9y X2VhY2hfcG9zc2libGVfY3B1KGNwdSkgeworCQlzbXBfY2FsbF9mdW5jdGlvbl9zaW5nbGUoY3B1 LCBhcm12OF9jaGVja19sMV9sMl9lY2NfaGVscGVyLAorCQkJZWRldl9jdGwsIDApOworCX0KK30K Kworc3RhdGljIGlycXJldHVybl90IGFybXY4X2wxX2wyX2hhbmRsZXIoaW50IGlycSwgdm9pZCAq ZHJ2ZGF0YSkKK3sKKwlpZiAoYXJtdjhfY2hlY2tfbDFfbDJfZWNjKHBhbmljX2hhbmRsZXJfZHJ2 ZGF0YS0+ZWRldl9jdGwpKQorCQlyZXR1cm4gSVJRX0hBTkRMRUQ7CisJcmV0dXJuIElSUV9OT05F OworfQorCitzdGF0aWMgaXJxcmV0dXJuX3QgYXJtdjhfbDNfc2N1X2hhbmRsZXIoaW50IGlycSwg dm9pZCAqZHJ2ZGF0YSkKK3sKKwlzdHJ1Y3QgZXJwX2RydmRhdGEgKmRydiA9IGRydmRhdGE7CisJ c3RydWN0IGVkYWNfZGV2aWNlX2N0bF9pbmZvICplZGV2X2N0bCA9IGRydi0+ZWRldl9jdGw7CisK KwlpZiAoYXJtdjhfY2hlY2tfbDNfc2N1X2Vycm9yKGVkZXZfY3RsKSkKKwkJcmV0dXJuIElSUV9I QU5ETEVEOworCXJldHVybiBJUlFfTk9ORTsKK30KKworc3RhdGljIHZvaWQgaW5pdGlhbGl6ZV9y ZWdpc3RlcnModm9pZCAqaW5mbykKK3sKKwlzZXRfZXJyeGN0bHJfZWwxKCk7CisJc2V0X2Vycnht aXNjX292ZXJmbG93KCk7Cit9CisKK3N0YXRpYyB2b2lkIGluaXRfcmVnc19vbl9jcHUoYm9vbCBh bGxfY3B1cykKK3sKKwlpbnQgY3B1OworCisJd3JpdGVfZXJyc2Vscl9lbDEoMCk7CisJaWYgKGFs bF9jcHVzKSB7CisJCWZvcl9lYWNoX3Bvc3NpYmxlX2NwdShjcHUpCisJCQlzbXBfY2FsbF9mdW5j dGlvbl9zaW5nbGUoY3B1LCBpbml0aWFsaXplX3JlZ2lzdGVycywKKwkJCQkJCU5VTEwsIDEpOwor CX0gZWxzZSB7CisJCWluaXRpYWxpemVfcmVnaXN0ZXJzKE5VTEwpOworCX0KKworCXdyaXRlX2Vy cnNlbHJfZWwxKDEpOworCWluaXRpYWxpemVfcmVnaXN0ZXJzKE5VTEwpOworfQorCitzdGF0aWMg aW50IGFybXY4X3BtdV9jcHVfcG1fbm90aWZ5KHN0cnVjdCBub3RpZmllcl9ibG9jayAqc2VsZiwK KwkJCQl1bnNpZ25lZCBsb25nIGFjdGlvbiwgdm9pZCAqdikKK3sKKwlzd2l0Y2ggKGFjdGlvbikg eworCWNhc2UgQ1BVX1BNX0VYSVQ6CisJCWluaXRfcmVnc19vbl9jcHUoZmFsc2UpOworCQlhcm12 OF9jaGVja19sM19zY3VfZXJyb3IocGFuaWNfaGFuZGxlcl9kcnZkYXRhLT5lZGV2X2N0bCk7CisJ CWFybXY4X2NoZWNrX2wxX2wyX2VjYyhwYW5pY19oYW5kbGVyX2RydmRhdGEtPmVkZXZfY3RsKTsK KwkJYnJlYWs7CisJfQorCisJcmV0dXJuIE5PVElGWV9PSzsKK30KKworc3RhdGljIGludCBhcm12 OF9jcHVfZXJwX3Byb2JlKHN0cnVjdCBwbGF0Zm9ybV9kZXZpY2UgKnBkZXYpCit7CisJc3RydWN0 IGRldmljZSAqZGV2ID0gJnBkZXYtPmRldjsKKwlzdHJ1Y3QgZXJwX2RydmRhdGEgKmRydjsKKwlp bnQgcmMgPSAwOworCWludCBmYWlsID0gMDsKKworCWluaXRfcmVnc19vbl9jcHUodHJ1ZSk7CisK KwlkcnYgPSBkZXZtX2t6YWxsb2MoZGV2LCBzaXplb2YoKmRydiksIEdGUF9LRVJORUwpOworCisJ aWYgKCFkcnYpCisJCXJldHVybiAtRU5PTUVNOworCisJZHJ2LT5lZGV2X2N0bCA9IGVkYWNfZGV2 aWNlX2FsbG9jX2N0bF9pbmZvKDAsICJjcHUiLAorCQkJCQludW1fcG9zc2libGVfY3B1cygpLCAi TCIsIDMsIDEsIE5VTEwsIDAsCisJCQkJCWVkYWNfZGV2aWNlX2FsbG9jX2luZGV4KCkpOworCisJ aWYgKCFkcnYtPmVkZXZfY3RsKQorCQlyZXR1cm4gLUVOT01FTTsKKworCWlmIChJU19FTkFCTEVE KENPTkZJR19FREFDX0FSTVY4X1BPTEwpKSB7CisJCWRydi0+ZWRldl9jdGwtPmVkYWNfY2hlY2sg PSBhcm12OF9wb2xsX2NhY2hlX2Vycm9yczsKKwkJZHJ2LT5lZGV2X2N0bC0+cG9sbF9tc2VjID0g cG9sbF9tc2VjOworCX0KKworCWRydi0+ZWRldl9jdGwtPmRldiA9IGRldjsKKwlkcnYtPmVkZXZf Y3RsLT5tb2RfbmFtZSA9IGRldl9uYW1lKGRldik7CisJZHJ2LT5lZGV2X2N0bC0+ZGV2X25hbWUg PSBkZXZfbmFtZShkZXYpOworCWRydi0+ZWRldl9jdGwtPmN0bF9uYW1lID0gImNhY2hlIjsKKwlk cnYtPmVkZXZfY3RsLT5wYW5pY19vbl91ZSA9IHBhbmljX29uX3VlOworCWRydi0+bmJfcG0ubm90 aWZpZXJfY2FsbCA9IGFybXY4X3BtdV9jcHVfcG1fbm90aWZ5OworCXBsYXRmb3JtX3NldF9kcnZk YXRhKHBkZXYsIGRydik7CisKKwlyYyA9IGVkYWNfZGV2aWNlX2FkZF9kZXZpY2UoZHJ2LT5lZGV2 X2N0bCk7CisJaWYgKHJjKQorCQlnb3RvIG91dF9tZW07CisKKwlwYW5pY19oYW5kbGVyX2RydmRh dGEgPSBkcnY7CisKKwlpZiAoIUlTX0VOQUJMRUQoQ09ORklHX0VEQUNfQVJNVjhfUE9MTCkpIHsK KwkJZmFpbCArPSByZXF1ZXN0X2VycF9pcnEocGRldiwgImwxLWwyLWlycSIsCisJCQkJImwxX2wy X2lycSIsCisJCQkJYXJtdjhfbDFfbDJfaGFuZGxlciwgZHJ2LCAxKTsKKworCQlmYWlsICs9IHJl cXVlc3RfZXJwX2lycShwZGV2LCAibDMtc2N1LWlycSIsCisJCQkJImwzX3NjdV9pcnEiLAorCQkJ CWFybXY4X2wzX3NjdV9oYW5kbGVyLCBkcnYsIDApOworCisJCWlmIChmYWlsID09IG9mX2lycV9j b3VudChkZXYtPm9mX25vZGUpKSB7CisJCQlwcl9lcnIoIkVSUDogQ291bGQgbm90IHJlcXVlc3Qg YW55IElSUXMuIEdpdmluZyB1cC5cbiIpOworCQkJcmMgPSAtRU5PREVWOworCQkJZ290byBvdXRf ZGV2OworCQl9CisJfQorCisJY3B1X3BtX3JlZ2lzdGVyX25vdGlmaWVyKCYoZHJ2LT5uYl9wbSkp OworCisJcmV0dXJuIDA7CisKK291dF9kZXY6CisJZWRhY19kZXZpY2VfZGVsX2RldmljZShkZXYp Oworb3V0X21lbToKKwllZGFjX2RldmljZV9mcmVlX2N0bF9pbmZvKGRydi0+ZWRldl9jdGwpOwor CXJldHVybiByYzsKK30KKworc3RhdGljIGludCBhcm12OF9jcHVfZXJwX3JlbW92ZShzdHJ1Y3Qg cGxhdGZvcm1fZGV2aWNlICpwZGV2KQoreworCXN0cnVjdCBlcnBfZHJ2ZGF0YSAqZHJ2ID0gZGV2 X2dldF9kcnZkYXRhKCZwZGV2LT5kZXYpOworCXN0cnVjdCBlZGFjX2RldmljZV9jdGxfaW5mbyAq ZWRhY19jdGwgPSBkcnYtPmVkZXZfY3RsOworCisJaWYgKGRydi0+ZXJwX2NwdV9kcnZkYXRhKSB7 CisJCWZyZWVfcGVyY3B1X2lycShkcnYtPnBwaSwgZHJ2LT5lcnBfY3B1X2RydmRhdGEpOworCQlm cmVlX3BlcmNwdShkcnYtPmVycF9jcHVfZHJ2ZGF0YSk7CisJfQorCisJZWRhY19kZXZpY2VfZGVs X2RldmljZShlZGFjX2N0bC0+ZGV2KTsKKwllZGFjX2RldmljZV9mcmVlX2N0bF9pbmZvKGVkYWNf Y3RsKTsKKworCXJldHVybiAwOworfQorCitzdGF0aWMgY29uc3Qgc3RydWN0IG9mX2RldmljZV9p ZCBhcm12OF9jcHVfZXJwX21hdGNoX3RhYmxlW10gPSB7CisJeyAuY29tcGF0aWJsZSA9ICJhcm0s YXJtdjgtY3B1LWVycCIgfSwKKwl7IH0KK307CisKK3N0YXRpYyBzdHJ1Y3QgcGxhdGZvcm1fZHJp dmVyIGFybXY4X2NwdV9lcnBfZHJpdmVyID0geworCS5wcm9iZSA9IGFybXY4X2NwdV9lcnBfcHJv YmUsCisJLnJlbW92ZSA9IGFybXY4X2NwdV9lcnBfcmVtb3ZlLAorCS5kcml2ZXIgPSB7CisJCS5u YW1lID0gImFybXY4X2NwdV9jYWNoZV9lcnAiLAorCQkub2ZfbWF0Y2hfdGFibGUgPSBvZl9tYXRj aF9wdHIoYXJtdjhfY3B1X2VycF9tYXRjaF90YWJsZSksCisJfSwKK307Cittb2R1bGVfcGxhdGZv cm1fZHJpdmVyKGFybXY4X2NwdV9lcnBfZHJpdmVyKTsKKworTU9EVUxFX0xJQ0VOU0UoIkdQTCB2 MiIpOworTU9EVUxFX0RFU0NSSVBUSU9OKCJBUk12OCBFREFDIGRyaXZlciIpOwo= From mboxrd@z Thu Jan 1 00:00:00 1970 From: kyan@codeaurora.org (Kyle Yan) Date: Fri, 12 Jan 2018 16:50:26 -0800 Subject: [PATCH v1] EDAC, armv8: Add Cache Error Reporting driver for ARMv8 processors Message-ID: <1515804626-21254-1-git-send-email-kyan@codeaurora.org> To: linux-arm-kernel@lists.infradead.org List-Id: linux-arm-kernel.lists.infradead.org Interrupt based EDAC driver for ARMv8 processors that implement RAS for error detection of CPU caches and lso allows optional polling of error syndrome registers if interrupts are not supported. Signed-off-by: Kyle Yan --- drivers/edac/Kconfig | 21 ++ drivers/edac/Makefile | 1 + drivers/edac/armv8_edac.c | 489 ++++++++++++++++++++++++++++++++++++++++++++++ 3 files changed, 511 insertions(+) create mode 100644 drivers/edac/armv8_edac.c diff --git a/drivers/edac/Kconfig b/drivers/edac/Kconfig index 96afb2a..47a68e3 100644 --- a/drivers/edac/Kconfig +++ b/drivers/edac/Kconfig @@ -457,4 +457,25 @@ config EDAC_XGENE Support for error detection and correction on the APM X-Gene family of SOCs. +config EDAC_ARMV8 + depends on (ARM || ARM64) + tristate "ARMv8 L1/L2/L3/SCU Caches ECC" + help + Support for error detection and correction on ARMv8 cores + supporting RAS features. Reports errors caught by ARMv8 + ECC mechanism. + For debugging issues having to do with stability and overall system + health, you should probably say 'Y' here. + +config EDAC_ARMV8_POLL + depends on EDAC_ARMV8 + bool "Poll on ARMv8 ECC registers" + help + This option chooses whether or not you want to poll on the Kryo3xx + ECC registers. When this is enabled, the polling rate can be set as + a module parameter. By default, it will call the polling function + every second. + This option should only be used if the associated interrupt lines + are not enabled. + endif # EDAC diff --git a/drivers/edac/Makefile b/drivers/edac/Makefile index 0fd9ffa..57113ba 100644 --- a/drivers/edac/Makefile +++ b/drivers/edac/Makefile @@ -43,6 +43,7 @@ obj-$(CONFIG_EDAC_IE31200) += ie31200_edac.o obj-$(CONFIG_EDAC_X38) += x38_edac.o obj-$(CONFIG_EDAC_I82860) += i82860_edac.o obj-$(CONFIG_EDAC_R82600) += r82600_edac.o +obj-$(CONFIG_EDAC_ARMV8) += armv8_edac.o amd64_edac_mod-y := amd64_edac.o amd64_edac_mod-$(CONFIG_EDAC_DEBUG) += amd64_edac_dbg.o diff --git a/drivers/edac/armv8_edac.c b/drivers/edac/armv8_edac.c new file mode 100644 index 0000000..d986c47 --- /dev/null +++ b/drivers/edac/armv8_edac.c @@ -0,0 +1,489 @@ +/* Copyright (c) 2016-2018, The Linux Foundation. All rights reserved. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 and + * only 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 +#include +#include +#include + +#include "edac_mc.h" +#include "edac_device.h" + +static int poll_msec = 1000; +module_param(poll_msec, int, 0444); + +static bool panic_on_ue = 0; +module_param_named(panic_on_ue, panic_on_ue, bool, 0664); + +#define L1 0x0 +#define L2 0x1 +#define L3 0x2 + +#define EDAC_CPU "armv8_edac" + +#define ERRXSTATUS_VALID(a) ((a >> 30) & 0x1) +#define ERRXSTATUS_UE(a) ((a >> 29) & 0x1) +#define ERRXSTATUS_SERR(a) (a & 0xFF) + +#define ERRXMISC_LVL(a) ((a >> 1) & 0x7) +#define ERRXMISC_WAY(a) ((a >> 28) & 0xF) + +#define ERRXCTLR_ENABLE 0x10f +#define ERRXMISC_OVERFLOW 0x7F7F00000000ULL + +static inline void set_errxctlr_el1(void) +{ + asm volatile("msr s3_0_c5_c4_1, %0" : : "r" (ERRXCTLR_ENABLE)); +} + +static inline void set_errxmisc_overflow(void) +{ + asm volatile("msr s3_0_c5_c5_0, %0" : : "r" (ERRXMISC_OVERFLOW)); +} + +static inline void write_errselr_el1(u64 val) +{ + asm volatile("msr s3_0_c5_c3_1, %0" : : "r" (val)); +} + +static inline u64 read_errxstatus_el1(void) +{ + u64 val; + + asm volatile("mrs %0, s3_0_c5_c4_2" : "=r" (val)); + return val; +} + +static inline u64 read_errxmisc_el1(void) +{ + u64 val; + + asm volatile("mrs %0, s3_0_c5_c5_0" : "=r" (val)); + return val; +} + +static inline void clear_errxstatus_valid(u64 val) +{ + asm volatile("msr s3_0_c5_c4_2, %0" : : "r" (val)); +} + +struct errors_edac { + const char * const msg; + void (*func)(struct edac_device_ctl_info *edac_dev, + int inst_nr, int block_nr, const char *msg); +}; + +static const struct errors_edac errors[] = { + { "L1 Correctable Error", edac_device_handle_ce }, + { "L1 Uncorrectable Error", edac_device_handle_ue }, + { "L2 Correctable Error", edac_device_handle_ce }, + { "L2 Uncorrectable Error", edac_device_handle_ue }, + { "L3 Correctable Error", edac_device_handle_ce }, + { "L3 Uncorrectable Error", edac_device_handle_ue }, +}; + +#define L1_CE 0 +#define L1_UE 1 +#define L2_CE 2 +#define L2_UE 3 +#define L3_CE 4 +#define L3_UE 5 + +#define DATA_BUF_ERR 0x2 +#define CACHE_DATA_ERR 0x6 +#define CACHE_TAG_DIRTY_ERR 0x7 +#define TLB_PARITY_ERR_DATA 0x8 +#define TLB_PARITY_ERR_TAG 0x9 +#define BUS_ERROR 0x12 + +struct erp_drvdata { + struct edac_device_ctl_info *edev_ctl; + struct erp_drvdata __percpu **erp_cpu_drvdata; + struct notifier_block nb_pm; + int ppi; +}; + +static struct erp_drvdata *panic_handler_drvdata; + +static DEFINE_SPINLOCK(armv8_edac_lock); + +static void l1_l2_irq_enable(void *info) +{ + int irq = *(int *)info; + + enable_percpu_irq(irq, IRQ_TYPE_LEVEL_HIGH); +} + +static int request_erp_irq(struct platform_device *pdev, const char *propname, + const char *desc, irq_handler_t handler, + void *ed, int percpu) +{ + int rc; + struct resource *r; + struct erp_drvdata *drv = ed; + + r = platform_get_resource_byname(pdev, IORESOURCE_IRQ, propname); + + if (!r) { + pr_err("ARMv8 CPU ERP: Could not find <%s> IRQ property. Proceeding anyway.\n", + propname); + goto out; + } + + if (!percpu) { + rc = devm_request_threaded_irq(&pdev->dev, r->start, NULL, + handler, + IRQF_ONESHOT | IRQF_TRIGGER_HIGH, + desc, + ed); + + if (rc) { + pr_err("ARMv8 CPU ERP: Failed to request IRQ %d: %d (%s / %s). Proceeding anyway.\n", + (int) r->start, rc, propname, desc); + goto out; + } + + } else { + drv->erp_cpu_drvdata = alloc_percpu(struct erp_drvdata *); + if (!drv->erp_cpu_drvdata) { + pr_err("Failed to allocate percpu erp data\n"); + goto out; + } + + *raw_cpu_ptr(drv->erp_cpu_drvdata) = drv; + rc = request_percpu_irq(r->start, handler, desc, + drv->erp_cpu_drvdata); + + if (rc) { + pr_err("ARMv8 CPU ERP: Failed to request IRQ %d: %d (%s / %s). Proceeding anyway.\n", + (int) r->start, rc, propname, desc); + goto out_free; + } + + drv->ppi = r->start; + on_each_cpu(l1_l2_irq_enable, &(r->start), 1); + } + + return 0; + +out_free: + free_percpu(drv->erp_cpu_drvdata); + drv->erp_cpu_drvdata = NULL; +out: + return 1; +} + +static void dump_err_reg(int errorcode, int level, u64 errxstatus, u64 errxmisc, + struct edac_device_ctl_info *edev_ctl) +{ + edac_printk(KERN_CRIT, EDAC_CPU, "ERRXSTATUS_EL1: %llx\n", errxstatus); + edac_printk(KERN_CRIT, EDAC_CPU, "ERRXMISC_EL1: %llx\n", errxmisc); + edac_printk(KERN_CRIT, EDAC_CPU, "Cache level: L%d\n", level+1); + + switch (ERRXSTATUS_SERR(errxstatus)) { + case DATA_BUF_ERR: + edac_printk(KERN_CRIT, EDAC_CPU, "ECC Error from internal data buffer\n"); + break; + + case CACHE_DATA_ERR: + edac_printk(KERN_CRIT, EDAC_CPU, "ECC Error from cache data RAM\n"); + break; + + case CACHE_TAG_DIRTY_ERR: + edac_printk(KERN_CRIT, EDAC_CPU, "ECC Error from cache tag or dirty RAM\n"); + break; + + case TLB_PARITY_ERR_DATA: + edac_printk(KERN_CRIT, EDAC_CPU, "Parity error on TLB DATA RAM\n"); + break; + + case TLB_PARITY_ERR_TAG: + edac_printk(KERN_CRIT, EDAC_CPU, "Parity error on TLB TAG RAM\n"); + break; + + case BUS_ERROR: + edac_printk(KERN_CRIT, EDAC_CPU, "Bus Error\n"); + break; + } + + if (level == L3) + edac_printk(KERN_CRIT, EDAC_CPU, + "Way: %d\n", (int) ERRXMISC_WAY(errxmisc)); + else + edac_printk(KERN_CRIT, EDAC_CPU, + "Way: %d\n", (int) ERRXMISC_WAY(errxmisc) >> 2); + + edev_ctl->panic_on_ue = panic_on_ue; + errors[errorcode].func(edev_ctl, smp_processor_id(), + level, errors[errorcode].msg); +} + +static void armv8_parse_l1_l2_cache_error(u64 errxstatus, u64 errxmisc, + struct edac_device_ctl_info *edev_ctl) +{ + switch (ERRXMISC_LVL(errxmisc)) { + case L1: + if (ERRXSTATUS_UE(errxstatus)) + dump_err_reg(L1_UE, L1, errxstatus, errxmisc, + edev_ctl); + else + dump_err_reg(L1_CE, L1, errxstatus, errxmisc, + edev_ctl); + break; + case L2: + if (ERRXSTATUS_UE(errxstatus)) + dump_err_reg(L2_UE, L2, errxstatus, errxmisc, + edev_ctl); + else + dump_err_reg(L2_CE, L2, errxstatus, errxmisc, + edev_ctl); + break; + default: + edac_printk(KERN_CRIT, EDAC_CPU, "Unknown ERRXMISC_LVL value\n"); + } +} + +static bool armv8_check_l1_l2_ecc(void *info) +{ + struct edac_device_ctl_info *edev_ctl = info; + u64 errxstatus; + u64 errxmisc; + unsigned long flags; + + spin_lock_irqsave(&armv8_edac_lock, flags); + write_errselr_el1(0); + errxstatus = read_errxstatus_el1(); + + if (ERRXSTATUS_VALID(errxstatus)) { + errxmisc = read_errxmisc_el1(); + edac_printk(KERN_CRIT, EDAC_CPU, + "CPU%d detected a L1/L2 cache error\n", + smp_processor_id()); + + armv8_parse_l1_l2_cache_error(errxstatus, errxmisc, edev_ctl); + clear_errxstatus_valid(errxstatus); + spin_unlock_irqrestore(&armv8_edac_lock, flags); + return true; + } + spin_unlock_irqrestore(&armv8_edac_lock, flags); + return false; +} + +static bool armv8_check_l3_scu_error(struct edac_device_ctl_info *edev_ctl) +{ + u64 errxstatus = 0; + u64 errxmisc = 0; + unsigned long flags; + + spin_lock_irqsave(&armv8_edac_lock, flags); + write_errselr_el1(1); + errxstatus = read_errxstatus_el1(); + errxmisc = read_errxmisc_el1(); + + if (ERRXSTATUS_VALID(errxstatus) && + ERRXMISC_LVL(errxmisc) == L3) { + if (ERRXSTATUS_UE(errxstatus)) { + edac_printk(KERN_CRIT, EDAC_CPU, "Detected L3 uncorrectable error\n"); + dump_err_reg(L3_UE, L3, errxstatus, errxmisc, + edev_ctl); + } else { + edac_printk(KERN_CRIT, EDAC_CPU, "Detected L3 correctable error\n"); + dump_err_reg(L3_CE, L3, errxstatus, errxmisc, + edev_ctl); + } + + clear_errxstatus_valid(errxstatus); + spin_unlock_irqrestore(&armv8_edac_lock, flags); + return true; + } + spin_unlock_irqrestore(&armv8_edac_lock, flags); + return false; +} + +static void armv8_check_l1_l2_ecc_helper(void *info) +{ + armv8_check_l1_l2_ecc(info); +} + +void armv8_poll_cache_errors(struct edac_device_ctl_info *edev_ctl) +{ + int cpu; + + if (!edev_ctl) + edev_ctl = panic_handler_drvdata->edev_ctl; + + armv8_check_l3_scu_error(edev_ctl); + for_each_possible_cpu(cpu) { + smp_call_function_single(cpu, armv8_check_l1_l2_ecc_helper, + edev_ctl, 0); + } +} + +static irqreturn_t armv8_l1_l2_handler(int irq, void *drvdata) +{ + if (armv8_check_l1_l2_ecc(panic_handler_drvdata->edev_ctl)) + return IRQ_HANDLED; + return IRQ_NONE; +} + +static irqreturn_t armv8_l3_scu_handler(int irq, void *drvdata) +{ + struct erp_drvdata *drv = drvdata; + struct edac_device_ctl_info *edev_ctl = drv->edev_ctl; + + if (armv8_check_l3_scu_error(edev_ctl)) + return IRQ_HANDLED; + return IRQ_NONE; +} + +static void initialize_registers(void *info) +{ + set_errxctlr_el1(); + set_errxmisc_overflow(); +} + +static void init_regs_on_cpu(bool all_cpus) +{ + int cpu; + + write_errselr_el1(0); + if (all_cpus) { + for_each_possible_cpu(cpu) + smp_call_function_single(cpu, initialize_registers, + NULL, 1); + } else { + initialize_registers(NULL); + } + + write_errselr_el1(1); + initialize_registers(NULL); +} + +static int armv8_pmu_cpu_pm_notify(struct notifier_block *self, + unsigned long action, void *v) +{ + switch (action) { + case CPU_PM_EXIT: + init_regs_on_cpu(false); + armv8_check_l3_scu_error(panic_handler_drvdata->edev_ctl); + armv8_check_l1_l2_ecc(panic_handler_drvdata->edev_ctl); + break; + } + + return NOTIFY_OK; +} + +static int armv8_cpu_erp_probe(struct platform_device *pdev) +{ + struct device *dev = &pdev->dev; + struct erp_drvdata *drv; + int rc = 0; + int fail = 0; + + init_regs_on_cpu(true); + + drv = devm_kzalloc(dev, sizeof(*drv), GFP_KERNEL); + + if (!drv) + return -ENOMEM; + + drv->edev_ctl = edac_device_alloc_ctl_info(0, "cpu", + num_possible_cpus(), "L", 3, 1, NULL, 0, + edac_device_alloc_index()); + + if (!drv->edev_ctl) + return -ENOMEM; + + if (IS_ENABLED(CONFIG_EDAC_ARMV8_POLL)) { + drv->edev_ctl->edac_check = armv8_poll_cache_errors; + drv->edev_ctl->poll_msec = poll_msec; + } + + drv->edev_ctl->dev = dev; + drv->edev_ctl->mod_name = dev_name(dev); + drv->edev_ctl->dev_name = dev_name(dev); + drv->edev_ctl->ctl_name = "cache"; + drv->edev_ctl->panic_on_ue = panic_on_ue; + drv->nb_pm.notifier_call = armv8_pmu_cpu_pm_notify; + platform_set_drvdata(pdev, drv); + + rc = edac_device_add_device(drv->edev_ctl); + if (rc) + goto out_mem; + + panic_handler_drvdata = drv; + + if (!IS_ENABLED(CONFIG_EDAC_ARMV8_POLL)) { + fail += request_erp_irq(pdev, "l1-l2-irq", + "l1_l2_irq", + armv8_l1_l2_handler, drv, 1); + + fail += request_erp_irq(pdev, "l3-scu-irq", + "l3_scu_irq", + armv8_l3_scu_handler, drv, 0); + + if (fail == of_irq_count(dev->of_node)) { + pr_err("ERP: Could not request any IRQs. Giving up.\n"); + rc = -ENODEV; + goto out_dev; + } + } + + cpu_pm_register_notifier(&(drv->nb_pm)); + + return 0; + +out_dev: + edac_device_del_device(dev); +out_mem: + edac_device_free_ctl_info(drv->edev_ctl); + return rc; +} + +static int armv8_cpu_erp_remove(struct platform_device *pdev) +{ + struct erp_drvdata *drv = dev_get_drvdata(&pdev->dev); + struct edac_device_ctl_info *edac_ctl = drv->edev_ctl; + + if (drv->erp_cpu_drvdata) { + free_percpu_irq(drv->ppi, drv->erp_cpu_drvdata); + free_percpu(drv->erp_cpu_drvdata); + } + + edac_device_del_device(edac_ctl->dev); + edac_device_free_ctl_info(edac_ctl); + + return 0; +} + +static const struct of_device_id armv8_cpu_erp_match_table[] = { + { .compatible = "arm,armv8-cpu-erp" }, + { } +}; + +static struct platform_driver armv8_cpu_erp_driver = { + .probe = armv8_cpu_erp_probe, + .remove = armv8_cpu_erp_remove, + .driver = { + .name = "armv8_cpu_cache_erp", + .of_match_table = of_match_ptr(armv8_cpu_erp_match_table), + }, +}; +module_platform_driver(armv8_cpu_erp_driver); + +MODULE_LICENSE("GPL v2"); +MODULE_DESCRIPTION("ARMv8 EDAC driver"); -- The Qualcomm Innovation Center, Inc. is a member of the Code Aurora Forum, a Linux Foundation Collaborative Project