[U-Boot-Users] Problem porting the POST instruction cache test to the MPC5200.

Hi all,
I'm trying to port the POST cache test to the MPC5200 and I've found some problems porting the cache_post_test5 function. I think the philosophy of the function (I think the comments are not updated) is to lock an instruction in the cache, modify the instruction position in memory with another instruction and verify that the instruction locked in the cache has been executed when we jump to the instruction . The locked instruction load the r3 register with a 0 value and the "new" instruction with a -1. When I debug the function with the gdb and the BDI2000 with the ddd front end I see in the Machine Code Window the intruction locked ( li r3, 0) but if I stepi the instruction the value in r3 will be -1. I can't understand what is happening. Who is telling the truth?. I think the problem seems to be with the lock proccess and I have a doubt: Must I activate the intruction MMU to lock the cache in a MPC5200? I have read the MPC5200 core manual and this aspect is not clear to me. How can I see the instruction cache with the gdb (or BDI2000) without write a specific function ?.
Any clue will be welcomed.
Attached my test cache file for the MPC5200 based on the cache_8xx.S file.
Thanks in advance.
Jose Maria Lopez.
/* * Copyright (C) 2002 Wolfgang Denk wd@denx.de * * See file CREDITS for list of people who contributed to this * project. * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License as * published by the Free Software Foundation; either version 2 of * the License, or (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 59 Temple Place, Suite 330, Boston, * MA 02111-1307 USA */
#include <config.h>
#ifdef CONFIG_POST #if defined(CONFIG_MPC5xxx)
#include <post.h> #include <ppc_asm.tmpl> #include <ppc_defs.h> #include <asm/cache.h> #include <mpc5xxx.h>
#if CONFIG_POST & CFG_POST_CACHE
.text
cache_post_dinvalidate: mfspr r5, HID0 mr r7, r5 lis r6, 0 ori r6, r6, HID0_DCI andc r5, r5, r6 ori r5, r5, HID0_DCE or r6, r6, r5 sync mtspr HID0, r6 sync mtspr HID0, r5 sync mtspr HID0, r7 blr cache_post_iinvalidate: mfspr r5, HID0 mr r7, r5 lis r6, 0 ori r6, r6, HID0_ICFI andc r5, r5, r6 ori r5, r5, HID0_ICE or r6, r6, r5 isync mtspr HID0, r6 isync mtspr HID0, r5 isync mtspr HID0, r7 blr cache_post_ddisable: mfspr r5, HID0 lis r6, 0 ori r6, r6, HID0_DCE andc r5, r5, r6 sync mtspr HID0, r5 blr
cache_post_dwb: mfspr r5, HID0 ori r5, r5, HID0_DCE sync mtspr HID0, r5 blr cache_post_dwt: blr
cache_post_idisable: mfspr r5, HID0 lis r6, 0 ori r6, r6, HID0_ICE andc r5, r5, r6 isync mtspr HID0, r5 blr
cache_post_ienable: mfspr r5, HID0 ori r5, r5, HID0_ICE isync mtspr HID0, r5 blr
cache_post_iunlock: mfspr r5, HID0 lis r6, 0 ori r6, r6, HID0_ILOCK andc r5, r5, r6 isync mtspr HID0, r5 blr
cache_post_ilock: mfspr r5, HID0 ori r5, r5, HID0_ILOCK isync mtspr HID0, r5 blr mmu_post_denable: mfmsr r5 lis r6, MSR_DR@h ori r6, r6, MSR_DR@l or r5, r5, r6 SYNC mtmsr r5 SYNC blr mmu_post_ddisable: mfmsr r5 lis r6, MSR_DR@h ori r6, r6, MSR_DR@l andc r5, r5, r6 SYNC mtmsr r5 SYNC blr /* * turn on the data cache * switch the data cache to write-back or write-through mode * invalidate the data cache * write the negative pattern to a cached area * read the area * * The negative pattern must be read at the last step */ .global cache_post_test1 cache_post_test1: mflr r0 stw r0, 4(r1)
stwu r3, -4(r1) stwu r4, -4(r1)
bl cache_post_dwb bl cache_post_dinvalidate
/* Write the negative pattern to the test area */ lwz r0, 0(r1) mtctr r0 li r0, 0xff lwz r3, 4(r1) subi r3, r3, 1 1: stbu r0, 1(r3) bdnz 1b
/* Read the test area */ lwz r0, 0(r1) mtctr r0 lwz r4, 4(r1) subi r4, r4, 1 li r3, 0 1: lbzu r0, 1(r4) cmpli cr0, r0, 0xff beq 2f li r3, -1 b 3f 2: bdnz 1b 3:
bl cache_post_ddisable bl cache_post_dinvalidate
addi r1, r1, 8
lwz r0, 4(r1) mtlr r0 blr
/* * turn on the data cache * switch the data cache to write-back or write-through mode * invalidate the data cache * write the zero pattern to a cached area * turn off the data cache * write the negative pattern to the area * turn on the data cache * read the area * * The negative pattern must be read at the last step */ .global cache_post_test2 cache_post_test2: mflr r0 stw r0, 4(r1)
stwu r3, -4(r1) stwu r4, -4(r1)
bl cache_post_dwb bl cache_post_dinvalidate
/* Write the zero pattern to the test area */ lwz r0, 0(r1) mtctr r0 li r0, 0 lwz r3, 4(r1) subi r3, r3, 1 1: stbu r0, 1(r3) bdnz 1b
bl cache_post_ddisable
/* Write the negative pattern to the test area */ lwz r0, 0(r1) mtctr r0 li r0, 0xff lwz r3, 4(r1) subi r3, r3, 1 1: stbu r0, 1(r3) bdnz 1b
bl cache_post_dwb
/* Read the test area */ lwz r0, 0(r1) mtctr r0 lwz r4, 4(r1) subi r4, r4, 1 li r3, 0 1: lbzu r0, 1(r4) cmpli cr0, r0, 0xff beq 2f li r3, -1 b 3f 2: bdnz 1b 3:
bl cache_post_ddisable bl cache_post_dinvalidate
addi r1, r1, 8
lwz r0, 4(r1) mtlr r0 blr
/* * turn on the data cache * switch the data cache to write-through mode * invalidate the data cache * write the zero pattern to a cached area * flush the data cache * write the negative pattern to the area * turn off the data cache * read the area * * The negative pattern must be read at the last step */ .global cache_post_test3 cache_post_test3: mflr r0 stw r0, 4(r1)
stwu r3, -4(r1) stwu r4, -4(r1)
bl cache_post_ddisable bl cache_post_dinvalidate
/* Write the zero pattern to the test area */ lwz r0, 0(r1) mtctr r0 li r0, 0 lwz r3, 4(r1) subi r3, r3, 1 1: stbu r0, 1(r3) bdnz 1b bl mmu_post_denable bl cache_post_dwb bl cache_post_dinvalidate
/* Write the negative pattern to the test area */ lwz r0, 0(r1) mtctr r0 li r0, 0xff lwz r3, 4(r1) subi r3, r3, 1 1: stbu r0, 1(r3) bdnz 1b
bl cache_post_ddisable bl cache_post_dinvalidate bl mmu_post_ddisable /* Read the test area */ lwz r0, 0(r1) mtctr r0 lwz r4, 4(r1) subi r4, r4, 1 li r3, 0 1: lbzu r0, 1(r4) cmpli cr0, r0, 0xff beq 2f li r3, -1 b 3f 2: bdnz 1b 3:
addi r1, r1, 8
lwz r0, 4(r1) mtlr r0 blr
/* * turn on the data cache * switch the data cache to write-back mode * invalidate the data cache * write the negative pattern to a cached area * flush the data cache * write the zero pattern to the area * invalidate the data cache * read the area * * The negative pattern must be read at the last step */ .global cache_post_test4 cache_post_test4: mflr r0 stw r0, 4(r1)
stwu r3, -4(r1) stwu r4, -4(r1)
bl cache_post_ddisable bl cache_post_dinvalidate
/* Write the negative pattern to the test area */ lwz r0, 0(r1) mtctr r0 li r0, 0xff lwz r3, 4(r1) subi r3, r3, 1 1: stbu r0, 1(r3) bdnz 1b
bl cache_post_dwb bl cache_post_dinvalidate
/* Write the zero pattern to the test area */ lwz r0, 0(r1) mtctr r0 li r0, 0 lwz r3, 4(r1) subi r3, r3, 1 1: stbu r0, 1(r3) bdnz 1b
bl cache_post_ddisable bl cache_post_dinvalidate
/* Read the test area */ lwz r0, 0(r1) mtctr r0 lwz r4, 4(r1) subi r4, r4, 1 li r3, 0 1: lbzu r0, 1(r4) cmpli cr0, r0, 0xff beq 2f li r3, -1 b 3f 2: bdnz 1b 3:
addi r1, r1, 8
lwz r0, 4(r1) mtlr r0 blr
cache_post_test5_1: li r3, 0 blr cache_post_test5_2: li r3, -1 blr
/* * turn on the instruction cache * unlock the entire instruction cache * invalidate the instruction cache * lock a branch instruction in the instruction cache * replace the branch instruction with "nop" * jump to the branch instruction * check that the branch instruction was executed */ .global cache_post_test5 cache_post_test5: mflr r0 stw r0, 4(r1)
bl cache_post_ienable bl cache_post_iunlock bl cache_post_iinvalidate
/* Compute r9 = cache_post_test5_reloc */ bl cache_post_test5_reloc cache_post_test5_reloc: mflr r9
/* Copy the test instruction to cache_post_test5_data */ lis r3, (cache_post_test5_1 - cache_post_test5_reloc)@h ori r3, r3, (cache_post_test5_1 - cache_post_test5_reloc)@l add r3, r3, r9 lis r4, (cache_post_test5_data - cache_post_test5_reloc)@h ori r4, r4, (cache_post_test5_data - cache_post_test5_reloc)@l add r4, r4, r9 lwz r0, 0(r3) stw r0, 0(r4)
bl cache_post_iinvalidate
/* Lock the branch instruction */ bl cache_post_test5_data bl cache_post_ilock /* Replace the test instruction */ lis r3, (cache_post_test5_2 - cache_post_test5_reloc)@h ori r3, r3, (cache_post_test5_2 - cache_post_test5_reloc)@l add r3, r3, r9 lis r4, (cache_post_test5_data - cache_post_test5_reloc)@h ori r4, r4, (cache_post_test5_data - cache_post_test5_reloc)@l add r4, r4, r9 lwz r0, 0(r3) stw r0, 0(r4)
bl cache_post_iinvalidate addi r4, r4, 8 mtlr r4 /* Execute to the test instruction */ cache_post_test5_data: nop blr bl cache_post_iunlock lwz r0, 4(r1) mtlr r0 blr
cache_post_test6_1: li r3, -1 blr cache_post_test6_2: li r3, 0 blr
/* * turn on the instruction cache * unlock the entire instruction cache * invalidate the instruction cache * lock a branch instruction in the instruction cache * replace the branch instruction with "nop" * jump to the branch instruction * check that the branch instruction was executed */ .global cache_post_test6 cache_post_test6: mflr r0 stw r0, 4(r1)
bl cache_post_ienable bl cache_post_iunlock bl cache_post_iinvalidate
/* Compute r9 = cache_post_test6_reloc */ bl cache_post_test6_reloc cache_post_test6_reloc: mflr r9
/* Copy the test instruction to cache_post_test6_data */ lis r3, (cache_post_test6_1 - cache_post_test6_reloc)@h ori r3, r3, (cache_post_test6_1 - cache_post_test6_reloc)@l add r3, r3, r9 lis r4, (cache_post_test6_data - cache_post_test6_reloc)@h ori r4, r4, (cache_post_test6_data - cache_post_test6_reloc)@l add r4, r4, r9 lwz r0, 0(r3) stw r0, 0(r4)
bl cache_post_iinvalidate
/* Replace the test instruction */ lis r3, (cache_post_test6_2 - cache_post_test6_reloc)@h ori r3, r3, (cache_post_test6_2 - cache_post_test6_reloc)@l add r3, r3, r9 lis r4, (cache_post_test6_data - cache_post_test6_reloc)@h ori r4, r4, (cache_post_test6_data - cache_post_test6_reloc)@l add r4, r4, r9 lwz r0, 0(r3) stw r0, 0(r4)
bl cache_post_iinvalidate
/* Execute to the test instruction */ cache_post_test6_data: nop
lwz r0, 4(r1) mtlr r0 blr
#endif /* CONFIG_MPC823 || MPC850 || MPC855 || MPC860 */ #endif /* CONFIG_POST & CFG_POST_CACHE */ #endif /* CONFIG_POST */

