Skip to content

Commit 82b0358

Browse files
BritChesleymergify[bot]
authored andcommitted
MdeModulePkg: SpiHc: SpiHc Drivers
Added SpiHc DXE and SMM drivers. This code receives bus transactions from the SpiBus layer and passes them onto the SpiHcPlatformLib Platform Initialization Spec 1.7 volume 5 section 18.1.7 Bugzilla tianocore#4753 Cc: Abner Chang <[email protected]> Cc: Abdul Lateef Attar <[email protected]> Signed-off-by: Brit Chesley <[email protected]> Reviewed-by: Abner Chang <[email protected]>
1 parent 5590cef commit 82b0358

File tree

7 files changed

+514
-0
lines changed

7 files changed

+514
-0
lines changed

MdeModulePkg/Bus/Spi/SpiHc/SpiHc.c

+115
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,115 @@
1+
/** @file
2+
3+
SPI Host Controller shell implementation, as host controller code is platform
4+
specfic.
5+
6+
Copyright (C) 2024 Advanced Micro Devices, Inc. All rights reserved.<BR>
7+
SPDX-License-Identifier: BSD-2-Clause-Patent
8+
9+
**/
10+
#include "SpiHc.h"
11+
12+
/**
13+
Assert or deassert the SPI chip select.
14+
15+
This routine is called at TPL_NOTIFY.
16+
Update the value of the chip select line for a SPI peripheral. The SPI bus
17+
layer calls this routine either in the board layer or in the SPI controller
18+
to manipulate the chip select pin at the start and end of a SPI transaction.
19+
20+
@param[in] This Pointer to an EFI_SPI_HC_PROTOCOL structure.
21+
@param[in] SpiPeripheral The address of an EFI_SPI_PERIPHERAL data structure
22+
describing the SPI peripheral whose chip select pin
23+
is to be manipulated. The routine may access the
24+
ChipSelectParameter field to gain sufficient
25+
context to complete the operati on.
26+
@param[in] PinValue The value to be applied to the chip select line of
27+
the SPI peripheral.
28+
29+
@retval EFI_SUCCESS The chip select was set as requested
30+
@retval EFI_NOT_READY Support for the chip select is not properly
31+
initialized
32+
@retval EFI_INVALID_PARAMETER The ChipSeLect value or its contents are
33+
invalid
34+
35+
**/
36+
EFI_STATUS
37+
EFIAPI
38+
ChipSelect (
39+
IN CONST EFI_SPI_HC_PROTOCOL *This,
40+
IN CONST EFI_SPI_PERIPHERAL *SpiPeripheral,
41+
IN BOOLEAN PinValue
42+
)
43+
{
44+
return PlatformSpiHcChipSelect (This, SpiPeripheral, PinValue);
45+
}
46+
47+
/**
48+
Set up the clock generator to produce the correct clock frequency, phase and
49+
polarity for a SPI chip.
50+
51+
This routine is called at TPL_NOTIFY.
52+
This routine updates the clock generator to generate the correct frequency
53+
and polarity for the SPI clock.
54+
55+
@param[in] This Pointer to an EFI_SPI_HC_PROTOCOL structure.
56+
@param[in] SpiPeripheral Pointer to a EFI_SPI_PERIPHERAL data structure from
57+
which the routine can access the ClockParameter,
58+
ClockPhase and ClockPolarity fields. The routine
59+
also has access to the names for the SPI bus and
60+
chip which can be used during debugging.
61+
@param[in] ClockHz Pointer to the requested clock frequency. The SPI
62+
host controller will choose a supported clock
63+
frequency which is less then or equal to this
64+
value. Specify zero to turn the clock generator
65+
off. The actual clock frequency supported by the
66+
SPI host controller will be returned.
67+
68+
@retval EFI_SUCCESS The clock was set up successfully
69+
@retval EFI_UNSUPPORTED The SPI controller was not able to support the
70+
frequency requested by ClockHz
71+
72+
**/
73+
EFI_STATUS
74+
EFIAPI
75+
Clock (
76+
IN CONST EFI_SPI_HC_PROTOCOL *This,
77+
IN CONST EFI_SPI_PERIPHERAL *SpiPeripheral,
78+
IN UINT32 *ClockHz
79+
)
80+
{
81+
return PlatformSpiHcClock (This, SpiPeripheral, ClockHz);
82+
}
83+
84+
/**
85+
Perform the SPI transaction on the SPI peripheral using the SPI host
86+
controller.
87+
88+
This routine is called at TPL_NOTIFY.
89+
This routine synchronously returns EFI_SUCCESS indicating that the
90+
asynchronous SPI transaction was started. The routine then waits for
91+
completion of the SPI transaction prior to returning the final transaction
92+
status.
93+
94+
@param[in] This Pointer to an EFI_SPI_HC_PROTOCOL structure.
95+
@param[in] BusTransaction Pointer to a EFI_SPI_BUS_ TRANSACTION containing
96+
the description of the SPI transaction to perform.
97+
98+
@retval EFI_SUCCESS The transaction completed successfully
99+
@retval EFI_BAD_BUFFER_SIZE The BusTransaction->WriteBytes value is invalid,
100+
or the BusTransaction->ReadinBytes value is
101+
invalid
102+
@retval EFI_UNSUPPORTED The BusTransaction-> Transaction Type is
103+
unsupported
104+
@retval EFI_DEVICE_ERROR SPI Host Controller failed transaction
105+
106+
**/
107+
EFI_STATUS
108+
EFIAPI
109+
Transaction (
110+
IN CONST EFI_SPI_HC_PROTOCOL *This,
111+
IN EFI_SPI_BUS_TRANSACTION *BusTransaction
112+
)
113+
{
114+
return PlatformSpiHcTransaction (This, BusTransaction);
115+
}

