From: asterix Date: Mon, 17 Mar 2008 16:01:10 +0000 (+0000) Subject: Define memory barrier for arm core, and use it. X-Git-Tag: 1.0.0~58 X-Git-Url: https://codewiz.org/gitweb?a=commitdiff_plain;ds=sidebyside;h=09f84dd1e880b343be5225b4f87867eb823fe818;p=bertos.git Define memory barrier for arm core, and use it. git-svn-id: https://src.develer.com/svnoss/bertos/trunk@1194 38d2e660-2303-0410-9eaa-f027e97ec537 --- diff --git a/cpu/attr.h b/cpu/attr.h index 302b38c9..5082a2f5 100644 --- a/cpu/attr.h +++ b/cpu/attr.h @@ -45,6 +45,7 @@ #include /* for uintXX_t */ #include /* ARCH_EMUL */ +#include "appconfig.h" // CONFIG_FAST_MEM /** * \name Macros for determining CPU endianness. @@ -103,13 +104,19 @@ #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__) @@ -134,6 +141,34 @@ */ #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 diff --git a/kern/proc.c b/kern/proc.c index 38cbc4de..5290c2c5 100644 --- a/kern/proc.c +++ b/kern/proc.c @@ -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);