OpenCoreAcpi.c 6.4 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 34 35 36 37

#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
  )
{
  EFI_STATUS           Status;
  UINT8                *TableData;
  UINT32               TableDataLength;
  UINT32               Index;
38 39
  OC_ACPI_ADD_ENTRY    *Table;
  CONST CHAR8          *TablePath;
40
  CHAR16               FullPath[OC_STORAGE_SAFE_PATH_MAX];
41 42

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

46 47
    if (!Table->Enabled || TablePath[0] == '\0') {
      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 93 94 95 96 97 98
  IN OC_GLOBAL_CONFIG    *Config,
  IN OC_ACPI_CONTEXT     *Context
  )
{
  EFI_STATUS           Status;
  UINT32               Index;
  UINT32               Signature;
  UINT64               OemTableId;
99
  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
      Context,
      Signature,
      Table->TableLength,
115 116
      OemTableId,
      Table->All
117 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 136 137 138 139
        Status
        ));
    }
  }
}

STATIC
VOID
OcAcpiPatchTables (
  IN OC_GLOBAL_CONFIG    *Config,
  IN OC_ACPI_CONTEXT     *Context
  )
{
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 158
      continue;
    }

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

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

V
vit9696 已提交
169 170 171 172 173 174 175 176 177 178 179
    Patch.Find  = OC_BLOB_GET (&UserPatch->Find);
    Patch.Replace = OC_BLOB_GET (&UserPatch->Replace);

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

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

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

    Status = AcpiApplyPatch (Context, &Patch);
    if (EFI_ERROR (Status)) {
      DEBUG ((DEBUG_WARN, "OC: ACPI patcher failed %u - %r\n", Index, Status));
    }
  }
195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216
}

VOID
OcLoadAcpiSupport (
  IN OC_STORAGE_CONTEXT  *Storage,
  IN OC_GLOBAL_CONFIG    *Config
  )
{
  EFI_STATUS        Status;
  OC_ACPI_CONTEXT   Context;

  Status = AcpiInitContext (&Context);

  if (EFI_ERROR (Status)) {
    DEBUG ((DEBUG_ERROR, "OC: Failed to initialize ACPI support - %r", Status));
    return;
  }

  if (Config->Acpi.Quirks.RebaseRegions) {
    AcpiLoadRegions (&Context);
  }

217 218
  OcAcpiPatchTables (Config, &Context);

219
  OcAcpiDeleteTables (Config, &Context);
220 221 222 223 224 225 226

  OcAcpiAddTables (Config, Storage, &Context);

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

227 228 229 230
  if (Config->Acpi.Quirks.ResetLogoStatus) {
    AcpiResetLogoStatus (&Context);
  }

231 232 233 234 235
  //
  // Log hardware signature.
  //
  AcpiHandleHardwareSignature (&Context, Config->Acpi.Quirks.ResetHwSig);

236 237 238 239 240 241 242 243
  if (Config->Acpi.Quirks.RebaseRegions) {
    AcpiRelocateRegions (&Context);
  }

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

244 245 246 247
  if (Config->Acpi.Quirks.SyncTableIds) {
    AcpiSyncTableIds (&Context);
  }

248 249 250 251
  AcpiApplyContext (&Context);

  AcpiFreeContext (&Context);
}