xref: /illumos-gate/usr/src/uts/common/io/qede/579xx/hsi/common_nvm.h (revision 14b24e2b79293068c8e016a69ef1d872fb5e2fd5)
1 /*
2 * CDDL HEADER START
3 *
4 * The contents of this file are subject to the terms of the
5 * Common Development and Distribution License, v.1,  (the "License").
6 * You may not use this file except in compliance with the License.
7 *
8 * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
9 * or http://opensource.org/licenses/CDDL-1.0.
10 * See the License for the specific language governing permissions
11 * and limitations under the License.
12 *
13 * When distributing Covered Code, include this CDDL HEADER in each
14 * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
15 * If applicable, add the following below this CDDL HEADER, with the
16 * fields enclosed by brackets "[]" replaced with your own identifying
17 * information: Portions Copyright [yyyy] [name of copyright owner]
18 *
19 * CDDL HEADER END
20 */
21 
22 /*
23 * Copyright 2014-2017 Cavium, Inc.
24 * The contents of this file are subject to the terms of the Common Development
25 * and Distribution License, v.1,  (the "License").
26 
27 * You may not use this file except in compliance with the License.
28 
29 * You can obtain a copy of the License at available
30 * at http://opensource.org/licenses/CDDL-1.0
31 
32 * See the License for the specific language governing permissions and
33 * limitations under the License.
34 */
35 
36 
37 #ifndef _COMMON_NVM_H_
38 #define _COMMON_NVM_H_
39 
40 #include "nvm_map.h"
41 #include "append.h"
42 // Callbacks:
43 
44 #ifndef MFW
45 #ifndef UEFI
46 	#define TRACE(module, ...) 	EDIAG_ERR(__VA_ARGS__)
47 #else // UEFI
48 	#define TRACE
49 #endif
50 #else // MFW
51 extern void memset32(u32 *ptr, u32 val, u32 byte_cnt);
52 extern void memcpy32(u32 *ptr, u32 *src, u32 byte_cnt);
53 #endif
54 
55 extern int nvm_read(u32 nvm_addr, u32 n_bytes, u32 *read_buf);
56 extern void compute_crc_from_buf(u32 *buf_p, u32 len, u32 *crc_p);
57 extern int nvm_write(u32 nvm_addr, u32 byte_cnt, u32 *buf);
58 extern int validate_dir(u32 bundle_id, u32 num_images);
59 extern void nvm_write_progress_cb(u32 byte_cnt, u32 orig_byte_cnt);
60 
61 #ifndef ERROR
62 #define ERROR (-1)
63 #endif
64 
65 #ifndef OK
66 #define OK (0)
67 #endif
68 
69 #define ROMIMG_NUM_MAX 		8
70 
71 #define PCIR_OFFSET(f)  ((u32)((int_ptr_t) &(((pci30_rom_hdr *)0)->f)))
72 
73 typedef enum {
74 	MBA_MBA_LEGACY_IDX = 0,
75 	MBA_MBA_PCI3CLP_IDX,
76 	MBA_MBA_PCI3_IDX,
77 	MBA_FCODE_IDX,
78 	EFI_X86_IDX,
79 	EFI_IPF_IDX,
80 	EFI_EBC_IDX,
81 	EFI_X64_IDX
82 } mba_image_t;
83 
84 typedef struct _exp_rom_hdr_t
85 {
86 #define ROM_HEADER_SIG		0x0AA55
87 	u16 Signature;
88 	u8  Size;
89 	u8  Entry[4];
90 	u8  Cksum;
91 	u16 VendorOffset;             /* Offset to vendor_data_t structure */
92 	u8  reserved1[12];
93 	u16 ROMIDoffset;
94 	u16 PCIdsOffset;
95 	u16 PnPehOffset;              /* Offset to pci_rom_hdr_t structure */
96 	u8  reserved2[4];
97 } exp_rom_hdr;
98 
99 typedef struct _pci30_rom_hdr_t
100 {
101 	u8  Signature[4]; /* PCIR */
102 	u16 VendorID;
103 	u16 DeviceID;
104 	u16 VP;
105 	u16 StructLength;
106 	u8  StructRev; /* PCI30 or not */
107 	u8  BaseClass;
108 	u8  SubClass;
109 	u8  Interface;
110 	u16 ImageLength;
111 	u16 ImageRev;
112 	u8  CodeType;
113 	u8  Indicator;
114 	u16 RunTimeImgLen;
115 	u16 CfgCodeHdr;
116 	u16 DmtfEntry;
117 } pci30_rom_hdr;
118 
119 /*****************************************************************************
120  *
121  * FUNCTION:       validate_image_header
122  *
123  * DESCRIPTION:    Returns the flash size in bytes.
124  *
125  * INPUT:          p_img_hdr
126  *
127  * OUTPUT:         None
128  *
129  * RETURNS:        Flash size in bytes
130  *****************************************************************************/
131 int validate_image_header(struct image_header *p_img_hdr);
132 
133 /*****************************************************************************
134  *
135  * FUNCTION:       get_flash_size
136  *
137  * DESCRIPTION:    Returns the flash size in bytes.
138  *
139  * INPUT:          None
140  *
141  * OUTPUT:         None
142  *
143  * RETURNS:        Flash size in bytes
144  *****************************************************************************/
145 u32 get_flash_size(void);
146 
147 /*****************************************************************************
148  *
149  * FUNCTION:       allocate_nvram_for_image
150  *
151  * DESCRIPTION:    Responsible allocating nvram room for an image.
152  *                 1. Remove the image from the directory (if exists)
153  *                 2. In case it is MIM or LIM, select the fixed nvram offset,
154  *                    otherwise, use the "find_room_for_image" to find room.
155  *                 3. Add the new image_header to the directory.
156  *
157  * INPUT:          p_dir - Pointer to directory
158  *                 p_image_header - Pointer to the requested image header.
159  *
160  * OUTPUT:         o_nvm_offset - nvm offset of the allocated room.
161  *
162  * RETURNS:        OK / ERROR
163  *****************************************************************************/
164 int allocate_nvram_for_image(struct nvm_dir *p_dir, struct image_header *p_image_header, u32 *o_nvm_offset);
165 
166 /*****************************************************************************
167  *
168  * FUNCTION:       find_room_for_image
169  *
170  * DESCRIPTION:    Finds room for new nvm image
171  *
172  * INPUT           image_type
173  *      	   byte_cnt
174  *      	   p_dir
175  * OUTPUT:         out_nvm_offset
176  *
177  * RETURNS:        OK/ERROR
178  *
179  *****************************************************************************/
180 int find_room_for_image(u32 image_type,
181 						u32 byte_cnt,
182 						struct nvm_dir *p_dir,
183 						u32 *out_nvm_offset);
184 
185 /*****************************************************************************
186  *
187  * FUNCTION:       get_active_dir
188  *
189  * DESCRIPTION:    Responsible allocating nvram room for an image.
190  *                 1. Read headers of both directories
191  *                 2. Validate their CRC with accordance to their sequence number.
192  *                 3. In case a directory is valid, return its id along with its next MFW.
193  * OUTPUT:         o_dir_id - Active Dir ID
194  *                 o_next_mfw - Next MFW scheduled to run from the dir.
195  *
196  * RETURNS:        OK / ERROR
197  *****************************************************************************/
198 int get_active_dir(u32 *o_dir_id, u32 *o_next_mfw);
199 
200 /*****************************************************************************
201  *
202  * FUNCTION:       prepare_bootstrap
203  *
204  * DESCRIPTION:    This function updates the active NVM bootstrap. The active bootstrap is
205  *                 read by the device ROM upon reset, and according to the bootstrap
206  *                 information it loads LIM, which starts running the MFW.
207  *
208  * INPUT:          i_lim_header - Image header of LIM
209  *
210  * OUTPUT:         o_bootstrap - Bootstrap struct to be stored in nvram.
211  *
212  * RETURNS:        none
213  *****************************************************************************/
214 void prepare_bootstrap(struct image_header *i_lim_header,
215                        struct legacy_bootstrap_region *o_bootstrap);
216 
217 /*****************************************************************************
218  *
219  * FUNCTION:       nvm_update_dir
220  *
221  * DESCRIPTION:    Update directory to nvram.
222  *
223  * INPUT:          p_dir - Pointer to the directory
224  *                 is_mfw - true/false
225  * INPUT/OUTPUT:   dir_id - Input - the current dir id. Output - The updated dir id
226  *
227  * RETURNS:        none
228  *****************************************************************************/
229 int nvm_update_dir(struct nvm_dir *p_dir, u32 *dir_id, u32 is_mfw);
230 
231 /*****************************************************************************
232  *
233  * FUNCTION:       add_nvm_entry_to_dir
234  *
235  * DESCRIPTION:    Adds new image entry to a given directory.
236  *                 1. Verify number of images doesn't exceed some crazy number - 200
237  *                 2. Since the dir is sorted according to nvram offset, move up
238  *                    all image entries higher than the requested offset for the
239  *                    new image entry
240  *                 3. Insert the new image entry
241  *                 4. Increase the number of entries in the directory.
242  *
243  * INPUT/OUTPUT    p_dir - Pointer to the directory buffer
244  *                 nvm_offset - The nvram address for the new image
245  *                 p_image_header - Pointer to the image header.
246  *
247  * RETURNS:        ERROR/OK
248  *****************************************************************************/
249 int add_nvm_entry_to_dir(struct nvm_dir *p_dir,
250                          u32 nvm_offset,
251                          struct image_header *p_image_header);
252 
253 /*****************************************************************************
254  * FUNCTION:       get_alt_image_type
255  *
256  * DESCRIPTION:    If image type is part of the MFW bundle (which has two
257  *                 bundles/slots in the nvram), then set the image type as the
258  *                 non-running one, otherwise, change nothing.
259  *
260  * INPUT:          running_mfw - 0/1
261  *                 image_type
262  *
263  * RETURNS:        Alternate image type
264  *****************************************************************************/
265 u32 get_alt_image_type(u32 running_mfw, u32 image_type);
266 
267 /*****************************************************************************
268  * FUNCTION:       load_active_nvm_dir
269  *
270  * DESCRIPTION:    Loads the active nvm dir to the o_dir_p
271  *
272  * INPUT:          None
273  *
274  * OUTPUT:         o_dir_p - Pointer to directory structure to be populated.
275  *                 o_cur_dir_id - Active Dir ID
276  *
277  * RETURNS:        OK/ERROR
278  *****************************************************************************/
279 int load_active_nvm_dir(struct nvm_dir *o_dir_p, u32 *o_cur_dir_id);
280 
281 /*****************************************************************************
282  *
283  * FUNCTION:       remove_image_from_dir
284  *
285  * DESCRIPTION:    Removes requested images from a giveN dir pointer, and
286  *                 squeeze images back. In case the requested image is not found,
287  *                 it does nothing.
288  *                 NOTE: This function doesn't recalc the CRC, or write the dir
289  *                 back to nvram !
290  *
291  * INPUT:          p_dir - pointer to the directory
292  *                 image_type - Requested image type to remove
293  *
294  * RETURNS:        OK - Image removed
295  *                 ERROR - Image not found
296  *****************************************************************************/
297 int remove_image_from_dir(struct nvm_dir *p_dir,
298                           u32 image_type);
299 
300 /*****************************************************************************
301  *
302  * FUNCTION:       inner_nvm_block_write
303  *
304  * DESCRIPTION:    Internal function for writting block of data to nvram.
305  *                 NOTE: 1. This function doesn't take nvram lock to allow multiple
306  *                          transactions within the same page.
307  *                       2. When calling this function, please use the nvm_flags
308  *                          correctly:
309  *                          MCP_REG_NVM_COMMAND_FIRST - Sets the FIRST flag on the first
310  *                                              transaction.
311  *                          MCP_REG_NVM_COMMAND_LAST  - Sets the LAST flag on the last byte write.
312  *                                               Avoid setting this flag for multiple
313  *                                               transaction on the same page, and set it
314  *                                               only for the last one.
315  *                                               In any case, the LAST flag will be set at
316  *                                               the end of NVM page (4KB).
317  *
318  * INPUT:          nvm_flags - MCP_REG_NVM_COMMAND_FIRST/MCP_REG_NVM_COMMAND_LAST/0 - See above
319  *                 nvm_addr  - Destination nvm address
320  *                 byte_cnt  - Number of bytes
321  *                 p_buf     - Pointer to the input buffer.
322  *
323  * RETURNS:        OK - Image removed
324  *                 ERROR - Image not found
325  *****************************************************************************/
326 #define MCP_REG_NVM_COMMAND_DISPLAY  (0x1<<31)
327 int inner_nvm_write(u32 nvm_flags, u32 nvm_addr, u32 byte_cnt, u32 *p_buf);
328 
329 /**********************************************************************
330  * FUNCTION:       find_image_by_type_in_dir
331  *
332  * DESCRIPTION:    Checks if the requested image type exist in the directory.
333  *                 If so, it provide it in the output parameter index, and returns OK
334  *                 Otherwise it returns ERROR;
335  *
336  * INPUT:          dir_p          - Pointer to directory
337  *                 requested_type - Image type to look for
338  *
339  * RETURNS:        OK - If requested image found
340  *                 ERROR - Otherwise.
341  ***********************************************************************/
342 int find_image_by_type_in_dir(struct nvm_dir *dir_p,
343                               u32 requested_type,
344                               u32 *index);
345 
346 #endif /* _COMMON_NVM_H_ */
347