From: ljsebald <ljs...@us...> - 2023-10-24 17:14:47
|
This is an automated email from the git hooks/post-receive script. It was generated because a ref change was pushed to the repository containing the project "A pseudo Operating System for the Dreamcast.". The branch, master has been updated via 6da37bf27613e8cb64db4ae00f46af20ed98330e (commit) from 8b380271151dea406c82ff4dd9179621ef1247cd (commit) Those revisions listed above that are new to this repository have not appeared on any other notification email; so we list those revisions in full, below. - Log ----------------------------------------------------------------- commit 6da37bf27613e8cb64db4ae00f46af20ed98330e Author: Ruslan Rostovtsev <sw...@21...> Date: Wed Oct 25 00:14:12 2023 +0700 SH4 cache improvements (#327) * Add support for purge the entire data/operand cache * Add support for allocate a block of data/operand cache. ----------------------------------------------------------------------- Summary of changes: kernel/arch/dreamcast/include/arch/cache.h | 43 +++++++++++++++++++----------- kernel/arch/dreamcast/kernel/cache.s | 33 +++++++++++------------ kernel/exports.txt | 2 +- 3 files changed, 44 insertions(+), 34 deletions(-) diff --git a/kernel/arch/dreamcast/include/arch/cache.h b/kernel/arch/dreamcast/include/arch/cache.h index 5208ddb..602f2b3 100644 --- a/kernel/arch/dreamcast/include/arch/cache.h +++ b/kernel/arch/dreamcast/include/arch/cache.h @@ -76,32 +76,45 @@ void dcache_flush_range(uint32 start, uint32 count); */ void dcache_purge_range(uint32 start, uint32 count); -/** \brief Prefetch memory to the data/operand cache. +/** \brief Purge all the data/operand cache. - This function prefetch a range of the data/operand cache. + This function flushes all the data/operand cache, forcing a write- + back and invalidate on all of the cache blocks. + + \param start The physical address for temporary buffer (32-byte aligned) + \param count The number of bytes of temporary buffer (8 KB or 16 KB) - \param start The physical address to begin prefetching at. - \param count The number of bytes to prefetch. - \return The physical address aligned to cache block size. */ -void *dcache_pref_range(uint32 start, uint32 count); +void dcache_purge_all(uint32 start, uint32 count); /** \brief Prefetch one block to the data/operand cache. - This function prefetch a range of the data/operand cache. + This function prefetch a block of the data/operand cache. - \param src The buffer to prefetch. - \return The buffer aligned to cache block size. + \param src The physical address to prefetch. */ -static __always_inline void *dcache_pref_block(const void *src) { - uint32 __cache_aligned = ((uint32)src) & ~(CPU_CACHE_BLOCK_SIZE - 1); - __asm__ __volatile__("pref @%[ptr]\n" - : - : [ptr] "r" (__cache_aligned) +static __always_inline void dcache_pref_block(const void *src) { + __asm__ __volatile__("pref @%0\n" : + : "r" (src) + : "memory" ); +} + +/** \brief Allocate one block of the data/operand cache. - return (void *)__cache_aligned; + This function allocate a block of the data/operand cache. + + \param src The physical address to allocate. + \param value The value written to first 4-byte. +*/ +static __always_inline void dcache_alloc_block(const void *src, uint32 value) { + register int __value __asm__("r0") = value; + __asm__ __volatile__ ("movca.l r0,@%0\n\t" + : + : "r" (src), "r" (__value) + : "memory" + ); } __END_DECLS diff --git a/kernel/arch/dreamcast/kernel/cache.s b/kernel/arch/dreamcast/kernel/cache.s index 9172a20..c2b8bdc 100644 --- a/kernel/arch/dreamcast/kernel/cache.s +++ b/kernel/arch/dreamcast/kernel/cache.s @@ -10,7 +10,7 @@ .globl _dcache_inval_range .globl _dcache_flush_range .globl _dcache_purge_range - .globl _dcache_pref_range + .globl _dcache_purge_all ! r4 is starting address ! r5 is count @@ -149,25 +149,22 @@ dpurge_loop: rts nop -! This routine prefetch to operand cache the specified data range. -! r4 is starting address -! r5 is count -_dcache_pref_range: - ! Get ending address from count and align start address - add r4,r5 - mov.l l1align,r0 - and r0,r4 - mov r4,r6 - -dpref_loop: - ! Prefetch to the O cache - pref @r4 - cmp/hs r4,r5 - bt/s dpref_loop - add #32,r4 ! += CPU_CACHE_BLOCK_SIZE +! This routine just forces a write-back and invalidate all O cache. +! r4 is address for temporary buffer 32-byte aligned +! r5 is size of temporary buffer (8 KB or 16 KB) +_dcache_purge_all: + mov #0, r0 + add r4, r5 +dpurge_all_loop: + ! Allocate and then invalidate the O cache block + movca.l r0, @r4 + ocbi @r4 + cmp/hs r4, r5 + bt/s dpurge_all_loop + add #32, r4 ! += CPU_CACHE_BLOCK_SIZE rts - mov r6,r0 + nop .align 2 diff --git a/kernel/exports.txt b/kernel/exports.txt index 3052c20..961ea1d 100644 --- a/kernel/exports.txt +++ b/kernel/exports.txt @@ -174,7 +174,7 @@ icache_flush_range dcache_inval_range dcache_flush_range dcache_purge_range -dcache_pref_range +dcache_purge_all # Low-level debug I/O dbgio_set_irq_usage hooks/post-receive -- A pseudo Operating System for the Dreamcast. |