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_ */