summaryrefslogtreecommitdiffstats
path: root/MdeModulePkg/Bus/Spi/SpiNorFlashJedecSfdp/SpiNorFlashJedecSfdpInternal.h
blob: 309d8dcea70f044423440e880e7e392dbd7be8d9 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
/** @file
  SPI NOR flash driver internal definitions.

  Copyright (C) 2024 Advanced Micro Devices, Inc. All rights reserved.

  SPDX-License-Identifier: BSD-2-Clause-Patent

**/

#ifndef SPI_NOR_FLASH_INSTANCE_H_
#define SPI_NOR_FLASH_INSTANCE_H_

#include <PiDxe.h>
#include <Protocol/SpiNorFlash.h>
#include <Protocol/SpiIo.h>
#include <IndustryStandard/SpiNorFlashJedecSfdp.h>

#define SPI_NOR_FLASH_SIGNATURE  SIGNATURE_32 ('s', 'n', 'f', 'm')

#define SPI_NOR_FLASH_FROM_THIS(a)  CR (a, SPI_NOR_FLASH_INSTANCE, Protocol, SPI_NOR_FLASH_SIGNATURE)

typedef struct {
  LIST_ENTRY    NextFastReadCap;     ///< Link list to next Fast read capability
  UINT8         FastReadInstruction; ///< Fast read instruction.
  UINT8         ModeClocks;          ///< Fast read clock.
  UINT8         WaitStates;          ///< Fast read wait dummy clocks
} SFPD_FAST_READ_CAPBILITY_RECORD;

typedef struct {
  LIST_ENTRY    NextEraseType;      ///< Link list to next erase type.
  UINT16        EraseType;          ///< Erase type this flash device supports.
  UINT8         EraseInstruction;   ///< Erase instruction
  UINT32        EraseSizeInByte;    ///< The size of byte in 2^EraseSize the erase type command
                                    ///< can erase.
  UINT32        EraseTypicalTime;   ///< Time the device typically takes to erase this type
                                    ///< size.
  UINT64        EraseTimeout;       ///< Maximum typical erase timeout.
} SFDP_SUPPORTED_ERASE_TYPE_RECORD;

typedef enum {
  SearchEraseTypeByType = 1,
  SearchEraseTypeByCommand,
  SearchEraseTypeBySize,
  SearchEraseTypeBySmallestSize,
  SearchEraseTypeByBiggestSize
} SFDP_SEARCH_ERASE_TYPE;

typedef struct {
  LIST_ENTRY                                NextCommand;          ///< Link list to next detection command.
  UINT32                                    CommandAddress;       ///< Address to issue the command.
  UINT8                                     CommandInstruction;   ///< Detection command instruction.
  UINT8                                     LatencyInClock;       ///< Command latency in clocks.
  SPDF_CONFIGURATION_COMMAND_ADDR_LENGTH    CommandAddressLength; ///< Adddress length of detection command.
  UINT8                                     ConfigurationBitMask; ///< The interest bit of the byte data retunred
                                                                  ///< after sending the detection command.
} SFDP_SECTOR_MAP_DETECTION_RECORD;

typedef struct {
  LIST_ENTRY    NextRegion;                                      ///< Link list to the next region.
  UINT32        RegionAddress;                                   ///< Region starting address.
  UINT32        RegionTotalSize;                                 ///< Region total size in bytes.
  UINT32        RegionSectors;                                   ///< Sectors in this region.
  UINT32        SectorSize;                                      ///< Sector size in byte (Minimum blcok erase size)
  UINT8         SupportedEraseTypeNum;                           ///< Number of erase type supported.
  UINT8         SupportedEraseType[SFDP_ERASE_TYPES_NUMBER];     ///< Erase types supported.
  UINT32        EraseTypeBySizeBitmap;                           ///< The bitmap of supoprted srase block sizes.
                                                                 ///< from big to small.
} SFDP_SECTOR_REGION_RECORD;

typedef struct {
  LIST_ENTRY    NextDescriptor;                                  ///< Link list to next flash map descriptor.
  UINT8         ConfigurationId;                                 ///< The ID of this configuration.
  UINT8         RegionCount;                                     ///< The regions of this sector map configuration.
  LIST_ENTRY    RegionList;                                      ///< The linked list of the regions.
} SFDP_SECTOR_MAP_RECORD;

