Changeset dc661c8 in rtems


Ignore:
Timestamp:
Aug 20, 2014, 10:08:23 PM (6 years ago)
Author:
Peter Dufault <dufault@…>
Branches:
4.11, 5, master
Children:
5787188
Parents:
a7ec6fa
git-author:
Peter Dufault <dufault@…> (08/20/14 22:08:23)
git-committer:
Joel Sherrill <joel.sherrill@…> (08/20/14 22:08:23)
Message:

mpc55xx/misc/flash_support.c: Properly flush cache when writing.

Also cleanup:

  • Remove un-needed interrupt disables.
  • Address errata "e989: FLASH: Disable Prefetch during programming and erase"
  • Use RTEMS_ARRAY_SIZE() macro instead of own macro.
File:
1 edited

Legend:

Unmodified
Added
Removed
  • c/src/lib/libcpu/powerpc/mpc55xx/misc/flash_support.c

    ra7ec6fa rdc661c8  
    136136}
    137137
    138 #define N(ARG) (sizeof(ARG)/sizeof(ARG[0]))
    139 
    140138/** Return the size of the on-chip flash
    141139 *  verifying that this is a device that we know about.
     
    208206    union SLMLR_tag slmlr;
    209207    union HLR_tag hlr;
    210     rtems_interrupt_level level;
    211208
    212209    /* If we're already locked return.
     
    218215    /* Do we have to lock something in the low or mid block?
    219216     */
    220     rtems_interrupt_disable(level);
    221217    lmlr = FLASH.LMLR;
    222218    if ((lsel || msel) && (lmlr.B.LME == 0)) {
     
    229225        lmlr.B.MLOCK != lmlr_unlock.B.MLOCK) {
    230226            if (p_locked == 0) {
    231                 rtems_interrupt_enable(level);
    232227                return MPC55XX_FLASH_LOCK_ERR;
    233228            } else {
     
    238233        }
    239234    }
    240     rtems_interrupt_enable(level);
    241 
    242     rtems_interrupt_disable(level);
     235
    243236    slmlr = FLASH.SLMLR;
    244237    if ((lsel || msel) && (slmlr.B.SLE == 0)) {
     
    251244        slmlr.B.SMLOCK != slmlr_unlock.B.SMLOCK) {
    252245            if (p_locked == 0) {
    253                 rtems_interrupt_enable(level);
    254246                return MPC55XX_FLASH_LOCK_ERR;
    255247            } else {
     
    260252        }
    261253    }
    262     rtems_interrupt_enable(level);
    263254
    264255    /* Do we have to unlock something in the high block?
    265256     */
    266     rtems_interrupt_disable(level);
    267257    hlr = FLASH.HLR;
    268258    if (hbsel && (hlr.B.HBE == 0)) {
     
    273263            if (p_locked == 0) {
    274264                return MPC55XX_FLASH_LOCK_ERR;
    275                 rtems_interrupt_enable(level);
    276265            } else {
    277266                *p_locked = 1;
     
    281270        }
    282271    }
    283     rtems_interrupt_enable(level);
    284272
    285273    return 0;
     
    399387    uint32_t udest, usrc, flash_size;
    400388    int r;
    401     int peg;            /* Program or Erase Good - Did it work? */
    402 
    403     int lsel;           /* Low block select bits. */
    404     int msel;           /* Mid block select bits. */
    405     int hbsel;          /* High block select bits. */
    406 
    407     int s_lsel;           /* Source Low block select bits. */
    408     int s_msel;           /* Source Mid block select bits. */
    409     int s_hbsel;          /* Source High block select bits. */
     389    int peg;                        /* Program or Erase Good - Did it work? */
     390
     391    int lsel;                       /* Low block select bits. */
     392    int msel;                       /* Mid block select bits. */
     393    int hbsel;                      /* High block select bits. */
     394
     395    int s_lsel;                     /* Source Low block select bits. */
     396    int s_msel;                     /* Source Mid block select bits. */
     397    int s_hbsel;                    /* Source High block select bits. */
    410398
    411399    int unlocked = 0;
    412400    int *p_unlocked;
    413401    int i;
    414     int nwords;         /* The number of 32 bit words to write. */
    415     volatile uint32_t *flash;    /* Where the flash is mapped in. */
    416     volatile uint32_t *memory;   /* What to copy into flash. */
    417     uint32_t offset;    /* Where the FLASH is mapped into memory. */
    418     rtems_interrupt_level level;
     402    int nwords;                     /* The number of 32 bit words to write. */
     403    volatile uint32_t *flash;       /* Where the flash is mapped in. */
     404    volatile uint32_t *memory;      /* What to copy into flash. */
     405    const void *flashing_from;      /* Where we are flahsing from.
     406                                     * "const" is to match invalidate cache function signature. */
     407    uint32_t offset;                /* Where the FLASH is mapped into memory. */
    419408
    420409    if ( (r = mpc55xx_flash_size(&flash_size))) {
     
    462451    /* Set up the bit masks for the blocks to program or erase.
    463452     */
    464     range_set(udest, udest + nbytes, &lsel,   lsel_ranges, N( lsel_ranges));
    465     range_set(udest, udest + nbytes, &msel,   msel_ranges, N( msel_ranges));
    466     range_set(udest, udest + nbytes, &hbsel, hbsel_ranges, N(hbsel_ranges));
    467 
    468     range_set(usrc, usrc + nbytes, &s_lsel,   lsel_ranges, N( lsel_ranges));
    469     range_set(usrc, usrc + nbytes, &s_msel,   msel_ranges, N( msel_ranges));
    470     range_set(usrc, usrc + nbytes, &s_hbsel, hbsel_ranges, N(hbsel_ranges));
     453    range_set(udest, udest + nbytes, &lsel,   lsel_ranges, RTEMS_ARRAY_SIZE( lsel_ranges));
     454    range_set(udest, udest + nbytes, &msel,   msel_ranges, RTEMS_ARRAY_SIZE( msel_ranges));
     455    range_set(udest, udest + nbytes, &hbsel, hbsel_ranges, RTEMS_ARRAY_SIZE(hbsel_ranges));
     456
     457    range_set(usrc, usrc + nbytes, &s_lsel,   lsel_ranges, RTEMS_ARRAY_SIZE( lsel_ranges));
     458    range_set(usrc, usrc + nbytes, &s_msel,   msel_ranges, RTEMS_ARRAY_SIZE( msel_ranges));
     459    range_set(usrc, usrc + nbytes, &s_hbsel, hbsel_ranges, RTEMS_ARRAY_SIZE(hbsel_ranges));
    471460
    472461    /* Are we attempting overlapping flash?
     
    482471  /* In the following sections any "Step N" notes refer to
    483472   * the steps in "13.4.2.3 Flash Programming" in the reference manual.
    484    * XXX Do parts of this neeed to be protected by interrupt locks?
    485473   */
    486474
    487475    if (opmask & MPC55XX_FLASH_ERASE) {   /* Erase. */
     476        uint32_t flash_biucr_r;
    488477        if ( (r = unlock_once(lsel, msel, hbsel, p_unlocked)) ) {
    489478            return r;
    490479        }
    491480
    492         rtems_interrupt_disable(level);
     481        /* Per errata "e989: FLASH: Disable Prefetch during programming and erase" */
     482        flash_biucr_r = FLASH.BIUCR.R;
     483        FLASH.BIUCR.B.PFLIM = 0;
     484
     485        FLASH.MCR.B.ESUS = 0;       /* Be sure ESUS is clear. */
     486
    493487        FLASH.MCR.B.ERS = 1;        /* Step 1: Select erase. */
    494488
     
    497491        FLASH.HSR.B.HBSEL = hbsel;
    498492
    499         flash[0] = 1;               /* Step 3: Write to any address in the flash
     493        flash[0] = 0xffffffff;      /* Step 3: Write to any address in the flash
    500494                                     * (the "erase interlock write)".
    501495                                     */
     496        rtems_cache_flush_multiple_data_lines(flash, sizeof(flash[0]));
     497
    502498        FLASH.MCR.B.EHV = 1;         /* Step 4: Enable high V to start erase. */
    503         rtems_interrupt_enable(level);
    504499        while (FLASH.MCR.B.DONE == 0) { /* Step 5: Wait until done. */
    505500        }
    506         rtems_interrupt_disable(level);
    507501        peg = FLASH.MCR.B.PEG;       /* Save result. */
    508502        FLASH.MCR.B.EHV = 0;         /* Disable high voltage. */
    509503        FLASH.MCR.B.ERS = 0;         /* De-select erase. */
    510         rtems_interrupt_enable(level);
     504        FLASH.BIUCR.R = flash_biucr_r;
     505
    511506        if (peg == 0) {
    512507            return MPC55XX_FLASH_ERASE_ERR; /* Flash erase failed. */
     
    535530        FLASH.MCR.B.PGM = 1;                /* Step 1 */
    536531
    537        rtems_interrupt_disable(level);
    538 
    539         for (i = 0; i < nwords; i += 2) {
     532        for (flashing_from = (const void *)flash, i = 0; i < nwords; i += 2) {
    540533           flash[i] = memory[i];            /* Step 2 */
    541534           flash[i + 1] = memory[i + 1];    /* Always program in min 64 bits. */
     
    549542           if (chunk == 4) {
    550543                /* Collected 4 64-bits for a 256 bit chunk. */
     544
     545                rtems_cache_flush_multiple_data_lines(flashing_from, 32);    /* Flush cache. */
     546
    551547                FLASH.MCR.B.EHV = 1;            /* Step 4: Enable high V. */
    552548
    553                 rtems_interrupt_enable(level);
    554549                while (FLASH.MCR.B.DONE == 0) { /* Step 5: Wait until done. */
    555550                }
    556                 rtems_interrupt_disable(level);
    557551
    558552                peg = FLASH.MCR.B.PEG;          /* Step 6: Save result. */
     
    560554                if (peg == 0) {
    561555                    FLASH.MCR.B.PGM = 0;
    562                     rtems_interrupt_enable(level);
    563556                    if (p_fail) {
    564557                        *p_fail = (uint32_t)(flash + i);
     
    567560                }
    568561                chunk = 0;                       /* Reset chunk counter. */
     562                flashing_from = (const void *)(flash + i);
    569563            }
    570564                                                 /* Step 8: Back to step 2. */
     
    573567       if (!chunk) {
    574568            FLASH.MCR.B.PGM = 0;
    575             rtems_interrupt_enable(level);
    576569       } else {
    577570           /* If there is anything left in that last chunk flush it out:
    578571            */
     572
     573            rtems_cache_flush_multiple_data_lines(flashing_from, chunk * 8);
     574
    579575            FLASH.MCR.B.EHV = 1;
    580576
    581             rtems_interrupt_enable(level);
    582577            while (FLASH.MCR.B.DONE == 0) {     /* Wait until done. */
    583578            }
    584             rtems_interrupt_disable(level);
    585579
    586580            peg = FLASH.MCR.B.PEG;              /* Save result. */
    587581            FLASH.MCR.B.EHV = 0;                /* Disable high voltage. */
    588582            FLASH.MCR.B.PGM = 0;
    589             rtems_interrupt_enable(level);
    590583
    591584            if (peg == 0) {
Note: See TracChangeset for help on using the changeset viewer.