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