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
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
/** @file
  Serial IO Private Lib implementation.
  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/SerialIoAccessLib.h>
#include <Library/SerialIoPrivateLib.h>
#include <Library/PciSegmentLib.h>
#include <Register/PchRegs.h>
#include <Register/SerialIoRegs.h>
#include <Include/PcieRegs.h>
#include <IndustryStandard/Pci30.h>
#include <PchReservedResources.h>
 
/**
  Checks if higher functions are enabled.
  Used for Function 0 Serial Io Device disabling
 
  @param[in] DeviceNum       Device Number
 
  @retval TRUE               At least one higher function device is enabled
          FALSE              Higher functions are disabled
**/
BOOLEAN
SerialIoHigherFunctionsEnabled (
  IN UINT8                    DeviceNum
  )
{
  UINT8 FuncNum;
  //
  // Check all other func devs(1 to 7) status except func 0.
  //
  for (FuncNum = 1; FuncNum <= PCI_MAX_FUNC; FuncNum++) {
    if (PciSegmentRead16 (PCI_SEGMENT_LIB_ADDRESS (DEFAULT_PCI_SEGMENT_NUMBER_PCH,
                                                   DEFAULT_PCI_BUS_NUMBER_PCH,
                                                   DeviceNum,
                                                   FuncNum,
                                                   PCI_DEVICE_ID_OFFSET)
                          ) != 0xFFFF) {
      return TRUE;
    }
  }
  return FALSE;
}
 
/**
  Places SerialIo device in D3
 
  @param[in] PciCfgBase       Pci Config Offset
 
**/
VOID
SerialIoSetD3 (
  IN UINT64                    PciCfgBase
  )
{
  if (PciCfgBase < PCH_SERIAL_IO_BASE_ADDRESS) {
    PciSegmentOr32 (PciCfgBase + R_SERIAL_IO_CFG_PME_CTRL_STS, BIT1 | BIT0);
  } else {
    MmioOr8 ((UINTN) PciCfgBase + R_SERIAL_IO_CFG_PME_CTRL_STS, BIT1 | BIT0);
    //
    // Reading back value after write to ensure bridge observes the BAR1 write access
    //
    MmioRead8 ((UINTN) PciCfgBase + R_SERIAL_IO_CFG_PME_CTRL_STS);
  }
}
 
/**
  Places SerialIo device in D0
 
  @param[in] PciCfgBase       Pci Config Offset
 
**/
VOID
SerialIoSetD0 (
  IN UINT64                    PciCfgBase
  )
{
  if (PciCfgBase < PCH_SERIAL_IO_BASE_ADDRESS) {
    PciSegmentAnd32 ((UINTN) PciCfgBase + R_SERIAL_IO_CFG_PME_CTRL_STS, (UINT32) ~(BIT1 | BIT0));
  } else {
    MmioAnd32 ((UINTN) PciCfgBase + R_SERIAL_IO_CFG_PME_CTRL_STS, (UINT32) ~(BIT1 | BIT0));
    //
    // Reading back value after write to ensure bridge observes the BAR1 write access
    //
    MmioRead32 ((UINTN) PciCfgBase + R_SERIAL_IO_CFG_PME_CTRL_STS);
  }
}
 
/**
  Allows memory access
 
  @param[in] PciCfgBase       Pci Config Offset
  @param[in] Hidden           Mode that determines access type
 
**/
VOID
SerialIoEnableMse (
  IN UINT64                    PciCfgBase,
  IN BOOLEAN                   Hidden
  )
{
  if (Hidden) {
    MmioOr16 ((UINTN) PciCfgBase + PCI_COMMAND_OFFSET, EFI_PCI_COMMAND_MEMORY_SPACE);
    //
    // Reading back value after write to ensure bridge observes the BAR1 write access
    //
    MmioRead16 ((UINTN) PciCfgBase + PCI_COMMAND_OFFSET);
  } else {
    PciSegmentOr16 ((UINTN) PciCfgBase + PCI_COMMAND_OFFSET, EFI_PCI_COMMAND_MEMORY_SPACE);
  }
}
 
/**
  Disable SerialIo memory access
 
  @param[in] PciCfgBase       Pci Config Offset
 
**/
VOID
SerialIoDisableMse (
  IN UINT64                    PciCfgBase
  )
{
  PciSegmentAnd16 ((UINTN) PciCfgBase + PCI_COMMAND_OFFSET, (UINT16) ~EFI_PCI_COMMAND_MEMORY_SPACE);
}
 
/**
  Disable SerialIo memory encoding
  Designated for Pci modes
 
  @param[in] PciCfgBase       Pci Config Offset
  @param[in] RemoveTempBar    Remove temporary mem base address or not
 
**/
VOID
SerialIoMmioDisable (
  IN UINT64                    PciCfgBase,
  IN BOOLEAN                   RemoveBar
  )
{
  SerialIoDisableMse (PciCfgBase);
 
  if (RemoveBar == TRUE) {
    PciSegmentWrite32 ((UINTN) PciCfgBase + R_SERIAL_IO_CFG_BAR0_LOW,  0x0);
    PciSegmentWrite32 ((UINTN) PciCfgBase + R_SERIAL_IO_CFG_BAR0_HIGH,  0x0);
  }
}