• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /** @file
2 
3   Copyright (c) 2015, Intel Corporation. All rights reserved.<BR>
4   This program and the accompanying materials
5   are licensed and made available under the terms and conditions of the BSD License
6   which accompanies this distribution.  The full text of the license may be found at
7   http://opensource.org/licenses/bsd-license.php
8 
9   THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
10   WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
11 
12 **/
13 
14 #ifndef _EMMC_BLOCK_IO_PEI_H_
15 #define _EMMC_BLOCK_IO_PEI_H_
16 
17 #include <PiPei.h>
18 
19 #include <Ppi/SdMmcHostController.h>
20 #include <Ppi/BlockIo.h>
21 #include <Ppi/BlockIo2.h>
22 
23 #include <Library/DebugLib.h>
24 #include <Library/BaseLib.h>
25 #include <Library/BaseMemoryLib.h>
26 #include <Library/MemoryAllocationLib.h>
27 #include <Library/IoLib.h>
28 #include <Library/TimerLib.h>
29 #include <Library/PeiServicesLib.h>
30 
31 #include <IndustryStandard/Emmc.h>
32 
33 typedef struct _EMMC_PEIM_HC_PRIVATE_DATA EMMC_PEIM_HC_PRIVATE_DATA;
34 typedef struct _EMMC_PEIM_HC_SLOT         EMMC_PEIM_HC_SLOT;
35 typedef struct _EMMC_TRB                  EMMC_TRB;
36 
37 #include "EmmcHci.h"
38 #include "EmmcHcMem.h"
39 
40 #define EMMC_PEIM_SIG               SIGNATURE_32 ('E', 'M', 'C', 'P')
41 #define EMMC_PEIM_SLOT_SIG          SIGNATURE_32 ('E', 'M', 'C', 'S')
42 
43 #define EMMC_PEIM_MAX_SLOTS         6
44 #define EMMC_PEIM_MAX_PARTITIONS    8
45 
46 struct _EMMC_PEIM_HC_SLOT {
47   UINT32                            Signature;
48   EFI_PEI_BLOCK_IO2_MEDIA           Media[EMMC_PEIM_MAX_PARTITIONS];
49   UINT8                             MediaNum;
50   EMMC_PARTITION_TYPE               PartitionType[EMMC_PEIM_MAX_PARTITIONS];
51 
52   UINTN                             EmmcHcBase;
53   EMMC_HC_SLOT_CAP                  Capability;
54   EMMC_CSD                          Csd;
55   EMMC_EXT_CSD                      ExtCsd;
56   BOOLEAN                           SectorAddressing;
57   EMMC_PEIM_HC_PRIVATE_DATA         *Private;
58 };
59 
60 struct _EMMC_PEIM_HC_PRIVATE_DATA {
61   UINT32                            Signature;
62   EMMC_PEIM_MEM_POOL                *Pool;
63   EFI_PEI_RECOVERY_BLOCK_IO_PPI     BlkIoPpi;
64   EFI_PEI_RECOVERY_BLOCK_IO2_PPI    BlkIo2Ppi;
65   EFI_PEI_PPI_DESCRIPTOR            BlkIoPpiList;
66   EFI_PEI_PPI_DESCRIPTOR            BlkIo2PpiList;
67   EMMC_PEIM_HC_SLOT                 Slot[EMMC_PEIM_MAX_SLOTS];
68   UINT8                             SlotNum;
69   UINT8                             TotalBlkIoDevices;
70 };
71 
72 #define EMMC_TIMEOUT                MultU64x32((UINT64)(3), 1000000)
73 #define GET_EMMC_PEIM_HC_PRIVATE_DATA_FROM_THIS(a) CR (a, EMMC_PEIM_HC_PRIVATE_DATA, BlkIoPpi, EMMC_PEIM_SIG)
74 #define GET_EMMC_PEIM_HC_PRIVATE_DATA_FROM_THIS2(a) CR (a, EMMC_PEIM_HC_PRIVATE_DATA, BlkIo2Ppi, EMMC_PEIM_SIG)
75 
76 struct _EMMC_TRB {
77   EMMC_PEIM_HC_SLOT                   *Slot;
78   UINT16                              BlockSize;
79 
80   EMMC_COMMAND_PACKET                 *Packet;
81   VOID                                *Data;
82   UINT32                              DataLen;
83   BOOLEAN                             Read;
84   EMMC_HC_TRANSFER_MODE               Mode;
85 
86   UINT64                              Timeout;
87 
88   EMMC_HC_ADMA_DESC_LINE              *AdmaDesc;
89   UINTN                               AdmaDescSize;
90 };
91 
92 /**
93   Gets the count of block I/O devices that one specific block driver detects.
94 
95   This function is used for getting the count of block I/O devices that one
96   specific block driver detects.  To the PEI ATAPI driver, it returns the number
97   of all the detected ATAPI devices it detects during the enumeration process.
98   To the PEI legacy floppy driver, it returns the number of all the legacy
99   devices it finds during its enumeration process. If no device is detected,
100   then the function will return zero.
101 
102   @param[in]  PeiServices          General-purpose services that are available
103                                    to every PEIM.
104   @param[in]  This                 Indicates the EFI_PEI_RECOVERY_BLOCK_IO_PPI
105                                    instance.
106   @param[out] NumberBlockDevices   The number of block I/O devices discovered.
107 
108   @retval     EFI_SUCCESS          The operation performed successfully.
109 
110 **/
111 EFI_STATUS
112 EFIAPI
113 EmmcBlockIoPeimGetDeviceNo (
114   IN  EFI_PEI_SERVICES               **PeiServices,
115   IN  EFI_PEI_RECOVERY_BLOCK_IO_PPI  *This,
116   OUT UINTN                          *NumberBlockDevices
117   );
118 
119 /**
120   Gets a block device's media information.
121 
122   This function will provide the caller with the specified block device's media
123   information. If the media changes, calling this function will update the media
124   information accordingly.
125 
126   @param[in]  PeiServices   General-purpose services that are available to every
127                             PEIM
128   @param[in]  This          Indicates the EFI_PEI_RECOVERY_BLOCK_IO_PPI instance.
129   @param[in]  DeviceIndex   Specifies the block device to which the function wants
130                             to talk. Because the driver that implements Block I/O
131                             PPIs will manage multiple block devices, the PPIs that
132                             want to talk to a single device must specify the
133                             device index that was assigned during the enumeration
134                             process. This index is a number from one to
135                             NumberBlockDevices.
136   @param[out] MediaInfo     The media information of the specified block media.
137                             The caller is responsible for the ownership of this
138                             data structure.
139 
140   @par Note:
141       The MediaInfo structure describes an enumeration of possible block device
142       types.  This enumeration exists because no device paths are actually passed
143       across interfaces that describe the type or class of hardware that is publishing
144       the block I/O interface. This enumeration will allow for policy decisions
145       in the Recovery PEIM, such as "Try to recover from legacy floppy first,
146       LS-120 second, CD-ROM third." If there are multiple partitions abstracted
147       by a given device type, they should be reported in ascending order; this
148       order also applies to nested partitions, such as legacy MBR, where the
149       outermost partitions would have precedence in the reporting order. The
150       same logic applies to systems such as IDE that have precedence relationships
151       like "Master/Slave" or "Primary/Secondary". The master device should be
152       reported first, the slave second.
153 
154   @retval EFI_SUCCESS        Media information about the specified block device
155                              was obtained successfully.
156   @retval EFI_DEVICE_ERROR   Cannot get the media information due to a hardware
157                              error.
158 
159 **/
160 EFI_STATUS
161 EFIAPI
162 EmmcBlockIoPeimGetMediaInfo (
163   IN  EFI_PEI_SERVICES               **PeiServices,
164   IN  EFI_PEI_RECOVERY_BLOCK_IO_PPI  *This,
165   IN  UINTN                          DeviceIndex,
166   OUT EFI_PEI_BLOCK_IO_MEDIA         *MediaInfo
167   );
168 
169 /**
170   Reads the requested number of blocks from the specified block device.
171 
172   The function reads the requested number of blocks from the device. All the
173   blocks are read, or an error is returned. If there is no media in the device,
174   the function returns EFI_NO_MEDIA.
175 
176   @param[in]  PeiServices   General-purpose services that are available to
177                             every PEIM.
178   @param[in]  This          Indicates the EFI_PEI_RECOVERY_BLOCK_IO_PPI instance.
179   @param[in]  DeviceIndex   Specifies the block device to which the function wants
180                             to talk. Because the driver that implements Block I/O
181                             PPIs will manage multiple block devices, PPIs that
182                             want to talk to a single device must specify the device
183                             index that was assigned during the enumeration process.
184                             This index is a number from one to NumberBlockDevices.
185   @param[in]  StartLBA      The starting logical block address (LBA) to read from
186                             on the device
187   @param[in]  BufferSize    The size of the Buffer in bytes. This number must be
188                             a multiple of the intrinsic block size of the device.
189   @param[out] Buffer        A pointer to the destination buffer for the data.
190                             The caller is responsible for the ownership of the
191                             buffer.
192 
193   @retval EFI_SUCCESS             The data was read correctly from the device.
194   @retval EFI_DEVICE_ERROR        The device reported an error while attempting
195                                   to perform the read operation.
196   @retval EFI_INVALID_PARAMETER   The read request contains LBAs that are not
197                                   valid, or the buffer is not properly aligned.
198   @retval EFI_NO_MEDIA            There is no media in the device.
199   @retval EFI_BAD_BUFFER_SIZE     The BufferSize parameter is not a multiple of
200                                   the intrinsic block size of the device.
201 
202 **/
203 EFI_STATUS
204 EFIAPI
205 EmmcBlockIoPeimReadBlocks (
206   IN  EFI_PEI_SERVICES               **PeiServices,
207   IN  EFI_PEI_RECOVERY_BLOCK_IO_PPI  *This,
208   IN  UINTN                          DeviceIndex,
209   IN  EFI_PEI_LBA                    StartLBA,
210   IN  UINTN                          BufferSize,
211   OUT VOID                           *Buffer
212   );
213 
214 /**
215   Gets the count of block I/O devices that one specific block driver detects.
216 
217   This function is used for getting the count of block I/O devices that one
218   specific block driver detects.  To the PEI ATAPI driver, it returns the number
219   of all the detected ATAPI devices it detects during the enumeration process.
220   To the PEI legacy floppy driver, it returns the number of all the legacy
221   devices it finds during its enumeration process. If no device is detected,
222   then the function will return zero.
223 
224   @param[in]  PeiServices          General-purpose services that are available
225                                    to every PEIM.
226   @param[in]  This                 Indicates the EFI_PEI_RECOVERY_BLOCK_IO2_PPI
227                                    instance.
228   @param[out] NumberBlockDevices   The number of block I/O devices discovered.
229 
230   @retval     EFI_SUCCESS          The operation performed successfully.
231 
232 **/
233 EFI_STATUS
234 EFIAPI
235 EmmcBlockIoPeimGetDeviceNo2 (
236   IN  EFI_PEI_SERVICES               **PeiServices,
237   IN  EFI_PEI_RECOVERY_BLOCK_IO2_PPI *This,
238   OUT UINTN                          *NumberBlockDevices
239   );
240 
241 /**
242   Gets a block device's media information.
243 
244   This function will provide the caller with the specified block device's media
245   information. If the media changes, calling this function will update the media
246   information accordingly.
247 
248   @param[in]  PeiServices   General-purpose services that are available to every
249                             PEIM
250   @param[in]  This          Indicates the EFI_PEI_RECOVERY_BLOCK_IO2_PPI instance.
251   @param[in]  DeviceIndex   Specifies the block device to which the function wants
252                             to talk. Because the driver that implements Block I/O
253                             PPIs will manage multiple block devices, the PPIs that
254                             want to talk to a single device must specify the
255                             device index that was assigned during the enumeration
256                             process. This index is a number from one to
257                             NumberBlockDevices.
258   @param[out] MediaInfo     The media information of the specified block media.
259                             The caller is responsible for the ownership of this
260                             data structure.
261 
262   @par Note:
263       The MediaInfo structure describes an enumeration of possible block device
264       types.  This enumeration exists because no device paths are actually passed
265       across interfaces that describe the type or class of hardware that is publishing
266       the block I/O interface. This enumeration will allow for policy decisions
267       in the Recovery PEIM, such as "Try to recover from legacy floppy first,
268       LS-120 second, CD-ROM third." If there are multiple partitions abstracted
269       by a given device type, they should be reported in ascending order; this
270       order also applies to nested partitions, such as legacy MBR, where the
271       outermost partitions would have precedence in the reporting order. The
272       same logic applies to systems such as IDE that have precedence relationships
273       like "Master/Slave" or "Primary/Secondary". The master device should be
274       reported first, the slave second.
275 
276   @retval EFI_SUCCESS        Media information about the specified block device
277                              was obtained successfully.
278   @retval EFI_DEVICE_ERROR   Cannot get the media information due to a hardware
279                              error.
280 
281 **/
282 EFI_STATUS
283 EFIAPI
284 EmmcBlockIoPeimGetMediaInfo2 (
285   IN  EFI_PEI_SERVICES               **PeiServices,
286   IN  EFI_PEI_RECOVERY_BLOCK_IO2_PPI *This,
287   IN  UINTN                          DeviceIndex,
288   OUT EFI_PEI_BLOCK_IO2_MEDIA        *MediaInfo
289   );
290 
291 /**
292   Reads the requested number of blocks from the specified block device.
293 
294   The function reads the requested number of blocks from the device. All the
295   blocks are read, or an error is returned. If there is no media in the device,
296   the function returns EFI_NO_MEDIA.
297 
298   @param[in]  PeiServices   General-purpose services that are available to
299                             every PEIM.
300   @param[in]  This          Indicates the EFI_PEI_RECOVERY_BLOCK_IO2_PPI instance.
301   @param[in]  DeviceIndex   Specifies the block device to which the function wants
302                             to talk. Because the driver that implements Block I/O
303                             PPIs will manage multiple block devices, PPIs that
304                             want to talk to a single device must specify the device
305                             index that was assigned during the enumeration process.
306                             This index is a number from one to NumberBlockDevices.
307   @param[in]  StartLBA      The starting logical block address (LBA) to read from
308                             on the device
309   @param[in]  BufferSize    The size of the Buffer in bytes. This number must be
310                             a multiple of the intrinsic block size of the device.
311   @param[out] Buffer        A pointer to the destination buffer for the data.
312                             The caller is responsible for the ownership of the
313                             buffer.
314 
315   @retval EFI_SUCCESS             The data was read correctly from the device.
316   @retval EFI_DEVICE_ERROR        The device reported an error while attempting
317                                   to perform the read operation.
318   @retval EFI_INVALID_PARAMETER   The read request contains LBAs that are not
319                                   valid, or the buffer is not properly aligned.
320   @retval EFI_NO_MEDIA            There is no media in the device.
321   @retval EFI_BAD_BUFFER_SIZE     The BufferSize parameter is not a multiple of
322                                   the intrinsic block size of the device.
323 
324 **/
325 EFI_STATUS
326 EFIAPI
327 EmmcBlockIoPeimReadBlocks2 (
328   IN  EFI_PEI_SERVICES               **PeiServices,
329   IN  EFI_PEI_RECOVERY_BLOCK_IO2_PPI *This,
330   IN  UINTN                          DeviceIndex,
331   IN  EFI_PEI_LBA                    StartLBA,
332   IN  UINTN                          BufferSize,
333   OUT VOID                           *Buffer
334   );
335 
336 /**
337   Initialize the memory management pool for the host controller.
338 
339   @param  Private               The Emmc Peim driver private data.
340 
341   @retval EFI_SUCCESS           The memory pool is initialized.
342   @retval Others                Fail to init the memory pool.
343 
344 **/
345 EFI_STATUS
346 EmmcPeimInitMemPool (
347   IN  EMMC_PEIM_HC_PRIVATE_DATA      *Private
348   );
349 
350 /**
351   Allocate some memory from the host controller's memory pool
352   which can be used to communicate with host controller.
353 
354   @param  Pool      The host controller's memory pool.
355   @param  Size      Size of the memory to allocate.
356 
357   @return The allocated memory or NULL.
358 
359 **/
360 VOID *
361 EmmcPeimAllocateMem (
362   IN  EMMC_PEIM_MEM_POOL        *Pool,
363   IN  UINTN                    Size
364   );
365 
366 /**
367   Free the allocated memory back to the memory pool.
368 
369   @param  Pool           The memory pool of the host controller.
370   @param  Mem            The memory to free.
371   @param  Size           The size of the memory to free.
372 
373 **/
374 VOID
375 EmmcPeimFreeMem (
376   IN EMMC_PEIM_MEM_POOL    *Pool,
377   IN VOID                 *Mem,
378   IN UINTN                Size
379   );
380 
381 #endif
382