[U-Boot-Users] Regarding Dcache Flush in MPC85xx

Hi, We are using MPC8555 processor and uboot 1.1.4 both the uboot and linux was up. Now we plan to port QNX, we are facing following issues.
1. Qnx is not jumping to the startup location. After giving go command control is still in the uboot only.
2. When searching in the mailling list we came to know qnx required to flush the Data Cache before disabling it in the uboot level (common/cmd_bootelf.c line no:59)
3. I checked other powerpc architecture like 7xx/74xx, 86xx and 4xx. These architecture has seperate cache.S file ( cpu/mpc86xx/cache.S). That file contains flush_data_cache function to flush the cache before disabling it. But in the MPC85xx flushing the data cache was missing.
4. This is a bug in the 85xx uboot code. Is there any work arround for this?
Thanks and Regards S.Balamurugan

On Feb 26, 2008, at 11:30 AM, s.balamurugan wrote:
Hi, We are using MPC8555 processor and uboot 1.1.4 both the uboot and linux was up. Now we plan to port QNX, we are facing following issues.
- Qnx is not jumping to the startup location. After giving go
command control is still in the uboot only.
- When searching in the mailling list we came to know qnx required
to flush the Data Cache before disabling it in the uboot level (common/cmd_bootelf.c line no:59)
- I checked other powerpc architecture like 7xx/74xx, 86xx and 4xx.
These architecture has seperate cache.S file ( cpu/mpc86xx/ cache.S). That file contains flush_data_cache function to flush the cache before disabling it. But in the MPC85xx flushing the data cache was missing.
- This is a bug in the 85xx uboot code. Is there any work arround for
this?
1.1.4 is a fairly old u-boot at this point. I believe we have reworked the PPC cache ops and fixed the fact that 85xx was missing flush_data_cache in the process.
- k

Kumar Gala wrote:
We are using MPC8555 processor and uboot 1.1.4 both the uboot and linux was up. Now we plan to port QNX, we are facing following issues.
- Qnx is not jumping to the startup location. After giving go
command control is still in the uboot only.
- When searching in the mailling list we came to know qnx required
to flush the Data Cache before disabling it in the uboot level (common/cmd_bootelf.c line no:59)
- I checked other powerpc architecture like 7xx/74xx, 86xx and 4xx.
These architecture has seperate cache.S file ( cpu/mpc86xx/ cache.S). That file contains flush_data_cache function to flush the cache before disabling it. But in the MPC85xx flushing the data cache was missing.
- This is a bug in the 85xx uboot code. Is there any work arround for
this?
1.1.4 is a fairly old u-boot at this point. I believe we have reworked the PPC cache ops and fixed the fact that 85xx was missing flush_data_cache in the process.
Not really, unfortunatelly: the 85xx still lacks flushing the d-cache before disabling it. I was going to fix this by refactoring existing d-cache disabling/flushing routines into a common code that would sit in the lib_ppc/ppccache.S (as mostly exisiting implementations are just copy/paste of the same thing) and have 85xx use it too, but didn't have time yet to clean it up. If anyone is willing to do it sooner, I won't complain :)
Rafal

