summaryrefslogtreecommitdiff
path: root/OvmfPkg/LoongArchVirt/Library/ResetSystemAcpiLib/BaseResetSystemAcpiGed.c
blob: a88ed2ace409a501ebb3d2a5bd7ca7e07c0f4445 (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
148
149
150
151
/** @file
  Base ResetSystem library implementation.

  Copyright (c) 2024 Loongson Technology Corporation Limited. All rights reserved.<BR>

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

**/

#include <Library/DebugLib.h>
#include <Library/MemoryAllocationLib.h>
#include <Library/QemuFwCfgLib.h>
#include "ResetSystemAcpiGed.h"

/**
  Get configuration item data by the firmware configuration file name.

  @param[in]  Name - Name of file to look up.

  @return    VOID*       The Pointer of Value of Firmware Configuration item read.
**/
STATIC
VOID *
GetFwCfgData (
  CONST CHAR8  *Name
  )
{
  FIRMWARE_CONFIG_ITEM  FwCfgItem;
  EFI_STATUS            Status;
  UINTN                 FwCfgSize;
  VOID                  *Data;

  Status = QemuFwCfgFindFile (Name, &FwCfgItem, &FwCfgSize);
  if (EFI_ERROR (Status)) {
    DEBUG ((DEBUG_ERROR, "%a %d read  %s error Status %d \n", __func__, __LINE__, Name, Status));
    return NULL;
  }

  Data = AllocatePool (FwCfgSize);
  if (Data == NULL) {
    return NULL;
  }

  QemuFwCfgSelectItem (FwCfgItem);
  QemuFwCfgReadBytes (FwCfgSize, Data);

  return Data;
}

/**
  Find the power manager related info from ACPI table

  @retval EFI_SUCCESS     Successfully find out all the required information.
  @retval EFI_NOT_FOUND   Failed to find the required info.
**/
STATIC
EFI_STATUS
GetPowerManagerByParseAcpiInfo (
  VOID
  )
{
  EFI_ACPI_5_0_FIXED_ACPI_DESCRIPTION_TABLE     *Fadt       = NULL;
  EFI_ACPI_3_0_ROOT_SYSTEM_DESCRIPTION_POINTER  *Rsdp       = NULL;
  EFI_ACPI_DESCRIPTION_HEADER                   *Xsdt       = NULL;
  EFI_ACPI_DESCRIPTION_HEADER                   *Rsdt       = NULL;
  VOID                                          *AcpiTables = NULL;
  UINT32                                        *Entry32    = NULL;
  UINTN                                         Entry32Num;
  UINT32                                        *Signature = NULL;
  UINTN                                         Idx;

  Rsdp = GetFwCfgData ("etc/acpi/rsdp");
  if (Rsdp == NULL) {
    DEBUG ((DEBUG_ERROR, "%a %d read etc/acpi/rsdp error \n", __func__, __LINE__));
    return EFI_NOT_FOUND;
  }

  AcpiTables = GetFwCfgData ("etc/acpi/tables");
  if (AcpiTables == NULL) {
    DEBUG ((DEBUG_ERROR, "%a %d read etc/acpi/tables error \n", __func__, __LINE__));
    FreePool (Rsdp);
    return EFI_NOT_FOUND;
  }

  Rsdt       = (EFI_ACPI_DESCRIPTION_HEADER *)((UINTN)AcpiTables +  Rsdp->RsdtAddress);
  Entry32    = (UINT32 *)(Rsdt + 1);
  Entry32Num = (Rsdt->Length - sizeof (EFI_ACPI_DESCRIPTION_HEADER)) >> 2;
  for (Idx = 0; Idx < Entry32Num; Idx++) {
    Signature = (UINT32 *)((UINTN)Entry32[Idx] + (UINTN)AcpiTables);
    if (*Signature == EFI_ACPI_5_0_FIXED_ACPI_DESCRIPTION_TABLE_SIGNATURE) {
      Fadt = (EFI_ACPI_5_0_FIXED_ACPI_DESCRIPTION_TABLE *)Signature;
      DEBUG ((DEBUG_INFO, "Found Fadt in Rsdt\n"));
      goto Done;
    }
  }

  Xsdt       = (EFI_ACPI_DESCRIPTION_HEADER *)((UINTN)AcpiTables +  Rsdp->XsdtAddress);
  Entry32    = (UINT32 *)(Xsdt + 1);
  Entry32Num = (Xsdt->Length - sizeof (EFI_ACPI_DESCRIPTION_HEADER)) >> 2;
  for (Idx = 0; Idx < Entry32Num; Idx++) {
    Signature = (UINT32 *)((UINTN)Entry32[Idx] + (UINTN)AcpiTables);
    if (*Signature == EFI_ACPI_5_0_FIXED_ACPI_DESCRIPTION_TABLE_SIGNATURE) {
      Fadt = (EFI_ACPI_5_0_FIXED_ACPI_DESCRIPTION_TABLE *)Signature;
      DEBUG ((DEBUG_INFO, "Found Fadt in Xsdt\n"));
      goto Done;
    }
  }

  FreePool (Rsdp);
  FreePool (AcpiTables);
  DEBUG ((DEBUG_ERROR, " Fadt Not Found\n"));
  return EFI_NOT_FOUND;

Done:
  mPowerManager.ResetRegAddr        = Fadt->ResetReg.Address;
  mPowerManager.ResetValue          = Fadt->ResetValue;
  mPowerManager.SleepControlRegAddr = Fadt->SleepControlReg.Address;
  mPowerManager.SleepStatusRegAddr  = Fadt->SleepStatusReg.Address;

  FreePool (Rsdp);
  FreePool (AcpiTables);

  return EFI_SUCCESS;
}

/**
  The constructor function to initialize mPowerManager.

  @retval EFI_SUCCESS     Initialize mPowerManager success.
  @retval EFI_NOT_FOUND   Failed to initialize mPowerManager.
**/
EFI_STATUS
EFI_API
ResetSystemLibConstructor (
  IN EFI_HANDLE        ImageHandle,
  IN EFI_SYSTEM_TABLE  *SystemTable
  )
{
  EFI_STATUS  Status;

  Status = GetPowerManagerByParseAcpiInfo ();
  if (EFI_ERROR (Status)) {
    DEBUG ((DEBUG_INFO, "%a:%d\n", __func__, __LINE__));
  }

  ASSERT (mPowerManager.SleepControlRegAddr);
  ASSERT (mPowerManager.SleepStatusRegAddr);
  ASSERT (mPowerManager.ResetRegAddr);

  return Status;
}