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
  EFI_STATUS           Status;
  UINT32               Index;
  OC_ACPI_PATCH_ENTRY  *UserPatch;
143
  CONST CHAR8          *Comment;
V
vit9696 已提交
144 145 146 147 148
  OC_ACPI_PATCH        Patch;

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

V
vit9696 已提交
149
    if (!UserPatch->Enabled) {
V
vit9696 已提交
150 151 152
      continue;
    }

153 154
    Comment = OC_BLOB_GET (&UserPatch->Comment);

V
vit9696 已提交
155 156 157 158 159 160
    //
    // Ignore patch if:
    // - There is nothing to replace.
    // - Find and replace mismatch in size.
    // - Mask and ReplaceMask mismatch in size when are available.
    //
161 162 163 164 165 166
    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)))
    {
167
      DEBUG ((DEBUG_ERROR, "OC: ACPI patch (%a) at %u is borked\n", Comment, Index));
V
vit9696 已提交
168 169 170 171
      continue;
    }

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

173
    Patch.Find    = OC_BLOB_GET (&UserPatch->Find);
V
vit9696 已提交
174 175 176
    Patch.Replace = OC_BLOB_GET (&UserPatch->Replace);

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

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

184 185 186 187 188 189
    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 已提交
190 191 192 193
    CopyMem (&Patch.TableSignature, UserPatch->TableSignature, sizeof (UserPatch->TableSignature));
    Patch.TableLength = UserPatch->TableLength;
    CopyMem (&Patch.OemTableId, UserPatch->OemTableId, sizeof (UserPatch->OemTableId));

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

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

VOID
OcLoadAcpiSupport (
  IN OC_STORAGE_CONTEXT  *Storage,
  IN OC_GLOBAL_CONFIG    *Config
  )
{
217 218
  EFI_STATUS       Status;
  OC_ACPI_CONTEXT  Context;
219 220 221 222

  Status = AcpiInitContext (&Context);

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

P
PMheart 已提交
227 228
  OcAcpiDeleteTables (Config, &Context);

229 230 231 232 233 234 235 236
  if (Config->Acpi.Quirks.RebaseRegions) {
    AcpiLoadRegions (&Context);
  }

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

237 238 239 240
  if (Config->Acpi.Quirks.ResetLogoStatus) {
    AcpiResetLogoStatus (&Context);
  }

241 242 243 244 245
  //
  // Log hardware signature.
  //
  AcpiHandleHardwareSignature (&Context, Config->Acpi.Quirks.ResetHwSig);

246 247 248 249 250 251 252 253
  if (Config->Acpi.Quirks.RebaseRegions) {
    AcpiRelocateRegions (&Context);
  }

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

254 255 256 257
  if (Config->Acpi.Quirks.SyncTableIds) {
    AcpiSyncTableIds (&Context);
  }

P
PMheart 已提交
258 259 260 261
  OcAcpiPatchTables (Config, &Context);

  OcAcpiAddTables (Config, Storage, &Context);

262 263 264 265
  AcpiApplyContext (&Context);

  AcpiFreeContext (&Context);
}