openbcm

Git mirror of https://github.com/Broadcom-Network-Switching-Software/OpenBCM
git clone git://git.finwo.net/mirror/broadcom/openbcm
Log | Files | Refs | README

spiflash.c (6242B)


      1 /*
      2  * 
      3  * This license is set out in https://raw.githubusercontent.com/Broadcom-Network-Switching-Software/OpenBCM/master/Legal/LICENSE file.
      4  * 
      5  * Copyright 2007-2019 Broadcom Inc. All rights reserved.
      6  *
      7  * Arm Processor Subsystem flash utility
      8  */
      9 
     10 #include <sal/core/libc.h>
     11 #include <appl/diag/aps/spiflash.h>
     12 
     13 #define ROUND_UP(x,y)           ((((uint32)(x)) + ((uint32)(y)) - 1) \
     14                                  & ~(uint32)((y) - 1))
     15 
     16 flash_info_t spiflash_info[] = {
     17     { "m25p10a",  0x202011,    256,  64*1024, 32*1024,  128*1024 },
     18     { "m25p20",   0x202012,    256,  64*1024, 64*1024,  256*1024 },
     19     { "m25p40",   0x202013,    256,  64*1024, 64*1024,  512*1024 },
     20     { "m25p80",   0x202014,    256,  64*1024, 64*1024, 1024*1024 },
     21     { "m25p16",   0x202015,    256,  64*1024, 64*1024, 2048*1024 },
     22 
     23     { "s25fl032p", 0x010215,   256,  64*1024, 64*1024, 4096*1024 },
     24 
     25     { "m45pe10",  0x204011,    256,      256, 64*1024,  128*1024 },
     26     { "m45pe20",  0x204012,    256,      256, 64*1024,  256*1024 },
     27     { "m45pe40",  0x204013,    256,      256, 64*1024,  512*1024 },
     28     { "m45pe80",  0x204014,    256,      256, 64*1024, 1024*1024 },
     29     { "m45pe16",  0x204015,    256,      256, 64*1024, 2048*1024 },
     30 
     31     { "mx25L0805d/6e", 0xc22014,  256,  4*1024, 64*1024, 1024*1024 },
     32     { "mx25L1605d/6e", 0xc22015,  256,  4*1024, 64*1024, 2048*1024 },
     33     { "mx25L3205d/6e", 0xc22016,  256,  4*1024, 64*1024, 4096*1024 },
     34     { "mx25L6405d/6e", 0xc22017,  256,  4*1024, 64*1024, 8192*1024 },
     35 
     36     { "w25x40bv", 0xef3013,    256,  4*1024, 64*1024,  512*1024 },
     37     
     38     { "at45db011d", 0x1f2200,    256,    256, 2*1024, 128*1024 },
     39     { "at45db021d", 0x1f2300,    256,    256, 2*1024, 256*1024 },
     40     { "at45db041d", 0x1f2400,    256,    256, 2*1024, 512*1024 },
     41     { "at45db081d", 0x1f2500,    256,    256, 2*1024, 1024*1024 }
     42 };
     43 
     44 /* @api
     45  * spiflash_info_by_name
     46  *
     47  * @brief
     48  * Lookup the SPI flash info based on it's name.
     49  *
     50  * @param=name - name of the flash
     51  *
     52  * @returns pointer to the flash_info_t or NULL
     53  */
     54 flash_info_t *spiflash_info_by_name(char *name)
     55 {
     56     int i;
     57 
     58     /* determine the minimum erase size for this flash */
     59     for (i = 0; i < sizeof(spiflash_info)/sizeof(spiflash_info[0]); ++i) {
     60         if (!sal_strcmp(name, spiflash_info[i].name)) {
     61             return &spiflash_info[i];
     62         }
     63     }
     64     return NULL;
     65 }
     66 
     67 /* @api
     68  * spiflash_info_by_rdid
     69  *
     70  * @brief
     71  * Lookup the SPI flash info based on it's RDID.
     72  *
     73  * @param=rdid - RDID for the flash
     74  *
     75  * @returns pointer to the flash_info_t or NULL
     76  */
     77 flash_info_t *spiflash_info_by_rdid(uint32 rdid)
     78 {
     79     int i;
     80 
     81     /* determine the minimum erase size for this flash */
     82     for (i = 0; i < sizeof(spiflash_info)/sizeof(spiflash_info[0]); ++i) {
     83         if (spiflash_info[i].rdid == rdid) {
     84             return &spiflash_info[i];
     85         }
     86     }
     87     return NULL;
     88 }
     89 
     90 /*@api
     91  * spiflash_calculate_flash_header
     92  *
     93  * @brief
     94  * Calculates the flash header based on the input parameters
     95  *
     96  * @param=flash_info - pointer to the flash_info_t for the flash
     97  * @param=header - pointer to the flash_header_t to fill in
     98  * @param=dmu_config - DMU configuration option to choose
     99  * @param=spi_speed - SPI speed to install (0 = no speed change)
    100  * @returns 0 - success
    101  * @returns !0 - error
    102  *
    103  * @desc
    104  */
    105 
    106 int spiflash_calculate_header(flash_info_t *flash_info,
    107                               flash_header_t *header,
    108                               uint32 dmu_config,
    109                               uint32 spi_speed)
    110 {
    111     int i;
    112     uint32 page;
    113     uint32 arm_pages;
    114     uint32 switch_pages;
    115     uint32 core_dump_pages;
    116     uint32 arm_image_size;
    117     uint32 switch_image_size;
    118     uint32 core_dump_size;
    119     uint32 avb_config_size;
    120     uint32 avb_config_pages;
    121 
    122     /* Calculate the avb config size */
    123     avb_config_size = ROUND_UP(FLASH_AVB_CONFIG_SIZE, SPIFLASH_PAGE_SIZE);
    124      /* allocate a page for the image header */
    125     avb_config_size += SPIFLASH_PAGE_SIZE;
    126     avb_config_pages = avb_config_size / SPIFLASH_PAGE_SIZE;
    127 
    128     /* Calculate the core dump size */
    129     core_dump_size = ROUND_UP(FLASH_CORE_IMAGE_SIZE, SPIFLASH_PAGE_SIZE);
    130      /* allocate a page for the image header */
    131     core_dump_size += SPIFLASH_PAGE_SIZE;
    132     core_dump_pages = core_dump_size / SPIFLASH_PAGE_SIZE;
    133 
    134     /* Calculate the ARM and switch pages based on the page size */
    135     arm_image_size = ROUND_UP(FLASH_ARM_IMAGE_SIZE, SPIFLASH_PAGE_SIZE);
    136     /* allocate a page for the image header */
    137     arm_image_size += SPIFLASH_PAGE_SIZE;
    138     arm_pages = arm_image_size / SPIFLASH_PAGE_SIZE;
    139 
    140     switch_image_size = ROUND_UP(FLASH_SWITCH_IMAGE_SIZE, SPIFLASH_PAGE_SIZE);
    141     /* allocate a page for the switch configuration header */
    142     switch_image_size += SPIFLASH_PAGE_SIZE;
    143     switch_pages = switch_image_size / SPIFLASH_PAGE_SIZE;
    144 
    145     sal_memset(header, 0, sizeof(flash_header_t));
    146 	header->magic = FLASH_HEADER_MAGIC;
    147 
    148 	/* Program the DMU configuration */
    149 	header->dmu_config = dmu_config;
    150 
    151 	/* Program the default spi-speed */
    152 	header->spi_speed = spi_speed;
    153 
    154     /* build the offsets in pages, starting after the TOC copies */
    155     page = (FLASH_NUM_HEADER_BLOCKS * flash_info->erase_page_size) / SPIFLASH_PAGE_SIZE;
    156     for (i = 0; i < FLASH_NUM_IMAGES; ++i) {
    157         header->image_offset[i] = page;
    158         page += arm_pages;
    159         page = ROUND_UP(page, flash_info->erase_page_size / SPIFLASH_PAGE_SIZE);
    160     }
    161     for (i = 0; i < FLASH_NUM_CONFIGS; ++i) {
    162         header->config_offset[i] = page;
    163         page += switch_pages;
    164         page = ROUND_UP(page, flash_info->erase_page_size / SPIFLASH_PAGE_SIZE);
    165     }
    166     for (i = 0; i < FLASH_NUM_CORE_DUMPS; ++i) {
    167         header->core_dump_offset[i] = page;
    168         page += core_dump_pages;
    169         page = ROUND_UP(page, flash_info->erase_page_size / SPIFLASH_PAGE_SIZE);
    170     }
    171     for (i = 0; i < FLASH_NUM_AVB_CONFIGS; ++i) {
    172         header->expansion[AVB_CFG_EXP_OFFSET + i].offset = page;
    173         page += avb_config_pages;
    174         page = ROUND_UP(page, flash_info->erase_page_size / SPIFLASH_PAGE_SIZE);
    175     }
    176 
    177     header->expansion[VPD_EXP_OFFSET].offset = page;
    178     /* No boot images yet */
    179     for (i = 0; i < FLASH_NUM_BOOT_IMAGES; ++i) {
    180         header->boot_image[i] = -1;
    181     }
    182 
    183 	return 0;
    184 }
    185