On Fri, Feb 29, 2008 at 06:10:10PM +0100, Rafal Jaworowski wrote:
Not really, unfortunatelly: the 85xx still lacks flushing the d-cache before disabling it. I was going to fix this by refactoring existing d-cache disabling/flushing routines into a common code that would sit in the lib_ppc/ppccache.S (as mostly exisiting implementations are just copy/paste of the same thing) and have 85xx use it too, but didn't have time yet to clean it up. If anyone is willing to do it sooner, I won't complain :)
The implementations for other CPUs such as 86xx are a bit questionable (arbitrarily using the cache line times 65536 as the size to flush, and inefficiently iterating 4 bytes at a time rather than a cache line).
Here's an 85xx implementation from an as-yet-unmerged Linux tree (replace KERNELBASE with something appropriate for U-boot) that dynamically figures out the cache and cache block sizes. Note that it assumes at most 8 ways.
_GLOBAL(flush_disable_L1) mfspr r3, SPRN_L1CFG0
rlwinm r5, r3, 9, 3 /* Extract cache block size */ twlgti r5, 1 /* Only 32 and 64 byte cache blocks * are currently defined. */ li r4, 32 subfic r6, r5, 2 /* r6 = log2(1KiB / cache block size) - * log2(number of ways) */ slw r5, r4, r5 /* r5 = cache block size */
rlwinm r7, r3, 0, 0xff /* Extract number of KiB in the cache */ mulli r7, r7, 13 /* An 8-way cache will require 13 * loads per way. */ slw r7, r7, r6
lis r4, KERNELBASE@h mtctr r7
1: lwz r0, 0(r4) /* Load... */ add r4, r4, r5 bdnz 1b
msync lis r4, KERNELBASE@h mtctr r7
1: dcbf 0, r4 /* ...and flush. */ add r4, r4, r5 bdnz 1b
mfspr r4, SPRN_L1CSR0 /* Invalidate and disable d-cache */ li r5, 2 rlwimi r4, r5, 0, 3 msync isync mtspr SPRN_L1CSR0, r4 isync
1: mfspr r4, SPRN_L1CSR0 /* Wait for the invalidate to finish */ andi. r4, r4, 2 bne 1b
rlwimi r4, r3, 2, 3 /* Extract cache type */ twlgti r4, 1 /* Only 0 (Harvard) and 1 (Unified) * are currently defined. */
andi. r4, r4, 1 /* If it's unified, we're done. */ bnelr
mfspr r4, SPRN_L1CSR1 /* Otherwise, invalidate the i-cache */ li r5, 2 rlwimi r4, r5, 0, 3 msync isync mtspr SPRN_L1CSR1, r4 isync
1: mfspr r4, SPRN_L1CSR1 /* Wait for the invalidate to finish */ andi. r4, r4, 2 bne 1b blr
_GLOBAL(invalidate_enable_L1) mfspr r4, SPRN_L1CSR0 /* Invalidate d-cache */ ori r4, r4, 2 msync isync mtspr SPRN_L1CSR0, r4 isync
1: mfspr r4, SPRN_L1CSR0 /* Wait for the invalidate to finish */ andi. r5, r4, 2 bne 1b
ori r4, r4, 1 /* Enable d-cache */ msync isync mtspr SPRN_L1CSR0, r4 isync
mfspr r3, SPRN_L1CFG0 rlwimi r4, r3, 2, 3 /* Extract cache type */ twlgti r4, 1 /* Only 0 (Harvard) and 1 (Unified) * are currently defined. */
andi. r4, r4, 1 /* If it's unified, we're done. */ bnelr
mfspr r4, SPRN_L1CSR1 /* Otherwise, do the i-cache as well */ ori r5, r4, 2 msync isync mtspr SPRN_L1CSR1, r4 isync
1: mfspr r4, SPRN_L1CSR1 /* Wait for the invalidate to finish */ andi. r4, r4, 2 bne 1b
ori r4, r4, 1 /* Enable i-cache */ msync isync mtspr SPRN_L1CSR1, r4 isync
blr
/* r3 = virtual address of L2 controller */ _GLOBAL(flush_disable_L2) /* It's a write-through cache, so only invalidation is needed. */ lwz r4, 0(r3) li r5, 1 rlwimi r4, r5, 30, 0xc0000000 stw r4, 0(r3)
/* Wait for the invalidate to finish */ 1: lwz r4, 0(r3) andis. r4, r4, 0x4000 bne 1b
blr
/* r3 = virtual address of L2 controller */ _GLOBAL(invalidate_enable_L2) lwz r4, 0(r3) li r5, 3 rlwimi r4, r5, 30, 0xc0000000 stw r4, 0(r3)
/* Wait for the invalidate to finish */ 1: lwz r4, 0(r3) andis. r4, r4, 0x4000 bne 1b
blr

Scott Wood wrote:
On Fri, Feb 29, 2008 at 06:10:10PM +0100, Rafal Jaworowski wrote:
Not really, unfortunatelly: the 85xx still lacks flushing the d-cache before disabling it. I was going to fix this by refactoring existing d-cache disabling/flushing routines into a common code that would sit in the lib_ppc/ppccache.S (as mostly exisiting implementations are just copy/paste of the same thing) and have 85xx use it too, but didn't have time yet to clean it up. If anyone is willing to do it sooner, I won't complain :)
The implementations for other CPUs such as 86xx are a bit questionable (arbitrarily using the cache line times 65536 as the size to flush, and inefficiently iterating 4 bytes at a time rather than a cache line).
Here's an 85xx implementation from an as-yet-unmerged Linux tree (replace KERNELBASE with something appropriate for U-boot) that dynamically figures out the cache and cache block sizes. Note that it assumes at most 8 ways.
Hi Scott,
Thanks for this code. It's true that bulk of current U-Boot implementations of the PPC flushing routines are not relevant to real parameters of the cache they operate against. I thought about making this auto-discovery too, so your code is a great hint. I don't know however when I'd be able to work on merging it with U-Boot and testing..
Rafal
participants (4)
-
Kumar Gala
-
Rafal Jaworowski
-
s.balamurugan
-
Scott Wood