MdeModulePkg/Bus/Spi/SpiHc/SpiHc.h

+117
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,117 @@
1+
/** @file
2+
3+
SPI Host Controller function declarations
4+
5+
Copyright (C) 2024 Advanced Micro Devices, Inc. All rights reserved.<BR>
6+
SPDX-License-Identifier: BSD-2-Clause-Patent
7+
8+
**/
9+
10+
#ifndef SPI_HC_H_
11+
#define SPI_HC_H_
12+
13+
#include <PiDxe.h>
14+
#include <Library/BaseLib.h>
15+
#include <Library/BaseMemoryLib.h>
16+
#include <Library/DebugLib.h>
17+
#include <Library/IoLib.h>
18+
#include <Protocol/SpiHc.h>
19+
#include <Library/SpiHcPlatformLib.h>
20+
21+
/**
22+
Assert or deassert the SPI chip select.
23+
24+
This routine is called at TPL_NOTIFY.
25+
Update the value of the chip select line for a SPI peripheral. The SPI bus
26+
layer calls this routine either in the board layer or in the SPI controller
27+
to manipulate the chip select pin at the start and end of a SPI transaction.
28+
29+
@param[in] This Pointer to an EFI_SPI_HC_PROTOCOL structure.
30+
@param[in] SpiPeripheral The address of an EFI_SPI_PERIPHERAL data structure
31+
describing the SPI peripheral whose chip select pin
32+
is to be manipulated. The routine may access the
33+
ChipSelectParameter field to gain sufficient
34+
context to complete the operati on.
35+
@param[in] PinValue The value to be applied to the chip select line of
36+
the SPI peripheral.
37+
38+
@retval EFI_SUCCESS The chip select was set as requested
39+
@retval EFI_NOT_READY Support for the chip select is not properly
40+
initialized
41+
@retval EFI_INVALID_PARAMETER The ChipSeLect value or its contents are
42+
invalid
43+
44+
**/
45+
EFI_STATUS
46+
EFIAPI
47+
ChipSelect (
48+
IN CONST EFI_SPI_HC_PROTOCOL *This,
49+
IN CONST EFI_SPI_PERIPHERAL *SpiPeripheral,
50+
IN BOOLEAN PinValue
51+
);
52+
53+
/**
54+
Set up the clock generator to produce the correct clock frequency, phase and
55+
polarity for a SPI chip.
56+
57+
This routine is called at TPL_NOTIFY.
58+
This routine updates the clock generator to generate the correct frequency
59+
and polarity for the SPI clock.
60+
61+
@param[in] This Pointer to an EFI_SPI_HC_PROTOCOL structure.
62+
@param[in] SpiPeripheral Pointer to a EFI_SPI_PERIPHERAL data structure from
63+
which the routine can access the ClockParameter,
64+
ClockPhase and ClockPolarity fields. The routine
65+
also has access to the names for the SPI bus and
66+
chip which can be used during debugging.
67+
@param[in] ClockHz Pointer to the requested clock frequency. The SPI
68+
host controller will choose a supported clock
69+
frequency which is less then or equal to this
70+
value. Specify zero to turn the clock generator
71+
off. The actual clock frequency supported by the
72+
SPI host controller will be returned.
73+
74+
@retval EFI_SUCCESS The clock was set up successfully
75+
@retval EFI_UNSUPPORTED The SPI controller was not able to support the
76+
frequency requested by ClockHz
77+
78+
**/
79+
EFI_STATUS
80+
EFIAPI
81+
Clock (
82+
IN CONST EFI_SPI_HC_PROTOCOL *This,
83+
IN CONST EFI_SPI_PERIPHERAL *SpiPeripheral,
84+
IN UINT32 *ClockHz
85+
);
86+
87+
/**
88+
Perform the SPI transaction on the SPI peripheral using the SPI host
89+
controller.
90+
91+
This routine is called at TPL_NOTIFY.
92+
This routine synchronously returns EFI_SUCCESS indicating that the
93+
asynchronous SPI transaction was started. The routine then waits for
94+
completion of the SPI transaction prior to returning the final transaction
95+
status.
96+
97+
@param[in] This Pointer to an EFI_SPI_HC_PROTOCOL structure.
98+
@param[in] BusTransaction Pointer to a EFI_SPI_BUS_ TRANSACTION containing
99+
the description of the SPI transaction to perform.
100+
101+
@retval EFI_SUCCESS The transaction completed successfully
102+
@retval EFI_BAD_BUFFER_SIZE The BusTransaction->WriteBytes value is invalid,
103+
or the BusTransaction->ReadinBytes value is
104+
invalid
105+
@retval EFI_UNSUPPORTED The BusTransaction-> Transaction Type is
106+
unsupported
107+
@retval EFI_DEVICE_ERROR SPI Host Controller failed transaction
108+
109+
**/
110+
EFI_STATUS
111+
EFIAPI
112+
Transaction (
113+
IN CONST EFI_SPI_HC_PROTOCOL *This,
114+
IN EFI_SPI_BUS_TRANSACTION *BusTransaction
115+
);
116+
117+
#endif //SPI_HC_H_

