summaryrefslogtreecommitdiffstats
path: root/DynamicTablesPkg/Library/Common/AmlLib/ResourceData/AmlResourceData.c
blob: 41cf0bc453145afb3e6693544de4e747cdb2203d (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
/** @file
  AML Resource Data.

  Copyright (c) 2019 - 2020, Arm Limited. All rights reserved.<BR>

  SPDX-License-Identifier: BSD-2-Clause-Patent

  @par Glossary:
  - Rd or RD   - Resource Data
  - Rds or RDS - Resource Data Small
  - Rdl or RDL - Resource Data Large
**/

#include <ResourceData/AmlResourceData.h>

/** Check whether the resource data has the input descriptor Id.

  The small/large bit is included in the descriptor Id,
  but the size bits are not included for small resource data elements.

  @param  [in]  Header        Pointer to the first byte of a resource data
                              element.
  @param  [in]  DescriptorId  The descriptor to check against.

  @retval TRUE    The resource data has the descriptor Id.
  @retval FALSE   Otherwise.
**/
BOOLEAN
EFIAPI
AmlRdCompareDescId (
  IN  CONST AML_RD_HEADER   * Header,
  IN        AML_RD_HEADER     DescriptorId
  )
{
  if (Header == NULL) {
    ASSERT (0);
    return FALSE;
  }

  if (AML_RD_IS_LARGE (Header)) {
    return ((*Header ^ DescriptorId) == 0);
  } else {
    return (((*Header & AML_RD_SMALL_ID_MASK) ^ DescriptorId) == 0);
  }
}

/** Get the descriptor Id of the resource data.

  The small/large bit is included in the descriptor Id,
  but the size bits are not included for small resource data elements.

  @param  [in]  Header  Pointer to the first byte of a resource data.

  @return A descriptor Id.
**/
AML_RD_HEADER
EFIAPI
AmlRdGetDescId (
  IN  CONST AML_RD_HEADER   * Header
  )
{
  if (Header == NULL) {
    ASSERT (0);
    return FALSE;
  }

  if (AML_RD_IS_LARGE (Header)) {
    return *Header;
  }

  // Header is a small resource data element.
  return *Header & AML_RD_SMALL_ID_MASK;
}

/** Get the size of a resource data element.

  If the resource data element is of the large type, the Header
  is expected to be at least 3 bytes long.

  @param  [in]  Header  Pointer to the first byte of a resource data.

  @return The size of the resource data element.
**/
UINT32
EFIAPI
AmlRdGetSize (
  IN  CONST AML_RD_HEADER   * Header
  )
{
  if (Header == NULL) {
    ASSERT (0);
    return FALSE;
  }

  if (AML_RD_IS_LARGE (Header)) {
    return ((ACPI_LARGE_RESOURCE_HEADER*)Header)->Length +
             sizeof (ACPI_LARGE_RESOURCE_HEADER);
  }

  // Header is a small resource data element.
  return ((ACPI_SMALL_RESOURCE_HEADER*)Header)->Bits.Length +
           sizeof (ACPI_SMALL_RESOURCE_HEADER);
}

/** Set the Checksum of an EndTag resource data.

  ACPI 6.4, s6.4.2.9 "End Tag":
  "This checksum is generated such that adding it to the sum of all the data
  bytes will produce a zero sum."
  "If the checksum field is zero, the resource data is treated as if the
  checksum operation succeeded. Configuration proceeds normally."

  @param  [in]  Header     Pointer to the first byte of a resource data.
  @param  [in]  CheckSum   Checksum value to set.

  @retval EFI_SUCCESS             The function completed successfully.
  @retval EFI_INVALID_PARAMETER   Invalid parameter.
**/
EFI_STATUS
EFIAPI
AmlRdSetEndTagChecksum (
  IN  CONST AML_RD_HEADER   * Header,
  IN        UINT8             CheckSum
  )
{
  if ((Header == NULL)  ||
      !AmlRdCompareDescId (
        Header,
        AML_RD_BUILD_SMALL_DESC_ID (ACPI_SMALL_END_TAG_DESCRIPTOR_NAME))) {
    ASSERT (0);
    return EFI_INVALID_PARAMETER;
  }

  ((EFI_ACPI_END_TAG_DESCRIPTOR*)Header)->Checksum = CheckSum;
  return EFI_SUCCESS;
}