Loading ...
Sorry, an error occurred while loading the content.

Flushing the cache after turning it off

Expand Messages
  • rsprowson
    Hi, I m noticing some slightly odd behaviour when turning the cache off which makes me suspicious that the details in the datasheet suggesting how to flush the
    Message 1 of 8 , Feb 14, 2006
    • 0 Attachment
      Hi,
      I'm noticing some slightly odd behaviour when turning the cache off
      which makes me suspicious that the details in the datasheet suggesting
      how to flush the cache aren't quite right.

      Anyone here had problems/successes in this area?

      The sequence is
      - power up processor, hence the cache is off
      - enable the cache, everything runs fine
      - disable the cache & flush
      - random skipping to wrong address

      My cache flush code doesn't use any stack (as the SDRAM in which the
      stack is is itself cached of course), and returns with a
      MOV pc, lr

      Cheers,
      Sprow.
    • kendwyer
      Hi, In your description you mention that you disable the cache & flush ... Do you diable and then flush or flush and then disable? Do you do a write back
      Message 2 of 8 , Feb 14, 2006
      • 0 Attachment
        Hi,

        In your description you mention that you "disable the cache & flush"...

        Do you diable and then flush or flush and then disable?
        Do you do a "write back" before the flush?
        What memory areas are cacheable?

        If you do not perform a writeback then there may be cache coherency
        issues. Also ensure that the cache is correctly initialized:

        void init_cache(void)
        {
        put_wvalue(CACHE, 0);
        put_wvalue(CON, 0);
        put_wvalue(FLUSH, 0x1);

        return;
        }


        Thanks,
        Ken

        --- In OKI-ARM-mcus@yahoogroups.com, "rsprowson" <news@...> wrote:
        >
        > Hi,
        > I'm noticing some slightly odd behaviour when turning the cache off
        > which makes me suspicious that the details in the datasheet suggesting
        > how to flush the cache aren't quite right.
        >
        > Anyone here had problems/successes in this area?
        >
        > The sequence is
        > - power up processor, hence the cache is off
        > - enable the cache, everything runs fine
        > - disable the cache & flush
        > - random skipping to wrong address
        >
        > My cache flush code doesn't use any stack (as the SDRAM in which the
        > stack is is itself cached of course), and returns with a
        > MOV pc, lr
        >
        > Cheers,
        > Sprow.
        >
      • rsprowson
        ... Hi, ... Flush then disable, though I realise that might sound odd. Essentially I used the description in 9.5.2 of the datasheet, and without posting the
        Message 3 of 8 , Feb 17, 2006
        • 0 Attachment
          --- In OKI-ARM-mcus@yahoogroups.com, "kendwyer" <kendwyer@...> wrote:
          Hi,

          > > I'm noticing some slightly odd behaviour when turning the cache
          > > off
          > > which makes me suspicious that the details in the datasheet
          > > suggesting how to flush the cache aren't quite right.
          > >
          > > Anyone here had problems/successes in this area?
          > >
          > > The sequence is
          > > - power up processor, hence the cache is off
          > > - enable the cache, everything runs fine
          > > - disable the cache & flush
          > > - random skipping to wrong address

          > In your description you mention that you "disable the cache &
          > flush"...
          >
          > Do you diable and then flush or flush and then disable?

          Flush then disable, though I realise that might sound odd.
          Essentially I used the description in 9.5.2 of the datasheet, and
          without posting the actual assembler here I do:

          Push non ATPCS preserved registers
          Disable I and F in the CPSR
          Get the address of a block of ROM which doesn't contain code
          Align the address onto an 8k boundary
          for (WAY=0; WAY<4; WAY++)
          {
          Lock WAY
          Read the 2k into the locked WAY
          }
          Write 0 into the CACHE register

          > Do you do a "write back" before the flush?

          Yes, as long as the above worked, which is where my suspicion lies.

          > What memory areas are cacheable?

          Bank 0 and 25 (SDRAM and ROM respectively).

          > If you do not perform a writeback then there may be cache coherency
          > issues. Also ensure that the cache is correctly initialized:
          >
          > void init_cache(void)
          > {
          > put_wvalue(CACHE, 0);
          > put_wvalue(CON, 0);
          > put_wvalue(FLUSH, 0x1);
          >
          > return;
          > }

          Yup, already doing that, albeit in assembler.
          Perhaps reading the 8k from a cached area is upsetting things, but I
          can't think why?

          It's doing /something/ as there are a couple of places where I need
          to be sure the value makes it back into SDRAM (incase someone resets
          the ARM at just that moment), without the flush those bits fail after
          a reset, with the flush they work as I anticipated.
          Sprow.
        • kendwyer
          Hi, Here is some code for doing the write back. Let me know if this helps... Thanks Ken /* constants */ #define DRAM_BASE (0xC0000000) /* base address of
          Message 4 of 8 , Feb 20, 2006
          • 0 Attachment
            Hi,

            Here is some code for doing the write back. Let me know if this helps...

            Thanks
            Ken

            /* constants */
            #define DRAM_BASE (0xC0000000) /* base address of external SDRAM */
            #define SRAM_BASE (0x50002000) /* base address of internal RAM */
            #define BYTE_2K (0x800) /* 2Kbyte size */
            #define BYTE_8K (0x2000) /* 8Kbyte size */


            /******************************************************************/
            /* Write Back test */
            /* Function : write_back */
            /* Parameters */
            /* Input : Nothing */
            /* Output : Nothing */
            /******************************************************************/
            void write_back()
            {
            UBYTE *address;

            /* Clean Internal-SRAM */
            for(address = (UBYTE*)SRAM_BASE;
            address<(UBYTE*)((void*)(SRAM_BASE+BYTE_8K)); address++){
            put_value(address, 0x00);
            }
            /* internal SRAM initialize */
            cache_on(CACHE_BANK10); /* SRAM BANK : Cache enable */
            /* Set 'F'data to Internal-SRAM */
            for(address = (UBYTE*)SRAM_BASE;
            address<(UBYTE*)((void*)(SRAM_BASE+BYTE_8K)); address++){
            put_value(address, 0xFF);
            }

            address = (UBYTE*)SRAM_BASE;
            put_wvalue(CON, CON_WAY0 | CON_LOAD | CON_LOCK0); /* Set Load
            mode to Way0 */
            sram_read((UWORD*)address); /* dummy data read (2Kbytes) */

            address = ((UBYTE*)SRAM_BASE + BYTE_2K);
            put_wvalue(CON, CON_WAY1 | CON_LOAD | CON_LOCK0); /* Set Load
            mode to Way1 */
            sram_read((UWORD*)address); /* dummy data read (2Kbytes) */

            address = ((UBYTE*)SRAM_BASE + (BYTE_2K * 2));
            put_wvalue(CON, CON_WAY2 | CON_LOAD | CON_LOCK0); /* Set Load
            mode to Way2 */
            sram_read((UWORD*)address); /* dummy data read (2Kbytes) */

            address = ((UBYTE*)SRAM_BASE + (BYTE_2K * 3));
            put_wvalue(CON, CON_WAY3 | CON_LOAD | CON_LOCK0); /* Set Load
            mode to Way3 */
            sram_read((UWORD*)address); /* dummy data read (2Kbytes) */

            put_wvalue(FLUSH, FLUSH_FLUSH);

            cache_off(CACHE_BANK10); /* SRAM BANK : Cache disable */

            return;
            }


            --- In OKI-ARM-mcus@yahoogroups.com, "rsprowson" <news@...> wrote:
            >
            > --- In OKI-ARM-mcus@yahoogroups.com, "kendwyer" <kendwyer@> wrote:
            > Hi,
            >
            > > > I'm noticing some slightly odd behaviour when turning the cache
            > > > off
            > > > which makes me suspicious that the details in the datasheet
            > > > suggesting how to flush the cache aren't quite right.
            > > >
            > > > Anyone here had problems/successes in this area?
            > > >
            > > > The sequence is
            > > > - power up processor, hence the cache is off
            > > > - enable the cache, everything runs fine
            > > > - disable the cache & flush
            > > > - random skipping to wrong address
            >
            > > In your description you mention that you "disable the cache &
            > > flush"...
            > >
            > > Do you diable and then flush or flush and then disable?
            >
            > Flush then disable, though I realise that might sound odd.
            > Essentially I used the description in 9.5.2 of the datasheet, and
            > without posting the actual assembler here I do:
            >
            > Push non ATPCS preserved registers
            > Disable I and F in the CPSR
            > Get the address of a block of ROM which doesn't contain code
            > Align the address onto an 8k boundary
            > for (WAY=0; WAY<4; WAY++)
            > {
            > Lock WAY
            > Read the 2k into the locked WAY
            > }
            > Write 0 into the CACHE register
            >
            > > Do you do a "write back" before the flush?
            >
            > Yes, as long as the above worked, which is where my suspicion lies.
            >
            > > What memory areas are cacheable?
            >
            > Bank 0 and 25 (SDRAM and ROM respectively).
            >
            > > If you do not perform a writeback then there may be cache coherency
            > > issues. Also ensure that the cache is correctly initialized:
            > >
            > > void init_cache(void)
            > > {
            > > put_wvalue(CACHE, 0);
            > > put_wvalue(CON, 0);
            > > put_wvalue(FLUSH, 0x1);
            > >
            > > return;
            > > }
            >
            > Yup, already doing that, albeit in assembler.
            > Perhaps reading the 8k from a cached area is upsetting things, but I
            > can't think why?
            >
            > It's doing /something/ as there are a couple of places where I need
            > to be sure the value makes it back into SDRAM (incase someone resets
            > the ARM at just that moment), without the flush those bits fail after
            > a reset, with the flush they work as I anticipated.
            > Sprow.
            >
          • rsprowson
            ... [snip code] ... What s the rationale behind the write to the Flush register? I didn t spot that in the datasheet. Or is it belt & braces ? Sadly, it
            Message 5 of 8 , Feb 23, 2006
            • 0 Attachment
              --- In OKI-ARM-mcus@yahoogroups.com, "kendwyer" <kendwyer@...> wrote:
              >
              > Hi,
              >
              > Here is some code for doing the write back. Let me know if this
              > helps...

              [snip code]

              > put_wvalue(FLUSH, FLUSH_FLUSH);

              What's the rationale behind the write to the Flush register? I didn't
              spot that in the datasheet. Or is it "belt & braces"?

              Sadly, it doesn't seem to make a difference. The cache is still
              turned off and looks like it is flushed, but with some undefined
              behaviour (hard to put my finger on as it manifests itself in unusual
              ways, but it's as though an ARM register got corrupted or maybe only
              a partial flush occurred).

              What happens if you run that test code using ROM during the flush
              instead of the SRAM? ie.

              zero fill SRAM
              turn cache on
              fill with non zero
              flush using ROM during the LOAD operations
              cache off

              I think I found a repeatable test case for my board this morning so
              might see if I can simplify it some more,
              Sprow.
            • kendwyer
              Hi, Note the following: Since the CPU will be made to wait until the cache memory initialization has been completed. The instruction of writing to the FLUSH
              Message 6 of 8 , Feb 24, 2006
              • 0 Attachment
                Hi,

                Note the following: "Since the CPU will be made to wait until the
                cache memory initialization has been completed. The instruction
                of writing to the FLUSH register will take about 128 instruction cycles."

                If you can send me the test case I will see if I can repeat on my setup.

                Thanks,
                Ken


                --- In OKI-ARM-mcus@yahoogroups.com, "rsprowson" <news@...> wrote:
                >
                > --- In OKI-ARM-mcus@yahoogroups.com, "kendwyer" <kendwyer@> wrote:
                > >
                > > Hi,
                > >
                > > Here is some code for doing the write back. Let me know if this
                > > helps...
                >
                > [snip code]
                >
                > > put_wvalue(FLUSH, FLUSH_FLUSH);
                >
                > What's the rationale behind the write to the Flush register? I didn't
                > spot that in the datasheet. Or is it "belt & braces"?
                >
                > Sadly, it doesn't seem to make a difference. The cache is still
                > turned off and looks like it is flushed, but with some undefined
                > behaviour (hard to put my finger on as it manifests itself in unusual
                > ways, but it's as though an ARM register got corrupted or maybe only
                > a partial flush occurred).
                >
                > What happens if you run that test code using ROM during the flush
                > instead of the SRAM? ie.
                >
                > zero fill SRAM
                > turn cache on
                > fill with non zero
                > flush using ROM during the LOAD operations
                > cache off
                >
                > I think I found a repeatable test case for my board this morning so
                > might see if I can simplify it some more,
                > Sprow.
                >
              • rsprowson
                ... Though equally 9.2.1 says A locked way will not be flushed even when a flushing operation is made using the FLUSH register. , which is why I queried it. I
                Message 7 of 8 , Feb 24, 2006
                • 0 Attachment
                  --- In OKI-ARM-mcus@yahoogroups.com, "kendwyer" <kendwyer@...> wrote:
                  >
                  > Hi,
                  >
                  > Note the following: "Since the CPU will be made to wait until the
                  > cache memory initialization has been completed. The instruction
                  > of writing to the FLUSH register will take about 128 instruction
                  > cycles."

                  Though equally 9.2.1 says "A locked way will not be flushed even when
                  a flushing operation is made using the FLUSH register.", which is why
                  I queried it. I interpret the FLUSH register as only being useful at
                  initialisation, not when disabling, though that's open to Oki's
                  ambiguity.

                  Quick question: in your test code you have
                  CACHE_CON_WAYn | CACHE_CON_LOAD | CACHE_CON_LOCK0 (for n=0 to 3)
                  whereas I have
                  CACHE_CON_WAYn | CACHE_CON_LOAD | CACHE_CON_LOCKn (for n=0 to 3)
                  was that just a copy and paste error?

                  Cor this is turning out to be more of a headache than I'd thought!
                  Sprow.
                • rsprowson
                  Right then - replying to myself, here s what fixed the problem for me: 1. Decided to leave the locking as it was CON_WAY0 | CON_LOAD | CON_LOCK0 CON_WAY1 |
                  Message 8 of 8 , Feb 25, 2006
                  • 0 Attachment
                    Right then - replying to myself, here's what fixed the problem for me:

                    1. Decided to leave the locking as it was
                    CON_WAY0 | CON_LOAD | CON_LOCK0
                    CON_WAY1 | CON_LOAD | CON_LOCK1
                    CON_WAY2 | CON_LOAD | CON_LOCK2
                    CON_WAY3 | CON_LOAD | CON_LOCK3
                    there are 4 ways, but only up to 3 can be locked (the defines are
                    slightly confusingly named) - this has the effect of setting the nth
                    way to be in load mode, and the previous n-1 ways are locked:

                    Loading way 0 => no ways locked obviously!
                    Loading way 1 => way 0 is now locked
                    Loading way 2 => way 0 and 1 now locked
                    Loading way 3 => way 0 and 1 and 2 now locked

                    Way 3 gets confusing since I guess either the loaded 2k of dummy data
                    or the cache flushing code could end up in the cache, but as long as
                    we load 2k of something and pending writes will be forced out.

                    When reenabling the cache all ways are unlocked anyway, you may need
                    to think more if you're selectively flushing just some of the cached
                    regions (in my code I have the SDRAM and ROM cached, but only ever
                    have both or neither cached, not one or the other).

                    2. Tried with and without the FLUSH_FLUSH write
                    I'm with Ken here that it should be in there in his example code (as
                    I also lock as described in (1) above, it's not really essential for
                    me).

                    If you're flushing when selectively disabling banks, it would need a
                    FLUSH_FLUSH, but for me globally disabling it there's little point
                    wasting 128 cycles since I do a FLUSH_FLUSH when reenabling the cache
                    anyway.

                    3. And the magic change was...
                    Neither (1) nor (2) actually made any difference. The difference was
                    to use a bank for the dummy read which is currently marked as
                    cacheable and a section of it which would never have been seen before
                    by the cache.

                    Previously I'd just been using somewhere (64k AND NOT 0x1FFF) away
                    from the cache flush loop, but as there's about 100k of code I would
                    have visited some of those locations already.

                    Fortunately, as the code is in the internal ROM, and the ROM is
                    marked as cacheable, I can simply use the top half of bank 25
                    (normally for external flash which is unused).


                    Previously my test would survive about 5s before bailing out with an
                    abort on data transfer (LDMIA'ing from a dodgy address), but has been
                    running all night,
                    Sprow.


                    --- In OKI-ARM-mcus@yahoogroups.com, "rsprowson" <news@...> wrote:
                    >
                    > --- In OKI-ARM-mcus@yahoogroups.com, "kendwyer" <kendwyer@> wrote:
                    > >
                    > > Hi,
                    > >
                    > > Note the following: "Since the CPU will be made to wait until the
                    >

                    > cache memory initialization has been completed. The instruction
                    > > of writing to the FLUSH register will take about 128 instruction
                    > > cycles."
                    >
                    > Though equally 9.2.1 says "A locked way will not be flushed even
                    when
                    > a flushing operation is made using the FLUSH register.", which is
                    why
                    > I queried it. I interpret the FLUSH register as only being useful
                    at
                    > initialisation, not when disabling, though that's open to Oki's
                    > ambiguity.
                    >
                    > Quick question: in your test code you have
                    > CACHE_CON_WAYn | CACHE_CON_LOAD | CACHE_CON_LOCK0 (for n=0 to 3)
                    > whereas I have
                    > CACHE_CON_WAYn | CACHE_CON_LOAD | CACHE_CON_LOCKn (for n=0 to 3)
                    > was that just a copy and paste error?
                    >
                    > Cor this is turning out to be more of a headache than I'd thought!
                    > Sprow.
                    >
                  Your message has been successfully submitted and would be delivered to recipients shortly.