MdeModulePkg/Bus/Spi/SpiHc/SpiHc.uni

+10
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
// /** @file
2+
//
3+
// Copyright (C) 2024 Advanced Micro Devices, Inc. All rights reserved.<BR>
4+
//
5+
// SPDX-License-Identifier: BSD-2-Clause-Patent
6+
//
7+
// **/
8+
9+
#string STR_PROPERTIES_MODULE_NAME
10+
#language en-US "SPI host controller driver"

MdeModulePkg/Bus/Spi/SpiHc/SpiHcDxe.c

+101
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,101 @@
1+
/** @file
2+
3+
SPI Host controller entry point for DXE
4+
5+
Copyright (C) 2024 Advanced Micro Devices, Inc. All rights reserved.<BR>
6+
SPDX-License-Identifier: BSD-2-Clause-Patent
7+
8+
**/
9+
#include <Base.h>
10+
#include <Library/BaseLib.h>
11+
#include <Library/DebugLib.h>
12+
#include <Library/PcdLib.h>
13+
#include <Library/UefiLib.h>
14+
#include <Library/MemoryAllocationLib.h>
15+
#include <Library/UefiBootServicesTableLib.h>
16+
#include <Library/UefiRuntimeServicesTableLib.h>
17+
#include <Library/SpiHcPlatformLib.h>
18+
#include <Protocol/SpiHc.h>
19+
#include <IndustryStandard/SpiNorFlashJedecSfdp.h>
20+
#include "SpiHc.h"
21+
22+
EFI_HANDLE mSpiHcHandle = 0;
23+
24+
/**
25+
Entry point of the SPI Host Controller driver. Installs the EFI_SPI_HC_PROTOCOL on mSpiHcHandle.
26+
Also installs the EFI_DEVICE_PATH_PROTOCOL corresponding to the SPI Host controller on the same
27+
mSpiHcHandle.
28+
29+
@param[in] ImageHandle Image handle of this driver.
30+
@param[in] SystemTable Pointer to standard EFI system table.
31+
32+
@retval EFI_SUCCESS Succeed.
33+
@retval EFI_OUT_RESOURCES If the system has run out of memory
34+
**/
35+
EFI_STATUS
36+
EFIAPI
37+
SpiHcProtocolEntry (
38+
IN EFI_HANDLE ImageHandle,
39+
IN EFI_SYSTEM_TABLE *SystemTable
40+
)
41+
{
42+
EFI_STATUS Status;
43+
EFI_SPI_HC_PROTOCOL *HcProtocol;
44+
EFI_DEVICE_PATH_PROTOCOL *HcDevicePath;
45+
46+
DEBUG ((DEBUG_VERBOSE, "%a - ENTRY\n", __func__));
47+
48+
// Allocate the SPI Host Controller protocol
49+
HcProtocol = AllocateZeroPool (sizeof (EFI_SPI_HC_PROTOCOL));
50+
ASSERT (HcProtocol != NULL);
51+
if (HcProtocol == NULL) {
52+
return EFI_OUT_OF_RESOURCES;
53+
}
54+
55+
// Fill in the SPI Host Controller Protocol
56+
Status = GetPlatformSpiHcDetails (
57+
&HcProtocol->Attributes,
58+
&HcProtocol->FrameSizeSupportMask,
59+
&HcProtocol->MaximumTransferBytes
60+
);
61+
62+
if (EFI_ERROR (Status)) {
63+
DEBUG ((DEBUG_VERBOSE, "Error, no Platform SPI HC details\n"));
64+
return Status;
65+
}
66+
67+
HcProtocol->ChipSelect = ChipSelect;
68+
HcProtocol->Clock = Clock;
69+
HcProtocol->Transaction = Transaction;
70+
71+
// Install Host Controller protocol
72+
Status = gBS->InstallProtocolInterface (
73+
&mSpiHcHandle,
74+
&gEfiSpiHcProtocolGuid,
75+
EFI_NATIVE_INTERFACE,
76+
HcProtocol
77+
);
78+
79+
if (EFI_ERROR (Status)) {
80+
DEBUG ((DEBUG_VERBOSE, "Error installing gEfiSpiHcProtocolGuid\n"));
81+
return Status;
82+
}
83+
84+
Status = GetSpiHcDevicePath (&HcDevicePath);
85+
86+
// Install HC device path here on this handle as well
87+
Status = gBS->InstallProtocolInterface (
88+
&mSpiHcHandle,
89+
&gEfiDevicePathProtocolGuid,
90+
EFI_NATIVE_INTERFACE,
91+
HcDevicePath
92+
);
93+
94+
if (EFI_ERROR (Status)) {
95+
DEBUG ((DEBUG_VERBOSE, "Error installing gEfiDevicePathProtocolGuid\n"));
96+
}
97+
98+
DEBUG ((DEBUG_VERBOSE, "%a - EXIT Status=%r\n", __func__, Status));
99+
100+
return Status;
101+
}
+47
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,47 @@
1+
## @file
2+
# The SPI Host Controller Module DXE driver INF file
3+
#
4+
# Copyright (C) 2024 Advanced Micro Devices, Inc. All rights reserved.
5+
#
6+
# SPDX-License-Identifier: BSD-2-Clause-Patent
7+
#
8+
##
9+
10+
[Defines]
11+
INF_VERSION = 1.27
12+
BASE_NAME = SpiHcDxe
13+
FILE_GUID = 95D148FF-5A23-43B9-9FC4-80AE0DD48D32
14+
MODULE_TYPE = DXE_DRIVER
15+
VERSION_STRING = 0.1
16+
PI_SPECIFICATION_VERSION = 0x0001000A
17+
ENTRY_POINT = SpiHcProtocolEntry
18+
19+
[Packages]
20+
MdePkg/MdePkg.dec
21+
MdeModulePkg/MdeModulePkg.dec
22+
23+
[LibraryClasses]
24+
BaseLib
25+
BaseMemoryLib
26+
DebugLib
27+
DevicePathLib
28+
MemoryAllocationLib
29+
SpiHcPlatformLib
30+
UefiBootServicesTableLib
31+
UefiDriverEntryPoint
32+
UefiLib
33+
UefiRuntimeServicesTableLib
34+
35+
[Sources]
36+
SpiHc.h
37+
SpiHc.c
38+
SpiHcDxe.c
39+
40+
[Protocols]
41+
gEfiSpiHcProtocolGuid
42+
43+
[Depex]
44+
TRUE
45+
46+
[UserExtensions.TianoCore."ExtraFiles"]
47+
SpiHc.uni

0 commit comments

Comments
 (0)