<div dir="ltr"><div dir="ltr"><div class="gmail_default" style="font-family:verdana,sans-serif"><br></div></div><br><div class="gmail_quote"><div dir="ltr" class="gmail_attr">On Fri, Apr 16, 2021 at 1:35 AM Colin Ian King <<a href="mailto:colin.king@canonical.com">colin.king@canonical.com</a>> wrote:<br></div><blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left:1px solid rgb(204,204,204);padding-left:1ex">On 16/04/2021 04:09, Alex Hung wrote:<br>
> There are signifcant changes in revision 2 which is not compatible with<br>
> revision 1.<br>
> <br>
> Signed-off-by: Alex Hung <<a href="mailto:alex.hung@canonical.com" target="_blank">alex.hung@canonical.com</a>><br>
> ---<br>
>  src/acpi/pmtt/pmtt.c        | 146 ++++++++++++++++++------------------<br>
>  src/lib/include/fwts_acpi.h |  21 ++----<br>
>  2 files changed, 78 insertions(+), 89 deletions(-)<br>
> <br>
> diff --git a/src/acpi/pmtt/pmtt.c b/src/acpi/pmtt/pmtt.c<br>
> index 27ec58b8..7cd0952b 100644<br>
> --- a/src/acpi/pmtt/pmtt.c<br>
> +++ b/src/acpi/pmtt/pmtt.c<br>
> @@ -23,10 +23,15 @@<br>
>  #include <inttypes.h><br>
>  #include <stdbool.h><br>
>  <br>
> +static void pmtt_memory_device(fwts_framework *fw, fwts_acpi_table_pmtt_header *entry, uint32_t offset, bool *passed);<br>
> +<br>
>  static fwts_acpi_table_info *table;<br>
>  acpi_table_init(PMTT, &table)<br>
>  <br>
> -static void pmtt_subtable_header_test(fwts_framework *fw, fwts_acpi_table_pmtt_header *entry, bool *passed)<br>
> +static void pmtt_subtable_header_test(<br>
> +     fwts_framework *fw,<br>
> +     fwts_acpi_table_pmtt_header *entry,<br>
> +     bool *passed)<br>
>  {<br>
>       fwts_log_info_verbatim(fw, "  PMTT Subtable:");<br>
>       fwts_log_info_simp_int(fw, "    Type:                           ", entry->type);<br>
> @@ -48,16 +53,14 @@ static void pmtt_subtable_header_test(fwts_framework *fw, fwts_acpi_table_pmtt_h<br>
>       fwts_acpi_reserved_zero_check("PMTT", "Reserved2", entry->reserved2, passed);<br>
>  }<br>
>  <br>
> -static void pmtt_physical_component_test(fwts_framework *fw, fwts_acpi_table_pmtt_physical_component *entry, bool *passed)<br>
> +static void pmtt_physical_component_test(<br>
> +     fwts_framework *fw,<br>
> +     fwts_acpi_table_pmtt_physical_component *entry,<br>
> +     bool *passed)<br>
>  {<br>
>       pmtt_subtable_header_test(fw, &entry->header, passed);<br>
> -     fwts_log_info_simp_int(fw, "    Physical Component Identifier:  ", entry->component_id);<br>
> -     fwts_log_info_simp_int(fw, "    Reserved:                       ", entry->reserved);<br>
> -     fwts_log_info_simp_int(fw, "    Size of DIMM:                   ", entry->memory_size);<br>
>       fwts_log_info_simp_int(fw, "    SMBIOS Handle:                  ", entry->bios_handle);<br>
>  <br>
> -     fwts_acpi_reserved_zero_check("PMTT", "Reserved", entry->reserved, passed);<br>
> -<br>
>       if ((entry->bios_handle & 0xFFFF0000) != 0 && entry->bios_handle != 0xFFFFFFFF) {<br>
>               *passed = false;<br>
>               fwts_failed(fw, LOG_LEVEL_HIGH,<br>
> @@ -67,43 +70,30 @@ static void pmtt_physical_component_test(fwts_framework *fw, fwts_acpi_table_pmt<br>
>       }<br>
>  }<br>
>  <br>
> -static void pmtt_controller_test(fwts_framework *fw, fwts_acpi_table_pmtt_controller *entry, bool *passed)<br>
> +static void pmtt_controller_test(<br>
> +     fwts_framework *fw,<br>
> +     fwts_acpi_table_pmtt_controller *entry,<br>
> +     uint32_t entry_offset,<br>
> +     bool *passed)<br>
>  {<br>
>       fwts_acpi_table_pmtt_header *header;<br>
>       uint32_t offset = 0;<br>
> -     size_t i;<br>
>  <br>
>       pmtt_subtable_header_test(fw, &entry->header, passed);<br>
> -     fwts_log_info_simp_int(fw, "    Read Latency:                   ", entry->read_latency);<br>
> -     fwts_log_info_simp_int(fw, "    Write latency:                  ", entry->write_latency);<br>
> -     fwts_log_info_simp_int(fw, "    Read Bandwidth:                 ", entry->read_bandwidth);<br>
> -     fwts_log_info_simp_int(fw, "    Write Bandwidth:                ", entry->write_bandwidth);<br>
> -     fwts_log_info_simp_int(fw, "    Optimal Access Unit:            ", entry->access_width);<br>
> -     fwts_log_info_simp_int(fw, "    Optimal Access Alignment:       ", entry->alignment);<br>
> +     fwts_log_info_simp_int(fw, "    Memory Controller ID            ", entry->memory_controller_id);<br>
>       fwts_log_info_simp_int(fw, "    Reserved:                       ", entry->reserved);<br>
> -     fwts_log_info_simp_int(fw, "    Number of Proximity Domains:    ", entry->domain_count);<br>
>  <br>
>       fwts_acpi_reserved_zero_check("PMTT", "Reserved", entry->reserved, passed);<br>
>  <br>
>       offset = sizeof(fwts_acpi_table_pmtt_controller);<br>
> -     if (entry->header.length < offset + sizeof(fwts_acpi_table_pmtt_domain) * entry->domain_count) {<br>
> -             *passed = false;<br>
> -             fwts_failed(fw, LOG_LEVEL_HIGH,<br>
> -                     "PMTTOutOfBound",<br>
> -                     "PMTT's length is too small to contain all fields");<br>
> -             return;<br>
> -     }<br>
> -<br>
> -     fwts_acpi_table_pmtt_domain *domain = (fwts_acpi_table_pmtt_domain *)(((char *) entry) + offset);<br>
> -     for (i = 0; i < entry->domain_count; i++) {<br>
> -             fwts_log_info_simp_int(fw, "    Proximity Domain:               ", domain->proximity_domain);<br>
> -             domain++;<br>
> -             /* TODO cross check proximity domain with SRAT table*/<br>
> -     }<br>
> -<br>
> -     offset += sizeof(fwts_acpi_table_pmtt_domain) * entry->domain_count;<br>
>       header = (fwts_acpi_table_pmtt_header *) (((char *) entry) + offset);<br>
>       while (offset < entry->header.length) {<br>
> +             /* stop if sub-structure is outside the table */<br>
> +             if (fwts_acpi_structure_range_check(fw, "PMTT", table->length, entry_offset + offset)) {<br>
> +                     *passed = false;<br>
> +                     break;<br>
> +             }<br>
> +<br>
>               if (header->length == 0) {<br>
>                       fwts_failed(fw, LOG_LEVEL_CRITICAL,<br>
>                               "PMTTBadSubtableLength",<br>
> @@ -111,22 +101,18 @@ static void pmtt_controller_test(fwts_framework *fw, fwts_acpi_table_pmtt_contro<br>
>                       break;<br>
>               }<br>
>  <br>
> -             if (header->type == FWTS_ACPI_PMTT_TYPE_DIMM) {<br>
> -                     pmtt_physical_component_test(fw, (fwts_acpi_table_pmtt_physical_component *) header, passed);<br>
> -             } else {<br>
> -                     *passed = false;<br>
> -                     fwts_failed(fw, LOG_LEVEL_HIGH,<br>
> -                             "PMTTBadSubtableType",<br>
> -                             "PMTT Controller must have subtable with Type 2, got "<br>
> -                             "0x%4.4" PRIx16 " instead", header->type);<br>
> -             }<br>
> +             pmtt_memory_device(fw, header, entry_offset + offset, passed);<br>
>  <br>
>               offset += header->length;<br>
>               header = (fwts_acpi_table_pmtt_header *)(((char *) entry) + offset);<br>
>       }<br>
>  }<br>
>  <br>
> -static void pmtt_socket_test(fwts_framework *fw, fwts_acpi_table_pmtt_socket *entry, bool *passed)<br>
> +static void pmtt_socket_test(<br>
> +     fwts_framework *fw,<br>
> +     fwts_acpi_table_pmtt_socket *entry,<br>
> +     uint32_t entry_offset,<br>
> +     bool *passed)<br>
>  {<br>
>       fwts_acpi_table_pmtt_header *header;<br>
>       uint32_t offset;<br>
> @@ -140,6 +126,12 @@ static void pmtt_socket_test(fwts_framework *fw, fwts_acpi_table_pmtt_socket *en<br>
>       offset = sizeof(fwts_acpi_table_pmtt_socket);<br>
>       header = (fwts_acpi_table_pmtt_header *) (((char *) entry) + offset);<br>
>       while (offset < entry->header.length) {<br>
> +             /* stop if sub-structure is outside the table */<br>
> +             if (fwts_acpi_structure_range_check(fw, "PMTT", table->length, entry_offset + offset)) {<br>
> +                     *passed = false;<br>
> +                     break;<br>
> +             }<br>
> +<br>
>               if (header->length == 0) {<br>
>                       fwts_failed(fw, LOG_LEVEL_CRITICAL,<br>
>                               "PMTTBadSubtableLength",<br>
> @@ -147,21 +139,42 @@ static void pmtt_socket_test(fwts_framework *fw, fwts_acpi_table_pmtt_socket *en<br>
>                       break;<br>
>               }<br>
>  <br>
> -             if (header->type == FWTS_ACPI_PMTT_TYPE_CONTROLLER) {<br>
> -                     pmtt_controller_test(fw, (fwts_acpi_table_pmtt_controller *) header, passed);<br>
> -             } else {<br>
> -                     *passed = false;<br>
> -                     fwts_failed(fw, LOG_LEVEL_HIGH,<br>
> -                             "PMTTBadSubtableType",<br>
> -                             "PMTT Socket must have subtable with Type 1, got "<br>
> -                             "0x%4.4" PRIx16 " instead", header->type);<br>
> -             }<br>
> +             pmtt_memory_device(fw, header, entry_offset + offset, passed);<br>
>  <br>
>               offset += header->length;<br>
>               header = (fwts_acpi_table_pmtt_header *)(((char *) entry) + offset);<br>
>       }<br>
>  }<br>
>  <br>
> +static void pmtt_memory_device(<br>
> +     fwts_framework *fw,<br>
> +     fwts_acpi_table_pmtt_header *entry,<br>
> +     uint32_t offset,<br>
> +     bool *passed)<br>
> +{<br>
> +     switch(entry->type) {<br>
> +             case FWTS_ACPI_PMTT_TYPE_SOCKET:<br>
> +                     pmtt_socket_test(fw, (fwts_acpi_table_pmtt_socket *) entry, offset, passed);<br>
> +                     break;<br>
> +             case FWTS_ACPI_PMTT_TYPE_CONTROLLER:<br>
> +                     pmtt_controller_test(fw, (fwts_acpi_table_pmtt_controller *) entry, offset, passed);<br>
> +                     break;<br>
> +             case FWTS_ACPI_PMTT_TYPE_DIMM:<br>
> +                     pmtt_physical_component_test(fw, (fwts_acpi_table_pmtt_physical_component *) entry, passed);<br>
> +                     break;<br>
> +             case FWTS_ACPI_PMTT_TYPE_VENDOR_SPECIFIC:<br>
> +                     /* no tests for vendor-specific type */<br>
> +                     break;<br>
> +             default:<br>
> +                     *passed = false;<br>
> +                     fwts_failed(fw, LOG_LEVEL_HIGH,<br>
> +                             "PMTTBadSubtableType",<br>
> +                             "PMTT must have subtable with Type 1..2 or 0xFF, got "<br>
> +                             "0x%4.4" PRIx16 " instead", entry->type);<br>
> +                     break;<br>
> +     }<br>
> +}<br>
> +<br>
>  static int pmtt_test1(fwts_framework *fw)<br>
>  {<br>
>       fwts_acpi_table_pmtt *pmtt = (fwts_acpi_table_pmtt*) table->data;<br>
> @@ -169,10 +182,14 @@ static int pmtt_test1(fwts_framework *fw)<br>
>       uint32_t offset;<br>
>       bool passed = true;<br>
>  <br>
> -     fwts_log_info_verbatim(fw, "PMTT Table:");<br>
> -     fwts_log_info_simp_int(fw, "  Reserved:                         ", pmtt->reserved);<br>
> +     if (pmtt->header.revision < 2) {<br>
> +             fwts_failed(fw, LOG_LEVEL_CRITICAL, "PMTTDeprecatedRevision",<br>
> +                     "PMTT Revision 1 has been deprecated in ACPI 6.4");<br>
> +             return FWTS_OK;<br>
> +     }<br>
>  <br>
> -     fwts_acpi_reserved_zero_check("PMTT", "Reserved", pmtt->reserved, &passed);<br>
> +     fwts_log_info_verbatim(fw, "PMTT Table:");<br>
> +     fwts_log_info_simp_int(fw, "  Number of Memory Devices:         ", pmtt->num_devices);<br>
>  <br>
>       entry = (fwts_acpi_table_pmtt_header *) (table->data + sizeof(fwts_acpi_table_pmtt));<br>
>       offset = sizeof(fwts_acpi_table_pmtt);<br>
> @@ -186,29 +203,12 @@ static int pmtt_test1(fwts_framework *fw)<br>
>                       break;<br>
>               }<br>
>  <br>
> -             switch(entry->type) {<br>
> -                     case FWTS_ACPI_PMTT_TYPE_SOCKET:<br>
> -                             pmtt_socket_test(fw, (fwts_acpi_table_pmtt_socket *) entry, &passed);<br>
> -                             break;<br>
> -                     case FWTS_ACPI_PMTT_TYPE_CONTROLLER:<br>
> -                             pmtt_controller_test(fw, (fwts_acpi_table_pmtt_controller *) entry, &passed);<br>
> -                             break;<br>
> -                     case FWTS_ACPI_PMTT_TYPE_DIMM:<br>
> -                             pmtt_physical_component_test(fw, (fwts_acpi_table_pmtt_physical_component *) entry, &passed);<br>
> -                             break;<br>
> -                     default:<br>
> -                             passed = false;<br>
> -                             fwts_failed(fw, LOG_LEVEL_HIGH,<br>
> -                                     "PMTTBadSubtableType",<br>
> -                                     "PMTT must have subtable with Type 1..2, got "<br>
> -                                     "0x%4.4" PRIx16 " instead", entry->type);<br>
> -                             break;<br>
> -             }<br>
> +             pmtt_memory_device(fw, entry, offset, &passed);<br>
>  <br>
>               offset += entry->length;<br>
>               entry = (fwts_acpi_table_pmtt_header *) (table->data + offset);<br>
> +             fwts_log_nl(fw);<br>
>       }<br>
> -     fwts_log_nl(fw);<br>
>  <br>
>       if (passed)<br>
>               fwts_passed(fw, "No issues found in PMTT table.");<br>
> diff --git a/src/lib/include/fwts_acpi.h b/src/lib/include/fwts_acpi.h<br>
> index 2a6c76ea..c1345803 100644<br>
> --- a/src/lib/include/fwts_acpi.h<br>
> +++ b/src/lib/include/fwts_acpi.h<br>
> @@ -1134,7 +1134,7 @@ typedef struct {<br>
>   */<br>
>  typedef struct {<br>
>       fwts_acpi_table_header  header;<br>
> -     uint32_t        reserved;<br>
> +     uint32_t        num_devices;<br>
>  } __attribute__ ((packed)) fwts_acpi_table_pmtt;<br>
>  <br>
>  typedef struct {<br>
> @@ -1143,13 +1143,15 @@ typedef struct {<br>
>       uint16_t        length;<br>
>       uint16_t        flags;<br>
>       uint16_t        reserved2;<br>
> +     uint32_t        num_devices;<br>
>  } __attribute__ ((packed)) fwts_acpi_table_pmtt_header;<br>
>  <br>
>  typedef enum {<br>
>       FWTS_ACPI_PMTT_TYPE_SOCKET              = 0,<br>
>       FWTS_ACPI_PMTT_TYPE_CONTROLLER          = 1,<br>
>       FWTS_ACPI_PMTT_TYPE_DIMM                = 2,<br>
> -     FWTS_ACPI_PMTT_TYPE_RESERVED            = 3 /* 0x03-0xFF are reserved */<br>
> +     FWTS_ACPI_PMTT_TYPE_RESERVED            = 3, /* 0x03-0xFE are reserved */<br>
> +     FWTS_ACPI_PMTT_TYPE_VENDOR_SPECIFIC     = 0xFF<br>
>  } fwts_acpi_pmtt_type;<br>
>  <br>
>  typedef struct {<br>
> @@ -1160,25 +1162,12 @@ typedef struct {<br>
>  <br>
>  typedef struct {<br>
>       fwts_acpi_table_pmtt_header     header;<br>
> -     uint32_t        read_latency;<br>
> -     uint32_t        write_latency;<br>
> -     uint32_t        read_bandwidth;<br>
> -     uint32_t        write_bandwidth;<br>
> -     uint16_t        access_width;<br>
> -     uint16_t        alignment;<br>
> +     uint16_t        memory_controller_id;<br>
>       uint16_t        reserved;<br>
> -     uint16_t        domain_count;<br>
>  } __attribute__ ((packed)) fwts_acpi_table_pmtt_controller;<br>
>  <br>
> -typedef struct {<br>
> -     uint32_t        proximity_domain;<br>
> -} __attribute__ ((packed)) fwts_acpi_table_pmtt_domain;<br>
> -<br>
>  typedef struct {<br>
>       fwts_acpi_table_pmtt_header     header;<br>
> -     uint16_t        component_id;<br>
> -     uint16_t        reserved;<br>
> -     uint32_t        memory_size;<br>
>       uint32_t        bios_handle;<br>
>  } __attribute__ ((packed)) fwts_acpi_table_pmtt_physical_component;<br>
>  <br>
> <br>
<br>
<br>
I'm getting a build issue based on today's tip:<br>
<br>
acpi/pmtt/pmtt.c:92:7: error: implicit declaration of function<br>
‘fwts_acpi_structure_range_check’; did you mean<br>
‘fwts_acpi_structure_length_check’? [-Werror=implicit-function-declaration]<br>
   92 |   if (fwts_acpi_structure_range_check(fw, "PMTT", table->length,<br>
entry_offset + offset)) {<br>
      |       ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~<br>
      |       fwts_acpi_structure_length_check<br>
<br>
<br>
I guess there are some pending changes that are not in the repo yet.<br></blockquote><div><br></div><div style="font-family:verdana,sans-serif" class="gmail_default">Yes the function is in another V2 patch (<a href="http://patchwork.ozlabs.org/project/fwts/patch/20210411205621.116069-1-alex.hung@canonical.com/">http://patchwork.ozlabs.org/project/fwts/patch/20210411205621.116069-1-alex.hung@canonical.com/</a>)</div><blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left:1px solid rgb(204,204,204);padding-left:1ex">
<br>
Colin<br>
<br>
</blockquote></div><br clear="all"><br>-- <br><div dir="ltr" class="gmail_signature"><div dir="ltr">Cheers,<br>Alex Hung<br></div></div></div>