typedef struct {
  UINTN                         Signature;
  EFI_HANDLE                    Handle;
  EFI_SPI_NOR_FLASH_PROTOCOL    Protocol;
  EFI_SPI_IO_PROTOCOL           *SpiIo;
  UINT32                        SfdpBasicFlashByteCount;
  UINT32                        SfdpSectorMapByteCount;
  SFDP_BASIC_FLASH_PARAMETER    *SfdpBasicFlash;
  SFDP_SECTOR_MAP_TABLE         *SfdpFlashSectorMap;
  UINT8                         *SpiTransactionWriteBuffer;
  UINT32                        SpiTransactionWriteBufferIndex;
  //
  // SFDP information.
  //
  SFDP_HEADER                   SfdpHeader;              ///< SFDP header.
  UINT32                        FlashDeviceSize;         ///< The total size of this flash device.
  UINT8                         CurrentAddressBytes;     ///< The current address bytes.

  //
  // This is a linked list in which the Fast Read capability tables
  // are linked from the low performance transfer to higher performance
  // transfer. The SPI read would use the first Fast Read entry for
  // SPI read operation.
  //
  LIST_ENTRY                    FastReadTableList;

  LIST_ENTRY                    SupportedEraseTypes;      ///< The linked list of supported erase types.
  BOOLEAN                       Uniform4KEraseSupported;  ///< The flash device supoprts uniform 4K erase.
  BOOLEAN                       WriteEnableLatchRequired; ///< Wether Write Enable Latch is supported.
  UINT8                         WriteEnableLatchCommand;  ///< Write Enable Latch command.
  //
  // Below is the linked list of flash device sector
  // map configuration detection command and map descriptors.
  //
  BOOLEAN                       ConfigurationCommandsNeeded; ///< Indicates whether sector map
                                                             ///< configuration detection is
                                                             ///< required.
  LIST_ENTRY                    ConfigurationCommandList;    ///< The linked list of configuration
                                                             ///< detection command sequence.
  LIST_ENTRY                    ConfigurationMapList;        ///< The linked list of configuration
                                                             ///< map descriptors.
  SFDP_SECTOR_MAP_RECORD        *CurrentSectorMap;           ///< The current activated flash device
                                                             ///< sector map.
} SPI_NOR_FLASH_INSTANCE;

/**
  This routine returns the desired Fast Read mode.

  @param[in]           Instance                 Spi Nor Flash Instance data with pointer to
                                                EFI_SPI_NOR_FLASH_PROTOCOL and EFI_SPI_IO_PROTOCOL
  @param[in,out]       FastReadInstruction      Fast Read instruction, the input is
                                                the default value.
  @param[in,out]       FastReadOperationClock   Fast Read operation clock, the input is
                                                the default value.
  @param[in,out]       FastReadDummyClocks      Fast Read wait state (Dummy clocks), the
                                                input is the default value.
  @retval EFI_SUCCESS     The parameters are updated.
  @retval EFI_NOT_FOUND   No desired Fas Read mode found.

**/
EFI_STATUS
GetFastReadParameter (
  IN     SPI_NOR_FLASH_INSTANCE  *Instance,
  IN OUT UINT8                   *FastReadInstruction,
  IN OUT UINT8                   *FastReadOperationClock,
  IN OUT UINT8                   *FastReadDummyClocks
  );

/**
  Read SFDP parameters into buffer

  This routine reads the JEDEC SPI Flash Discoverable Parameters from the SPI
  chip.

  @param[in]  Instance    Spi Nor Flash Instance data with pointer to
  EFI_SPI_NOR_FLASH_PROTOCOL and EFI_SPI_IO_PROTOCOL

  @retval EFI_SUCCESS            The SPI part size is filled.
  @retval EFI_DEVICE_ERROR       Invalid data received from SPI flash part.

**/
EFI_STATUS
ReadSfdpBasicParameterTable (
  IN  SPI_NOR_FLASH_INSTANCE  *Instance
  );

/**
  Read SFDP Sector Map Parameter into buffer

  This routine reads the JEDEC SPI Flash Discoverable Parameters from the SPI
  chip.

  @param[in]  Instance           Spi Nor Flash Instance data with pointer to
                                 EFI_SPI_NOR_FLASH_PROTOCOL and EFI_SPI_IO_PROTOCOL

  @retval EFI_SUCCESS            The SPI part size is filled.
  @retval EFI_DEVICE_ERROR       Invalid data received from SPI flash part.

**/
EFI_STATUS
ReadSfdpSectorMapParameterTable (
  IN  SPI_NOR_FLASH_INSTANCE  *Instance
  );

/**
  Return flash device size from SFDP Basic Flash Parameter Table DWORD 2

  @param[in]  Instance    Spi Nor Flash Instance data with pointer to
                          EFI_SPI_NOR_FLASH_PROTOCOL and
                          EFI_SPI_IO_PROTOCOL.

* @retval   UINT32        Flash device size in byte, zero indicates error.

**/
UINT32
SfdpGetFlashSize (
  IN  SPI_NOR_FLASH_INSTANCE  *Instance
  );

