Back to home page

LXR

 
 

    


File indexing completed on 2025-05-11 08:23:53

0001 #ifndef FLASH_GLUE_INTERFACE_H
0002 #define FLASH_GLUE_INTERFACE_H
0003 
0004 
0005 /* Trivial flash programmer (for restrictions see below)     */
0006 
0007 /* Author: Till Straumann <strauman@slac.stanford.edu>, 2006 */
0008 
0009 /* DO NOT INCLUDE THIS HEADER FROM APPLICATION CODE          */
0010 
0011 /*
0012  * Glue interface -- to be used only internally by BSP
0013  * and chip drivers:
0014  * - BSP provides info about what chip drivers to use
0015  *   as well as 'wiring' info (how many devices are
0016  *   operated in parallel etc).
0017  * - Chip drivers provide low-level 'methods' / 'ops'
0018  *   for performing basic operations which are used
0019  *   by the code in 'flash.c'.
0020  */
0021 
0022 /* To keep things simple, this API makes a few assumptions about the
0023  * hardware:
0024  *
0025  * - devices operate with 16-bit data width
0026  * - two devices are used in parallel (stride 4) to
0027  *   provide 32-bit data. I.e., the devices are
0028  *   organized like this:
0029  *   unsigned short flash[FLASH_SIZE][2];
0030  * - no endianness issues (i.e., flash endianness ==  CPU endianness)
0031  * - fixed block size
0032  * - fixed buffer size
0033  * - all devices in a bank are identical
0034  * - NOT THREAD SAFE; no locking scheme is implemented.
0035  * - cannot copy within same flash bank.
0036  * - write-timeout uses polling/busy-wait
0037  *
0038  * FIXME: code should be revised to remove assumptions on stride and 16-bit
0039  *        width to make it more generic.
0040  */
0041 
0042 /*
0043  * Authorship
0044  * ----------
0045  * This software was created by
0046  *     Till Straumann <strauman@slac.stanford.edu>, 2005-2007,
0047  *     Stanford Linear Accelerator Center, Stanford University.
0048  *
0049  * Acknowledgement of sponsorship
0050  * ------------------------------
0051  * The software was produced by
0052  *     the Stanford Linear Accelerator Center, Stanford University,
0053  *     under Contract DE-AC03-76SFO0515 with the Department of Energy.
0054  *
0055  * Government disclaimer of liability
0056  * ----------------------------------
0057  * Neither the United States nor the United States Department of Energy,
0058  * nor any of their employees, makes any warranty, express or implied, or
0059  * assumes any legal liability or responsibility for the accuracy,
0060  * completeness, or usefulness of any data, apparatus, product, or process
0061  * disclosed, or represents that its use would not infringe privately owned
0062  * rights.
0063  *
0064  * Stanford disclaimer of liability
0065  * --------------------------------
0066  * Stanford University makes no representations or warranties, express or
0067  * implied, nor assumes any liability for the use of this software.
0068  *
0069  * Stanford disclaimer of copyright
0070  * --------------------------------
0071  * Stanford University, owner of the copyright, hereby disclaims its
0072  * copyright and all other rights in this software.  Hence, anyone may
0073  * freely use it for any purpose without restriction.
0074  *
0075  * Maintenance of notices
0076  * ----------------------
0077  * In the interest of clarity regarding the origin and status of this
0078  * SLAC software, this and all the preceding Stanford University notices
0079  * are to remain affixed to any copy or derivative of this software made
0080  * or distributed by the recipient and are to be affixed to any copy of
0081  * software made or distributed by the recipient that contains a copy or
0082  * derivative of this software.
0083  *
0084  * ------------------ SLAC Software Notices, Set 4 OTT.002a, 2004 FEB 03
0085  */
0086 
0087 #include <stdint.h>
0088 
0089 #define NumberOf(arr)       (sizeof(arr)/sizeof(arr[0]))
0090 
0091 #define FLASH_STRIDE(b)     4 /* bytes; currently fixed */
0092 #define FLASH_WIDTH(b)      ((b)->width)
0093 #define FLASH_NDEVS(b)      (FLASH_STRIDE(b)/FLASH_WIDTH(b))
0094 
0095 /* Type declarations */
0096 
0097 /* Registers          */
0098 typedef uint8_t           _u8_a_t  __attribute__((may_alias));
0099 typedef uint16_t          _u16_a_t __attribute__((may_alias));
0100 typedef uint32_t          _u32_a_t __attribute__((may_alias));
0101 
0102 /* Register addresses */
0103 typedef volatile _u8_a_t  *A8;
0104 typedef volatile _u16_a_t *A16;
0105 typedef volatile _u32_a_t *A32;
0106 
0107 struct flash_bank_ops;
0108 
0109 /*
0110  * Description of a flash bank. Multiple
0111  * devices that are used in parallel to
0112  * make up words of FLASH_STRIDE bytes
0113  * are a 'physical' bank.
0114  *
0115  * A bank can even be a 'logical' bank
0116  * if it includes chip-select logic, i.e.,
0117  * int can contain multiple adjacent
0118  * 'physical' banks
0119  *
0120  * The BSP must provide an array of 'bankdesc'
0121  * structs and it must initialize the fields
0122  *
0123  *   'start'
0124  *     size of bank; may be set to zero to instruct
0125  *     the driver to scan a bank of 'max_size' for
0126  *     devices (i.e., bank may not be fully populated)
0127  *   'max_size'
0128  *     size of fully populated bank (defines address range
0129  *     that is scanned for devices).
0130  *     If 'max_size' is negative then scanning starts from
0131  *     the top rather than from the bottom.
0132  *   'width'
0133  *     width of a single device (in bytes). E.g., if
0134  *     2 16-bit devices are used to form a (ATM fixed)
0135  *     stride of 4 then 'width = 2'. If four 8-bit
0136  *     devices are employed then 'width=1'.
0137  *   'knownVendors'
0138  *     array of vendors descriptions to use for scanning
0139  *     the bank.
0140  *
0141  */
0142 struct bankdesc {
0143     uint32_t    start;      /* start of bank (CPU address)              */
0144     uint32_t    size;       /* in bytes (figured out automatically)     */
0145     int         max_size;   /* in case multiple banks are adjacent;
0146                              * if max_size < 0 then the bank is scanned
0147                              * backwards (from top->bottom) for devices
0148                              */
0149     int         width;      /* FIXME there might be implicit assumptions still
0150                              * that width == 2
0151                              */
0152     struct vendesc        *knownVendors;
0153     /* TODO: we assume identical devices within a bank... */
0154 
0155     /* The next three variables cache information obtained
0156      * from the applicable vendor and device descriptions.
0157      * They are written by BSP_flashCheckId().
0158      */
0159     uint32_t    fblksz;     /* block size in bytes; includes counting
0160                              * parallel 16-bit devices, i.e., if a
0161                              * single device has a block-size of xxx
0162                              * then fblksz = xxx*ndevs.
0163                              */
0164     struct devdesc        *dd;
0165     struct flash_bank_ops *ops;
0166 };
0167 
0168 struct devdesc {
0169     uint32_t    id;     /* numerical ID (matched against
0170                          * ID read from device).
0171                          */
0172     char        *name;  /* informational name           */
0173     uint32_t    size;   /* bytes                        */
0174     uint32_t    bufsz;  /* size of write buffer (bytes) */
0175     uint32_t    fblksz; /* sector/block size (bytes)    */
0176 };
0177 
0178 struct vendesc {
0179     uint32_t    id;     /* numerical ID (matched against
0180                          * ID read from device).
0181                          */
0182     char        *name;  /* informational name */
0183 
0184                         /* array of supported devices;
0185                          * the 'ops' specified below
0186                          * are used to access these devices
0187                          */
0188     struct devdesc        *known_devs;
0189                         /* access methods for talking to
0190                          * devices associated with this
0191                          * vendor description.
0192                          */
0193     struct flash_bank_ops *ops;
0194 };
0195 
0196 /* Device Access Methods ('ops'); these must be
0197  * implemented by low-level chip drivers
0198  */
0199 
0200 struct flash_bank_ops {
0201 /* Read vendor/device ID; Return 0 on success, nonzero if unable to read id */
0202     int            (*get_id)(struct bankdesc *b, uint32_t addr, uint32_t *pVendorId, uint32_t *pDeviceId);
0203 /* Unlock block holding 'addr'ess
0204  *
0205  *   NOTES: - device switched back to array mode on exit.
0206  *          - 'addr' must be 32-bit aligned.
0207  */
0208 
0209     void           (*unlock_block)(struct bankdesc *b, uint32_t addr);
0210 /* Lock block holding 'addr'ess
0211  *
0212  *   NOTES: - device switched back to array mode on exit.
0213  *          - 'addr' must be 32-bit aligned.
0214  */
0215 
0216     void           (*lock_block)(struct bankdesc *b, uint32_t addr);
0217 /* Erase single block holding 'addr'ess. The routine may
0218  * assume that the address is block/sector aligned.
0219  *
0220  * RETURNS: zero on error, device status on failure.
0221  *
0222  *   NOTES: - device switched back to array mode on exit.
0223  *          - 'addr' must be 32-bit aligned.
0224  */
0225     int            (*erase_block)(struct bankdesc *b, uint32_t addr);
0226 /* Query the status of the device and assert it's readiness
0227  * leave off in array-reading mode.
0228  *
0229  * RETURNS: 0 on success, error status (result of status query) on error.
0230  *
0231  *   NOTES: - error message is printed to stderr.
0232  *          - device switched back to array mode on exit.
0233  *          - 'addr' must be 32-bit aligned.
0234  */
0235     uint32_t       (*check_ready)(struct bankdesc *b, uint32_t addr);
0236 /* Dump status bits (F_CMD_RD_STA results);
0237  * 'verbose' prints non-error bits, too
0238  */
0239     void           (*print_stat)(struct bankdesc *b, uint32_t sta, int verbose);
0240 /* Switch to array mode; 'addr' can be assumed to be stride-aligned */
0241     void           (*array_mode)(struct bankdesc *b, uint32_t addr);
0242 /* Write N bytes from 'src' to flash:
0243  * 'src[0] .. src[N-1]' -> addr[0]..addr[N-1].
0244  * N may be assumed to be a multiple of 'stride'
0245  * RETURNS: failure status or zero on success.
0246  */
0247     uint32_t       (*write_line)(struct bankdesc *b, uint32_t addr, const char *src, uint32_t N);
0248 };
0249 
0250 /* BSP ops (detect banks, handle write-protection on board);
0251  * these must be implemented by the BSP.
0252  */
0253 
0254 struct flash_bsp_ops {
0255 /* Return descriptor for bank # 'bank' or NULL (invalid arg) */
0256     struct bankdesc *(*bankcheck)(int bank, int quiet);
0257 /* set (enbl:1), clear (enbl:0) or query (enbl:-1)
0258  * on-board write protection.
0259  *
0260  * RETURNS 0 on success, nonzero on error.
0261  */
0262     int              (*flash_wp)(int bank, int enbl);
0263 /* read a running us clock (for polling timeout) */
0264     uint32_t         (*read_us_timer)(void);
0265 };
0266 
0267 /* This must be provided by the BSP */
0268 extern struct flash_bsp_ops BSP_flashBspOps;
0269 
0270 /* Available low-level flash drivers, so far */
0271 extern struct vendesc        BSP_flash_vendor_intel[];
0272 extern struct vendesc        BSP_flash_vendor_spansion[];
0273 
0274 #endif