TianoCore EDK2 master
Loading...
Searching...
No Matches
SpiBusDxe.c
Go to the documentation of this file.
1
9#include <Base.h>
10#include <Library/BaseLib.h>
11#include <Library/DebugLib.h>
15#include <Protocol/SpiHc.h>
16#include <Protocol/SpiIo.h>
17#include "SpiBus.h"
18
31EFIAPI
33 IN EFI_HANDLE ImageHandle,
34 IN EFI_SYSTEM_TABLE *SystemTable
35 )
36{
37 EFI_STATUS Status;
38 SPI_IO_CHIP *SpiChip;
40 EFI_SPI_CONFIGURATION_PROTOCOL *SpiConfiguration;
41 EFI_SPI_PERIPHERAL *SpiPeripheral;
42 EFI_SPI_BUS *Bus;
43 UINTN BusIndex;
44 UINTN HcIndex;
45 EFI_HANDLE *SpiHcHandles;
46 UINTN HandleCount;
47 EFI_DEVICE_PATH_PROTOCOL *SpiHcDevicePath;
48
49 DEBUG ((DEBUG_VERBOSE, "%a - ENTRY\n", __func__));
50
51 // Get all SPI HC protocols, could be multiple SPI HC's on a single platform
52 Status = gBS->LocateHandleBuffer (
54 &gEfiSpiHcProtocolGuid,
55 NULL,
56 &HandleCount,
57 &SpiHcHandles
58 );
59
60 if (EFI_ERROR (Status)) {
61 DEBUG ((DEBUG_VERBOSE, "No SpiHcProtocol is found\n"));
62 Status = EFI_NOT_FOUND;
63 goto Exit;
64 }
65
66 // Locate the SPI Configuration Protocol
67 Status = gBS->LocateProtocol (
68 &gEfiSpiConfigurationProtocolGuid,
69 NULL,
70 (VOID **)&SpiConfiguration
71 );
72
73 if (EFI_ERROR (Status)) {
74 DEBUG ((DEBUG_VERBOSE, "No SpiConfigurationProtocol is found\n"));
75 Status = EFI_NOT_FOUND;
76 goto Exit;
77 }
78
79 // Parse through Hc protocols, find correct device path
80 for (HcIndex = 0; HcIndex < HandleCount; HcIndex++) {
81 Status = gBS->HandleProtocol (
82 SpiHcHandles[HcIndex],
83 &gEfiDevicePathProtocolGuid,
84 (VOID **)&SpiHcDevicePath
85 );
86
87 if (EFI_ERROR (Status)) {
88 DEBUG ((DEBUG_VERBOSE, "Error locating EFI device path for this SPI controller, status=%r \n", Status));
89 continue; // Continue searching
90 }
91
92 // Parse through SpiConfiguration's SpiBuses, find matching devicepath for SpiHc
93 for (BusIndex = 0; BusIndex < SpiConfiguration->BusCount; BusIndex++) {
94 Bus = (EFI_SPI_BUS *)SpiConfiguration->Buslist[BusIndex];
95 if (!DevicePathsAreEqual (SpiHcDevicePath, Bus->ControllerPath)) {
96 DEBUG ((DEBUG_VERBOSE, "SpiHc and SpiConfig device paths dont match, continue parsing\n"));
97 continue;
98 }
99
100 DEBUG ((
101 DEBUG_VERBOSE,
102 "%a: Found matching device paths, Enumerating SPI BUS: %s with DevicePath: %s\n",
103 __func__,
104 Bus->FriendlyName,
105 ConvertDevicePathToText (SpiHcDevicePath, FALSE, FALSE)
106 ));
107
108 // Get SpiHc from the SpiHcHandles
109 Status = gBS->HandleProtocol (
110 SpiHcHandles[HcIndex],
111 &gEfiDevicePathProtocolGuid,
112 (VOID **)&SpiHc
113 );
114
115 if (EFI_ERROR (Status)) {
116 DEBUG ((DEBUG_VERBOSE, "%a - Error getting SpiHc from Handle\n", __func__));
117 goto Exit;
118 }
119
120 SpiPeripheral = (EFI_SPI_PERIPHERAL *)Bus->Peripherallist;
121 if (SpiPeripheral != NULL) {
122 do {
123 DEBUG ((
124 DEBUG_VERBOSE,
125 "%a: Installing SPI IO protocol for %s, by %s, PN=%s\n",
126 __func__,
127 SpiPeripheral->FriendlyName,
128 SpiPeripheral->SpiPart->Vendor,
129 SpiPeripheral->SpiPart->PartNumber
130 ));
131 // Allocate the SPI IO Device
132 SpiChip = AllocateZeroPool (sizeof (SPI_IO_CHIP));
133 ASSERT (SpiChip != NULL);
134 if (SpiChip != NULL) {
135 // Fill in the SpiChip
136 SpiChip->Signature = SPI_IO_SIGNATURE;
137 SpiChip->SpiConfig = SpiConfiguration;
138 SpiChip->SpiHc = SpiHc;
139 SpiChip->SpiBus = Bus;
140 SpiChip->Protocol.SpiPeripheral = SpiPeripheral;
141 SpiChip->Protocol.OriginalSpiPeripheral = SpiPeripheral;
142 SpiChip->Protocol.FrameSizeSupportMask = SpiHc->FrameSizeSupportMask;
143 SpiChip->Protocol.MaximumTransferBytes = SpiHc->MaximumTransferBytes;
144 if ((SpiHc->Attributes & HC_TRANSFER_SIZE_INCLUDES_ADDRESS) != 0) {
145 SpiChip->Protocol.Attributes |= SPI_IO_TRANSFER_SIZE_INCLUDES_ADDRESS;
146 }
147
148 if ((SpiHc->Attributes & HC_TRANSFER_SIZE_INCLUDES_OPCODE) != 0) {
149 SpiChip->Protocol.Attributes |= SPI_IO_TRANSFER_SIZE_INCLUDES_OPCODE;
150 }
151
152 if ((SpiHc->Attributes & HC_SUPPORTS_8_BIT_DATA_BUS_WIDTH) != 0) {
153 SpiChip->Protocol.Attributes |= SPI_IO_SUPPORTS_8_BIT_DATA_BUS_WIDTH;
154 }
155
156 if ((SpiHc->Attributes & HC_SUPPORTS_4_BIT_DATA_BUS_WIDTH) != 0) {
157 SpiChip->Protocol.Attributes |= SPI_IO_SUPPORTS_4_BIT_DATA_BUS_WIDTH;
158 }
159
160 if ((SpiHc->Attributes & HC_SUPPORTS_2_BIT_DATA_BUS_WIDTH) != 0) {
162 }
163
164 SpiChip->Protocol.Transaction = Transaction;
165 SpiChip->Protocol.UpdateSpiPeripheral = UpdateSpiPeripheral;
166 // Install the SPI IO Protocol
167 Status = gBS->InstallProtocolInterface (
168 &SpiChip->Handle,
169 (GUID *)SpiPeripheral->SpiPeripheralDriverGuid,
171 &SpiChip->Protocol
172 );
173 if (EFI_ERROR (Status)) {
174 DEBUG ((DEBUG_VERBOSE, "%a - Error installing SpiIoProtocol\n", __func__));
175 continue;
176 }
177 } else {
178 Status = EFI_OUT_OF_RESOURCES;
179 DEBUG ((
180 DEBUG_ERROR,
181 "%a: Out of Memory resources\n",
182 __func__
183 ));
184 break;
185 }
186
187 SpiPeripheral = (EFI_SPI_PERIPHERAL *)SpiPeripheral->NextSpiPeripheral;
188 } while (SpiPeripheral != NULL);
189 } else {
190 Status = EFI_DEVICE_ERROR;
191 }
192 }
193 }
194
195Exit:
196 DEBUG ((DEBUG_VERBOSE, "%a - EXIT (Status = %r)\n", __func__, Status));
197 return Status;
198}
UINT64 UINTN
CHAR16 *EFIAPI ConvertDevicePathToText(IN CONST EFI_DEVICE_PATH_PROTOCOL *DevicePath, IN BOOLEAN DisplayOnly, IN BOOLEAN AllowShortcuts)
VOID *EFIAPI AllocateZeroPool(IN UINTN AllocationSize)
#define NULL
Definition: Base.h:319
#define FALSE
Definition: Base.h:307
#define IN
Definition: Base.h:279
#define DEBUG(Expression)
Definition: DebugLib.h:434
EFI_STATUS EFIAPI UpdateSpiPeripheral(IN CONST EFI_SPI_IO_PROTOCOL *This, IN CONST EFI_SPI_PERIPHERAL *SpiPeripheral)
Definition: SpiBus.c:399
EFI_STATUS EFIAPI Transaction(IN CONST EFI_SPI_IO_PROTOCOL *This, IN EFI_SPI_TRANSACTION_TYPE TransactionType, IN BOOLEAN DebugTransaction, IN UINT32 ClockHz OPTIONAL, IN UINT32 BusWidth, IN UINT32 FrameSize, IN UINT32 WriteBytes, IN UINT8 *WriteBuffer, IN UINT32 ReadBytes, OUT UINT8 *ReadBuffer)
Definition: SpiBus.c:231
BOOLEAN EFIAPI DevicePathsAreEqual(IN CONST EFI_DEVICE_PATH_PROTOCOL *DevicePath1, IN CONST EFI_DEVICE_PATH_PROTOCOL *DevicePath2)
Definition: SpiBus.c:28
EFI_STATUS EFIAPI SpiBusEntry(IN EFI_HANDLE ImageHandle, IN EFI_SYSTEM_TABLE *SystemTable)
Definition: SpiBusDxe.c:32
#define SPI_IO_SUPPORTS_2_BIT_DATA_BUS_WIDTH
Definition: SpiIo.h:230
VOID EFIAPI Exit(IN EFI_STATUS Status)
RETURN_STATUS EFI_STATUS
Definition: UefiBaseType.h:29
VOID * EFI_HANDLE
Definition: UefiBaseType.h:33
EFI_BOOT_SERVICES * gBS
@ EFI_NATIVE_INTERFACE
Definition: UefiSpec.h:1193
@ ByProtocol
Definition: UefiSpec.h:1518
CONST EFI_SPI_PERIPHERAL * Peripherallist
CONST EFI_DEVICE_PATH_PROTOCOL * ControllerPath
CONST CHAR16 * FriendlyName
CONST EFI_SPI_BUS *CONST *CONST Buslist
CONST EFI_SPI_PERIPHERAL * SpiPeripheral
Definition: SpiIo.h:245
UINT32 Attributes
Definition: SpiIo.h:278
UINT32 MaximumTransferBytes
Definition: SpiIo.h:265
EFI_SPI_IO_PROTOCOL_TRANSACTION Transaction
Definition: SpiIo.h:288
EFI_SPI_IO_PROTOCOL_UPDATE_SPI_PERIPHERAL UpdateSpiPeripheral
Definition: SpiIo.h:293
UINT32 FrameSizeSupportMask
Definition: SpiIo.h:260
CONST EFI_SPI_PERIPHERAL * OriginalSpiPeripheral
Definition: SpiIo.h:251
CONST CHAR16 * Vendor
CONST CHAR16 * PartNumber
CONST GUID * SpiPeripheralDriverGuid
CONST EFI_SPI_PERIPHERAL * NextSpiPeripheral
CONST CHAR16 * FriendlyName
CONST EFI_SPI_PART * SpiPart
Definition: Base.h:213