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