Define memory barrier for arm core, and use it.
authorasterix <asterix@38d2e660-2303-0410-9eaa-f027e97ec537>
Mon, 17 Mar 2008 16:01:10 +0000 (16:01 +0000)
committerasterix <asterix@38d2e660-2303-0410-9eaa-f027e97ec537>
Mon, 17 Mar 2008 16:01:10 +0000 (16:01 +0000)
git-svn-id: https://src.develer.com/svnoss/bertos/trunk@1194 38d2e660-2303-0410-9eaa-f027e97ec537

cpu/attr.h
kern/proc.c

index 302b38c987089043a0ac7b2f8deabb6342b4f4bd..5082a2f536056af85c8f0a710d923dde1c5fdcb5 100644 (file)
@@ -45,6 +45,7 @@
 #include <cfg/compiler.h> /* for uintXX_t */
 #include <cfg/arch_config.h>  /* ARCH_EMUL */
 
+#include "appconfig.h" // CONFIG_FAST_MEM
 
 /**
  * \name Macros for determining CPU endianness.
        #define CPU_STACK_GROWS_UPWARD 0
        #define CPU_SP_ON_EMPTY_SLOT   0
        #define CPU_HARVARD            0
+       /*
+        * Force compiler to realod context variable.
+        */
+       #define CPU_MEMORY_BARRIER     asm volatile ("" : : : "memory")
 
        #ifdef __IAR_SYSTEMS_ICC__
                #warning Check CPU_BYTE_ORDER
                #define CPU_BYTE_ORDER (__BIG_ENDIAN__ ? CPU_BIG_ENDIAN : CPU_LITTLE_ENDIAN)
 
                #define NOP            __no_operation()
-       #else /* !__IAR_SYSTEMS_ICC__ */
+
+       #else /* GCC and compatibles */
+
                #if defined(__ARMEB__)
                        #define CPU_BYTE_ORDER CPU_BIG_ENDIAN
                #elif defined(__ARMEL__)
                 */
                #define CPU_REG_INIT_VALUE(reg) (reg == (CPU_SAVED_REGS_CNT - 1) ? 0x13 : 0)
 
+               #if CONFIG_FAST_MEM
+                       /**
+                        * Function attribute for use with performance critical code.
+                        *
+                        * On the AT91 family, code residing in flash has wait states.
+                        * Moving functions to the data section is a quick & dirty way
+                        * to get them transparently copied to SRAM for zero-wait-state
+                        * operation.
+                        */
+                       #define FAST_FUNC __attribute__((section(".data")))
+
+                       /**
+                        * Data attribute to move constant data to fast memory storage.
+                        *
+                        * \see FAST_FUNC
+                        */
+                       #define FAST_RODATA __attribute__((section(".data")))
+
+               #else // !CONFIG_FAST_MEM
+                       #define FAST_RODATA /**/
+                       #define FAST_FUNC /**/
+               #endif
+
+               /**
+                * Function attribute to declare an interrupt service routine.
+                */
+               #define ISR_FUNC __attribute__((interrupt))
+
        #endif /* !__IAR_SYSTEMS_ICC_ */
 
 #elif CPU_PPC
index 38cbc4decfb285fe1ec81831472cc1718fbb2c32..5290c2c5129d6095cf2d9a0aca2a9ce192123b1c 100644 (file)
@@ -175,7 +175,7 @@ struct Process *proc_new_with_name(UNUSED(const char *, name), void (*entry)(voi
 
 #if CONFIG_KERN_MONITOR
        /* Fill-in the stack with a special marker to help debugging */
-       memset(stack_base, (char)CONFIG_KERN_STACKFILLCODE, stacksize);
+       memset(stack_base, CONFIG_KERN_STACKFILLCODE, stacksize / sizeof(cpustack_t));
 #endif
 
        /* Initialize the process control block */
@@ -264,12 +264,18 @@ void proc_schedule(void)
                 * are idle-spinning, we must allow interrupts, otherwise no
                 * process will ever wake up.
                 *
+                * During idle-spinning, can occur an interrupt, it may be able to
+                * modify \p ProcReadyList. To ensure that compiler reload this
+                * variable every while cycle we call CPU_MEMORY_BARRIER.
+                * The memory barrier ensure that all variables used in this context
+                * are reloaded.
                 * \todo If there was a way to write sig_wait() so that it does not
                 * disable interrupts while waiting, there would not be any
                 * reason to do this.
                 */
                IRQ_ENABLE;
                CPU_IDLE;
+               CPU_MEMORY_BARRIER;
                IRQ_DISABLE;
        }
        IRQ_RESTORE(flags);