Consolidate inline assembler code in a set of header files
In order to have a better compiler support consolidate
inline assembler code in a set of header files.
If another compiler is used, that supports a different
inline assembler format, asm_inline_<compiler name>.h
heder files have to be provided.
Change-Id: Iecc7d96419efd767a8463933badd4db4a557de5b
Signed-off-by: Dmitriy Korovkin <dmitriy.korovkin@windriver.com>
diff --git a/arch/arm/include/CortexM/asm_inline_gcc.h b/arch/arm/include/CortexM/asm_inline_gcc.h
new file mode 100644
index 0000000..df6bfeb
--- /dev/null
+++ b/arch/arm/include/CortexM/asm_inline_gcc.h
@@ -0,0 +1,80 @@
+/* ARM CortexM GCC specific inline assembler functions and macros */
+
+/*
+ * Copyright (c) 2015, Wind River Systems, Inc.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *
+ * 1) Redistributions of source code must retain the above copyright notice,
+ * this list of conditions and the following disclaimer.
+ *
+ * 2) Redistributions in binary form must reproduce the above copyright notice,
+ * this list of conditions and the following disclaimer in the documentation
+ * and/or other materials provided with the distribution.
+ *
+ * 3) Neither the name of Wind River Systems nor the names of its contributors
+ * may be used to endorse or promote products derived from this software without
+ * specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#ifndef _ASM_INLINE_GCC_H
+#define _ASM_INLINE_GCC_H
+
+/*
+ * The file must not be included directly
+ * Include asm_inline.h instead
+ */
+
+#ifndef _ASMLANGUAGE
+
+/*******************************************************************************
+*
+* _IpsrGet - obtain value of IPSR register
+*
+* Obtain and return current value of IPSR register.
+*
+* RETURNS: the contents of the IPSR register
+*
+* \NOMANUAL
+*/
+
+static ALWAYS_INLINE uint32_t _IpsrGet(void)
+{
+ uint32_t vector;
+
+ __asm__ volatile("mrs %0, IPSR\n\t" : "=r"(vector));
+ return vector;
+}
+
+/*******************************************************************************
+*
+* _MspSet - set the value of the Main Stack Pointer register
+*
+* Store the value of <msp> in MSP register.
+*
+* RETURNS: N/A
+*
+* \NOMANUAL
+*/
+
+static ALWAYS_INLINE void _MspSet(uint32_t msp /* value to store in MSP */
+ )
+{
+ __asm__ volatile("msr MSP, %0\n\t" : : "r"(msp));
+}
+
+#endif /* _ASMLANGUAGE */
+#endif /* _ASM_INLINE_GCC_H */
diff --git a/arch/arm/include/CortexM/exc.h b/arch/arm/include/CortexM/exc.h
index eb81f02..5c31310 100644
--- a/arch/arm/include/CortexM/exc.h
+++ b/arch/arm/include/CortexM/exc.h
@@ -39,6 +39,7 @@
#define _ARM_CORTEXM_ISR__H_
#include <nanokernel/cpu.h>
+#include <asm_inline.h>
#ifdef _ASMLANGUAGE
@@ -48,32 +49,6 @@
/*******************************************************************************
*
-* _IpsrGet - obtain value of IPSR register
-*
-* Obtain and return current value of IPSR register.
-*
-* RETURNS: the contents of the IPSR register
-*
-* \NOMANUAL
-*/
-
-#if defined(__GNUC__)
-static ALWAYS_INLINE uint32_t _IpsrGet(void)
-{
- uint32_t vector;
-
- __asm__ volatile("mrs %0, IPSR\n\t" : "=r"(vector));
- return vector;
-}
-#elif defined(__DCC__)
-__asm volatile uint32_t _IpsrGet(void)
-{
- % !"r0" mrs r0, IPSR
-}
-#endif
-
-/*******************************************************************************
-*
* _IsInIsr - find out if running in an ISR context
*
* The current executing vector is found in the IPSR register. We consider the
diff --git a/arch/arm/include/CortexM/stack.h b/arch/arm/include/CortexM/stack.h
index 2511f59..75c8563 100644
--- a/arch/arm/include/CortexM/stack.h
+++ b/arch/arm/include/CortexM/stack.h
@@ -39,6 +39,7 @@
#define _ARM_CORTEXM_STACK__H_
#include <nanok.h>
+#include <asm_inline.h>
#ifdef CONFIG_STACK_GROWS_DOWN
#define STACK_DIR STACK_GROWS_DOWN
@@ -69,30 +70,6 @@
/*******************************************************************************
*
-* _MspSet - set the value of the Main Stack Pointer register
-*
-* Store the value of <msp> in MSP register.
-*
-* RETURNS: N/A
-*
-* \NOMANUAL
-*/
-
-#if defined(__GNUC__)
-static ALWAYS_INLINE void _MspSet(uint32_t msp /* value to store in MSP */
- )
-{
- __asm__ volatile("msr MSP, %0\n\t" : : "r"(msp));
-}
-#elif defined(__DCC__)
-__asm volatile void _MspSet(uint32_t msp)
-{
- % reg msp !"r0" msr MSP, msp
-}
-#endif
-
-/*******************************************************************************
-*
* _InterruptStackSetup - setup interrupt stack
*
* On Cortex-M, the interrupt stack is registered in the MSP (main stack
diff --git a/arch/arm/include/asm_inline.h b/arch/arm/include/asm_inline.h
new file mode 100644
index 0000000..dcb6578
--- /dev/null
+++ b/arch/arm/include/asm_inline.h
@@ -0,0 +1,46 @@
+/* Inline assembler kernel functions and macros */
+
+/*
+ * Copyright (c) 2015, Wind River Systems, Inc.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *
+ * 1) Redistributions of source code must retain the above copyright notice,
+ * this list of conditions and the following disclaimer.
+ *
+ * 2) Redistributions in binary form must reproduce the above copyright notice,
+ * this list of conditions and the following disclaimer in the documentation
+ * and/or other materials provided with the distribution.
+ *
+ * 3) Neither the name of Wind River Systems nor the names of its contributors
+ * may be used to endorse or promote products derived from this software without
+ * specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#ifndef _ASM_INLINE_H
+#define _ASM_INLINE_H
+
+#if !defined(VXMICRO_ARCH_arm) || !defined(CONFIG_CPU_CORTEXM)
+#error arch/arm/include/asm_inline.h is for ARM CortexM only
+#endif
+
+#if defined(__GNUC__)
+#include <CortexM/asm_inline_gcc.h>
+#else
+#include <CortexM/asm_inline_other.h>
+#endif /* __GNUC__ */
+
+#endif /* _ASM_INLINE_H */
diff --git a/arch/x86/bsp/rand32.c b/arch/x86/bsp/rand32.c
index 2ef619c..1b9ee1c 100644
--- a/arch/x86/bsp/rand32.c
+++ b/arch/x86/bsp/rand32.c
@@ -38,6 +38,8 @@
(yet) provide a random number generator.
*/
+#include <nanokernel.h>
+#include <nanokernel/cpu.h>
#include <drivers/rand32.h>
#if defined(CONFIG_TEST_RANDOM_GENERATOR)
@@ -65,20 +67,9 @@
* RETURNS: a 32-bit number
*/
-#if defined(__GNUC__)
uint32_t _Rand32Get(void)
{
- uint32_t rv;
-
- __asm__ volatile("rdtsc" : "=a"(rv) : : "%edx");
-
- return rv;
+ return _do_read_cpu_timestamp32();
}
-#elif defined(__DCC__)
-__asm volatile uint32_t _Rand32Get(void)
-{
- % !"ax", "dx" rdtsc
-}
-#endif /* __GNUCC__/__DCC__ */
#endif /* CONFIG_TEST_RANDOM_GENERATOR */
diff --git a/arch/x86/core/excstub.s b/arch/x86/core/excstub.s
index 2fa2606..e839537 100644
--- a/arch/x86/core/excstub.s
+++ b/arch/x86/core/excstub.s
@@ -309,14 +309,6 @@
#ifdef CONFIG_AUTOMATIC_FP_ENABLING
-#if defined(__GNUC__)
-NANO_CPU_EXC_CONNECT_NO_ERR(_FpNotAvailableExcHandler,IV_DEVICE_NOT_AVAILABLE,0)
-#elif defined(__DCC__)
- NANO_CPU_INT_REGISTER_ASM(_FpNotAvailableExcHandler,IV_DEVICE_NOT_AVAILABLE,0)
- GTEXT(MK_STUB_NAME(_FpNotAvailableExcHandler))
- SECTION_FUNC(TEXT, MK_STUB_NAME(_FpNotAvailableExcHandler))
- NANO_CPU_EXC_CONNECT_NO_ERR_CODE(_FpNotAvailableExcHandler)
-#endif
-
+SYS_NANO_CPU_EXC_CONNECT(_FpNotAvailableExcHandler,IV_DEVICE_NOT_AVAILABLE)
#endif /* CONFIG_AUTOMATIC_FP_ENABLING */
diff --git a/arch/x86/core/nanofloat.c b/arch/x86/core/nanofloat.c
index b6096da..bf37c4c 100644
--- a/arch/x86/core/nanofloat.c
+++ b/arch/x86/core/nanofloat.c
@@ -102,6 +102,7 @@
#include <nanok.h>
#include <toolchain.h>
+#include <asm_inline.h>
/* the entire library vanishes without the FP_SHARING option enabled */
@@ -111,40 +112,6 @@
extern uint32_t _Mxcsr; /* SSE control/status register default value */
#endif /* CONFIG_SSE */
-#ifdef CONFIG_AUTOMATIC_FP_ENABLING
-
-/*******************************************************************************
-*
-* _FpAccessDisable - disallow use of floating point capabilities
-*
-* This routine sets CR0[TS] to 1, which disallows the use of FP instructions
-* by the currently executing context.
-*
-* RETURNS: N/A
-*/
-
-#if defined(__GNUC__)
-static void _FpAccessDisable(void)
-{
- void *tempReg;
-
- __asm__ volatile(
- "movl %%cr0, %0;\n\t"
- "orl $0x8, %0;\n\t"
- "movl %0, %%cr0;\n\t"
- : "=r"(tempReg)
- :
- : "memory");
-}
-#elif defined(__DCC__)
-__asm volatile void _FpAccessDisable(void)
-{
- % !"ax" movl % cr0, % eax orl $0x8, % eax movl % eax, % cr0
-}
-#endif /* __GNUC__ */
-
-#endif /* CONFIG_AUTOMATIC_FP_ENABLING */
-
/*******************************************************************************
*
* _FpCtxSave - save non-integer context information
@@ -156,39 +123,10 @@
* RETURNS: N/A
*/
-#if defined(__GNUC__)
static void _FpCtxSave(tCCS *ccs)
{
-#ifdef CONFIG_SSE
- if (ccs->flags & USE_SSE) {
- __asm__ volatile("fxsave (%0);\n\t"
- :
- : "r"(&ccs->preempFloatReg)
- : "memory");
- } else
-#endif /* CONFIG_SSE */
- {
- __asm__ volatile("fnsave (%0);\n\t"
- :
- : "r"(&ccs->preempFloatReg)
- : "memory");
- }
+ _do_fp_ctx_save(ccs->flags & USE_SSE, &ccs->preempFloatReg);
}
-#elif defined(__DCC__)
-__asm volatile void _FpCtxSave(tCCS *ccs)
-{
- % mem ccs !"ax", "cx" movl ccs,
- % eax leal __tCCS_preempFloatReg_OFFSET(% eax),
- % ecx /* &preempFloatReg */
-#ifdef CONFIG_SSE
- testl $0x20,
- __tCCS_flags_OFFSET(% eax) jz 0f fxsave(% ecx) jmp 1f 0
- : fnsave(% ecx)1 :
-#else
- fnsave(% ecx)
-#endif /* CONFIG_SSE */
-}
-#endif
/*******************************************************************************
*
@@ -199,43 +137,10 @@
* RETURNS: N/A
*/
-#if defined(__GNUC__)
static inline void _FpCtxInit(tCCS *ccs)
{
- /* initialize x87 FPU */
- __asm__ volatile("fninit\n\t");
-
-
-#ifdef CONFIG_SSE
- if (ccs->flags & USE_SSE) {
- /* initialize SSE (since context uses it) */
- __asm__ volatile("ldmxcsr _Mxcsr\n\t");
-
- }
-#else
- ARG_UNUSED(ccs);
-#endif /* CONFIG_SSE */
+ _do_fp_ctx_init(ccs->flags & USE_SSE);
}
-#elif defined(__DCC__)
-__asm volatile void _FpCtxInit(tCCS *ccs)
-{
- % mem ccs !"ax"
- /* initialize x87 FPU */
- fninit
-
-
-#ifdef CONFIG_SSE
- movl ccs,
- % eax testl $0x20,
- __tCCS_flags_OFFSET(% eax) jz 0f
-
- /* initialize SSE (since context uses it) */
- ldmxcsr _Mxcsr
-
-0 :
-#endif /* CONFIG_SSE */
-}
-#endif
/*******************************************************************************
*
diff --git a/arch/x86/generic_pc/board.h b/arch/x86/generic_pc/board.h
index eafe2db..84ba7cb 100644
--- a/arch/x86/generic_pc/board.h
+++ b/arch/x86/generic_pc/board.h
@@ -168,61 +168,11 @@
* expected to provide implementations of these macros.
*/
-#define PLB_BYTE_REG_WRITE(data, address) outByte(data, (unsigned int)address)
-#define PLB_BYTE_REG_READ(address) inByte((unsigned int)address)
+#define PLB_BYTE_REG_WRITE(data, address) sys_out8(data, (unsigned int)address)
+#define PLB_BYTE_REG_READ(address) sys_in8((unsigned int)address)
-/*******************************************************************************
-*
-* outByte - output a byte to an IA-32 I/O port
-*
-* This function issues the 'out' instruction to write a byte to the specified
-* I/O port.
-*
-* RETURNS: N/A
-*
-* NOMANUAL
-*/
-
-#if defined(__DCC__)
-__asm volatile void outByte(unsigned char data, unsigned int port)
-{
- % mem data, port;
- !"ax", "dx" movl port, % edx movb data, % al outb % al, % dx
-}
-#elif defined(__GNUC__)
-static inline void outByte(unsigned char data, unsigned int port)
-{
- __asm__ volatile("outb %%al, %%dx;\n\t" : : "a"(data), "d"(port));
-}
-#endif
-
-/*******************************************************************************
-*
-* inByte - input a byte from an IA-32 I/O port
-*
-* This function issues the 'in' instruction to read a byte from the specified
-* I/O port.
-*
-* RETURNS: the byte read from the specified I/O port
-*
-* NOMANUAL
-*/
-
-#if defined(__DCC__)
-__asm volatile unsigned char inByte(unsigned int port)
-{
- % mem port;
- !"ax", "dx" movl port, % edx inb % dx, % al
-}
-#elif defined(__GNUC__)
-static inline unsigned char inByte(unsigned int port)
-{
- char retByte;
-
- __asm__ volatile("inb %%dx, %%al;\n\t" : "=a"(retByte) : "d"(port));
- return retByte;
-}
-#endif
+#define outByte(data, address) sys_out8(data, (unsigned int)address)
+#define inByte(address) sys_in8((unsigned int)address)
/*
* Device drivers utilize the macros PLB_WORD_REG_WRITE() and
@@ -231,61 +181,9 @@
* expected to provide implementations of these macros.
*/
-#define PLB_WORD_REG_WRITE(data, address) outWord(data, (unsigned int)address)
-#define PLB_WORD_REG_READ(address) inWord((unsigned int)address)
+#define PLB_WORD_REG_WRITE(data, address) sys_out16(data, (unsigned int)address)
+#define PLB_WORD_REG_READ(address) sys_in16((unsigned int)address)
-/*******************************************************************************
-*
-* outWord - output a word to an IA-32 I/O port
-*
-* This function issues the 'out' instruction to write a word to the
-* specified I/O port.
-*
-* RETURNS: N/A
-*
-* NOMANUAL
-*/
-
-#if defined(__DCC__)
-__asm volatile void outWord(unsigned short data, unsigned int port)
-{
- % mem data, port;
- !"ax", "dx" movl port, % edx movw data, % ax outw % ax, % dx
-}
-#elif defined(__GNUC__)
-static inline void outWord(unsigned short data, unsigned int port)
-{
- __asm__ volatile("outw %%ax, %%dx;\n\t" : : "a"(data), "d"(port));
-}
-#endif
-
-/*******************************************************************************
-*
-* inWord - input a word from an IA-32 I/O port
-*
-* This function issues the 'in' instruction to read a word from the
-* specified I/O port.
-*
-* RETURNS: the word read from the specified I/O port
-*
-* NOMANUAL
-*/
-
-#if defined(__DCC__)
-__asm volatile unsigned short inWord(unsigned int port)
-{
- % mem port;
- !"ax", "dx" movl port, % edx inw % dx, % ax
-}
-#elif defined(__GNUC__)
-static inline unsigned short inWord(unsigned int port)
-{
- unsigned short retWord;
-
- __asm__ volatile("inw %%dx, %%ax;\n\t" : "=a"(retWord) : "d"(port));
- return retWord;
-}
-#endif
/*
* Device drivers utilize the macros PLB_LONG_REG_WRITE() and
@@ -294,61 +192,8 @@
* expected to provide implementations of these macros.
*/
-#define PLB_LONG_REG_WRITE(data, address) outLong(data, (unsigned int)address)
-#define PLB_LONG_REG_READ(address) inLong((unsigned int)address)
-
-/*******************************************************************************
-*
-* outLong - output a long word to an IA-32 I/O port
-*
-* This function issues the 'out' instruction to write a long word to the
-* specified I/O port.
-*
-* RETURNS: N/A
-*
-* NOMANUAL
-*/
-
-#if defined(__DCC__)
-__asm volatile void outLong(unsigned int data, unsigned int port)
-{
- % mem data, port;
- !"ax", "dx" movl port, % edx movl data, % eax outl % eax, % dx
-}
-#elif defined(__GNUC__)
-static inline void outLong(unsigned int data, unsigned int port)
-{
- __asm__ volatile("outl %%eax, %%dx;\n\t" : : "a"(data), "d"(port));
-}
-#endif
-
-/*******************************************************************************
-*
-* inLong - input a long word from an IA-32 I/O port
-*
-* This function issues the 'in' instruction to read a long word from the
-* specified I/O port.
-*
-* RETURNS: the long read from the specified I/O port
-*
-* NOMANUAL
-*/
-
-#if defined(__DCC__)
-__asm volatile unsigned long inLong(unsigned int port)
-{
- % mem port;
- !"ax", "dx" movl port, % edx inl % dx, % eax
-}
-#elif defined(__GNUC__)
-static inline unsigned long inLong(unsigned int port)
-{
- unsigned long retLong;
-
- __asm__ volatile("inl %%dx, %%eax;\n\t" : "=a"(retLong) : "d"(port));
- return retLong;
-}
-#endif
+#define PLB_LONG_REG_WRITE(data, address) sys_out32(data, (unsigned int)address)
+#define PLB_LONG_REG_READ(address) sys_in32((unsigned int)address)
extern void _SysIntVecProgram(unsigned int vector, unsigned int);
#else /* _ASMLANGUAGE */
diff --git a/arch/x86/include/asm_inline.h b/arch/x86/include/asm_inline.h
new file mode 100644
index 0000000..dcbefa9
--- /dev/null
+++ b/arch/x86/include/asm_inline.h
@@ -0,0 +1,46 @@
+/* Inline assembler kernel functions and macros */
+
+/*
+ * Copyright (c) 2015, Wind River Systems, Inc.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *
+ * 1) Redistributions of source code must retain the above copyright notice,
+ * this list of conditions and the following disclaimer.
+ *
+ * 2) Redistributions in binary form must reproduce the above copyright notice,
+ * this list of conditions and the following disclaimer in the documentation
+ * and/or other materials provided with the distribution.
+ *
+ * 3) Neither the name of Wind River Systems nor the names of its contributors
+ * may be used to endorse or promote products derived from this software without
+ * specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#ifndef _ASM_INLINE_H
+#define _ASM_INLINE_H
+
+#if !defined(VXMICRO_ARCH_x86)
+#error The arch/x86/include/asm_inline.h is only for x86 architecture
+#endif
+
+#if defined(__GNUC__)
+#include <asm_inline_gcc.h>
+#else
+#include <asm_inline_other.h>
+#endif /* __GNUC__ */
+
+#endif /* _ASM_INLINE_H */
diff --git a/arch/x86/include/asm_inline_gcc.h b/arch/x86/include/asm_inline_gcc.h
new file mode 100644
index 0000000..dfdd279
--- /dev/null
+++ b/arch/x86/include/asm_inline_gcc.h
@@ -0,0 +1,159 @@
+/* Intel x86 GCC specific kernel inline assembler functions and macros */
+
+/*
+ * Copyright (c) 2015, Wind River Systems, Inc.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *
+ * 1) Redistributions of source code must retain the above copyright notice,
+ * this list of conditions and the following disclaimer.
+ *
+ * 2) Redistributions in binary form must reproduce the above copyright notice,
+ * this list of conditions and the following disclaimer in the documentation
+ * and/or other materials provided with the distribution.
+ *
+ * 3) Neither the name of Wind River Systems nor the names of its contributors
+ * may be used to endorse or promote products derived from this software without
+ * specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#ifndef _ASM_INLINE_GCC_H
+#define _ASM_INLINE_GCC_H
+
+/*
+ * The file must not be included directly
+ * Include asm_inline.h instead
+ */
+
+#ifdef _ASMLANGUAGE
+
+#define SYS_NANO_CPU_EXC_CONNECT(handler,vector) \
+NANO_CPU_EXC_CONNECT_NO_ERR(handler,vector,0)
+
+#else /* !_ASMLANGUAGE */
+
+/*******************************************************************************
+*
+* EflagsGet - return the current value of the EFLAGS register
+*
+* RETURNS: the EFLAGS register.
+*
+* \NOMANUAL
+*/
+
+static inline unsigned int EflagsGet(void)
+{
+ unsigned int eflags; /* EFLAGS register contents */
+
+ __asm__ volatile(
+ "pushfl;\n\t"
+ "popl %0;\n\t"
+ : "=r"(eflags)
+ : );
+
+ return eflags;
+}
+
+
+#ifdef CONFIG_FP_SHARING
+
+/*******************************************************************************
+*
+* _FpAccessDisable - disallow use of floating point capabilities
+*
+* This routine sets CR0[TS] to 1, which disallows the use of FP instructions
+* by the currently executing context.
+*
+* RETURNS: N/A
+*/
+
+static inline void _FpAccessDisable(void)
+{
+ void *tempReg;
+
+ __asm__ volatile(
+ "movl %%cr0, %0;\n\t"
+ "orl $0x8, %0;\n\t"
+ "movl %0, %%cr0;\n\t"
+ : "=r"(tempReg)
+ :
+ : "memory");
+}
+
+
+/*******************************************************************************
+*
+* _do_fp_ctx_save - save non-integer context information
+*
+* This routine saves the system's "live" non-integer context into the
+* specified area. If the specified task or fiber supports SSE then
+* x87/MMX/SSEx context info is saved, otherwise only x87/MMX context is saved.
+* Function is invoked by _FpCtxSave(tCCS *ccs)
+*
+* RETURNS: N/A
+*/
+
+static inline void _do_fp_ctx_save(int flags, void *preemp_float_reg)
+{
+#ifdef CONFIG_SSE
+ if (flags) {
+ __asm__ volatile("fxsave (%0);\n\t"
+ :
+ : "r"(preemp_float_reg)
+ : "memory");
+ } else
+#else
+ ARG_UNUSED(flags);
+#endif /* CONFIG_SSE */
+ {
+ __asm__ volatile("fnsave (%0);\n\t"
+ :
+ : "r"(preemp_float_reg)
+ : "memory");
+ }
+}
+
+/*******************************************************************************
+*
+* _do_fp_ctx_init - initialize non-integer context information
+*
+* This routine initializes the system's "live" non-integer context.
+* Function is invoked by _FpCtxInit(tCCS *ccs)
+*
+* RETURNS: N/A
+*/
+
+static inline void _do_fp_ctx_init(int flags)
+{
+ /* initialize x87 FPU */
+ __asm__ volatile("fninit\n\t");
+
+
+#ifdef CONFIG_SSE
+ if (flags) {
+ /* initialize SSE (since context uses it) */
+ __asm__ volatile("ldmxcsr _Mxcsr\n\t");
+
+ }
+#else
+ ARG_UNUSED(flags);
+#endif /* CONFIG_SSE */
+}
+
+#endif /* CONFIG_FP_SHARING */
+
+#endif /* _ASMLANGUAGE */
+#endif /* _ASM_INLINE_GCC_H */
diff --git a/arch/x86/include/nanok.h b/arch/x86/include/nanok.h
index 75248d0..d6bb81d 100644
--- a/arch/x86/include/nanok.h
+++ b/arch/x86/include/nanok.h
@@ -51,6 +51,7 @@
#include <toolchain.h>
#include <sections.h>
+#include <asm_inline.h>
#ifndef _ASMLANGUAGE
#include <nanokernel.h> /* public nanokernel API */
@@ -855,35 +856,6 @@
*(unsigned int *)(fiber->coopReg.esp) = value;
}
-/*******************************************************************************
-*
-* EflagsGet - return the current value of the EFLAGS register
-*
-* RETURNS: the EFLAGS register.
-*
-* \NOMANUAL
-*/
-
-#if defined(__GNUC__)
-static inline unsigned int EflagsGet(void)
-{
- unsigned int eflags; /* EFLAGS register contents */
-
- __asm__ volatile(
- "pushfl;\n\t"
- "popl %0;\n\t"
- : "=r"(eflags)
- : );
-
- return eflags;
-}
-#elif defined(__DCC__)
-__asm volatile unsigned int EflagsGet(void)
-{
- % !"ax" pushfl popl % eax
-}
-#endif
-
/* definitions to support nanoCpuExcConnect() */
#define _EXC_STUB_SIZE 0x14
diff --git a/arch/x86/quark/board.h b/arch/x86/quark/board.h
index 6654077..a7079d5 100644
--- a/arch/x86/quark/board.h
+++ b/arch/x86/quark/board.h
@@ -155,61 +155,8 @@
*/
#define PLB_BYTE_REG_WRITE(data, address) \
- io_outByte(data, (unsigned int)address)
-#define PLB_BYTE_REG_READ(address) io_inByte((unsigned int)address)
-
-/*******************************************************************************
-*
-* io_outByte - output a byte to an IA-32 I/O port
-*
-* This function issues the 'out' instruction to write a byte to the specified
-* I/O port.
-*
-* RETURNS: N/A
-*
-* NOMANUAL
-*/
-
-#if defined(__DCC__)
-__asm volatile void io_outByte(unsigned char data, unsigned int port)
-{
- % mem data, port;
- !"ax", "dx" movl port, % edx movb data, % al outb % al, % dx
-}
-#elif defined(__GNUC__)
-static inline void io_outByte(unsigned char data, unsigned int port)
-{
- __asm__ volatile("outb %%al, %%dx;\n\t" : : "a"(data), "d"(port));
-}
-#endif
-
-/*******************************************************************************
-*
-* io_inByte - input a byte from an IA-32 I/O port
-*
-* This function issues the 'in' instruction to read a byte from the specified
-* I/O port.
-*
-* RETURNS: the byte read from the specified I/O port
-*
-* NOMANUAL
-*/
-
-#if defined(__DCC__)
-__asm volatile unsigned char io_inByte(unsigned int port)
-{
- % mem port;
- !"ax", "dx" movl port, % edx inb % dx, % al
-}
-#elif defined(__GNUC__)
-static inline unsigned char io_inByte(unsigned int port)
-{
- char retByte;
-
- __asm__ volatile("inb %%dx, %%al;\n\t" : "=a"(retByte) : "d"(port));
- return retByte;
-}
-#endif
+ sys_out8(data, (unsigned int)address)
+#define PLB_BYTE_REG_READ(address) sys_in8((unsigned int)address)
/*******************************************************************************
*
@@ -250,61 +197,8 @@
*/
#define PLB_WORD_REG_WRITE(data, address) \
- io_outWord(data, (unsigned int)address)
-#define PLB_WORD_REG_READ(address) io_inWord((unsigned int)address)
-
-/*******************************************************************************
-*
-* io_outWord - output a word to an IA-32 I/O port
-*
-* This function issues the 'out' instruction to write a word to the
-* specified I/O port.
-*
-* RETURNS: N/A
-*
-* NOMANUAL
-*/
-
-#if defined(__DCC__)
-__asm volatile void io_outWord(unsigned short data, unsigned int port)
-{
- % mem data, port;
- !"ax", "dx" movl port, % edx movw data, % ax outw % ax, % dx
-}
-#elif defined(__GNUC__)
-static inline void io_outWord(unsigned short data, unsigned int port)
-{
- __asm__ volatile("outw %%ax, %%dx;\n\t" : : "a"(data), "d"(port));
-}
-#endif
-
-/*******************************************************************************
-*
-* io_inWord - input a word from an IA-32 I/O port
-*
-* This function issues the 'in' instruction to read a word from the
-* specified I/O port.
-*
-* RETURNS: the word read from the specified I/O port
-*
-* NOMANUAL
-*/
-
-#if defined(__DCC__)
-__asm volatile unsigned short io_inWord(unsigned int port)
-{
- % mem port;
- !"ax", "dx" movl port, % edx inw % dx, % ax
-}
-#elif defined(__GNUC__)
-static inline unsigned short io_inWord(unsigned int port)
-{
- unsigned short retWord;
-
- __asm__ volatile("inw %%dx, %%ax;\n\t" : "=a"(retWord) : "d"(port));
- return retWord;
-}
-#endif
+ sys_out16(data, (unsigned int)address)
+#define PLB_WORD_REG_READ(address) sys_in16((unsigned int)address)
/*******************************************************************************
*
@@ -345,61 +239,8 @@
*/
#define PLB_LONG_REG_WRITE(data, address) \
- io_outLong(data, (unsigned int)address)
-#define PLB_LONG_REG_READ(address) io_inLong((unsigned int)address)
-
-/*******************************************************************************
-*
-* io_outLong - output a long word to an IA-32 I/O port
-*
-* This function issues the 'out' instruction to write a long word to the
-* specified I/O port.
-*
-* RETURNS: N/A
-*
-* NOMANUAL
-*/
-
-#if defined(__DCC__)
-__asm volatile void io_outLong(unsigned int data, unsigned int port)
-{
- % mem data, port;
- !"ax", "dx" movl port, % edx movl data, % eax outl % eax, % dx
-}
-#elif defined(__GNUC__)
-static inline void io_outLong(unsigned int data, unsigned int port)
-{
- __asm__ volatile("outl %%eax, %%dx;\n\t" : : "a"(data), "d"(port));
-}
-#endif
-
-/*******************************************************************************
-*
-* io_inLong - input a long word from an IA-32 I/O port
-*
-* This function issues the 'in' instruction to read a long word from the
-* specified I/O port.
-*
-* RETURNS: the long read from the specified I/O port
-*
-* NOMANUAL
-*/
-
-#if defined(__DCC__)
-__asm volatile unsigned long io_inLong(unsigned int port)
-{
- % mem port;
- !"ax", "dx" movl port, % edx inl % dx, % eax
-}
-#elif defined(__GNUC__)
-static inline unsigned long io_inLong(unsigned int port)
-{
- unsigned long retLong;
-
- __asm__ volatile("inl %%dx, %%eax;\n\t" : "=a"(retLong) : "d"(port));
- return retLong;
-}
-#endif
+ sys_out32(data, (unsigned int)address)
+#define PLB_LONG_REG_READ(address) sys_in32((unsigned int)address)
/*******************************************************************************
*
diff --git a/drivers/timer/i8253.c b/drivers/timer/i8253.c
index 646d2fd..48046db 100644
--- a/drivers/timer/i8253.c
+++ b/drivers/timer/i8253.c
@@ -157,18 +157,6 @@
extern struct nano_stack _k_command_stack;
#endif /* ! CONFIG_MICROKERNEL */
-#ifdef __DCC__
-__asm volatile unsigned int intLock_inline(void)
-{
- % !"ax" pushfl cli popl % eax
-}
-
-__asm volatile void intUnlock_inline(unsigned int key)
-{
- % mem key !testl $0x200, key jz 1f sti 1 :
-}
-#endif
-
/*******************************************************************************
*
* _i8253CounterRead - read the i8253 counter register's value
@@ -575,17 +563,7 @@
* Expending irq_lock_inline() code since directly calling it would
* would end up in infinite recursion.
*/
-#if defined(__GNUC__)
- __asm__ volatile(
- "pushfl;\n\t"
- "cli;\n\t"
- "popl %0;\n\t"
- : "=g"(key)
- :
- : "memory");
-#elif defined(__DCC__)
- key = intLock_inline();
-#endif
+ key = _do_irq_lock_inline();
#else
key = irq_lock_inline();
#endif
@@ -611,18 +589,8 @@
* Expending irq_unlock_inline() code since directly calling it would
* would end up in infinite recursion.
*/
-#if defined(__GNUC__)
- __asm__ volatile(
- "testl $0x200, %0;\n\t"
- "jz 0f;\n\t"
- "sti;\n\t"
- "0:\n\t"
- :
- : "g"(key)
- : "cc", "memory");
-#elif defined(__DCC__)
- intUnlock_inline(key);
-#endif
+ if (key & 0x200)
+ _do_irq_unlock_inline();
#else
irq_unlock_inline(key);
#endif
diff --git a/include/nanokernel/arm/CortexM/asm_inline.h b/include/nanokernel/arm/CortexM/asm_inline.h
new file mode 100644
index 0000000..21bcc71
--- /dev/null
+++ b/include/nanokernel/arm/CortexM/asm_inline.h
@@ -0,0 +1,47 @@
+/* Intel ARM inline assembler functions and macros for public functions */
+
+/*
+ * Copyright (c) 2015, Wind River Systems, Inc.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *
+ * 1) Redistributions of source code must retain the above copyright notice,
+ * this list of conditions and the following disclaimer.
+ *
+ * 2) Redistributions in binary form must reproduce the above copyright notice,
+ * this list of conditions and the following disclaimer in the documentation
+ * and/or other materials provided with the distribution.
+ *
+ * 3) Neither the name of Wind River Systems nor the names of its contributors
+ * may be used to endorse or promote products derived from this software without
+ * specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#ifndef _ASM_INLINE_PUBLIC_H
+#define _ASM_INLINE_PUBLIC_H
+
+/*
+ * The file must not be included directly
+ * Include nanokernel/cpu.h instead
+ */
+
+#if defined(__GNUC__)
+#include <nanokernel/arm/CortexM/asm_inline_gcc.h>
+#else
+#include <nanokernel/arm/CortexM/asm_inline_other.h>
+#endif
+
+#endif /* _ASM_INLINE_PUBLIC_H */
diff --git a/include/nanokernel/arm/CortexM/asm_inline_gcc.h b/include/nanokernel/arm/CortexM/asm_inline_gcc.h
new file mode 100644
index 0000000..885604d
--- /dev/null
+++ b/include/nanokernel/arm/CortexM/asm_inline_gcc.h
@@ -0,0 +1,181 @@
+/* Intel ARM GCC specific public inline assembler functions and macros */
+
+/*
+ * Copyright (c) 2015, Wind River Systems, Inc.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *
+ * 1) Redistributions of source code must retain the above copyright notice,
+ * this list of conditions and the following disclaimer.
+ *
+ * 2) Redistributions in binary form must reproduce the above copyright notice,
+ * this list of conditions and the following disclaimer in the documentation
+ * and/or other materials provided with the distribution.
+ *
+ * 3) Neither the name of Wind River Systems nor the names of its contributors
+ * may be used to endorse or promote products derived from this software without
+ * specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ */
+
+/* Either public functions or macros or invoked by public functions */
+
+#ifndef _ASM_INLINE_GCC_PUBLIC_GCC_H
+#define _ASM_INLINE_GCC_PUBLIC_GCC_H
+
+/*
+ * The file must not be included directly
+ * Include nanokernel/cpu.h instead
+ */
+
+#ifdef _ASMLANGUAGE
+
+#define _SCS_BASE_ADDR _PPB_INT_SCS
+#define _SCS_ICSR (_SCS_BASE_ADDR + 0xd04)
+#define _SCS_ICSR_PENDSV (1 << 28)
+#define _SCS_ICSR_UNPENDSV (1 << 27)
+#define _SCS_ICSR_RETTOBASE (1 << 11)
+
+#else /* !_ASMLANGUAGE */
+#include <stdint.h>
+#include <nanokernel/arm/CortexM/nvic.h>
+
+/*******************************************************************************
+*
+* find_last_set_inline - find first set bit (searching from most significant bit)
+*
+* This routine finds the first bit set in the argument passed it and returns
+* the index of that bit. Bits are numbered starting at 1 from the least
+* significant bit. A return value of zero indicates that the value passed
+* is zero.
+*
+* RETURNS: most significant bit set
+*/
+
+static ALWAYS_INLINE unsigned int find_last_set_inline(unsigned int op)
+{
+ unsigned int bit;
+
+ __asm__ volatile(
+ "cmp %1, #0;\n\t"
+ "itt ne;\n\t"
+ " clzne %1, %1;\n\t"
+ " rsbne %0, %1, #32;\n\t"
+ : "=r"(bit)
+ : "r"(op));
+
+ return bit;
+}
+
+
+/*******************************************************************************
+*
+* find_first_set_inline - find first set bit (from the least significant bit)
+*
+* This routine finds the first bit set in the argument passed it and
+* returns the index of that bit. Bits are numbered starting
+* at 1 from the least significant bit. A return value of zero indicates that
+* the value passed is zero.
+*
+* RETURNS: least significant bit set
+*/
+
+static ALWAYS_INLINE unsigned int find_first_set_inline(unsigned int op)
+{
+ unsigned int bit;
+
+ __asm__ volatile(
+ "rsb %0, %1, #0;\n\t"
+ "ands %0, %0, %1;\n\t" /* r0 = x & (-x): only LSB set */
+ "itt ne;\n\t"
+ " clzne %0, %0;\n\t" /* count leading zeroes */
+ " rsbne %0, %0, #32;\n\t"
+ : "=&r"(bit)
+ : "r"(op));
+
+ return bit;
+}
+
+
+/*******************************************************************************
+*
+* irq_lock_inline - disable all interrupts on the CPU (inline)
+*
+* This routine disables interrupts. It can be called from either interrupt,
+* task or fiber level. This routine returns an architecture-dependent
+* lock-out key representing the "interrupt disable state" prior to the call;
+* this key can be passed to irq_unlock_inline() to re-enable interrupts.
+*
+* The lock-out key should only be used as the argument to the
+* irq_unlock_inline() API. It should never be used to manually re-enable
+* interrupts or to inspect or manipulate the contents of the source register.
+*
+* WARNINGS
+* Invoking a VxMicro routine with interrupts locked may result in
+* interrupts being re-enabled for an unspecified period of time. If the
+* called routine blocks, interrupts will be re-enabled while another
+* context executes, or while the system is idle.
+*
+* The "interrupt disable state" is an attribute of a context. Thus, if a
+* fiber or task disables interrupts and subsequently invokes a VxMicro
+* system routine that causes the calling context to block, the interrupt
+* disable state will be restored when the context is later rescheduled
+* for execution.
+*
+* RETURNS: An architecture-dependent lock-out key representing the
+* "interrupt disable state" prior to the call.
+*
+* \NOMANUAL
+*/
+
+static ALWAYS_INLINE unsigned int irq_lock_inline(void)
+{
+ unsigned int key;
+
+ __asm__ volatile(
+ "movs.n %%r1, %1;\n\t"
+ "mrs %0, BASEPRI;\n\t"
+ "msr BASEPRI, %%r1;\n\t"
+ : "=r"(key)
+ : "i"(_EXC_IRQ_DEFAULT_PRIO)
+ : "r1");
+
+ return key;
+}
+
+
+/*******************************************************************************
+*
+* irq_unlock_inline - enable all interrupts on the CPU (inline)
+*
+* This routine re-enables interrupts on the CPU. The <key> parameter
+* is an architecture-dependent lock-out key that is returned by a previous
+* invocation of irq_lock_inline().
+*
+* This routine can be called from either interrupt, task or fiber level.
+*
+* RETURNS: N/A
+*
+* \NOMANUAL
+*/
+
+static ALWAYS_INLINE void irq_unlock_inline(unsigned int key)
+{
+ __asm__ volatile("msr BASEPRI, %0;\n\t" : : "r"(key));
+}
+
+
+#endif /* _ASMLANGUAGE */
+#endif /* _ASM_INLINE_GCC_PUBLIC_GCC_H */
diff --git a/include/nanokernel/arm/CortexM/ffs.h b/include/nanokernel/arm/CortexM/ffs.h
index 2646e06..45faa28 100644
--- a/include/nanokernel/arm/CortexM/ffs.h
+++ b/include/nanokernel/arm/CortexM/ffs.h
@@ -45,76 +45,6 @@
extern unsigned find_first_set(unsigned int);
extern unsigned find_last_set(unsigned int);
-/*******************************************************************************
-*
-* find_last_set_inline - Find First Set bit (searching from most significant bit)
-*
-* This routine finds the first bit set in the argument passed it and returns
-* the index of that bit. Bits are numbered starting at 1 from the least
-* significant bit. A return value of zero indicates that the value passed
-* is zero.
-*
-* RETURNS: most significant bit set
-*/
-
-#if defined(__GNUC__)
-static ALWAYS_INLINE unsigned int find_last_set_inline(unsigned int op)
-{
- unsigned int bit;
-
- __asm__ volatile(
- "cmp %1, #0;\n\t"
- "itt ne;\n\t"
- " clzne %1, %1;\n\t"
- " rsbne %0, %1, #32;\n\t"
- : "=r"(bit)
- : "r"(op));
-
- return bit;
-}
-#elif defined(__DCC__)
-__asm volatile unsigned int find_last_set_inline(unsigned int op)
-{
- % reg op !"r0" cmp op, #0 itt ne clzne r0, op rsbne r0, r0, #32
-}
-#endif
-
-/*******************************************************************************
-*
-* find_first_set - find first set bit (searching from the least significant bit)
-*
-* This routine finds the first bit set in the argument passed it and
-* returns the index of that bit. Bits are numbered starting
-* at 1 from the least significant bit. A return value of zero indicates that
-* the value passed is zero.
-*
-* RETURNS: least significant bit set
-*/
-
-#if defined(__GNUC__)
-static ALWAYS_INLINE unsigned int find_first_set_inline(unsigned int op)
-{
- unsigned int bit;
-
- __asm__ volatile(
- "rsb %0, %1, #0;\n\t"
- "ands %0, %0, %1;\n\t" /* r0 = x & (-x): only LSB set */
- "itt ne;\n\t"
- " clzne %0, %0;\n\t" /* count leading zeroes */
- " rsbne %0, %0, #32;\n\t"
- : "=&r"(bit)
- : "r"(op));
-
- return bit;
-}
-#elif defined(__DCC__)
-__asm volatile unsigned int find_first_set_inline(unsigned int op)
-{
- % reg op !"r0", "r1" rsb r1, op, #0 ands r0, r1, op itt ne clzne r0,
- r0 rsbne r0, r0, #32
-}
-#endif
-
#endif /* _ASMLANGUAGE */
#endif /* _ARCH_ARM_CORTEXM_FFS_H_ */
diff --git a/include/nanokernel/arm/CortexM/irq.h b/include/nanokernel/arm/CortexM/irq.h
index e85999a..33ea1be 100644
--- a/include/nanokernel/arm/CortexM/irq.h
+++ b/include/nanokernel/arm/CortexM/irq.h
@@ -71,91 +71,6 @@
extern void _IntExit(void);
-/*******************************************************************************
-*
-* irq_lock_inline - disable all interrupts on the CPU (inline)
-*
-* This routine disables interrupts. It can be called from either interrupt,
-* task or fiber level. This routine returns an architecture-dependent
-* lock-out key representing the "interrupt disable state" prior to the call;
-* this key can be passed to irq_unlock_inline() to re-enable interrupts.
-*
-* The lock-out key should only be used as the argument to the
-* irq_unlock_inline() API. It should never be used to manually re-enable
-* interrupts or to inspect or manipulate the contents of the source register.
-*
-* WARNINGS
-* Invoking a VxMicro routine with interrupts locked may result in
-* interrupts being re-enabled for an unspecified period of time. If the
-* called routine blocks, interrupts will be re-enabled while another
-* context executes, or while the system is idle.
-*
-* The "interrupt disable state" is an attribute of a context. Thus, if a
-* fiber or task disables interrupts and subsequently invokes a VxMicro
-* system routine that causes the calling context to block, the interrupt
-* disable state will be restored when the context is later rescheduled
-* for execution.
-*
-* RETURNS: An architecture-dependent lock-out key representing the
-* "interrupt disable state" prior to the call.
-*
-* \NOMANUAL
-*/
-
-#if defined(__GNUC__)
-static ALWAYS_INLINE unsigned int irq_lock_inline(void)
-{
- unsigned int key;
-
- __asm__ volatile(
- "movs.n %%r1, %1;\n\t"
- "mrs %0, BASEPRI;\n\t"
- "msr BASEPRI, %%r1;\n\t"
- : "=r"(key)
- : "i"(_EXC_IRQ_DEFAULT_PRIO)
- : "r1");
-
- return key;
-}
-#elif defined(__DCC__)
-__asm volatile unsigned int __irq_lock_inline(unsigned char pri)
-{
- % con pri !"r0", "r1" movs r1, #pri mrs r0, BASEPRI msr BASEPRI, r1
-}
-
-static ALWAYS_INLINE unsigned int irq_lock_inline(void)
-{
- return __irq_lock_inline(_EXC_IRQ_DEFAULT_PRIO);
-}
-#endif
-
-/*******************************************************************************
-*
-* irq_unlock_inline - enable all interrupts on the CPU (inline)
-*
-* This routine re-enables interrupts on the CPU. The <key> parameter
-* is an architecture-dependent lock-out key that is returned by a previous
-* invocation of irq_lock_inline().
-*
-* This routine can be called from either interrupt, task or fiber level.
-*
-* RETURNS: N/A
-*
-* \NOMANUAL
-*/
-
-#if defined(__GNUC__)
-static ALWAYS_INLINE void irq_unlock_inline(unsigned int key)
-{
- __asm__ volatile("msr BASEPRI, %0;\n\t" : : "r"(key));
-}
-#elif defined(__DCC__)
-__asm volatile void irq_unlock_inline(unsigned int key)
-{
- % reg key !"r0" msr BASEPRI, key
-}
-#endif
-
#endif /* _ASMLANGUAGE */
#endif /* _ARCH_ARM_CORTEXM_IRQ_H_ */
diff --git a/include/nanokernel/arm/CortexM/scs.h b/include/nanokernel/arm/CortexM/scs.h
index 22b08ed..ac92f1f 100644
--- a/include/nanokernel/arm/CortexM/scs.h
+++ b/include/nanokernel/arm/CortexM/scs.h
@@ -75,27 +75,6 @@
#include <nanokernel/arm/CortexM/memory_map.h>
-#if defined(__GNUC__)
-
-#define _SCS_BASE_ADDR _PPB_INT_SCS
-#define _SCS_ICSR (_SCS_BASE_ADDR + 0xd04)
-#define _SCS_ICSR_PENDSV (1 << 28)
-#define _SCS_ICSR_UNPENDSV (1 << 27)
-#define _SCS_ICSR_RETTOBASE (1 << 11)
-
-#elif defined(__DCC__)
-
-/*
- * This is hardcoded to 0xe000e000 as the Diab compiler
- * sees an overflow in _PPB_INT_SCS.
- */
-_SCS_BASE_ADDR:
-.equ(0xe000e000) _SCS_ICSR : .equ(_SCS_BASE_ADDR + 0xd04) _SCS_ICSR_PENDSV :
- .equ(1 << 28) _SCS_ICSR_UNPENDSV
- : .equ(1 << 27) _SCS_ICSR_RETTOBASE : .equ(1 << 11)
-
-#endif
-
#else /* _ASMLANGUAGE */
#include <nanokernel.h>
diff --git a/include/nanokernel/arm/arch.h b/include/nanokernel/arm/arch.h
index e92366c..7a6d5d9 100644
--- a/include/nanokernel/arm/arch.h
+++ b/include/nanokernel/arm/arch.h
@@ -61,6 +61,7 @@
#include <nanokernel/arm/CortexM/nvic.h>
#include <nanokernel/arm/CortexM/memory_map.h>
#include <nanokernel/arm/CortexM/gdb_stub.h>
+#include <nanokernel/arm/CortexM/asm_inline.h>
#endif
#ifdef __cplusplus
diff --git a/include/nanokernel/x86/Intelprc.h b/include/nanokernel/x86/Intelprc.h
index ef0512b..7e47a4c 100644
--- a/include/nanokernel/x86/Intelprc.h
+++ b/include/nanokernel/x86/Intelprc.h
@@ -52,8 +52,8 @@
#include <stdint.h>
#include <toolchain.h>
#include <misc/util.h>
-#include <nanokernel/x86/k_mem.h>
#include <nanokernel/x86/addr_types.h>
+#include <nanokernel/x86/asm_inline.h>
#include <drivers/system_timer.h> /* timer_driver() needed by kernel_main.c */
/*
diff --git a/include/nanokernel/x86/arch.h b/include/nanokernel/x86/arch.h
index 1c4bf92..2ef59ee 100644
--- a/include/nanokernel/x86/arch.h
+++ b/include/nanokernel/x86/arch.h
@@ -201,53 +201,6 @@
#ifndef _ASMLANGUAGE
-/********************************************************
-*
-* _NanoTscRead - read timestamp register ensuring serialization
-*/
-
-#if defined (__GNUC__)
-static inline uint64_t _NanoTscRead(void)
-{
- union {
- struct {
- uint32_t lo;
- uint32_t hi;
- };
- uint64_t value;
- } rv;
-
- /* rdtsc & cpuid clobbers eax, ebx, ecx and edx registers */
- __asm__ volatile (/* serialize */
- "xorl %%eax,%%eax;\n\t"
- "cpuid;\n\t"
- :
- :
- : "%eax", "%ebx", "%ecx", "%edx"
- );
- /*
- * We cannot use "=A", since this would use %rax on x86_64 and
- * return only the lower 32bits of the TSC
- */
- __asm__ volatile ("rdtsc" : "=a" (rv.lo), "=d" (rv.hi));
-
-
- return rv.value;
- }
-
-#elif defined (__DCC__)
-__asm volatile uint64_t _NanoTscRead (void)
- {
-%
-! "ax", "bx", "cx", "dx"
- xorl %eax, %eax
- pushl %ebx
- cpuid
- rdtsc /* 64-bit timestamp returned in EDX:EAX */
- popl %ebx
- }
-#endif
-
#ifdef CONFIG_NO_ISRS
@@ -294,23 +247,10 @@
* \NOMANUAL
*/
-#if defined(__GNUC__)
static inline __attribute__((always_inline))
- unsigned int irq_lock_inline
- (
- void
- )
+ unsigned int irq_lock_inline(void)
{
- unsigned int key;
-
- __asm__ volatile (
- "pushfl;\n\t"
- "cli;\n\t"
- "popl %0;\n\t"
- : "=g" (key)
- :
- : "memory"
- );
+ unsigned int key = _do_irq_lock_inline();
#ifdef CONFIG_INT_LATENCY_BENCHMARK
_int_latency_start ();
@@ -318,23 +258,6 @@
return key;
}
-#elif defined(__DCC__)
-__asm volatile unsigned int irq_lock_inline (void)
- {
-%
-#ifdef CONFIG_INT_LATENCH_BENCHMARK
-! "ax", "cx", "dx"
-#else
-! "ax"
-#endif /* !CONFIG_INT_LATENCH_BENCHMARK */
- pushfl
- cli
-#ifdef CONFIG_INT_LATENCY_BENCHMARK
- call _int_latency_start
-#endif
- popl %eax
- }
-#endif
/*******************************************************************************
@@ -352,225 +275,19 @@
* \NOMANUAL
*/
-#if defined(__GNUC__)
static inline __attribute__((always_inline))
- void irq_unlock_inline
- (
- unsigned int key
- )
+ void irq_unlock_inline(unsigned int key)
{
- /*
- * The assembler code is split into two parts and
- * _int_latency_stop (); is invoked as a legitimate C
- * function to let the compiler preserve registers
- * before the function invocation
- *
- * Neither the Intel C Compiler, nor DIAB C Compiler understand
- * asm goto construction
- */
-
-#if defined (__INTEL_COMPILER)
if (!(key & 0x200))
return;
-#else
- __asm__ volatile goto (
-
- "testl $0x200, %0;\n\t"
- "jz %l[end];\n\t"
- :
- : "g" (key)
- : "cc"
- : end
- );
-#endif
-
#ifdef CONFIG_INT_LATENCY_BENCHMARK
_int_latency_stop ();
#endif
- __asm__ volatile (
-
- "sti;\n\t"
- : :
-
- );
-#if defined(__GNUC__) && !defined (__INTEL_COMPILER)
- end:
-#endif
+ _do_irq_unlock_inline();
return;
}
-#elif defined (__DCC__)
-__asm volatile void irq_unlock_inline
- (
- unsigned int key
- )
- {
-% mem key; lab end
-#ifdef CONFIG_INT_LATENCY_BENCHMARK
-! "ax", "cx", "dx"
-#else
-! "ax"
-#endif /* !CONFIG_INT_LATENCY_BENCHMARK */
- testl $0x200, key
- jz end
-#ifdef CONFIG_INT_LATENCY_BENCHMARK
- call _int_latency_stop
-#endif /* CONFIG_INT_LATENCY_BENCHMARK */
- sti
-end:
- }
-#endif
-
#endif /* CONFIG_NO_ISRS */
-
-/*******************************************************************************
-*
-* find_first_set_inline - find first set bit searching from the LSB (inline)
-*
-* This routine finds the first bit set in the argument passed it and
-* returns the index of that bit. Bits are numbered starting
-* at 1 from the least significant bit to 32 for the most significant bit.
-* A return value of zero indicates that the value passed is zero.
-*
-* RETURNS: bit position from 1 to 32, or 0 if the argument is zero.
-*
-* INTERNAL
-* For Intel64 (x86_64) architectures, the 'cmovzl' can be removed
-* and leverage the fact that the 'bsfl' doesn't modify the destination operand
-* when the source operand is zero. The "bitpos" variable can be preloaded
-* into the destination register, and given the unconditional ++bitpos that
-* is performed after the 'cmovzl', the correct results are yielded.
-*/
-
-#if defined __GNUC__
-static inline unsigned int find_first_set_inline (unsigned int op)
- {
- int bitpos;
-
- __asm__ volatile (
-
-#if !defined(CONFIG_CMOV_UNSUPPORTED)
-
- "bsfl %1, %0;\n\t"
- "cmovzl %2, %0;\n\t"
- : "=r" (bitpos)
- : "rm" (op), "r" (-1)
- : "cc"
-
-#else
-
- "bsfl %1, %0;\n\t"
- "jnz 1f;\n\t"
- "movl $-1, %0;\n\t"
- "1:\n\t"
- : "=r" (bitpos)
- : "rm" (op)
- : "cc"
-
-#endif /* !CONFIG_CMOV_UNSUPPORTED */
- );
-
- return (bitpos + 1);
- }
-#elif defined(__DCC__)
-__asm volatile unsigned int find_first_set_inline
- (
- unsigned int op
- )
- {
-#if !defined(CONFIG_CMOV_UNSUPPORTED)
-% mem op
-! "ax", "cx"
- movl $-1, %ecx
- bsfl op, %eax
- cmovz %ecx, %eax
- incl %eax
-#else
-% mem op; lab unchanged
-! "ax"
- bsfl op, %eax
- jnz unchanged
- movl $-1, %eax
-unchanged:
- incl %eax
-#endif
- }
-#endif
-
-
-/*******************************************************************************
-*
-* find_last_set_inline - find first set bit searching from the MSB (inline)
-*
-* This routine finds the first bit set in the argument passed it and
-* returns the index of that bit. Bits are numbered starting
-* at 1 from the least significant bit to 32 for the most significant bit.
-* A return value of zero indicates that the value passed is zero.
-*
-* RETURNS: bit position from 1 to 32, or 0 if the argument is zero.
-*
-* INTERNAL
-* For Intel64 (x86_64) architectures, the 'cmovzl' can be removed
-* and leverage the fact that the 'bsfl' doesn't modify the destination operand
-* when the source operand is zero. The "bitpos" variable can be preloaded
-* into the destination register, and given the unconditional ++bitpos that
-* is performed after the 'cmovzl', the correct results are yielded.
-*/
-
-#if defined(__GNUC__)
-static inline unsigned int find_last_set_inline (unsigned int op)
- {
- int bitpos;
-
- __asm__ volatile (
-
-#if !defined(CONFIG_CMOV_UNSUPPORTED)
-
- "bsrl %1, %0;\n\t"
- "cmovzl %2, %0;\n\t"
- : "=r" (bitpos)
- : "rm" (op), "r" (-1)
-
-#else
-
- "bsrl %1, %0;\n\t"
- "jnz 1f;\n\t"
- "movl $-1, %0;\n\t"
- "1:\n\t"
- : "=r" (bitpos)
- : "rm" (op)
- : "cc"
-
-#endif /* CONFIG_CMOV_UNSUPPORTED */
- );
-
- return (bitpos + 1);
- }
-#elif defined(__DCC__)
-__asm volatile unsigned int find_last_set_inline
- (
- unsigned int op
- )
- {
-#if !defined(CONFIG_CMOV_UNSUPPORTED)
-% mem op
-! "ax", "cx"
- movl $-1, %ecx
- bsrl op, %eax
- cmovz %ecx, %eax
- incl %eax
-#else
-% mem op; lab unchanged
-! "ax"
- bsrl op, %eax
- jnz unchanged
- movl $-1, %eax
-unchanged:
- incl %eax
-#endif
- }
-#endif
-
/* interrupt/exception/error related definitions */
typedef void (*NANO_EOI_GET_FUNC) (void *);
diff --git a/include/nanokernel/x86/asm_inline.h b/include/nanokernel/x86/asm_inline.h
new file mode 100644
index 0000000..22a3303
--- /dev/null
+++ b/include/nanokernel/x86/asm_inline.h
@@ -0,0 +1,47 @@
+/* Intel x86 inline assembler functions and macros for public functions */
+
+/*
+ * Copyright (c) 2015, Wind River Systems, Inc.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *
+ * 1) Redistributions of source code must retain the above copyright notice,
+ * this list of conditions and the following disclaimer.
+ *
+ * 2) Redistributions in binary form must reproduce the above copyright notice,
+ * this list of conditions and the following disclaimer in the documentation
+ * and/or other materials provided with the distribution.
+ *
+ * 3) Neither the name of Wind River Systems nor the names of its contributors
+ * may be used to endorse or promote products derived from this software without
+ * specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#ifndef _ASM_INLINE_PUBLIC_H
+#define _ASM_INLINE_PUBLIC_H
+
+/*
+ * The file must not be included directly
+ * Include nanokernel/cpu.h instead
+ */
+
+#if defined(__GNUC__)
+#include <nanokernel/x86/asm_inline_gcc.h>
+#else
+#include <nanokernel/x86/asm_inline_other.h>
+#endif
+
+#endif /* _ASM_INLINE_PUBLIC_H */
diff --git a/include/nanokernel/x86/asm_inline_gcc.h b/include/nanokernel/x86/asm_inline_gcc.h
new file mode 100644
index 0000000..e1dd0b3
--- /dev/null
+++ b/include/nanokernel/x86/asm_inline_gcc.h
@@ -0,0 +1,462 @@
+/* Intel x86 GCC specific public inline assembler functions and macros */
+
+/*
+ * Copyright (c) 2015, Wind River Systems, Inc.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *
+ * 1) Redistributions of source code must retain the above copyright notice,
+ * this list of conditions and the following disclaimer.
+ *
+ * 2) Redistributions in binary form must reproduce the above copyright notice,
+ * this list of conditions and the following disclaimer in the documentation
+ * and/or other materials provided with the distribution.
+ *
+ * 3) Neither the name of Wind River Systems nor the names of its contributors
+ * may be used to endorse or promote products derived from this software without
+ * specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ */
+
+/* Either public functions or macros or invoked by public functions */
+
+#ifndef _ASM_INLINE_GCC_PUBLIC_GCC_H
+#define _ASM_INLINE_GCC_PUBLIC_GCC_H
+
+/*
+ * The file must not be included directly
+ * Include nanokernel/cpu.h instead
+ */
+
+#ifndef _ASMLANGUAGE
+#include <stdint.h>
+#include <stddef.h>
+
+/*******************************************************************************
+*
+* _do_irq_lock_inline - disable all interrupts on the CPU (inline)
+*
+* This routine disables interrupts. It can be called from either interrupt,
+* task or fiber level. This routine returns an architecture-dependent
+* lock-out key representing the "interrupt disable state" prior to the call;
+* this key can be passed to irq_unlock_inline() to re-enable interrupts.
+*
+* The lock-out key should only be used as the argument to the
+* irq_unlock_inline() API. It should never be used to manually re-enable
+* interrupts or to inspect or manipulate the contents of the source register.
+*
+* WARNINGS
+* Invoking a VxMicro routine with interrupts locked may result in
+* interrupts being re-enabled for an unspecified period of time. If the
+* called routine blocks, interrupts will be re-enabled while another
+* context executes, or while the system is idle.
+*
+* The "interrupt disable state" is an attribute of a context. Thus, if a
+* fiber or task disables interrupts and subsequently invokes a VxMicro
+* system routine that causes the calling context to block, the interrupt
+* disable state will be restored when the context is later rescheduled
+* for execution.
+*
+* RETURNS: An architecture-dependent lock-out key representing the
+* "interrupt disable state" prior to the call.
+*
+* \NOMANUAL
+*/
+
+static inline __attribute__((always_inline))
+ unsigned int _do_irq_lock_inline(void)
+{
+ unsigned int key;
+
+ __asm__ volatile (
+ "pushfl;\n\t"
+ "cli;\n\t"
+ "popl %0;\n\t"
+ : "=g" (key)
+ :
+ : "memory"
+ );
+
+ return key;
+}
+
+
+/*******************************************************************************
+*
+* _do_irq_unlock_inline - enable all interrupts on the CPU (inline)
+*
+* This routine can be called from either interrupt, task or fiber level.
+* Invoked by kernel or by irq_unlock_inline()
+*
+* RETURNS: N/A
+*
+* \NOMANUAL
+*/
+
+static inline __attribute__((always_inline))
+ void _do_irq_unlock_inline(void)
+{
+ __asm__ volatile (
+ "sti;\n\t"
+ : :
+ );
+}
+
+
+/*******************************************************************************
+*
+* find_first_set_inline - find first set bit searching from the LSB (inline)
+*
+* This routine finds the first bit set in the argument passed it and
+* returns the index of that bit. Bits are numbered starting
+* at 1 from the least significant bit to 32 for the most significant bit.
+* A return value of zero indicates that the value passed is zero.
+*
+* RETURNS: bit position from 1 to 32, or 0 if the argument is zero.
+*
+* INTERNAL
+* For Intel64 (x86_64) architectures, the 'cmovzl' can be removed
+* and leverage the fact that the 'bsfl' doesn't modify the destination operand
+* when the source operand is zero. The "bitpos" variable can be preloaded
+* into the destination register, and given the unconditional ++bitpos that
+* is performed after the 'cmovzl', the correct results are yielded.
+*/
+
+static inline __attribute__((always_inline))
+ unsigned int find_first_set_inline (unsigned int op)
+{
+ int bitpos;
+
+ __asm__ volatile (
+
+#if !defined(CONFIG_CMOV_UNSUPPORTED)
+
+ "bsfl %1, %0;\n\t"
+ "cmovzl %2, %0;\n\t"
+ : "=r" (bitpos)
+ : "rm" (op), "r" (-1)
+ : "cc"
+
+#else
+
+ "bsfl %1, %0;\n\t"
+ "jnz 1f;\n\t"
+ "movl $-1, %0;\n\t"
+ "1:\n\t"
+ : "=r" (bitpos)
+ : "rm" (op)
+ : "cc"
+
+#endif /* !CONFIG_CMOV_UNSUPPORTED */
+ );
+
+ return (bitpos + 1);
+}
+
+
+/*******************************************************************************
+*
+* find_last_set_inline - find first set bit searching from the MSB (inline)
+*
+* This routine finds the first bit set in the argument passed it and
+* returns the index of that bit. Bits are numbered starting
+* at 1 from the least significant bit to 32 for the most significant bit.
+* A return value of zero indicates that the value passed is zero.
+*
+* RETURNS: bit position from 1 to 32, or 0 if the argument is zero.
+*
+* INTERNAL
+* For Intel64 (x86_64) architectures, the 'cmovzl' can be removed
+* and leverage the fact that the 'bsfl' doesn't modify the destination operand
+* when the source operand is zero. The "bitpos" variable can be preloaded
+* into the destination register, and given the unconditional ++bitpos that
+* is performed after the 'cmovzl', the correct results are yielded.
+*/
+
+static inline inline __attribute__((always_inline))
+ unsigned int find_last_set_inline (unsigned int op)
+{
+ int bitpos;
+
+ __asm__ volatile (
+
+#if !defined(CONFIG_CMOV_UNSUPPORTED)
+
+ "bsrl %1, %0;\n\t"
+ "cmovzl %2, %0;\n\t"
+ : "=r" (bitpos)
+ : "rm" (op), "r" (-1)
+
+#else
+
+ "bsrl %1, %0;\n\t"
+ "jnz 1f;\n\t"
+ "movl $-1, %0;\n\t"
+ "1:\n\t"
+ : "=r" (bitpos)
+ : "rm" (op)
+ : "cc"
+
+#endif /* CONFIG_CMOV_UNSUPPORTED */
+ );
+
+ return (bitpos + 1);
+}
+
+
+/********************************************************
+*
+* _NanoTscRead - read timestamp register ensuring serialization
+*/
+
+static inline uint64_t _NanoTscRead(void)
+{
+ union {
+ struct {
+ uint32_t lo;
+ uint32_t hi;
+ };
+ uint64_t value;
+ } rv;
+
+ /* rdtsc & cpuid clobbers eax, ebx, ecx and edx registers */
+ __asm__ volatile (/* serialize */
+ "xorl %%eax,%%eax;\n\t"
+ "cpuid;\n\t"
+ :
+ :
+ : "%eax", "%ebx", "%ecx", "%edx"
+ );
+ /*
+ * We cannot use "=A", since this would use %rax on x86_64 and
+ * return only the lower 32bits of the TSC
+ */
+ __asm__ volatile ("rdtsc" : "=a" (rv.lo), "=d" (rv.hi));
+
+
+ return rv.value;
+}
+
+
+/*******************************************************************************
+ *
+ * _do_read_cpu_timestamp - get a 32 bit CPU timestamp counter
+ *
+ * RETURNS: a 32-bit number
+ */
+
+static inline inline __attribute__((always_inline))
+ uint32_t _do_read_cpu_timestamp32(void)
+{
+ uint32_t rv;
+
+ __asm__ volatile("rdtsc" : "=a"(rv) : : "%edx");
+
+ return rv;
+}
+
+
+/*******************************************************************************
+*
+* sys_out8 - output a byte to an IA-32 I/O port
+*
+* This function issues the 'out' instruction to write a byte to the specified
+* I/O port.
+*
+* RETURNS: N/A
+*
+* NOMANUAL
+*/
+
+static inline inline __attribute__((always_inline))
+ void sys_out8(unsigned char data, unsigned int port)
+{
+ __asm__ volatile("outb %%al, %%dx;\n\t" : : "a"(data), "d"(port));
+}
+
+
+/*******************************************************************************
+*
+* sys_in8 - input a byte from an IA-32 I/O port
+*
+* This function issues the 'in' instruction to read a byte from the specified
+* I/O port.
+*
+* RETURNS: the byte read from the specified I/O port
+*
+* NOMANUAL
+*/
+
+static inline inline __attribute__((always_inline))
+ unsigned char sys_in8(unsigned int port)
+{
+ char retByte;
+
+ __asm__ volatile("inb %%dx, %%al;\n\t" : "=a"(retByte) : "d"(port));
+ return retByte;
+}
+
+
+/*******************************************************************************
+*
+* sys_out16 - output a word to an IA-32 I/O port
+*
+* This function issues the 'out' instruction to write a word to the
+* specified I/O port.
+*
+* RETURNS: N/A
+*
+* NOMANUAL
+*/
+
+static inline inline __attribute__((always_inline))
+ void sys_out16(unsigned short data, unsigned int port)
+{
+ __asm__ volatile("outw %%ax, %%dx;\n\t" : : "a"(data), "d"(port));
+}
+
+
+/*******************************************************************************
+*
+* sys_in16 - input a word from an IA-32 I/O port
+*
+* This function issues the 'in' instruction to read a word from the
+* specified I/O port.
+*
+* RETURNS: the word read from the specified I/O port
+*
+* NOMANUAL
+*/
+
+static inline inline __attribute__((always_inline))
+ unsigned short sys_in16(unsigned int port)
+{
+ unsigned short retWord;
+
+ __asm__ volatile("inw %%dx, %%ax;\n\t" : "=a"(retWord) : "d"(port));
+ return retWord;
+}
+
+
+/*******************************************************************************
+*
+* sys_out32 - output a long word to an IA-32 I/O port
+*
+* This function issues the 'out' instruction to write a long word to the
+* specified I/O port.
+*
+* RETURNS: N/A
+*
+* NOMANUAL
+*/
+
+static inline inline __attribute__((always_inline))
+ void sys_out32(unsigned int data, unsigned int port)
+{
+ __asm__ volatile("outl %%eax, %%dx;\n\t" : : "a"(data), "d"(port));
+}
+
+
+/*******************************************************************************
+*
+* sys_in32 - input a long word from an IA-32 I/O port
+*
+* This function issues the 'in' instruction to read a long word from the
+* specified I/O port.
+*
+* RETURNS: the long read from the specified I/O port
+*
+* NOMANUAL
+*/
+
+static inline inline __attribute__((always_inline))
+ unsigned long sys_in32(unsigned int port)
+{
+ unsigned long retLong;
+
+ __asm__ volatile("inl %%dx, %%eax;\n\t" : "=a"(retLong) : "d"(port));
+ return retLong;
+}
+
+
+/********************************************************
+ *
+ * k_memcpy - copy memory area
+ *
+ * Copy _n bytes from source _s to destination _d
+ *
+ * RETURNS: N/A
+ *
+ * \NOMANUAL
+ */
+
+static inline void k_memcpy(void *_d, const void *_s, size_t _n)
+{
+ /* _d & _s must be aligned to use movsl. */
+#ifndef CONFIG_UNALIGNED_WRITE_UNSUPPORTED
+ if ((_n&3) == 0) {
+ /* _n is multiple of words, much more efficient to do word moves */
+ _n >>= 2;
+ __asm__ volatile ("rep movsl" :
+ "+D" (_d), "+S" (_s), "+c" (_n) :
+ :
+ "cc", "memory");
+ } else
+#endif /* CONFIG_UNALIGNED_WRITE_UNSUPPORTED */
+ {
+ __asm__ volatile ("rep movsb" :
+ "+D" (_d), "+S" (_s), "+c" (_n) :
+ :
+ "cc", "memory");
+ }
+}
+
+
+/********************************************************
+ *
+ * k_memset - set memory area
+ *
+ * Set _n bytes in the area _d to value _v
+ *
+ * RETURNS: N/A
+ *
+ * \NOMANUAL
+ */
+
+static inline void k_memset(void *_d, int _v, size_t _n)
+{
+ /* _d must be aligned to use stosl. */
+#ifndef CONFIG_UNALIGNED_WRITE_UNSUPPORTED
+ if ((_n&3) == 0) {
+ /* _n is multiple of words, much more efficient to do word stores */
+ _n >>= 2;
+ _v |= _v<<8;
+ _v |= _v<<16;
+ __asm__ volatile ("rep stosl" :
+ "+D" (_d), "+c" (_n) :
+ "a" (_v) :
+ "cc", "memory");
+ } else
+#endif /* CONFIG_UNALIGNED_WRITE_UNSUPPORTED */
+ {
+ __asm__ volatile ("rep stosb" :
+ "+D" (_d), "+c" (_n) :
+ "a" (_v) :
+ "cc", "memory");
+ }
+}
+
+#endif /* _ASMLANGUAGE */
+#endif /* _ASM_INLINE_GCC_PUBLIC_GCC_H */
diff --git a/include/nanokernel/x86/k_mem-gcc.h b/include/nanokernel/x86/k_mem-gcc.h
deleted file mode 100644
index b2d99f2..0000000
--- a/include/nanokernel/x86/k_mem-gcc.h
+++ /dev/null
@@ -1,75 +0,0 @@
-/* x86 GCC implementation of k_memset, k_memcpy, etc */
-
-/*
- * Copyright (c) 2015 Wind River Systems, Inc.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions are met:
- *
- * 1) Redistributions of source code must retain the above copyright notice,
- * this list of conditions and the following disclaimer.
- *
- * 2) Redistributions in binary form must reproduce the above copyright notice,
- * this list of conditions and the following disclaimer in the documentation
- * and/or other materials provided with the distribution.
- *
- * 3) Neither the name of Wind River Systems nor the names of its contributors
- * may be used to endorse or promote products derived from this software without
- * specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
- * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
- * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
- * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
- * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
- * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
- * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
- * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
- * POSSIBILITY OF SUCH DAMAGE.
- */
-
-static inline void k_memcpy(void *_d, const void *_s, size_t _n)
-{
- /* _d & _s must be aligned to use movsl. */
-#ifndef CONFIG_UNALIGNED_WRITE_UNSUPPORTED
- if ((_n&3) == 0) {
- /* _n is multiple of words, much more efficient to do word moves */
- _n >>= 2;
- __asm__ volatile ("rep movsl" :
- "+D" (_d), "+S" (_s), "+c" (_n) :
- :
- "cc", "memory");
- } else
-#endif /* CONFIG_UNALIGNED_WRITE_UNSUPPORTED */
- {
- __asm__ volatile ("rep movsb" :
- "+D" (_d), "+S" (_s), "+c" (_n) :
- :
- "cc", "memory");
- }
-}
-
-static inline void k_memset(void *_d, int _v, size_t _n)
-{
- /* _d must be aligned to use stosl. */
-#ifndef CONFIG_UNALIGNED_WRITE_UNSUPPORTED
- if ((_n&3) == 0) {
- /* _n is multiple of words, much more efficient to do word stores */
- _n >>= 2;
- _v |= _v<<8;
- _v |= _v<<16;
- __asm__ volatile ("rep stosl" :
- "+D" (_d), "+c" (_n) :
- "a" (_v) :
- "cc", "memory");
- } else
-#endif /* CONFIG_UNALIGNED_WRITE_UNSUPPORTED */
- {
- __asm__ volatile ("rep stosb" :
- "+D" (_d), "+c" (_n) :
- "a" (_v) :
- "cc", "memory");
- }
-}
diff --git a/include/nanokernel/x86/k_mem-other.h b/include/nanokernel/x86/k_mem-other.h
deleted file mode 100644
index 2a6fa54..0000000
--- a/include/nanokernel/x86/k_mem-other.h
+++ /dev/null
@@ -1,91 +0,0 @@
-/* x86 implementation of k_memset, k_memcpy, etc for other toolchains */
-
-/*
- * Copyright (c) 2015 Wind River Systems, Inc.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions are met:
- *
- * 1) Redistributions of source code must retain the above copyright notice,
- * this list of conditions and the following disclaimer.
- *
- * 2) Redistributions in binary form must reproduce the above copyright notice,
- * this list of conditions and the following disclaimer in the documentation
- * and/or other materials provided with the distribution.
- *
- * 3) Neither the name of Wind River Systems nor the names of its contributors
- * may be used to endorse or promote products derived from this software without
- * specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
- * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
- * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
- * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
- * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
- * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
- * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
- * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
- * POSSIBILITY OF SUCH DAMAGE.
- */
-
-/* Diab */
-#if defined(__DCC__)
-__asm volatile void k_memcpy(void *_d, const void *_s, size_t_n)
-{
-#ifndef CONFIG_UNALIGNED_WRITE_UNSUPPORTED
-% mem _d, _s, _n; lab unaligned, done
-! "si", "di", "cx"
- movl _d, %edi
- movl _s, %esi
- movl _n, %ecx
- testl $3, %ecx
- jnz unaligned
- shrl $2, %ecx
- rep movsl
- jmp done
-unaligned:
- rep movsb
-done:
-#else /* CONFIG_UNALIGNED_WRITE_UNSUPPORTED */
-% mem _d, _s, _n
-! "si", "di", "cx"
- movl _d, %edi
- movl _s, %esi
- movl _n, %ecx
- rep movsb
-#endif /* CONFIG_UNALIGNED_WRITE_UNSUPPORTED */
-}
-
-__asm volatile void k_memset(void *_d, int _v, size_t _n)
-{
-#ifndef CONFIG_UNALIGNED_WRITE_UNSUPPORTED
-% mem _d, _v, _n; lab unaligned, done
-! "ax", "di", "cx", "dx"
- movl _d, %edi
- movl _v, %eax
- movl _n, %ecx
- andl $0xff, %eax
- testl $3, %ecx
- movb %al, %ah
- jnz unaligned
- movl %eax, %edx
- shll $16, %eax
- shrl $2, %ecx
- orl %edx, %eax
- rep stosl
- jmp done
-unaligned:
- rep stosb
-done:
-#else /* CONFIG_UNALIGNED_WRITE_UNSUPPORTED */
-% mem _d, _v, _n
-! "ax", "di", "cx"
- movl _d, %edi
- movl _v, %eax
- movl _n, %ecx
- rep stosb
-#endif /* CONFIG_UNALIGNED_WRITE_UNSUPPORTED */
-}
-#endif /* __DCC__ */
diff --git a/include/nanokernel/x86/k_mem.h b/include/nanokernel/x86/k_mem.h
deleted file mode 100644
index 6370e99..0000000
--- a/include/nanokernel/x86/k_mem.h
+++ /dev/null
@@ -1,66 +0,0 @@
-/* x86 implementation of k_memset, k_memcpy, etc */
-
-/*
- * Copyright (c) 2015 Wind River Systems, Inc.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions are met:
- *
- * 1) Redistributions of source code must retain the above copyright notice,
- * this list of conditions and the following disclaimer.
- *
- * 2) Redistributions in binary form must reproduce the above copyright notice,
- * this list of conditions and the following disclaimer in the documentation
- * and/or other materials provided with the distribution.
- *
- * 3) Neither the name of Wind River Systems nor the names of its contributors
- * may be used to endorse or promote products derived from this software without
- * specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
- * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
- * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
- * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
- * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
- * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
- * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
- * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
- * POSSIBILITY OF SUCH DAMAGE.
- */
-
-/*
-DESCRIPTION
-The conditional definitions of k_memcpy() and k_memset() exist because it
-has been found that depending upon the choice of compiler, calls to memcpy()
-and memset() may or may not be size-optimized to "rep movsb" or "rep stosb".
-Consequently, without these conditional defines, there could be unresolved
-symbols to memcpy() and memset().
-
-This file is included indirectly by a number of HostServer source files
-which include microkernel/k_struct.h. These files define VXMICRO_HOST_TOOLS
-when including target header files. The Microsoft Visual C++ compiler
-used to build the HostServer does not handle the "static inline"
-declaration, so the HostServer uses the memcpy/memset implementations.
-
-Typical use of the inline function has the size (_s) and value (_v) parameters
-defined as immediate value and therefore the compiler optimization resolves the
-if and shift operations in order to generate minimal code with maximum
-performance.
-*/
-
-#ifndef _K_MEM_H
-#define _K_MEM_H
-
-#include <toolchain.h>
-#include <sections.h>
-#include <stddef.h>
-
-#if defined(__GNUC__)
- #include <nanokernel/x86/k_mem-gcc.h>
-#else
- #include <nanokernel/x86/k_mem-other.h>
-#endif
-
-#endif /* _K_MEM_H */