Hi Mr. Lopez,
I've already implemented a POST cache test for the MPC5200. This was done while porting U-Boot to one of our new boards pf5200_st. Unfortunately I forked from the U-Boot tree several month ago. To catch up to the current U-Boot tree I will need about one or two weeks. Then I will be able to post a patch against the current version.
If you want you may get my source files in advance. Please contact me directly.
To answer some of your questions from my experience:
Am 14.11.2005 17:07:23 schrieb(en) Txema Lopez:
Hi all,
I'm trying to port the POST cache test to the MPC5200 and I've found some problems porting the cache_post_test5 function. I think the philosophy of the function (I think the comments are not updated) is to lock an instruction in the cache, modify the instruction position in memory with another instruction and verify that the instruction locked in the cache has been executed when we jump to the instruction .
This was also my idea about this function.
The locked instruction load the r3 register with a 0 value and the "new" instruction with a -1. When I debug the function with the gdb and the BDI2000 with the ddd front end I see in the Machine Code Window the intruction locked ( li r3, 0) but if I stepi the instruction the value in r3 will be -1. I can't understand what is happening. Who is telling the truth?.
I don't really know, but I think a least from PPC instruction level there is no way to read the contents of the instruction cache on the G2 core (nearly a 603e).
I think the problem seems to be with the lock proccess and I have a doubt: Must I activate the intruction MMU to lock the cache in a MPC5200? I have read the MPC5200 core manual and this aspect is not clear to me.
For locking only you don't need the MMU. But some parts of the POST cache test (especially the data write through stuff) are only working with MMU enabled.
How can I see the instruction cache with the gdb (or BDI2000) without write a specific function ?.
I really don't know.
I believe the problem is not the locking of the instruction cache. The difficult thing is to get the right instructions into the cache before the locking is done.
The solution that works for me was to call the test instruction once then lock the cache and after that replace the instruction in memory. The second call then has to deliver the value set up by the locked instruction.
The reason for this is the completely different cache handling on 8xx cores and on the G2/603e core. The 603e core misses any instruction to load and lock explicitely a cache line.
Also the code to load and lock instructions in the cache which is depicted in the G2 Core Reference manual will not work because one of its preconditions is that the loading code is executed from an area from which the core can read two instructions in one beat (64 bit data path). There is no memory area on the MPC5200 that would fulfill this precondition. Maybe except the SRAM, but I didn't test that after having a working solution.
Thanks in advance.
Jose Maria Lopez.
participants (2)
-
Stefan Mätje
-
Txema Lopez