summaryrefslogtreecommitdiffstats
path: root/PrmPkg/PrmSsdtInstallDxe/PrmSsdtInstallDxe.c
blob: bd9ce2c6fa0200c60abe6a06d511698e1ab52054 (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
/** @file

  This file contains a sample implementation of the Platform Runtime Mechanism (PRM)
  SSDT Install library.

  Copyright (c) Microsoft Corporation
  Copyright (c) 2020, Intel Corporation. All rights reserved.<BR>
  SPDX-License-Identifier: BSD-2-Clause-Patent

**/

#include <IndustryStandard/Acpi.h>
#include <Library/BaseLib.h>
#include <Library/BaseMemoryLib.h>
#include <Library/DebugLib.h>
#include <Library/DxeServicesLib.h>
#include <Library/UefiBootServicesTableLib.h>
#include <Protocol/AcpiTable.h>

#define _DBGMSGID_  "[PRMSSDTINSTALL]"

/**
  Installs the PRM SSDT.

  @param[in]  OemId                       OEM ID to be used in the SSDT installation.

  @retval EFI_SUCCESS                     The PRM SSDT was installed successfully.
  @retval EFI_INVALID_PARAMETER           The OemId pointer argument is NULL.
  @retval EFI_NOT_FOUND                   An instance of gEfiAcpiTableProtocolGuid was not found installed or
                                          the SSDT (AML RAW section) could not be found in the current FV.
  @retval EFI_OUT_OF_RESOURCES            Insufficient memory resources to install the PRM SSDT.

**/
EFI_STATUS
InstallPrmSsdt (
  IN  CONST UINT8                         *OemId
  )
{
  EFI_STATUS                              Status;
  UINTN                                   SsdtSize;
  UINTN                                   TableKey;
  EFI_ACPI_TABLE_PROTOCOL                 *AcpiTableProtocol;
  EFI_ACPI_DESCRIPTION_HEADER             *Ssdt;

  DEBUG ((DEBUG_INFO, "%a %a - Entry.\n", _DBGMSGID_, __FUNCTION__));

  if (OemId == NULL) {
    return EFI_INVALID_PARAMETER;
  }

  Status = gBS->LocateProtocol (&gEfiAcpiTableProtocolGuid, NULL, (VOID **) &AcpiTableProtocol);
  if (!EFI_ERROR (Status)) {
    //
    // Discover the SSDT
    //
    Status =  GetSectionFromFv (
                &gEfiCallerIdGuid,
                EFI_SECTION_RAW,
                0,
                (VOID **) &Ssdt,
                &SsdtSize
                );
    ASSERT_EFI_ERROR (Status);
    DEBUG ((DEBUG_INFO, "%a %a: SSDT loaded...\n", _DBGMSGID_, __FUNCTION__));

    //
    // Update OEM ID in the SSDT
    //
    CopyMem (&Ssdt->OemId, OemId, sizeof (Ssdt->OemId));

    //
    // Publish the SSDT. Table is re-checksummed.
    //
    TableKey = 0;
    Status = AcpiTableProtocol->InstallAcpiTable (
                                  AcpiTableProtocol,
                                  Ssdt,
                                  SsdtSize,
                                  &TableKey
                                  );
    ASSERT_EFI_ERROR (Status);
  }

  return Status;
}

/**
  The entry point for this module.

  @param[in]  ImageHandle    The firmware allocated handle for the EFI image.
  @param[in]  SystemTable    A pointer to the EFI System Table.

  @retval EFI_SUCCESS    The entry point is executed successfully.
  @retval Others         An error occurred when executing this entry point.

**/
EFI_STATUS
EFIAPI
PrmSsdtInstallEntryPoint (
  IN EFI_HANDLE                           ImageHandle,
  IN EFI_SYSTEM_TABLE                     *SystemTable
  )
{
  EFI_STATUS    Status;

  Status = InstallPrmSsdt ((UINT8 *) PcdGetPtr (PcdAcpiDefaultOemId));
  ASSERT_EFI_ERROR (Status);

  return Status;
}