TianoCore EDK2 master
Loading...
Searching...
No Matches
SpiBusSmm.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/SpiSmmHc.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
44 DEBUG ((DEBUG_VERBOSE, "%a - ENTRY\n", __func__));
45
46 // Only a single Spi HC protocol in SMM
47 Status = gMmst->MmLocateProtocol (
48 &gEfiSpiSmmHcProtocolGuid,
49 NULL,
50 (VOID **)&SpiHc
51 );
52
53 if (EFI_ERROR (Status)) {
54 DEBUG ((DEBUG_VERBOSE, "No SpiHcProtocol is found\n"));
55 Status = EFI_NOT_FOUND;
56 goto Exit;
57 }
58
59 // Locate the SPI Configuration Protocol
60 Status = gMmst->MmLocateProtocol (
61 &gEfiSpiSmmConfigurationProtocolGuid,
62 NULL,
63 (VOID **)&SpiConfiguration
64 );
65
66 if (EFI_ERROR (Status)) {
67 DEBUG ((DEBUG_VERBOSE, "No SpiConfigurationProtocol is found\n"));
68 Status = EFI_NOT_FOUND;
69 goto Exit;
70 }
71
72 // Only one SpiBus supported in SMM
73 if (SpiConfiguration->BusCount != 1) {
74 DEBUG ((DEBUG_VERBOSE, "Only one SPI Bus supported in SMM\n"));
75 Status = EFI_UNSUPPORTED;
76 goto Exit;
77 }
78
79 Bus = (EFI_SPI_BUS *)SpiConfiguration->Buslist[0];
80
81 if (EFI_ERROR (Status)) {
82 DEBUG ((DEBUG_VERBOSE, "%a - Error getting SpiHc from Handle\n", __func__));
83 goto Exit;
84 }
85
86 SpiPeripheral = (EFI_SPI_PERIPHERAL *)Bus->Peripherallist;
87 if (SpiPeripheral != NULL) {
88 do {
89 DEBUG ((
90 DEBUG_VERBOSE,
91 "%a: Installing SPI IO protocol for %s, by %s, PN=%s\n",
92 __func__,
93 SpiPeripheral->FriendlyName,
94 SpiPeripheral->SpiPart->Vendor,
95 SpiPeripheral->SpiPart->PartNumber
96 ));
97 // Allocate the SPI IO Device
98 SpiChip = AllocateZeroPool (sizeof (SPI_IO_CHIP));
99 ASSERT (SpiChip != NULL);
100 if (SpiChip != NULL) {
101 // Fill in the SpiChip
102 SpiChip->Signature = SPI_IO_SIGNATURE;
103 SpiChip->SpiConfig = SpiConfiguration;
104 SpiChip->SpiHc = SpiHc;
105 SpiChip->SpiBus = Bus;
106 SpiChip->Protocol.SpiPeripheral = SpiPeripheral;
107 SpiChip->Protocol.OriginalSpiPeripheral = SpiPeripheral;
108 SpiChip->Protocol.FrameSizeSupportMask = SpiHc->FrameSizeSupportMask;
109 SpiChip->Protocol.MaximumTransferBytes = SpiHc->MaximumTransferBytes;
110 if ((SpiHc->Attributes & HC_TRANSFER_SIZE_INCLUDES_ADDRESS) != 0) {
111 SpiChip->Protocol.Attributes |= SPI_IO_TRANSFER_SIZE_INCLUDES_ADDRESS;
112 }
113
114 if ((SpiHc->Attributes & HC_TRANSFER_SIZE_INCLUDES_OPCODE) != 0) {
115 SpiChip->Protocol.Attributes |= SPI_IO_TRANSFER_SIZE_INCLUDES_OPCODE;
116 }
117
118 if ((SpiHc->Attributes & HC_SUPPORTS_8_BIT_DATA_BUS_WIDTH) != 0) {
119 SpiChip->Protocol.Attributes |= SPI_IO_SUPPORTS_8_BIT_DATA_BUS_WIDTH;
120 }
121
122 if ((SpiHc->Attributes & HC_SUPPORTS_4_BIT_DATA_BUS_WIDTH) != 0) {
123 SpiChip->Protocol.Attributes |= SPI_IO_SUPPORTS_4_BIT_DATA_BUS_WIDTH;
124 }
125
126 if ((SpiHc->Attributes & HC_SUPPORTS_2_BIT_DATA_BUS_WIDTH) != 0) {
128 }
129
130 SpiChip->Protocol.Transaction = Transaction;
131 SpiChip->Protocol.UpdateSpiPeripheral = UpdateSpiPeripheral;
132 // Install the SPI IO Protocol
133 Status = gMmst->MmInstallProtocolInterface (
134 &SpiChip->Handle,
135 (GUID *)SpiPeripheral->SpiPeripheralDriverGuid,
137 &SpiChip->Protocol
138 );
139 if (EFI_ERROR (Status)) {
140 DEBUG ((DEBUG_VERBOSE, "%a - Error installing SpiIoProtocol\n", __func__));
141 continue;
142 }
143 } else {
144 Status = EFI_OUT_OF_RESOURCES;
145 DEBUG ((
146 DEBUG_ERROR,
147 "%a: Out of Memory resources\n",
148 __func__
149 ));
150 break;
151 }
152
153 SpiPeripheral = (EFI_SPI_PERIPHERAL *)SpiPeripheral->NextSpiPeripheral;
154 } while (SpiPeripheral != NULL);
155 } else {
156 Status = EFI_DEVICE_ERROR;
157 }
158
159Exit:
160 DEBUG ((DEBUG_VERBOSE, "%a - EXIT (Status = %r)\n", __func__, Status));
161 return Status;
162}
VOID *EFIAPI AllocateZeroPool(IN UINTN AllocationSize)
#define NULL
Definition: Base.h:319
#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
EFI_STATUS EFIAPI SpiBusEntry(IN EFI_HANDLE ImageHandle, IN EFI_SYSTEM_TABLE *SystemTable)
Definition: SpiBusSmm.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_NATIVE_INTERFACE
Definition: UefiSpec.h:1193
EFI_INSTALL_PROTOCOL_INTERFACE MmInstallProtocolInterface
Definition: PiMmCis.h:327
CONST EFI_SPI_PERIPHERAL * Peripherallist
CONST EFI_SPI_BUS *CONST *CONST Buslist
UINT32 Attributes
Definition: SpiHc.h:168
UINT32 MaximumTransferBytes
Definition: SpiHc.h:180
UINT32 FrameSizeSupportMask
Definition: SpiHc.h:175
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