[PATCH 1/5] or1k: Add functions for entire cache operations

2016-11-25 Thread Martin Erik Werner
Add functions for flushing and invalidating whole cache.

Since we don't have system calls that can operate on anything more than
a single cache line, these simply retrieves the cache size and iterates
over the full size, invalidating each line.

The current implementation assumes that there's only one level of cache.

These changes were contributed by Antmicro under contract by ÅAC
Microtec AB.

Close #2602
---
 c/src/lib/libcpu/or1k/shared/cache/cache.c | 45 --
 1 file changed, 42 insertions(+), 3 deletions(-)

diff --git a/c/src/lib/libcpu/or1k/shared/cache/cache.c 
b/c/src/lib/libcpu/or1k/shared/cache/cache.c
index 54728e1..88cda1a 100644
--- a/c/src/lib/libcpu/or1k/shared/cache/cache.c
+++ b/c/src/lib/libcpu/or1k/shared/cache/cache.c
@@ -1,4 +1,8 @@
 /*
+ * COPYRIGHT (c) 2014 ÅAC Microtec AB 
+ * Contributor(s):
+ *  Karol Gugala 
+ *
  * COPYRIGHT (c) 2014 Hesham ALMatary 
  *
  * COPYRIGHT (c) 1989-2006
@@ -14,6 +18,7 @@
 #include 
 #include 
 #include 
+#include 
 
 static inline void _CPU_OR1K_Cache_enable_data(void)
 {
@@ -206,17 +211,51 @@ void _CPU_cache_unfreeze_instruction(void)
 
 void _CPU_cache_flush_entire_data(void)
 {
-
+  int addr;
+
+  /* We have only 0 level cache so we do not need to invalidate others */
+  for (
+  addr = _CPU_cache_get_data_cache_size(0);
+  addr > 0;
+  addr -= CPU_DATA_CACHE_ALIGNMENT
+  ) {
+_CPU_OR1K_Cache_data_block_flush((uintptr_t) addr);
+  }
 }
 
 void _CPU_cache_invalidate_entire_data(void)
 {
-
+  int addr;
+
+  /* We have only 0 level cache so we do not need to invalidate others */
+  for (
+  addr = _CPU_cache_get_data_cache_size(0);
+  addr > 0;
+  addr -= CPU_DATA_CACHE_ALIGNMENT
+  ) {
+_CPU_cache_invalidate_1_data_line((uintptr_t) addr);
+  }
 }
 
 void _CPU_cache_invalidate_entire_instruction(void)
 {
-
+  int addr;
+
+  /* We have only 0 level cache so we do not need to invalidate others */
+  for (
+  addr = _CPU_cache_get_instruction_cache_size(0);
+  addr > 0;
+  addr -= CPU_INSTRUCTION_CACHE_ALIGNMENT
+  ) {
+_CPU_cache_invalidate_1_instruction_line((uintptr_t) addr);
+  }
+
+  /* Flush instructions out of instruction buffer */
+  __asm__ volatile("l.nop");
+  __asm__ volatile("l.nop");
+  __asm__ volatile("l.nop");
+  __asm__ volatile("l.nop");
+  __asm__ volatile("l.nop");
 }
 
 void _CPU_cache_enable_data(void)
-- 
2.1.4

___
devel mailing list
devel@rtems.org
http://lists.rtems.org/mailman/listinfo/devel

[PATCH 0/5] or1k: Optimisation and implementation of cache manager functions

2016-11-25 Thread Martin Erik Werner
These patches are mainly optimisation changes to the or1k cache manager
functions. They were made for use on our custom boards, but should be applicable
to or1k in general.

We have used and tested these patches as part of a larger set of changes for
our boards on the 4.11 branch on top of rtems commit 5807328.

No testing except compilation has been performed on the rebased patch set on
master.

Martin Erik Werner (5):
  or1k: Add functions for entire cache operations
  or1k: Indent & comment fix in cache.c
  or1k: Avoid excessive ISR toggle in cache manager
  or1k: Remove secondary functions in cache manager
  or1k: Avoid multiple iterations over cache

 c/src/lib/libcpu/or1k/shared/cache/cache.c  | 316 +++-
 c/src/lib/libcpu/or1k/shared/cache/cache_.h |   6 +
 2 files changed, 228 insertions(+), 94 deletions(-)

-- 
2.1.4

___
devel mailing list
devel@rtems.org
http://lists.rtems.org/mailman/listinfo/devel


[PATCH 3/5] or1k: Avoid excessive ISR toggle in cache manager

