OpenCoreAcpi.c 6.7 KB
Newer Older
1 2 3 4 5 6 7 8 9 10 11 12 13 14
/** @file
  OpenCore driver.

Copyright (c) 2019, vit9696. All rights reserved.<BR>
This program and the accompanying materials
are licensed and made available under the terms and conditions of the BSD License
which accompanies this distribution.  The full text of the license may be found at
http://opensource.org/licenses/bsd-license.php

THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.

**/

15
#include <Library/OcMainLib.h>
16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33

#include <Library/BaseLib.h>
#include <Library/DebugLib.h>
#include <Library/MemoryAllocationLib.h>
#include <Library/OcAcpiLib.h>
#include <Library/OcMiscLib.h>
#include <Library/OcStringLib.h>
#include <Library/PrintLib.h>
#include <Library/UefiBootServicesTableLib.h>

STATIC
VOID
OcAcpiAddTables (
  IN OC_GLOBAL_CONFIG    *Config,
  IN OC_STORAGE_CONTEXT  *Storage,
  IN OC_ACPI_CONTEXT     *Context
  )
{
34 35 36 37 38 39 40
  EFI_STATUS         Status;
  UINT8              *TableData;
  UINT32             TableDataLength;
  UINT32             Index;
  OC_ACPI_ADD_ENTRY  *Table;
  CONST CHAR8        *TablePath;
  CHAR16             FullPath[OC_STORAGE_SAFE_PATH_MAX];
41 42

  for (Index = 0; Index < Config->Acpi.Add.Count; ++Index) {
43
    Table     = Config->Acpi.Add.Values[Index];
44
    TablePath = OC_BLOB_GET (&Table->Path);
45

46
    if (!Table->Enabled || (TablePath[0] == '\0')) {
47
      DEBUG ((DEBUG_INFO, "OC: Skipping add ACPI %a (%d)\n", TablePath, Table->Enabled));
48 49 50
      continue;
    }

51 52 53 54 55 56 57 58 59 60 61
    Status = OcUnicodeSafeSPrint (FullPath, sizeof (FullPath), OPEN_CORE_ACPI_PATH "%a", TablePath);
    if (EFI_ERROR (Status)) {
      DEBUG ((
        DEBUG_WARN,
        "OC: Failed to fit ACPI path %s%a",
        OPEN_CORE_ACPI_PATH,
        TablePath
        ));
      continue;
    }

62 63 64 65 66 67 68 69
    UnicodeUefiSlashes (FullPath);

    TableData = OcStorageReadFileUnicode (Storage, FullPath, &TableDataLength);

    if (TableData == NULL) {
      DEBUG ((
        DEBUG_WARN,
        "OC: Failed to find ACPI %a\n",
70
        TablePath
71 72 73 74 75 76 77 78 79 80
        ));
      continue;
    }

    Status = AcpiInsertTable (Context, TableData, TableDataLength);

    if (EFI_ERROR (Status)) {
      DEBUG ((
        DEBUG_WARN,
        "OC: Failed to add ACPI %a - %r\n",
81
        TablePath,
82 83 84 85 86 87 88 89
        Status
        ));
    }
  }
}

STATIC
VOID
90
OcAcpiDeleteTables (
91 92
  IN OC_GLOBAL_CONFIG  *Config,
  IN OC_ACPI_CONTEXT   *Context
93 94
  )
{
95 96 97 98 99
  EFI_STATUS            Status;
  UINT32                Index;
  UINT32                Signature;
  UINT64                OemTableId;
  OC_ACPI_DELETE_ENTRY  *Table;
100

101 102
  for (Index = 0; Index < Config->Acpi.Delete.Count; ++Index) {
    Table = Config->Acpi.Delete.Values[Index];
103

V
vit9696 已提交
104
    if (!Table->Enabled) {
105 106 107 108 109 110
      continue;
    }

    CopyMem (&Signature, Table->TableSignature, sizeof (Table->TableSignature));
    CopyMem (&OemTableId, Table->OemTableId, sizeof (Table->OemTableId));

111
    Status = AcpiDeleteTable (
112 113 114 115 116 117
               Context,
               Signature,
               Table->TableLength,
               OemTableId,
               Table->All
               );
118 119 120 121

    if (EFI_ERROR (Status)) {
      DEBUG ((
        DEBUG_WARN,
V
vit9696 已提交
122
        "OC: Failed to drop ACPI %08X %016LX %u (%d) - %r\n",
123 124 125
        Signature,
        OemTableId,
        Table->TableLength,
V
vit9696 已提交
126
        Table->All,
127 128 129 130 131 132 133 134 135
        Status
        ));
    }
  }
}