/**
  Read SFDP
  This routine reads the JEDEC SPI Flash Discoverable Parameters. We just
  read the necessary tables in this routine.

  @param[in]  Instance    Spi Nor Flash Instance data with pointer to
                          EFI_SPI_NOR_FLASH_PROTOCOL and EFI_SPI_IO_PROTOCOL

  @retval EFI_SUCCESS            Header is filled in
  @retval EFI_DEVICE_ERROR       Invalid data received from SPI flash part.

**/
EFI_STATUS
ReadSfdp (
  IN  SPI_NOR_FLASH_INSTANCE  *Instance
  );

/**
  Set EraseBlockBytes in SPI NOR Flash Protocol

  @param[in]  Instance    Spi Nor Flash Instance data with pointer to
                          EFI_SPI_NOR_FLASH_PROTOCOL and EFI_SPI_IO_PROTOCOL

  @retval EFI_SUCCESS     The erase block size is returned.
  @retval Otherwise       Failed to get erase block size.

**/
EFI_STATUS
SetSectorEraseBlockSize (
  IN  SPI_NOR_FLASH_INSTANCE  *Instance
  );

/**
  Get the erase block attribute for the target address.

  @param[in]      Instance              Spi Nor Flash Instance data with pointer to
                                        EFI_SPI_NOR_FLASH_PROTOCOL and EFI_SPI_IO_PROTOCOL
  @param[in]      FlashRegion           The region the flash address belong.
  @param[in]      FlashAddress          The target flash address.
  @param[in]      RemainingSize         Remaining size to erase.
  @param[in, out] BlockSizeToErase      Input  - The block erase size for this continious blocks.
                                        Output - The determined block size for erasing.
  @param[in, out] BlockCountToErase     Input  - The expected blocks to erase.
                                        Output - The determined number of blocks to erase.
  @param[out]     BlockEraseCommand     The erase command used for this continious blocks.
  @param[out]     TypicalTime           Pointer to receive the typical time in millisecond
                                        to erase this erase type size.
  @param[out]     MaximumTimeout        Pointer to receive the maximum timeout in millisecond
                                        to erase this erase type size.
  @retval EFI_SUCCESS          The erase block attribute is returned.
  @retval EFI_DEVICE_ERROR     No valid SFDP discovered.
  @retval EFI_NOT_FOUND        No valud erase block attribute found.

**/
EFI_STATUS
GetEraseBlockAttribute (
  IN     SPI_NOR_FLASH_INSTANCE     *Instance,
  IN     SFDP_SECTOR_REGION_RECORD  *FlashRegion,
  IN     UINT32                     FlashAddress,
  IN     UINT32                     RemainingSize,
  IN OUT UINT32                     *BlockSizeToErase,
  IN OUT UINT32                     *BlockCountToErase,
  OUT    UINT8                      *BlockEraseCommand,
  OUT    UINT32                     *TypicalTime,
  OUT    UINT64                     *MaximumTimeout
  );

/**
  Get the erase block attribute for the target address.

  @param[in]   Instance                Spi Nor Flash Instance data with pointer to
                                       EFI_SPI_NOR_FLASH_PROTOCOL and EFI_SPI_IO_PROTOCOL
  @param[in]   FlashAddress            The target flash address.
  @param[out]  FlashRegion             The target flash address.

  @retval EFI_SUCCESS             The region is returned.
  @retval EFI_INVALID_PARAMETER   FlashAddress is not belong to any region.
  @retval EFI_INVALID_PARAMETER   Other errors.

**/
EFI_STATUS
GetRegionByFlashAddress (
  IN  SPI_NOR_FLASH_INSTANCE     *Instance,
  IN  UINT32                     FlashAddress,
  OUT SFDP_SECTOR_REGION_RECORD  **FlashRegion
  );

/**
  Initial SPI_NOR_FLASH_INSTANCE structure.

  @param[in]   Instance                Pointer to SPI_NOR_FLASH_INSTANCE.
                                       EFI_SPI_NOR_FLASH_PROTOCOL and EFI_SPI_IO_PROTOCOL

  @retval EFI_SUCCESS                  SPI_NOR_FLASH_INSTANCE is initialized according to
                                       SPI NOR Flash SFDP specification.
  @retval Otherwisw                    Failed to initial SPI_NOR_FLASH_INSTANCE structure.

**/
EFI_STATUS
InitialSpiNorFlashSfdpInstance (
  IN SPI_NOR_FLASH_INSTANCE  *Instance
  );

#endif // SPI_NOR_FLASH_INSTANCE_H_