hc
2024-03-22 a0752693d998599af469473b8dc239ef973a012f
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
152
153
154
155
156
/** @file
  Initializes Serial IO Controllers.
 
  Copyright (c) 2019 Intel Corporation. All rights reserved. <BR>
 
  SPDX-License-Identifier: BSD-2-Clause-Patent
**/
 
#include <Library/DebugLib.h>
#include <Library/IoLib.h>
#include <Library/BaseMemoryLib.h>
#include <Library/S3BootScriptLib.h>
#include <Library/UefiBootServicesTableLib.h>
#include <Library/DxeServicesTableLib.h>
 
#include "PchInit.h"
#include <Library/PchSerialIoLib.h>
#include <Library/DevicePathLib.h>
#include <IndustryStandard/Pci30.h>
#include <Register/PchRegsSerialIo.h>
 
typedef struct {
  ACPI_HID_DEVICE_PATH          RootPort;
  ACPI_EXTENDED_HID_DEVICE_PATH AcpiDev;
  CHAR8                         HidString[8];
  CHAR8                         UidString;
  CHAR8                         CidString;
  EFI_DEVICE_PATH_PROTOCOL      End;
} SERIALIO_DEVICE_PATH;
 
#define gPciRootBridge {{ACPI_DEVICE_PATH, ACPI_DP, {(UINT8)(sizeof(ACPI_HID_DEVICE_PATH)), 0}}, EISA_PNP_ID (0x0A03), 0}
#define gAcpiDev {{ACPI_DEVICE_PATH,ACPI_EXTENDED_DP,{(UINT8)(sizeof(ACPI_EXTENDED_HID_DEVICE_PATH)+SERIALIO_TOTAL_ID_LENGTH),0}},0,0,0}
#define gEndEntire {END_DEVICE_PATH_TYPE,END_ENTIRE_DEVICE_PATH_SUBTYPE,{END_DEVICE_PATH_LENGTH,0}}
 
GLOBAL_REMOVE_IF_UNREFERENCED SERIALIO_DEVICE_PATH gSerialIoPath = {
  gPciRootBridge,
  gAcpiDev,
  "\0\0\0\0\0\0\0",
  '\0',
  '\0',
  gEndEntire
};
 
/**
Mark memory used by SerialIo devices in ACPI mode as allocated
 
@retval EFI_SUCCESS             The function completed successfully
**/
EFI_STATUS
AllocateSerialIoMemory (
  VOID
  )
{
  PCH_SERIAL_IO_CONTROLLER i;
  UINT8                    BarNumber;
  UINTN                    Bar;
  EFI_STATUS               Status;
 
  for (i=0; i<PchSerialIoIndexMax; i++) {
    if (mPchConfigHob->SerialIo.DevMode[i] == PchSerialIoHidden ||
        mPchConfigHob->SerialIo.DevMode[i] == PchSerialIoAcpi) {
      for (BarNumber = 0; BarNumber<=1; BarNumber++) {
        Bar = FindSerialIoBar (i,BarNumber);
        Status = gDS->AddMemorySpace (
                        EfiGcdMemoryTypeReserved,
                        Bar,
                        V_SERIAL_IO_CFG_BAR_SIZE,
                        0
                        );
        ASSERT_EFI_ERROR (Status);
        if (EFI_ERROR (Status)) {
          return Status;
        }
        Status = gDS->AllocateMemorySpace (
                        EfiGcdAllocateAddress,
                        EfiGcdMemoryTypeReserved,
                        N_SERIAL_IO_CFG_BAR_ALIGNMENT,
                        V_SERIAL_IO_CFG_BAR_SIZE,
                        &Bar,
                        mImageHandle,
                        NULL
                        );
        ASSERT_EFI_ERROR (Status);
        if (EFI_ERROR (Status)) {
          return Status;
        }
      }
    }
  }
  return EFI_SUCCESS;
}
 
VOID
CreateSerialIoHandles (
  VOID
  )
{
  EFI_HANDLE NewHandle;
  EFI_DEVICE_PATH_PROTOCOL *NewPath;
  UINT32 Controller;
 
  for (Controller = 0; Controller < PchSerialIoIndexMax; Controller++) {
    if (mPchConfigHob->SerialIo.DevMode[Controller] == PchSerialIoAcpi) {
      NewHandle = NULL;
      CopyMem (gSerialIoPath.HidString, GetSerialIoAcpiHid (Controller), SERIALIO_HID_LENGTH);
      NewPath = DuplicateDevicePath ((EFI_DEVICE_PATH_PROTOCOL*)&gSerialIoPath);
      gBS->InstallMultipleProtocolInterfaces (
             &NewHandle,
             &gEfiDevicePathProtocolGuid,
             NewPath,
             NULL );
    }
  }
}
 
/**
  Puts all SerialIo controllers (except UARTs in debug mode) in D3.
  Clears MemoryEnable for all PCI-mode controllers on S3 resume
**/
VOID
ConfigureSerialIoAtS3Resume (
  VOID
  )
{
  PCH_SERIAL_IO_CONTROLLER Index;
  UINTN                    PciCfgBase;
  UINT32                   Data32;
 
  for (Index = 0; Index < PchSerialIoIndexMax; Index++) {
    if (mPchConfigHob->SerialIo.DevMode[Index] == PchSerialIoDisabled) {
      if (IsSerialIoFunctionZero (Index)) {
        if (IsSerialIoDeviceEnabled (GetSerialIoDeviceNumber (Index), GetSerialIoFunctionNumber (Index))) {
          PciCfgBase = FindSerialIoBar (Index,1);
          Data32 = MmioRead32 (PciCfgBase + R_SERIAL_IO_CFG_PME_CTRL_STS);
          Data32 |= B_SERIAL_IO_CFG_PME_CTRL_STS_PWR_ST;
          S3BootScriptSaveMemWrite (S3BootScriptWidthUint32, PciCfgBase + R_SERIAL_IO_CFG_PME_CTRL_STS, 1, &Data32);
        }
      }
      continue;
    }
    if ((Index >= PchSerialIoIndexUart0) &&
        (mPchConfigHob->SerialIo.EnableDebugUartAfterPost) &&
        (mPchConfigHob->SerialIo.DebugUartNumber == (UINT32) (Index - PchSerialIoIndexUart0))) {
      continue;
    }
    PciCfgBase = FindSerialIoBar (Index,1);
    Data32 = MmioRead32 (PciCfgBase + R_SERIAL_IO_CFG_PME_CTRL_STS);
    Data32 |= B_SERIAL_IO_CFG_PME_CTRL_STS_PWR_ST;
    S3BootScriptSaveMemWrite (S3BootScriptWidthUint32, PciCfgBase + R_SERIAL_IO_CFG_PME_CTRL_STS, 1, &Data32);
    if (mPchConfigHob->SerialIo.DevMode[Index] == PchSerialIoPci) {
      Data32 = MmioRead32 (PciCfgBase + PCI_COMMAND_OFFSET);
      Data32 &= (UINT32)~(EFI_PCI_COMMAND_MEMORY_SPACE | EFI_PCI_COMMAND_BUS_MASTER);
      S3BootScriptSaveMemWrite (S3BootScriptWidthUint32, PciCfgBase + PCI_COMMAND_OFFSET, 1, &Data32);
    }
  }
}