2016-11-25 Thread Martin Erik Werner
Previously _ISR_Local_{disable,enable}() was executed twice for each
cache line operation, and since operations over the entire cache were
implemented by calling the single-line operations in a loop, this made
those operations rather costly.

Fix the double-toggle by calling _OR1K_mtspr() directly, and removing
the now-unused corresponding _CPU_OR1K_Cache_* functions.

Fix the entire-operations by moving the ISR toggle outside of the
loop, and by calling _OR1K_mtspr() directly instead of the single-line
operations.

Also implement range functions, since otherwise the cache manager falls
back on looping over the single-line operations.
---
 c/src/lib/libcpu/or1k/shared/cache/cache.c  | 161 
 c/src/lib/libcpu/or1k/shared/cache/cache_.h |   6 ++
 2 files changed, 123 insertions(+), 44 deletions(-)

diff --git a/c/src/lib/libcpu/or1k/shared/cache/cache.c 
b/c/src/lib/libcpu/or1k/shared/cache/cache.c
index 5d7053f..e1b2b1d 100644
--- a/c/src/lib/libcpu/or1k/shared/cache/cache.c
+++ b/c/src/lib/libcpu/or1k/shared/cache/cache.c
@@ -1,7 +1,8 @@
 /*
- * COPYRIGHT (c) 2014 ÅAC Microtec AB 
+ * COPYRIGHT (c) 2014, 2016 ÅAC Microtec AB 
  * Contributor(s):
  *  Karol Gugala 
+ *  Martin Werner 
  *
  * COPYRIGHT (c) 2014 Hesham ALMatary 
  *
@@ -83,28 +84,6 @@ static inline void _CPU_OR1K_Cache_data_block_prefetch(const 
void *d_addr)
   _ISR_Local_enable(level);
 }
 
-static inline void _CPU_OR1K_Cache_data_block_flush(const void *d_addr)
-{
-  ISR_Level level;
-
-  _ISR_Local_disable (level);
-
-  _OR1K_mtspr(CPU_OR1K_SPR_DCBFR, (uintptr_t) d_addr);
-
-  _ISR_Local_enable(level);
-}
-
-static inline void _CPU_OR1K_Cache_data_block_invalidate(const void *d_addr)
-{
-  ISR_Level level;
-
-  _ISR_Local_disable (level);
-
-  _OR1K_mtspr(CPU_OR1K_SPR_DCBIR, (uintptr_t) d_addr);
-
-  _ISR_Local_enable(level);
-}
-
 static inline void _CPU_OR1K_Cache_data_block_writeback(const void *d_addr)
 {
   ISR_Level level;
@@ -139,18 +118,6 @@ static inline void 
_CPU_OR1K_Cache_instruction_block_prefetch
   _ISR_Local_enable(level);
 }
 
-static inline void _CPU_OR1K_Cache_instruction_block_invalidate
-(const void *d_addr)
-{
-  ISR_Level level;
-
-  _ISR_Local_disable (level);
-
-  _OR1K_mtspr(CPU_OR1K_SPR_ICBIR, (uintptr_t) d_addr);
-
-  _ISR_Local_enable(level);
-}
-
 static inline void _CPU_OR1K_Cache_instruction_block_lock
 (const void *d_addr)
 {
@@ -171,7 +138,7 @@ void _CPU_cache_flush_1_data_line(const void *d_addr)
 
   _ISR_Local_disable (level);
 
-  _CPU_OR1K_Cache_data_block_flush(d_addr);
+  _OR1K_mtspr(CPU_OR1K_SPR_DCBFR, (uintptr_t) d_addr);
 
   //__asm__ volatile("l.csync");
 
@@ -184,7 +151,7 @@ void _CPU_cache_invalidate_1_data_line(const void *d_addr)
 
   _ISR_Local_disable (level);
 
-  _CPU_OR1K_Cache_data_block_invalidate(d_addr);
+  _OR1K_mtspr(CPU_OR1K_SPR_DCBIR, (uintptr_t) d_addr);
 
   _ISR_Local_enable(level);
 }
@@ -205,7 +172,7 @@ void _CPU_cache_invalidate_1_instruction_line(const void 
*d_addr)
 
   _ISR_Local_disable (level);
 
-  _CPU_OR1K_Cache_instruction_block_invalidate(d_addr);
+  _OR1K_mtspr(CPU_OR1K_SPR_ICBIR, (uintptr_t) d_addr);
 
   _ISR_Local_enable(level);
 }
@@ -222,7 +189,10 @@ void _CPU_cache_unfreeze_instruction(void)
 
 void _CPU_cache_flush_entire_data(void)
 {
-  int addr;
+  size_t addr;
+  ISR_Level level;
+
+  _ISR_Local_disable (level);
 
   /* We have only 0 level cache so we do not need to invalidate others */
   for (
@@ -230,13 +200,18 @@ void _CPU_cache_flush_entire_data(void)
   addr > 0;
   addr -= CPU_DATA_CACHE_ALIGNMENT
   ) {
-_CPU_OR1K_Cache_data_block_flush((uintptr_t) addr);
+_OR1K_mtspr(CPU_OR1K_SPR_DCBFR, (uintptr_t) addr);
   }
