summaryrefslogtreecommitdiff
path: root/usr/src/uts/common/io/qede/579xx/hsi/common_nvm.h
blob: 2d8f3d1cdc8eb6cba9d9a9e5c12fea7b2580b469 (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
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
/*
* CDDL HEADER START
*
* The contents of this file are subject to the terms of the
* Common Development and Distribution License, v.1,  (the "License").
* You may not use this file except in compliance with the License.
*
* You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
* or http://opensource.org/licenses/CDDL-1.0.
* See the License for the specific language governing permissions
* and limitations under the License.
*
* When distributing Covered Code, include this CDDL HEADER in each
* file and include the License file at usr/src/OPENSOLARIS.LICENSE.
* If applicable, add the following below this CDDL HEADER, with the
* fields enclosed by brackets "[]" replaced with your own identifying
* information: Portions Copyright [yyyy] [name of copyright owner]
*
* CDDL HEADER END
*/

/*
* Copyright 2014-2017 Cavium, Inc. 
* The contents of this file are subject to the terms of the Common Development 
* and Distribution License, v.1,  (the "License").

* You may not use this file except in compliance with the License.

* You can obtain a copy of the License at available 
* at http://opensource.org/licenses/CDDL-1.0

* See the License for the specific language governing permissions and 
* limitations under the License.
*/


#ifndef _COMMON_NVM_H_ 
#define _COMMON_NVM_H_ 

#include "nvm_map.h"
#include "append.h"
// Callbacks:

#ifndef MFW
#ifndef UEFI
	#define TRACE(module, ...) 	EDIAG_ERR(__VA_ARGS__)
#else // UEFI	
	#define TRACE	
#endif
#else // MFW
extern void memset32(u32 *ptr, u32 val, u32 byte_cnt);
extern void memcpy32(u32 *ptr, u32 *src, u32 byte_cnt);
#endif

extern int nvm_read(u32 nvm_addr, u32 n_bytes, u32 *read_buf);
extern void compute_crc_from_buf(u32 *buf_p, u32 len, u32 *crc_p);
extern int nvm_write(u32 nvm_addr, u32 byte_cnt, u32 *buf);
extern int validate_dir(u32 bundle_id, u32 num_images);
extern void nvm_write_progress_cb(u32 byte_cnt, u32 orig_byte_cnt);

#ifndef ERROR
#define ERROR (-1)
#endif

#ifndef OK
#define OK (0)
#endif

#define ROMIMG_NUM_MAX 		8

#define PCIR_OFFSET(f)  ((u32)((int_ptr_t) &(((pci30_rom_hdr *)0)->f)))

typedef enum {
	MBA_MBA_LEGACY_IDX = 0,
	MBA_MBA_PCI3CLP_IDX,
	MBA_MBA_PCI3_IDX,
	MBA_FCODE_IDX,
	EFI_X86_IDX,
	EFI_IPF_IDX,
	EFI_EBC_IDX,
	EFI_X64_IDX
} mba_image_t;

typedef struct _exp_rom_hdr_t
{
#define ROM_HEADER_SIG		0x0AA55
	u16 Signature;
	u8  Size;
	u8  Entry[4];
	u8  Cksum;
	u16 VendorOffset;             /* Offset to vendor_data_t structure */
	u8  reserved1[12];
	u16 ROMIDoffset;
	u16 PCIdsOffset;
	u16 PnPehOffset;              /* Offset to pci_rom_hdr_t structure */
	u8  reserved2[4];
} exp_rom_hdr;

typedef struct _pci30_rom_hdr_t
{
	u8  Signature[4]; /* PCIR */
	u16 VendorID;
	u16 DeviceID;
	u16 VP;
	u16 StructLength;
	u8  StructRev; /* PCI30 or not */
	u8  BaseClass;
	u8  SubClass;
	u8  Interface;
	u16 ImageLength;
	u16 ImageRev;
	u8  CodeType;
	u8  Indicator;
	u16 RunTimeImgLen;
	u16 CfgCodeHdr;
	u16 DmtfEntry;
} pci30_rom_hdr;

/*****************************************************************************
 *
 * FUNCTION:       validate_image_header
 *
 * DESCRIPTION:    Returns the flash size in bytes.
 *
 * INPUT:          p_img_hdr
 *         
 * OUTPUT:         None
 * 
 * RETURNS:        Flash size in bytes
 *****************************************************************************/
int validate_image_header(struct image_header *p_img_hdr);

/*****************************************************************************
 *
 * FUNCTION:       get_flash_size
 *
 * DESCRIPTION:    Returns the flash size in bytes.
 *
 * INPUT:          None
 *         
 * OUTPUT:         None
 * 
 * RETURNS:        Flash size in bytes
 *****************************************************************************/
u32 get_flash_size(void);

/*****************************************************************************
 *
 * FUNCTION:       allocate_nvram_for_image
 *
 * DESCRIPTION:    Responsible allocating nvram room for an image.
 *                 1. Remove the image from the directory (if exists)
 *                 2. In case it is MIM or LIM, select the fixed nvram offset,
 *                    otherwise, use the "find_room_for_image" to find room.
 *                 3. Add the new image_header to the directory.
 *                
 * INPUT:          p_dir - Pointer to directory
 *                 p_image_header - Pointer to the requested image header.
 * 
 * OUTPUT:         o_nvm_offset - nvm offset of the allocated room.
 * 
 * RETURNS:        OK / ERROR
 *****************************************************************************/
int allocate_nvram_for_image(struct nvm_dir *p_dir, struct image_header *p_image_header, u32 *o_nvm_offset);

/*****************************************************************************
 *
 * FUNCTION:       find_room_for_image
 *
 * DESCRIPTION:    Finds room for new nvm image
 *
 * INPUT           image_type
 *      	   byte_cnt
 *      	   p_dir
 * OUTPUT:         out_nvm_offset
 *
 * RETURNS:        OK/ERROR
 *
 *****************************************************************************/
int find_room_for_image(u32 image_type,
						u32 byte_cnt,
						struct nvm_dir *p_dir,
						u32 *out_nvm_offset);

/*****************************************************************************
 *
 * FUNCTION:       get_active_dir
 *
 * DESCRIPTION:    Responsible allocating nvram room for an image.
 *                 1. Read headers of both directories
 *                 2. Validate their CRC with accordance to their sequence number.
 *                 3. In case a directory is valid, return its id along with its next MFW.
 * OUTPUT:         o_dir_id - Active Dir ID
 *                 o_next_mfw - Next MFW scheduled to run from the dir.
 * 
 * RETURNS:        OK / ERROR
 *****************************************************************************/
int get_active_dir(u32 *o_dir_id, u32 *o_next_mfw);

/*****************************************************************************
 *
 * FUNCTION:       prepare_bootstrap
 *
 * DESCRIPTION:    This function updates the active NVM bootstrap. The active bootstrap is
 *                 read by the device ROM upon reset, and according to the bootstrap
 *                 information it loads LIM, which starts running the MFW.
 *
 * INPUT:          i_lim_header - Image header of LIM
 * 
 * OUTPUT:         o_bootstrap - Bootstrap struct to be stored in nvram.
 * 
 * RETURNS:        none
 *****************************************************************************/
void prepare_bootstrap(struct image_header *i_lim_header,
                       struct legacy_bootstrap_region *o_bootstrap);

/*****************************************************************************
 *
 * FUNCTION:       nvm_update_dir
 *
 * DESCRIPTION:    Update directory to nvram.
 *
 * INPUT:          p_dir - Pointer to the directory
 *                 is_mfw - true/false
 * INPUT/OUTPUT:   dir_id - Input - the current dir id. Output - The updated dir id
 * 
 * RETURNS:        none
 *****************************************************************************/
int nvm_update_dir(struct nvm_dir *p_dir, u32 *dir_id, u32 is_mfw);

/*****************************************************************************
 *
 * FUNCTION:       add_nvm_entry_to_dir
 *
 * DESCRIPTION:    Adds new image entry to a given directory.
 *                 1. Verify number of images doesn't exceed some crazy number - 200
 *                 2. Since the dir is sorted according to nvram offset, move up
 *                    all image entries higher than the requested offset for the
 *                    new image entry
 *                 3. Insert the new image entry
 *                 4. Increase the number of entries in the directory.
 *
 * INPUT/OUTPUT    p_dir - Pointer to the directory buffer
 *                 nvm_offset - The nvram address for the new image
 *                 p_image_header - Pointer to the image header.
 *
 * RETURNS:        ERROR/OK
 *****************************************************************************/
int add_nvm_entry_to_dir(struct nvm_dir *p_dir,
                         u32 nvm_offset,
                         struct image_header *p_image_header);

/*****************************************************************************
 * FUNCTION:       get_alt_image_type
 *
 * DESCRIPTION:    If image type is part of the MFW bundle (which has two
 *                 bundles/slots in the nvram), then set the image type as the
 *                 non-running one, otherwise, change nothing.
 * 
 * INPUT:          running_mfw - 0/1
 *                 image_type
 *
 * RETURNS:        Alternate image type
 *****************************************************************************/
u32 get_alt_image_type(u32 running_mfw, u32 image_type);

/*****************************************************************************
 * FUNCTION:       load_active_nvm_dir
 *
 * DESCRIPTION:    Loads the active nvm dir to the o_dir_p
 * 
 * INPUT:          None
 * 
 * OUTPUT:         o_dir_p - Pointer to directory structure to be populated.
 *                 o_cur_dir_id - Active Dir ID
 *
 * RETURNS:        OK/ERROR
 *****************************************************************************/
int load_active_nvm_dir(struct nvm_dir *o_dir_p, u32 *o_cur_dir_id);

/*****************************************************************************
 *
 * FUNCTION:       remove_image_from_dir
 *
 * DESCRIPTION:    Removes requested images from a giveN dir pointer, and
 *                 squeeze images back. In case the requested image is not found,
 *                 it does nothing.
 *                 NOTE: This function doesn't recalc the CRC, or write the dir
 *                 back to nvram !
 *
 * INPUT:          p_dir - pointer to the directory
 *                 image_type - Requested image type to remove
 *
 * RETURNS:        OK - Image removed
 *                 ERROR - Image not found
 *****************************************************************************/
int remove_image_from_dir(struct nvm_dir *p_dir,
                          u32 image_type);

/*****************************************************************************
 *
 * FUNCTION:       inner_nvm_block_write
 *
 * DESCRIPTION:    Internal function for writting block of data to nvram.
 *                 NOTE: 1. This function doesn't take nvram lock to allow multiple
 *                          transactions within the same page.
 *                       2. When calling this function, please use the nvm_flags
 *                          correctly:
 *                          MCP_REG_NVM_COMMAND_FIRST - Sets the FIRST flag on the first
 *                                              transaction.
 *                          MCP_REG_NVM_COMMAND_LAST  - Sets the LAST flag on the last byte write.
 *                                               Avoid setting this flag for multiple
 *                                               transaction on the same page, and set it
 *                                               only for the last one.
 *                                               In any case, the LAST flag will be set at
 *                                               the end of NVM page (4KB).
 *
 * INPUT:          nvm_flags - MCP_REG_NVM_COMMAND_FIRST/MCP_REG_NVM_COMMAND_LAST/0 - See above
 *                 nvm_addr  - Destination nvm address
 *                 byte_cnt  - Number of bytes
 *                 p_buf     - Pointer to the input buffer.
 *
 * RETURNS:        OK - Image removed
 *                 ERROR - Image not found
 *****************************************************************************/
#define MCP_REG_NVM_COMMAND_DISPLAY  (0x1<<31)
int inner_nvm_write(u32 nvm_flags, u32 nvm_addr, u32 byte_cnt, u32 *p_buf);

/**********************************************************************
 * FUNCTION:       find_image_by_type_in_dir
 *
 * DESCRIPTION:    Checks if the requested image type exist in the directory.
 *                 If so, it provide it in the output parameter index, and returns OK
 *                 Otherwise it returns ERROR;
 *
 * INPUT:          dir_p          - Pointer to directory
 *                 requested_type - Image type to look for
 *
 * RETURNS:        OK - If requested image found
 *                 ERROR - Otherwise.
 ***********************************************************************/
int find_image_by_type_in_dir(struct nvm_dir *dir_p,
                              u32 requested_type,
                              u32 *index);

#endif /* _COMMON_NVM_H_ */