hc
2024-03-25 edb30157bad0c0001c32b854271ace01d3b9a16a
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
/** @file
  Serial IO Private Lib implementation - UART part
  All function in this library is available for PEI, DXE, and SMM,
  But do not support UEFI RUNTIME environment call.
 
  Copyright (c) 2021, Intel Corporation. All rights reserved.<BR>
  SPDX-License-Identifier: BSD-2-Clause-Patent
**/
 
#include <Base.h>
#include <Uefi/UefiBaseType.h>
#include <Library/IoLib.h>
#include <Library/BaseLib.h>
#include <Library/PchInfoLib.h>
#include <Library/PciSegmentLib.h>
#include <Library/SerialIoAccessLib.h>
#include <Library/SerialIoPrivateLib.h>
#include <IndustryStandard/Pci30.h>
#include <Register/PchRegs.h>
#include <Register/SerialIoRegs.h>
#include <SerialIoPrivateLibInternal.h>
#include <PchLimits.h>
#include <Library/PchPciBdfLib.h>
 
/**
  Checks if UART is Hidden, and it's Pci Config space available
 
  @param[in]      UartNumber     Selects Serial IO UART device
 
  @retval   TRUE             UART is in hidden mode
  @retval   FALSE            UART is not in hidden mode
**/
BOOLEAN
IsSerialIoUartHidden (
  IN UINT8               UartNumber
  )
{
  if (MmioRead16 (GetSerialIoUartFixedPciCfgAddress (UartNumber) + PCI_DEVICE_ID_OFFSET) == GetSerialIoUartDeviceId (UartNumber)) {
    return TRUE;
  }
  return FALSE;
}
 
/**
  Configures Serial IO Controller before control is passd to the OS
 
  @param[in] UartNumber         UART Number
  @param[in] UartDeviceConfig   SerialIo UART Config
 
**/
VOID
SerialIoUartBootHandler (
  IN UINT8                      UartNumber,
  IN SERIAL_IO_UART_CONFIG      *UartDeviceConfig
  )
{
  UINT64   PciCfgBase;
  BOOLEAN  TurnOff;
 
  TurnOff = FALSE;
 
  //
  // Even if Uart is Hidden and in D3 SerialIoUartLib is capable of setting D0 during each write/read.
  // In case it is required for Os Debug DBG2 must be set to TRUE.
  //
  if (UartDeviceConfig->Mode == SerialIoUartPci || UartDeviceConfig->Mode == SerialIoUartHidden) {
    TurnOff = TRUE;
  }
 
  //
  // Uart in Com mode will be placed in D3 depending on PG configuration through ACPI _PS3
  //
 
  if ((UartDeviceConfig->Mode == SerialIoUartDisabled) && (SerialIoUartFuncNumber (UartNumber) == 0x0)) {
    if (SerialIoHigherFunctionsEnabled (SerialIoUartDevNumber (UartNumber))) {
      TurnOff = TRUE;
    }
  }
 
  if (UartDeviceConfig->DBG2 == TRUE) {
    TurnOff = FALSE;
  }
 
  if (TurnOff) {
    PciCfgBase = GetSerialIoUartPciCfg (UartNumber);
    SerialIoSetD3 (PciCfgBase);
    if ((UartDeviceConfig->Mode == SerialIoUartPci) || (UartDeviceConfig->Mode == SerialIoUartDisabled)) {
      SerialIoMmioDisable (PciCfgBase, TRUE);
    }
  }
}
 
/**
  Sets Pme Control Status and Command register values required for S3 Boot Script
 
  @param[in]     UartNumber         UART Number
  @param[in]     UartDeviceConfig   SerialIo UART Config
  @param[in/out] S3PciCfgBase       S3 Boot Script Pci Config Base
  @param[in/out] Command            Pci Command register data to save
  @param[in/out] Pme                Pci Pme Control register data to save
 
**/
VOID
SerialIoUartS3Handler (
  IN     UINT8                  UartNumber,
  IN     SERIAL_IO_UART_CONFIG  *UartDeviceConfig,
  IN OUT UINT64                 *S3PciCfgBase,
  IN OUT UINT32                 *Command,
  IN OUT UINT32                 *Pme
  )
{
  BOOLEAN  TurnOff;
  UINT64   PciCfgBase;
 
  *S3PciCfgBase = 0;
  TurnOff       = FALSE;
 
  if (UartDeviceConfig->Mode == SerialIoUartPci) {
    TurnOff = TRUE;
  }
 
  if ((UartDeviceConfig->Mode == SerialIoUartDisabled) && (SerialIoUartFuncNumber (UartNumber) == 0x0)) {
    if (SerialIoHigherFunctionsEnabled (SerialIoUartDevNumber (UartNumber))) {
      TurnOff = TRUE;
    }
  }
 
  if (TurnOff) {
    *S3PciCfgBase = GetSerialIoUartS3PciBase (UartNumber);
    PciCfgBase    = GetSerialIoUartPciCfg (UartNumber);
    *Pme          = PciSegmentRead32 ((UINTN) PciCfgBase + R_SERIAL_IO_CFG_PME_CTRL_STS);
    *Pme          = *Pme | BIT0 | BIT1;
    *Command      = PciSegmentRead32 ((UINTN) PciCfgBase + PCI_COMMAND_OFFSET);
    *Command      = *Command & (UINT32)~(EFI_PCI_COMMAND_MEMORY_SPACE | EFI_PCI_COMMAND_BUS_MASTER);
  }
}