+
+  _ISR_Local_enable (level);
 }
 
 void _CPU_cache_invalidate_entire_data(void)
 {
-  int addr;
+  size_t addr;
+  ISR_Level level;
+
+  _ISR_Local_disable (level);
 
   /* We have only 0 level cache so we do not need to invalidate others */
   for (
@@ -244,13 +219,18 @@ void _CPU_cache_invalidate_entire_data(void)
   addr > 0;
   addr -= CPU_DATA_CACHE_ALIGNMENT
   ) {
-_CPU_cache_invalidate_1_data_line((uintptr_t) addr);
+_OR1K_mtspr(CPU_OR1K_SPR_DCBIR, (uintptr_t) addr);
   }
+
+  _ISR_Local_enable (level);
 }
 
 void _CPU_cache_invalidate_entire_instruction(void)
 {
-  int addr;
+  size_t addr;
+  ISR_Level level;
+
+  _ISR_Local_disable (level);
 
   /* We have only 0 level cache so we do not need to invalidate others */
   for (
@@ -258,7 +238,7 @@ void _CPU_cache_invalidate_entire_instruction(void)
   addr > 0;
   addr -= CPU_INSTRUCTION_CACHE_ALIGNMENT
   ) {
-_CPU_cache_invalidate_1_instruction_line((uintptr_t) addr);
+_OR1K_mtspr(CPU_OR1K_SPR_ICBIR, (uintptr_t) addr);
   }
 
   /* Flush instructions out of instruction buffer */
@@ -267,6 +247,99 @@ void _CPU_cache_invalidate_entire_instruction(void)
   __asm__ volatile("l.nop");
   __asm__ volatile("l.nop");
   

[PATCH 5/5] or1k: Avoid multiple iterations over cache

2016-11-25 Thread Martin Erik Werner
Previously, if the cache range operations were called with a range that
was larger than the cache size, this would lead to multiple iterations
over the cache, which is unnecessary.

Limit this so that if the range is larger than the cache size, the
operations will only iterate over the whole cache once.
---
 c/src/lib/libcpu/or1k/shared/cache/cache.c | 27 +++
 1 file changed, 27 insertions(+)

diff --git a/c/src/lib/libcpu/or1k/shared/cache/cache.c 
b/c/src/lib/libcpu/or1k/shared/cache/cache.c
index 6c1f9d9..47bc8f8 100644
--- a/c/src/lib/libcpu/or1k/shared/cache/cache.c
+++ b/c/src/lib/libcpu/or1k/shared/cache/cache.c
@@ -224,6 +224,15 @@ void _CPU_cache_flush_data_range(const void *d_addr, 
size_t n_bytes)
   final_address = (void *)((size_t)d_addr + n_bytes - 1);
   d_addr = (void *)((size_t)d_addr & ~(CPU_DATA_CACHE_ALIGNMENT - 1));
 
+  if( final_address - d_addr > _CPU_cache_get_data_cache_size(0) ) {
+/*
+ * Avoid iterating over the whole cache multiple times if the range is
+ * larger than the cache size.
+ */
+_CPU_cache_flush_entire_data();
+return;
+  }
+
   _ISR_Local_disable (level);
 
   while( d_addr <= final_address )  {
@@ -252,6 +261,15 @@ void _CPU_cache_invalidate_data_range(const void *d_addr, 
size_t n_bytes)
   final_address = (void *)((size_t)d_addr + n_bytes - 1);
   d_addr = (void *)((size_t)d_addr & ~(CPU_DATA_CACHE_ALIGNMENT - 1));
 
+  if( final_address - d_addr > _CPU_cache_get_data_cache_size(0) ) {
+/*
+ * Avoid iterating over the whole cache multiple times if the range is
+ * larger than the cache size.
+ */
+_CPU_cache_invalidate_entire_data();
+return;
+  }
+
   _ISR_Local_disable (level);
 
   while( d_addr <= final_address )  {
@@ -280,6 +298,15 @@ void _CPU_cache_invalidate_instruction_range(const void 
*i_addr, size_t n_bytes)
   final_address = (void *)((size_t)i_addr + n_bytes - 1);
   i_addr = (void *)((size_t)i_addr & ~(CPU_INSTRUCTION_CACHE_ALIGNMENT - 1));
 
+  if( final_address - i_addr > _CPU_cache_get_data_cache_size(0) ) {
+/*
+ * Avoid iterating over the whole cache multiple times if the range is
+ * larger than the cache size.
+ */
+_CPU_cache_invalidate_entire_instruction();
+return;
+  }
+
   _ISR_Local_disable (level);
 
   while( i_addr <= final_address )  {
-- 
2.1.4

___
devel mailing list
devel@rtems.org
http://lists.rtems.org/mailman/listinfo/devel


[PATCH 4/5] or1k: Remove secondary functions in cache manager

2016-11-25 Thread Martin Erik Werner
Move the code of the _CPU_OR1K_Cache_{enable,disable}_* functions into the
equivalent exported _CPU_cache_{enable,disable}_* functions instead, and
then delete them, in order to reduce the code indirection and aid
readability.

This does not touch the currently unused prefetch, writeback, and lock
functions.
---
 c/src/lib/libcpu/or1k/shared/cache/cache.c | 90 +++---
 1 file changed, 34 insertions(+), 56 deletions(-)

diff --git a/c/src/lib/libcpu/or1k/shared/cache/cache.c 
b/c/src/lib/libcpu/or1k/shared/cache/cache.c
index e1b2b1d..6c1f9d9 100644
--- a/c/src/lib/libcpu/or1k/shared/cache/cache.c
+++ b/c/src/lib/libcpu/or1k/shared/cache/cache.c
@@ -21,58 +21,6 @@
 #include 
 #include 
 
-static inline void _CPU_OR1K_Cache_enable_data(void)
-{
-  uint32_t sr;
-  ISR_Level level;
-
-  _ISR_Local_disable (level);
-
-  sr = _OR1K_mfspr(CPU_OR1K_SPR_SR);
-  _OR1K_mtspr(CPU_OR1K_SPR_SR, sr | CPU_OR1K_SPR_SR_DCE);
-
-  _ISR_Local_enable(level);
-}
-
-static inline void _CPU_OR1K_Cache_disable_data(void)
-{
-  uint32_t sr;
-  ISR_Level level;
-
-  _ISR_Local_disable (level);
-
-  sr = _OR1K_mfspr(CPU_OR1K_SPR_SR);
-  _OR1K_mtspr(CPU_OR1K_SPR_SR, (sr & ~CPU_OR1K_SPR_SR_DCE));
-
-  _ISR_Local_enable(level);
-}
-
-static inline void _CPU_OR1K_Cache_enable_instruction(void)
-{
-  uint32_t sr;
-  ISR_Level level;
-
-  _ISR_Local_disable (level);
-
-  sr = _OR1K_mfspr(CPU_OR1K_SPR_SR);
-  _OR1K_mtspr(CPU_OR1K_SPR_SR, sr | CPU_OR1K_SPR_SR_ICE);
-
-  _ISR_Local_enable(level);
-}
-
-static inline void _CPU_OR1K_Cache_disable_instruction(void)
-{
-  uint32_t sr;
-  ISR_Level level;
-
-  _ISR_Local_disable (level);
-
-  sr = _OR1K_mfspr(CPU_OR1K_SPR_SR);
-  _OR1K_mtspr(CPU_OR1K_SPR_SR, (sr & ~CPU_OR1K_SPR_SR_ICE));
-
-  _ISR_Local_enable(level);
-}
-
 static inline void _CPU_OR1K_Cache_data_block_prefetch(const void *d_addr)
 {
   ISR_Level level;
@@ -344,22 +292,52 @@ void _CPU_cache_invalidate_instruction_range(const void 
*i_addr, size_t n_bytes)
 
 void _CPU_cache_enable_data(void)
 {
-  _CPU_OR1K_Cache_enable_data();
+  uint32_t sr;
+  ISR_Level level;
+
+  _ISR_Local_disable (level);
+
+  sr = _OR1K_mfspr(CPU_OR1K_SPR_SR);
+  _OR1K_mtspr(CPU_OR1K_SPR_SR, sr | CPU_OR1K_SPR_SR_DCE);
+
+  _ISR_Local_enable(level);
 }
 
 void _CPU_cache_disable_data(void)
 {
-  _CPU_OR1K_Cache_disable_data();
+  uint32_t sr;
+  ISR_Level level;
 
+  _ISR_Local_disable (level);
+
+  sr = _OR1K_mfspr(CPU_OR1K_SPR_SR);
+  _OR1K_mtspr(CPU_OR1K_SPR_SR, (sr & ~CPU_OR1K_SPR_SR_DCE));
+
+  _ISR_Local_enable(level);
 }
 
 void _CPU_cache_enable_instruction(void)
 {
+  uint32_t sr;
+  ISR_Level level;
+
+  _ISR_Local_disable (level);
+
+  sr = _OR1K_mfspr(CPU_OR1K_SPR_SR);
+  _OR1K_mtspr(CPU_OR1K_SPR_SR, sr | CPU_OR1K_SPR_SR_ICE);
 
-  _CPU_OR1K_Cache_enable_instruction();
+  _ISR_Local_enable(level);
 }
 
 void _CPU_cache_disable_instruction(void)
 {
-  _CPU_OR1K_Cache_disable_instruction();
+  uint32_t sr;
+  ISR_Level level;
+
+  _ISR_Local_disable (level);
+
+  sr = _OR1K_mfspr(CPU_OR1K_SPR_SR);
+  _OR1K_mtspr(CPU_OR1K_SPR_SR, (sr & ~CPU_OR1K_SPR_SR_ICE));
+
+  _ISR_Local_enable(level);
 }
-- 
2.1.4

___
devel mailing list
devel@rtems.org
http://lists.rtems.org/mailman/listinfo/devel


Re: [PATCH] rtems/gdb: Fix powerpc builds on FreeBSD.

2016-11-25 Thread Joel Sherrill
This has had great support from the gdb developers.

Did any of the other targets show an issue?

I think this got applied to the 7.12 branch and master, right?

--joel

On Fri, Nov 25, 2016 at 2:58 AM, Chris Johns  wrote:

> This patch add a GDB patch to the gdb-7.12 build so the PowerPC
> builds on FreeBSD.
>
>  https://sourceware.org/bugzilla/show_bug.cgi?id=20863
> ---
>  rtems/config/tools/rtems-gdb-7.12-1.cfg | 5 +
>  1 file changed, 5 insertions(+)
>
> diff --git a/rtems/config/tools/rtems-gdb-7.12-1.cfg
> b/rtems/config/tools/rtems-gdb-7.12-1.cfg
> index 215b954..aac4dd6 100644
> --- a/rtems/config/tools/rtems-gdb-7.12-1.cfg
> +++ b/rtems/config/tools/rtems-gdb-7.12-1.cfg
> @@ -24,6 +24,11 @@
>  %endif
>
>  #
> +# Simulator error fix.
> +#
> +%patch add gdb --rsb-file=PATCH_Define_an_error_function_in_the_PPC_simulator
> -p1 https://sourceware.org/cgi-bin/get-raw-msg?listname=gdb-
> patches=2016-11=20161124152917.52189-1-jhb%40FreeBSD.org
> +
> +#
>  # The gdb build instructions. We use 7.xx Release 1.
>  #
>  %include %{_configdir}/gdb-7-1.cfg
> --
> 2.9.0
>
> ___
> devel mailing list
> devel@rtems.org
> http://lists.rtems.org/mailman/listinfo/devel
>
___
devel mailing list
devel@rtems.org
http://lists.rtems.org/mailman/listinfo/devel

[PATCH] rtems/gdb: Fix powerpc builds on FreeBSD.

2016-11-25 Thread Chris Johns
This patch add a GDB patch to the gdb-7.12 build so the PowerPC
builds on FreeBSD.

 https://sourceware.org/bugzilla/show_bug.cgi?id=20863
---
 rtems/config/tools/rtems-gdb-7.12-1.cfg | 5 +
 1 file changed, 5 insertions(+)

diff --git a/rtems/config/tools/rtems-gdb-7.12-1.cfg 
b/rtems/config/tools/rtems-gdb-7.12-1.cfg
index 215b954..aac4dd6 100644
--- a/rtems/config/tools/rtems-gdb-7.12-1.cfg
+++ b/rtems/config/tools/rtems-gdb-7.12-1.cfg
@@ -24,6 +24,11 @@
 %endif
 
 #
+# Simulator error fix.
+#
+%patch add gdb --rsb-file=PATCH_Define_an_error_function_in_the_PPC_simulator 
-p1 
https://sourceware.org/cgi-bin/get-raw-msg?listname=gdb-patches=2016-11=20161124152917.52189-1-jhb%40FreeBSD.org
+
+#
 # The gdb build instructions. We use 7.xx Release 1.
 #
 %include %{_configdir}/gdb-7-1.cfg
-- 
2.9.0

___
devel mailing list
devel@rtems.org
http://lists.rtems.org/mailman/listinfo/devel