STATIC
VOID
OcAcpiPatchTables (
136 137
  IN OC_GLOBAL_CONFIG  *Config,
  IN OC_ACPI_CONTEXT   *Context
138 139
  )
{
V
vit9696 已提交
140 141 142 143 144 145 146 147
  EFI_STATUS           Status;
  UINT32               Index;
  OC_ACPI_PATCH_ENTRY  *UserPatch;
  OC_ACPI_PATCH        Patch;

  for (Index = 0; Index < Config->Acpi.Patch.Count; ++Index) {
    UserPatch = Config->Acpi.Patch.Values[Index];

V
vit9696 已提交
148
    if (!UserPatch->Enabled) {
V
vit9696 已提交
149 150 151 152 153 154 155 156 157
      continue;
    }

    //
    // Ignore patch if:
    // - There is nothing to replace.
    // - Find and replace mismatch in size.
    // - Mask and ReplaceMask mismatch in size when are available.
    //
158 159 160 161 162 163
    if (  (UserPatch->Replace.Size == 0)
       || ((UserPatch->Find.Size > 0) && (UserPatch->Find.Size != UserPatch->Replace.Size))
       || ((UserPatch->Find.Size == 0) && (OC_BLOB_GET (&UserPatch->Base)[0] == '\0'))
       || ((UserPatch->Mask.Size > 0) && (UserPatch->Find.Size != UserPatch->Mask.Size))
       || ((UserPatch->ReplaceMask.Size > 0) && (UserPatch->Replace.Size != UserPatch->ReplaceMask.Size)))
    {
164
      DEBUG ((DEBUG_ERROR, "OC: ACPI patch (%a) at %u is borked\n", UserPatch->Comment, Index));
V
vit9696 已提交
165 166 167 168
      continue;
    }

    ZeroMem (&Patch, sizeof (Patch));
169

170
    Patch.Find    = OC_BLOB_GET (&UserPatch->Find);
V
vit9696 已提交
171 172 173
    Patch.Replace = OC_BLOB_GET (&UserPatch->Replace);

    if (UserPatch->Mask.Size > 0) {
174
      Patch.Mask = OC_BLOB_GET (&UserPatch->Mask);
V
vit9696 已提交
175 176 177 178 179 180
    }

    if (UserPatch->ReplaceMask.Size > 0) {
      Patch.ReplaceMask = OC_BLOB_GET (&UserPatch->ReplaceMask);
    }

181 182 183 184 185 186
    Patch.Base     = OC_BLOB_GET (&UserPatch->Base);
    Patch.BaseSkip = UserPatch->BaseSkip;
    Patch.Size     = UserPatch->Replace.Size;
    Patch.Count    = UserPatch->Count;
    Patch.Skip     = UserPatch->Skip;
    Patch.Limit    = UserPatch->Limit;
V
vit9696 已提交
187 188 189 190
    CopyMem (&Patch.TableSignature, UserPatch->TableSignature, sizeof (UserPatch->TableSignature));
    Patch.TableLength = UserPatch->TableLength;
    CopyMem (&Patch.OemTableId, UserPatch->OemTableId, sizeof (UserPatch->OemTableId));

191 192
    DEBUG ((
      DEBUG_INFO,
193
      "OC: Applying %u byte ACPI patch (%a) at %u, skip %u, count %u\n",
194
      Patch.Size,
195
      UserPatch->Comment,
M
Marvin Häuser 已提交
196
      Index,
197 198 199 200
      Patch.Skip,
      Patch.Count
      ));

V
vit9696 已提交
201 202
    Status = AcpiApplyPatch (Context, &Patch);
    if (EFI_ERROR (Status)) {
203
      DEBUG ((DEBUG_WARN, "OC: ACPI patcher failed (%a) at %u - %r\n", UserPatch->Comment, Index, Status));
V
vit9696 已提交
204 205
    }
  }
206 207 208 209 210 211 212 213
}

VOID
OcLoadAcpiSupport (
  IN OC_STORAGE_CONTEXT  *Storage,
  IN OC_GLOBAL_CONFIG    *Config
  )
{
214 215
  EFI_STATUS       Status;
  OC_ACPI_CONTEXT  Context;
216 217 218 219

  Status = AcpiInitContext (&Context);

  if (EFI_ERROR (Status)) {
220
    DEBUG ((DEBUG_ERROR, "OC: Failed to initialize ACPI support - %r\n", Status));
221 222 223
    return;
  }

P
PMheart 已提交
224 225
  OcAcpiDeleteTables (Config, &Context);

226 227 228 229 230 231 232 233
  if (Config->Acpi.Quirks.RebaseRegions) {
    AcpiLoadRegions (&Context);
  }

  if (Config->Acpi.Quirks.FadtEnableReset) {
    AcpiFadtEnableReset (&Context);
  }

234 235 236 237
  if (Config->Acpi.Quirks.ResetLogoStatus) {
    AcpiResetLogoStatus (&Context);
  }

238 239 240 241 242
  //
  // Log hardware signature.
  //
  AcpiHandleHardwareSignature (&Context, Config->Acpi.Quirks.ResetHwSig);

243 244 245 246 247 248 249 250
  if (Config->Acpi.Quirks.RebaseRegions) {
    AcpiRelocateRegions (&Context);
  }

  if (Config->Acpi.Quirks.NormalizeHeaders) {
    AcpiNormalizeHeaders (&Context);
  }

251 252 253 254
  if (Config->Acpi.Quirks.SyncTableIds) {
    AcpiSyncTableIds (&Context);
  }

P
PMheart 已提交
255 256 257 258
  OcAcpiPatchTables (Config, &Context);

  OcAcpiAddTables (Config, Storage, &Context);

259 260 261 262
  AcpiApplyContext (&Context);

  AcpiFreeContext (&Context);
}