summaryrefslogtreecommitdiffstats
path: root/ShellPkg/Library/UefiShellAcpiViewCommandLib/Parsers/Wsmt/WsmtParser.c
blob: 3c7252b0bf54f70faa477822a337b14fed9e779e (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
/** @file
  WSMT table parser

  Copyright (C) 2024 Advanced Micro Devices, Inc. All rights reserved.
  SPDX-License-Identifier: BSD-2-Clause-Patent

  @par Reference(s):
    - Windows SMM Security Mitigation Table spec, version 1.0
**/

#include <Library/UefiLib.h>
#include <IndustryStandard/WindowsSmmSecurityMitigationTable.h>
#include "AcpiParser.h"

STATIC ACPI_DESCRIPTION_HEADER_INFO  AcpiHdrInfo;

/**
  This function validates the WSMT Protection flag.

  @param [in] Ptr  Pointer to the start of the buffer.
  @param [in] Context Pointer to context specific information e.g. this
                      could be a pointer to the ACPI table header.

**/
STATIC
VOID
EFIAPI
ValidateWsmtProtectionFlag (
  IN UINT8  *Ptr,
  IN VOID   *Context
  )
{
  UINT32  ProtectionFlag;

  ProtectionFlag = *(UINT32 *)Ptr;

  if ((ProtectionFlag & EFI_WSMT_PROTECTION_FLAGS_COMM_BUFFER_NESTED_PTR_PROTECTION) \
      == EFI_WSMT_PROTECTION_FLAGS_COMM_BUFFER_NESTED_PTR_PROTECTION)
  {
    if ((ProtectionFlag & EFI_WSMT_PROTECTION_FLAGS_FIXED_COMM_BUFFERS) \
        != EFI_WSMT_PROTECTION_FLAGS_FIXED_COMM_BUFFERS)
    {
      IncrementErrorCount ();
      Print (L"ERROR: COMM_BUFFER_NESTED_PTR_PROTECTION is set but FIXED_COMM_BUFFERS is not set.\n");
    }
  }
}

/**
  This function validates the reserved bits in the WSMT Protection flag.

  @param [in] Ptr  Pointer to the start of the buffer.
  @param [in] Context Pointer to context specific information e.g. this
                      could be a pointer to the ACPI table header.
**/
STATIC
VOID
EFIAPI
ValidateReserved (
  IN UINT8  *Ptr,
  IN VOID   *Context
  )
{
  UINT32  ProtectionFlag;

  ProtectionFlag = *(UINT32 *)Ptr;

  if ((ProtectionFlag & 0xFFFFFFF8) != 0) {
    IncrementErrorCount ();
    Print (L"ERROR: Reserved bits are not zero.\n");
  }
}

/**
  An ACPI_PARSER array describing the WSMT Protection flag .
**/
STATIC CONST ACPI_PARSER  WsmtProtectionFlagParser[] = {
  { L"FIXED_COMM_BUFFERS ",                1,  0, L"0x%x", NULL, NULL, NULL,             NULL },
  { L"COMM_BUFFER_NESTED_PTR_PROTECTION ", 1,  1, L"0x%x", NULL, NULL, NULL,             NULL },
  { L"SYSTEM_RESOURCE_PROTECTION ",        1,  2, L"0x%x", NULL, NULL, NULL,             NULL },
  { L"Reserved ",                          29, 3, L"0x%x", NULL, NULL, ValidateReserved, NULL },
};

/**
  This function prints WSMT Protection flag.
  If no format string is specified the Format must be NULL.

  @param [in] Format  Optional format string for tracing the data.
  @param [in] Ptr     Pointer to the start of the buffer.
**/
VOID
EFIAPI
DumpWsmtProtectionFlag (
  IN CONST CHAR16  *Format OPTIONAL,
  IN UINT8         *Ptr
  )
{
  if (Format != NULL) {
    Print (Format, *(UINT32 *)Ptr);
    return;
  }

  Print (L"0x%X\n", *(UINT32 *)Ptr);
  ParseAcpiBitFields (
    TRUE,
    2,
    NULL,
    Ptr,
    4,
    PARSER_PARAMS (WsmtProtectionFlagParser)
    );
}

/**
  An ACPI_PARSER array describing the ACPI WSMT Table.
**/
STATIC CONST ACPI_PARSER  WsmtParser[] = {
  PARSE_ACPI_HEADER (&AcpiHdrInfo),
  { L"Protection Flag",            4,36, NULL, DumpWsmtProtectionFlag, NULL, ValidateWsmtProtectionFlag, NULL }
};

/**
  This function parses the ACPI WSMT table.

  @param [in] Trace              If TRUE, trace the ACPI fields.
  @param [in] Ptr                Pointer to the start of the buffer.
  @param [in] AcpiTableLength    Length of the ACPI table.
  @param [in] AcpiTableRevision  Revision of the ACPI table.
**/
VOID
EFIAPI
ParseAcpiWsmt (
  IN BOOLEAN  Trace,
  IN UINT8    *Ptr,
  IN UINT32   AcpiTableLength,
  IN UINT8    AcpiTableRevision
  )
{
  ParseAcpi (
    Trace,
    0,
    "WSMT",
    Ptr,
    AcpiTableLength,
    PARSER_PARAMS (WsmtParser)
    );
}