ACK: [PATCH][V2] acpi/method: add tests for NVDIMM control methods for ACPI 6.3
ivanhu
ivan.hu at canonical.com
Mon Feb 18 15:35:36 UTC 2019
On 2/18/19 6:09 PM, ivanhu wrote:
> On 2/12/19 1:42 PM, Alex Hung wrote:
>> Signed-off-by: Alex Hung <alex.hung at canonical.com>
>> ---
>> src/acpi/method/method.c | 286 ++++++++++++++++++++++++
>> src/lib/include/fwts_acpi_object_eval.h | 40 ++++
>> 2 files changed, 326 insertions(+)
>>
>> diff --git a/src/acpi/method/method.c b/src/acpi/method/method.c
>> index 654112d9..48a5c039 100644
>> --- a/src/acpi/method/method.c
>> +++ b/src/acpi/method/method.c
>> @@ -138,6 +138,11 @@
>> * _MSG Y
>> * _MSM N
>> * _MTL Y
>> + * _NBS Y
>> + * _NCH Y
>> + * _NIC Y
>> + * _NIH Y
>> + * _NIG Y
>> * _NTT Y
>> * _OFF Y
>> * _ON_ Y
>> @@ -3574,6 +3579,280 @@ static int method_test_TIV(fwts_framework *fw)
>> "_TIV", arg, 1, fwts_method_test_integer_return, NULL);
>> }
>>
>> +/*
>> + * Section 9.20 NVDIMM Devices
>> + */
>> +static void check_nvdimm_status(
>> + fwts_framework *fw,
>> + char *name,
>> + uint16_t status,
>> + bool *failed)
>> +{
>> + if (status > 6) {
>> + *failed = true;
>> + fwts_failed(fw, LOG_LEVEL_MEDIUM,
>> + "MethodBadStatus",
>> + "%s: Expected Status to be 0..6, got %" PRIx16,
>> + name, status);
>> + }
>> +}
>> +
>> +static void check_nvdimm_extended_status(
>> + fwts_framework *fw,
>> + char *name,
>> + uint16_t ext_status,
>> + uint16_t expected,
>> + bool *failed)
>> +{
>> + if (ext_status != expected) {
>> + *failed = true;
>> + fwts_failed(fw, LOG_LEVEL_MEDIUM,
>> + "MethodBadExtendedStatus",
>> + "%s: Expected Extended Status to be %" PRIx16
>> + ", got %" PRIx16, name, expected, ext_status);
>> + }
>> +}
>> +
>> +static void method_test_NBS_return(
>> + fwts_framework *fw,
>> + char *name,
>> + ACPI_BUFFER *buf,
>> + ACPI_OBJECT *obj,
>> + void *private)
>> +{
>> + bool failed = false;
>> + nbs_return_t *ret;
>> +
>> + FWTS_UNUSED(private);
>> +
>> + if (fwts_method_check_type(fw, name, buf, ACPI_TYPE_BUFFER) != FWTS_OK)
>> + return;
>> +
>> + if (obj->Buffer.Length != 64) {
>> + failed = true;
>> + fwts_failed(fw, LOG_LEVEL_CRITICAL,
>> + "Method_NBSBadBufferSize",
>> + "%s should return a buffer of 64 bytes, but "
>> + "instead just returned %" PRIu32,
>> + name, obj->Buffer.Length);
>> + }
>> +
>> + ret = (nbs_return_t *) obj->Buffer.Pointer;
>> + check_nvdimm_status(fw, name, ret->status, &failed);
>> + check_nvdimm_extended_status(fw, name, ret->extended_status, 0, &failed);
>> + fwts_acpi_reserved_bits_check(fw, "_NBS", "Validation Flags", ret->validation_flags, sizeof(uint16_t), 1, 15, &failed);
> Should check the rest return bytes are reserved?
>> +
>> + if (!failed)
>> + fwts_method_passed_sane(fw, name, "buffer");
>> +}
>> +
>> +static int method_test_NBS(fwts_framework *fw)
>> +{
>> + return method_evaluate_method(fw, METHOD_OPTIONAL,
>> + "_NBS", NULL, 0, method_test_NBS_return, NULL);
>> +}
>> +
>> +static void method_test_NCH_return(
>> + fwts_framework *fw,
>> + char *name,
>> + ACPI_BUFFER *buf,
>> + ACPI_OBJECT *obj,
>> + void *private)
>> +{
>> + bool failed = false;
>> + nch_return_t *ret;
>> +
>> + FWTS_UNUSED(private);
>> +
>> + if (fwts_method_check_type(fw, name, buf, ACPI_TYPE_BUFFER) != FWTS_OK)
>> + return;
>> +
>> + if (obj->Buffer.Length != 64) {
>> + failed = true;
>> + fwts_failed(fw, LOG_LEVEL_CRITICAL,
>> + "Method_NCHBadBufferSize",
>> + "%s should return a buffer of 64 bytes, but "
>> + "instead just returned %" PRIu32,
>> + name, obj->Buffer.Length);
>> + }
>> +
>> + ret = (nch_return_t *) obj->Buffer.Pointer;
>> + check_nvdimm_status(fw, name, ret->status, &failed);
>> + check_nvdimm_extended_status(fw, name, ret->extended_status, 0, &failed);
>> + fwts_acpi_reserved_bits_check(fw, "_NCH", "Validation Flags", ret->extended_status, sizeof(uint16_t), 2, 15, &failed);
>> +
>> + /* Health Status Flags [2..7], [11.15], [19..31] are reserved */
>> + fwts_acpi_reserved_bits_check(fw, "_NCH", "Health Status Flags", ret->health_status_flags, sizeof(uint32_t), 2, 7, &failed);
>> + fwts_acpi_reserved_bits_check(fw, "_NCH", "Health Status Flags", ret->health_status_flags, sizeof(uint32_t), 11, 15, &failed);
>> + fwts_acpi_reserved_bits_check(fw, "_NCH", "Health Status Flags", ret->health_status_flags, sizeof(uint32_t), 19, 31, &failed);
>> +
>> + fwts_acpi_reserved_bits_check(fw, "_NCH", "Health Status Attributes", ret->health_status_attributes, sizeof(uint32_t), 1, 31, &failed);
>> +
> Should check the rest return bytes are reserved?
>> + if (!failed)
>> + fwts_method_passed_sane(fw, name, "buffer");
>> +}
>> +
>> +static int method_test_NCH(fwts_framework *fw)
>> +{
>> + return method_evaluate_method(fw, METHOD_OPTIONAL,
>> + "_NCH", NULL, 0, method_test_NCH_return, NULL);
>> +}
>> +
>> +static void method_test_NIC_return(
>> + fwts_framework *fw,
>> + char *name,
>> + ACPI_BUFFER *buf,
>> + ACPI_OBJECT *obj,
>> + void *private)
>> +{
>> + bool failed = false;
>> + nic_return_t *ret;
>> +
>> + FWTS_UNUSED(private);
>> +
>> + if (fwts_method_check_type(fw, name, buf, ACPI_TYPE_BUFFER) != FWTS_OK)
>> + return;
>> +
>> + if (obj->Buffer.Length != 64) {
>> + failed = true;
>> + fwts_failed(fw, LOG_LEVEL_CRITICAL,
>> + "Method_NICBadBufferSize",
>> + "%s should return a buffer of 64 bytes, but "
>> + "instead just returned %" PRIu32,
>> + name, obj->Buffer.Length);
>> + }
>> +
>> + ret = (nic_return_t *) obj->Buffer.Pointer;
>> + check_nvdimm_status(fw, name, ret->status, &failed);
>> + check_nvdimm_extended_status(fw, name, ret->extended_status, 0, &failed);
>> +
>> + /* Health Error Injection Capabilities [2..7], [11.15], [19..31] are reserved */
>> + fwts_acpi_reserved_bits_check(fw, "_NIC", "Health Error Injection Capabilities", ret->health_error_injection, sizeof(uint32_t), 2, 7, &failed);
>> + fwts_acpi_reserved_bits_check(fw, "_NIC", "Health Error Injection Capabilities", ret->health_error_injection, sizeof(uint32_t), 11, 15, &failed);
>> + fwts_acpi_reserved_bits_check(fw, "_NIC", "Health Error Injection Capabilities", ret->health_error_injection, sizeof(uint32_t), 19, 31, &failed);
>> +
>> + fwts_acpi_reserved_bits_check(fw, "_NIC", "Health Status Attributes Capabilities", ret->health_status_attributes, sizeof(uint32_t), 1, 31, &failed);
> same here.
>> +
>> + if (!failed)
>> + fwts_method_passed_sane(fw, name, "buffer");
>> +}
>> +
>> +static int method_test_NIC(fwts_framework *fw)
>> +{
>> + return method_evaluate_method(fw, METHOD_OPTIONAL,
>> + "_NIC", NULL, 0, method_test_NIC_return, NULL);
>> +}
>> +
>> +static void method_test_NIH_return(
>> + fwts_framework *fw,
>> + char *name,
>> + ACPI_BUFFER *buf,
>> + ACPI_OBJECT *obj,
>> + void *private)
>> +{
>> + bool failed = false;
>> + nih_return_t *ret;
>> +
>> + FWTS_UNUSED(private);
>> +
>> + if (fwts_method_check_type(fw, name, buf, ACPI_TYPE_BUFFER) != FWTS_OK)
>> + return;
>> +
>> + if (obj->Buffer.Length != 64) {
>> + failed = true;
>> + fwts_failed(fw, LOG_LEVEL_CRITICAL,
>> + "Method_NIHBadBufferSize",
>> + "%s should return a buffer of 64 bytes, but "
>> + "instead just returned %" PRIu32,
>> + name, obj->Buffer.Length);
>> + }
>> +
>> + ret = (nih_return_t *) obj->Buffer.Pointer;
>> + check_nvdimm_status(fw, name, ret->status, &failed);
>> + check_nvdimm_extended_status(fw, name, ret->extended_status, 1, &failed);
>> +
>> + if (!failed)
>> + fwts_method_passed_sane(fw, name, "buffer");
>> +}
>> +
>> +static int method_test_NIH(fwts_framework *fw)
>> +{
>> + ACPI_OBJECT arg0;
>> + char data[64];
>> + int result;
>> + int i, j;
>> +
>> + memset(data, 0, sizeof(data));
>> + arg0.Type = ACPI_TYPE_BUFFER;
>> + arg0.Buffer.Length = 64;
>> + arg0.Buffer.Pointer = (void *)data;
>> +
>> + /* not permanent (j = 0) and permanent (j = 1) errors */
>> + for (j = 0; j <= 1; j++) {
>> + /* inject (i = 1) and clear (i = 2) errors */
>> + for (i = 1; i <= 2; i++) {
>> + data[0] = i;
>> + data[4] = 3;
>> + data[5] = 7;
>> + data[6] = 7;
>> + data[8] = j;
>> +
>> + result = method_evaluate_method(fw, METHOD_OPTIONAL,
>> + "_NIH", &arg0, 1, method_test_NIH_return, NULL);
>> +
>> + if (result != FWTS_OK)
>> + return result;
>> + }
>> + }
>> +
>> + return FWTS_OK;
>> +}
>> +
>> +static void method_test_NIG_return(
>> + fwts_framework *fw,
>> + char *name,
>> + ACPI_BUFFER *buf,
>> + ACPI_OBJECT *obj,
>> + void *private)
>> +{
>> + bool failed = false;
>> + nig_return_t *ret;
>> +
>> + FWTS_UNUSED(private);
>> +
>> + if (fwts_method_check_type(fw, name, buf, ACPI_TYPE_BUFFER) != FWTS_OK)
>> + return;
>> +
>> + if (obj->Buffer.Length != 64) {
>> + failed = true;
>> + fwts_failed(fw, LOG_LEVEL_CRITICAL,
>> + "Method_NIGBadBufferSize",
>> + "%s should return a buffer of 64 bytes, but "
>> + "instead just returned %" PRIu32,
>> + name, obj->Buffer.Length);
>> + }
>> +
>> + ret = (nig_return_t *) obj->Buffer.Pointer;
>> + check_nvdimm_status(fw, name, ret->status, &failed);
>> + check_nvdimm_extended_status(fw, name, ret->extended_status, 0, &failed);
>> + fwts_acpi_reserved_bits_check(fw, "_NIG", "Validation Flags", ret->validation_flags, sizeof(uint16_t), 2, 15, &failed);
>> +
>> + /* Injected Health Status Errors [2..7], [11.15], [19..31] are reserved */
>> + fwts_acpi_reserved_bits_check(fw, "_NIG", "Injected Health Status Errors", ret->health_status_errors, sizeof(uint32_t), 2, 7, &failed);
>> + fwts_acpi_reserved_bits_check(fw, "_NIG", "Injected Health Status Errors", ret->health_status_errors, sizeof(uint32_t), 11, 15, &failed);
>> + fwts_acpi_reserved_bits_check(fw, "_NIG", "Injected Health Status Errors", ret->health_status_errors, sizeof(uint32_t), 19, 31, &failed);
>> +
>> + fwts_acpi_reserved_bits_check(fw, "_NIG", "Health Status Attributes of Injected Errors", ret->health_status_attributes, sizeof(uint32_t), 1, 31, &failed);
>> +
> same here.
>> + if (!failed)
>> + fwts_method_passed_sane(fw, name, "buffer");
>> +}
>> +
>> +static int method_test_NIG(fwts_framework *fw)
>> +{
>> + return method_evaluate_method(fw, METHOD_OPTIONAL,
>> + "_NIG", NULL, 0, method_test_NIG_return, NULL);
>> +}
>>
>> /*
>> * Section 10.1 Smart Battery
>> @@ -5896,6 +6175,13 @@ static fwts_framework_minor_test method_tests[] = {
>> { method_test_TIP, "Test _TIP (Expired Timer Wake Policy)." },
>> { method_test_TIV, "Test _TIV (Timer Values)." },
>>
>> + /* Section 9.20 NVDIMM Devices */
>> + { method_test_NBS, "Test _NBS (NVDIMM Boot Status)." },
>> + { method_test_NCH, "Test _NCH (NVDIMM Current Health Information)." },
>> + { method_test_NIC, "Test _NIC (NVDIMM Health Error Injection Capabilities)." },
>> + { method_test_NIH, "Test _NIH (NVDIMM Inject/Clear Health Errors)." },
>> + { method_test_NIG, "Test _NIG (NVDIMM Inject Health Error Status)." },
>> +
>> /* Section 10.1 Smart Battery */
>>
>> { method_test_SBS, "Test _SBS (Smart Battery Subsystem)." },
>> diff --git a/src/lib/include/fwts_acpi_object_eval.h b/src/lib/include/fwts_acpi_object_eval.h
>> index 4a7c5ed9..565af728 100644
>> --- a/src/lib/include/fwts_acpi_object_eval.h
>> +++ b/src/lib/include/fwts_acpi_object_eval.h
>> @@ -66,6 +66,46 @@ typedef struct {
>> uint8_t pad2[3];
>> } __attribute__ ((packed)) fwts_acpi_time_buffer;
>>
>> +/* Returns for NVDIMM control methods */
>> +typedef struct {
>> + uint16_t status;
>> + uint16_t extended_status;
>> + uint16_t validation_flags;
>> + uint32_t health_status_flags;
>> + uint32_t health_status_attributes;
>> + uint8_t reserved[50];
>> +} __attribute__ ((packed)) nch_return_t;
>> +
>> +typedef struct {
>> + uint16_t status;
>> + uint16_t extended_status;
>> + uint16_t validation_flags;
>> + uint32_t data_loss_count;
>> + uint8_t reserved[54];
>> +} __attribute__ ((packed)) nbs_return_t;
>> +
>> +typedef struct {
>> + uint16_t status;
>> + uint16_t extended_status;
>> + uint32_t health_error_injection;
>> + uint32_t health_status_attributes;
>> + uint8_t reserved[52];
>> +} __attribute__ ((packed)) nic_return_t;
>> +
>> +typedef struct {
>> + uint16_t status;
>> + uint16_t extended_status;
>> +} __attribute__ ((packed)) nih_return_t;
>> +
>> +typedef struct {
>> + uint16_t status;
>> + uint16_t extended_status;
>> + uint16_t validation_flags;
>> + uint32_t health_status_errors;
>> + uint32_t health_status_attributes;
>> + uint8_t reserved[50];
>> +} __attribute__ ((packed)) nig_return_t;
>> +
>> #define fwts_method_check_type(fw, name, buf, type) \
>> fwts_method_check_type__(fw, name, buf, type, #type)
Ack this patch first, can do the reserved return size on next patch.
Acked-by: Ivan Hu <ivan.hu at canonical.com>
-------------- next part --------------
A non-text attachment was scrubbed...
Name: signature.asc
Type: application/pgp-signature
Size: 473 bytes
Desc: OpenPGP digital signature
URL: <https://lists.ubuntu.com/archives/fwts-devel/attachments/20190218/41f5b2a0/attachment.sig>
More information about the fwts-devel
mailing list