Disabling L3 (CPC) cache during runtime (P4080)

cancel
Showing results for 
Show  only  | Search instead for 
Did you mean: 

Disabling L3 (CPC) cache during runtime (P4080)

1,339 Views
clemensreibetan
Contributor I

Hi,

I try to disable the CPC cache during runtime.

I follow the instructions given in P4080RM at page 350.

To flush the CPC cache and ensure that no valid entries exist after the flush (that is, for the purposes of powering down or disabling) the following high level sequence of operations should be used:

1. Clear all bits in CPCPAR0-CPCPAR15 to prevent new transactions from allocating in the CPC

2. Set CPCCSR0[CPCFL]

3. Wait for CPCCSR0[CPCFL] to be cleared by hardware

4. Clear CPCCSR0[CPCE]

In my code this looks like:

// 1. Clear all bits in CPCPAR0-CPCPAR15 to prevent new transactions from allocating in the CPC

for (int k=0; k < 16; k++) {

    asm ("mbar");

    asm ("isync");

    // CPC1_CPCPARn register clear

    *((uint32_t*) (0xFE000000 + 0x10208 + 0x10 * k)) = 0;

    // CPC2_CPCPARn register clear

    *((uint32_t*) (0xFE000000 + 0x11208 + 0x10 * k)) = 0;       

    asm ("mbar");

}

// 2. Set CPCCSR0[CPCFL]

// 3. Wait for CPCCSR0[CPCFL] to be cleared by hardware

// CPC 1

asm ("mbar");

asm ("isync");

*((uint32_t*) (0xFE000000 + 0x10000)) |= (1 << (31-20));

while ((*((uint32_t*) (0xFE000000 + 0x10000)) >> (31-20)) & 1) {}

asm ("mbar");

// CPC2

asm ("mbar");

asm ("isync");

*((uint32_t*) (0xFE000000 + 0x11000)) = *((uint32_t*) (0xFE000000 + 0x11000)) | (1 << (31-20));

while ((*((uint32_t*) (0xFE000000 + 0x11000)) >> (31-20)) & 1) {}

asm ("mbar");

// 4. Clear CPCCSR0[CPCE]

// CPC1

asm ("mbar");

asm ("isync");

*((uint32_t*) (0xFE000000 + 0x10000)) &= ~(1 << (31-0));

cache_register = *((uint32_t*) (0xFE000000 + 0x10000));

asm ("mbar");

// CPC2

asm ("mbar");

asm ("isync");

*((uint32_t*) (0xFE000000 + 0x11000)) &= ~(1 << (31-0));

cache_register = *((uint32_t*) (0xFE000000 + 0x11000));

asm ("mbar");

The problem is that after disabling the CPC I get an alignment error and a machine check interrupt at a std::cout.

Am I doing anything wrong when disabling CPC? Did I forget anything? Why do these error occur?

Thanks in advance

Clemens

Labels (1)
0 Kudos
6 Replies

684 Views
lunminliang
NXP Employee
NXP Employee

Hello Clemens Reibetanz,

I do not know your reference manual revision, but in my P4080Rm Rev 2, Changing the Configuration of an Enabled CPC contains 5 steps as below. The difference is one more step for clearing all lock bits by setting CPCCSR0[CPCLFC] and wait for hardware to clear it by polling loop:

1. Clear all bits of CPCPARn (this prevents any new transactions from allocating into the CPC) using write operation.

2. Flush the CPC using one of the two following methods:

• Harware flush: Set CPCCSR0[CPCFL] and wait for hardware to clear CPCCSR0[CPCFL] by polling

• Software flush: perform a dcbf operation to each coherency granule mapped to the memory target (that is, one dcbf for each 64 bytes).

3. Clear all lock bits by setting CPCCSR0[CPCLFC].

4. Wait for hardware to clear CPCCSR0[CPCLFC] using a polling loop.

5. Disable the CPC by clearing CPCCSR0[CPCE].

What if you add this step?


Have a great day,
Lunmin

-----------------------------------------------------------------------------------------------------------------------
Note: If this post answers your question, please click the Correct Answer button. Thank you!
-----------------------------------------------------------------------------------------------------------------------

0 Kudos

684 Views
clemensreibetan
Contributor I

Hi Lunmin,

I also tried adding this step but there is no change in behavior.

I am also using P4080RM Rev 2.

Thanks for your answer.

0 Kudos

684 Views
scottwood
NXP Employee
NXP Employee

What is the asm instruction and address that takes the alignment exception?  Have you disabled L2 cache as well?  What is MCSR for the machine check?

When accessing registers, make sure that the compiler cannot optimize away or reorder anything.  It's best to use inline asm to access registers, but even using volatile would better than nothing.

When using inline asm, use volatile and add a "memory" clobber.

What environment is this code running in?

0 Kudos

684 Views
clemensreibetan
Contributor I

Hi Scott, thanks for the fast answer.

The asm instruction that takes the alignment exception is

0012d440:   stfdu fp21,-16657(r13)

L1 and L2 cache are both enabled.

Right now, I am not able to reproduce the machine check interrupt. But as far as i remember there was 0xDEADBEEF in the MCSR.

Thanks for the hints with the volatile and inline assembler. Because I am using -O0 there is no problem with my code. I checked the asm listing and they look ok.

This code is running bare metal on core0 of a P4080DS. I am debugging with a CodeWarrior TAP.

0 Kudos

684 Views
scottwood
NXP Employee
NXP Employee

I see that "stfdu fp21,-16657(r13)" is the decoding of 0xdeadbeef -- so the underlying problem is that you're executing from uninitialized memory (U-Boot fills memory with 0xdeadbeef when initializing the memory controller).  Perhaps something is wrong with your DDR config?  What happens if you never enable CPC in the first place?

0 Kudos

684 Views
scottwood
NXP Employee
NXP Employee

0xdeadbeef is not a valid value for MCSR -- if you saw this then something is wrong with your exception handling code.

What is the address being accessed by stfdu?  -16657 looks unaligned, though it depends on the value in r13.  e500mc does not support unaligned floating point loads/stores, according to section 4.9.7 (Alignment Interrupt--IVOR5) of E500MCRM.  I don't know why disabling CPC makes a difference, except that maybe it has a timing (or some other) effect on how other code runs and this changes whether your code attempts to do an unaligned floating point access.

0 Kudos