]> git.proxmox.com Git - mirror_edk2.git/blob - QuarkSocPkg/QuarkNorthCluster/Spi/RuntimeDxe/PchSpi.c
QuarkSocPkg: Replace BSD License with BSD+Patent License
[mirror_edk2.git] / QuarkSocPkg / QuarkNorthCluster / Spi / RuntimeDxe / PchSpi.c
1 /** @file
2 PCH SPI Runtime Driver implements the SPI Host Controller Compatibility Interface.
3
4 Copyright (c) 2013-2015 Intel Corporation.
5
6 SPDX-License-Identifier: BSD-2-Clause-Patent
7
8 **/
9 #include "PchSpi.h"
10
11 extern EFI_GUID gEfiEventVirtualAddressChangeGuid;
12
13 //
14 // Global variables
15 //
16 SPI_INSTANCE *mSpiInstance;
17 CONST UINT32 mSpiRegister[] = {
18 R_QNC_RCRB_SPIS,
19 R_QNC_RCRB_SPIPREOP,
20 R_QNC_RCRB_SPIOPMENU,
21 R_QNC_RCRB_SPIOPMENU + 4
22 };
23
24 //
25 // Function implementations
26 //
27 VOID
28 PchSpiVirtualddressChangeEvent (
29 IN EFI_EVENT Event,
30 IN VOID *Context
31 )
32 /*++
33
34 Routine Description:
35
36 Fixup internal data pointers so that the services can be called in virtual mode.
37
38 Arguments:
39
40 Event The event registered.
41 Context Event context. Not used in this event handler.
42
43 Returns:
44
45 None.
46
47 --*/
48 {
49 gRT->ConvertPointer (EFI_INTERNAL_POINTER, (VOID *) &(mSpiInstance->PchRootComplexBar));
50 gRT->ConvertPointer (EFI_INTERNAL_POINTER, (VOID *) &(mSpiInstance->SpiProtocol.Init));
51 gRT->ConvertPointer (EFI_INTERNAL_POINTER, (VOID *) &(mSpiInstance->SpiProtocol.Lock));
52 gRT->ConvertPointer (EFI_INTERNAL_POINTER, (VOID *) &(mSpiInstance->SpiProtocol.Execute));
53 gRT->ConvertPointer (EFI_INTERNAL_POINTER, (VOID *) &(mSpiInstance));
54 }
55
56 EFI_STATUS
57 EFIAPI
58 InstallPchSpi (
59 IN EFI_HANDLE ImageHandle,
60 IN EFI_SYSTEM_TABLE *SystemTable
61 )
62 /*++
63
64 Routine Description:
65
66 Entry point for the SPI host controller driver.
67
68 Arguments:
69
70 ImageHandle Image handle of this driver.
71 SystemTable Global system service table.
72
73 Returns:
74
75 EFI_SUCCESS Initialization complete.
76 EFI_UNSUPPORTED The chipset is unsupported by this driver.
77 EFI_OUT_OF_RESOURCES Do not have enough resources to initialize the driver.
78 EFI_DEVICE_ERROR Device error, driver exits abnormally.
79
80 --*/
81 {
82 EFI_STATUS Status;
83 UINT64 BaseAddress;
84 UINT64 Length;
85 EFI_GCD_MEMORY_SPACE_DESCRIPTOR GcdMemorySpaceDescriptor;
86 UINT64 Attributes;
87 EFI_EVENT Event;
88
89 DEBUG ((DEBUG_INFO, "InstallPchSpi() Start\n"));
90
91 //
92 // Allocate Runtime memory for the SPI protocol instance.
93 //
94 mSpiInstance = AllocateRuntimeZeroPool (sizeof (SPI_INSTANCE));
95 if (mSpiInstance == NULL) {
96 return EFI_OUT_OF_RESOURCES;
97 }
98 //
99 // Initialize the SPI protocol instance
100 //
101 Status = SpiProtocolConstructor (mSpiInstance);
102 if (EFI_ERROR (Status)) {
103 return Status;
104 }
105 //
106 // Install the EFI_SPI_PROTOCOL interface
107 //
108 Status = gBS->InstallMultipleProtocolInterfaces (
109 &(mSpiInstance->Handle),
110 &gEfiSpiProtocolGuid,
111 &(mSpiInstance->SpiProtocol),
112 NULL
113 );
114 if (EFI_ERROR (Status)) {
115 FreePool (mSpiInstance);
116 return EFI_DEVICE_ERROR;
117 }
118 //
119 // Set RCBA space in GCD to be RUNTIME so that the range will be supported in
120 // virtual address mode in EFI aware OS runtime.
121 // It will assert if RCBA Memory Space is not allocated
122 // The caller is responsible for the existence and allocation of the RCBA Memory Spaces
123 //
124 BaseAddress = (EFI_PHYSICAL_ADDRESS) (mSpiInstance->PchRootComplexBar);
125 Length = PcdGet64 (PcdRcbaMmioSize);
126
127 Status = gDS->GetMemorySpaceDescriptor (BaseAddress, &GcdMemorySpaceDescriptor);
128 ASSERT_EFI_ERROR (Status);
129
130 Attributes = GcdMemorySpaceDescriptor.Attributes | EFI_MEMORY_RUNTIME;
131
132 Status = gDS->AddMemorySpace (
133 EfiGcdMemoryTypeMemoryMappedIo,
134 BaseAddress,
135 Length,
136 EFI_MEMORY_RUNTIME | EFI_MEMORY_UC
137 );
138 ASSERT_EFI_ERROR(Status);
139
140 Status = gDS->SetMemorySpaceAttributes (
141 BaseAddress,
142 Length,
143 Attributes
144 );
145 ASSERT_EFI_ERROR (Status);
146
147 Status = gBS->CreateEventEx (
148 EVT_NOTIFY_SIGNAL,
149 TPL_NOTIFY,
150 PchSpiVirtualddressChangeEvent,
151 NULL,
152 &gEfiEventVirtualAddressChangeGuid,
153 &Event
154 );
155 ASSERT_EFI_ERROR (Status);
156
157 DEBUG ((DEBUG_INFO, "InstallPchSpi() End\n"));
158
159 return EFI_SUCCESS;
160 }
161
162 VOID
163 EFIAPI
164 SpiPhaseInit (
165 VOID
166 )
167 /*++
168 Routine Description:
169
170 This function is a a hook for Spi Dxe phase specific initialization
171
172 Arguments:
173
174 None
175
176 Returns:
177
178 None
179
180 --*/
181 {
182 UINTN Index;
183
184 //
185 // Disable SMM BIOS write protect if it's not a SMM protocol
186 //
187 MmioAnd8 (
188 PciDeviceMmBase (PCI_BUS_NUMBER_QNC,
189 PCI_DEVICE_NUMBER_QNC_LPC,
190 PCI_FUNCTION_NUMBER_QNC_LPC) + R_QNC_LPC_BIOS_CNTL,
191 (UINT8) (~B_QNC_LPC_BIOS_CNTL_SMM_BWP)
192 );
193
194 //
195 // Save SPI Registers for S3 resume usage
196 //
197 for (Index = 0; Index < sizeof (mSpiRegister) / sizeof (UINT32); Index++) {
198 S3BootScriptSaveMemWrite (
199 S3BootScriptWidthUint32,
200 (UINTN) (mSpiInstance->PchRootComplexBar + mSpiRegister[Index]),
201 1,
202 (VOID *) (UINTN) (mSpiInstance->PchRootComplexBar + mSpiRegister[Index])
203 );
204 }
205 }