[PATCH 2/3] bsps/i386: use Pentimum instructions for pc586 and pc686 builds.
From: Pavel Pisa When GCC option -march is not specifies i386-rtems toolchain defaults to i386 architecture instruction set. It does not provide atomic instructions which results in really inefficient atomic_fetch_or even on UP build. SMP build is broken with i386 set because libatomic and GCC generate infinite loop for __atomic_fetch_add_4 used in rtems_interrupt_lock_acquire __atomic_fetch_add_4: push %ebp mov%esp,%ebp movl $0x5,0x10(%ebp) pop%ebp jmp__atomic_fetch_add_4 --- c/src/lib/libbsp/i386/pc386/make/custom/pc586.cfg | 2 +- c/src/lib/libbsp/i386/pc386/make/custom/pc686.cfg | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/c/src/lib/libbsp/i386/pc386/make/custom/pc586.cfg b/c/src/lib/libbsp/i386/pc386/make/custom/pc586.cfg index 73e42cd..6f9cfcb 100644 --- a/c/src/lib/libbsp/i386/pc386/make/custom/pc586.cfg +++ b/c/src/lib/libbsp/i386/pc386/make/custom/pc586.cfg @@ -6,7 +6,7 @@ RTEMS_CPU_MODEL=pentium # This contains the compiler options necessary to select the CPU model # and (hopefully) optimize for it. -CPU_CFLAGS = -mtune=pentium +CPU_CFLAGS = -mtune=pentium -march=pentium include $(RTEMS_ROOT)/make/custom/pc386.cfg diff --git a/c/src/lib/libbsp/i386/pc386/make/custom/pc686.cfg b/c/src/lib/libbsp/i386/pc386/make/custom/pc686.cfg index 04f001f..b27e8ae 100644 --- a/c/src/lib/libbsp/i386/pc386/make/custom/pc686.cfg +++ b/c/src/lib/libbsp/i386/pc386/make/custom/pc686.cfg @@ -6,7 +6,7 @@ RTEMS_CPU_MODEL=pentiumpro # This contains the compiler options necessary to select the CPU model # and (hopefully) optimize for it. -CPU_CFLAGS = -mtune=pentiumpro +CPU_CFLAGS = -mtune=pentiumpro -march=pentium include $(RTEMS_ROOT)/make/custom/pc386.cfg -- 1.9.1 ___ devel mailing list devel@rtems.org http://lists.rtems.org/mailman/listinfo/devel
[PATCH 0/3] bsps/i386: updates to allow SMP build of x86 BSP
From: Pavel Pisa The elimination of global interrupt lock is necessity condition but far from being sufficient for RTEMS x86 SMP support. Provided changes allows to build i386 BSP with configure option --enable-smp. The build BSP runs in UP and SMP configurations on QEMU when only one/boot CPU is used. Testing with more CPUs has not been done and I expect that fundamental parts of code are missing. IRQ processing of i8259 interrupts could be sufficient for SMP configuration now when legacy interrupts are routed to single core only. But there is missing mechanism to wait for finishing interrupt service routine running on one CPU when interrupt disable is called on another CPU. Local, IO APIC and MSI interrupts seems to be missing. Pavel Pisa (3): bsps/i386: replace global interrupt disable by SMP build supporting locking. bsps/i386: use Pentimum instructions for pc586 and pc686 builds. libchip/network/if_fxp.c: do not use rtems_interrupt_disable. c/src/lib/libbsp/i386/pc386/clock/ckinit.c| 19 +--- c/src/lib/libbsp/i386/pc386/console/inch.c| 10 +++-- c/src/lib/libbsp/i386/pc386/console/keyboard.c| 55 +++ c/src/lib/libbsp/i386/pc386/console/vt.c | 13 +++--- c/src/lib/libbsp/i386/pc386/include/bsp.h | 5 +++ c/src/lib/libbsp/i386/pc386/make/custom/pc586.cfg | 2 +- c/src/lib/libbsp/i386/pc386/make/custom/pc686.cfg | 2 +- c/src/lib/libbsp/i386/pc386/timer/timer.c | 45 --- c/src/lib/libbsp/i386/shared/irq/idt.c| 34 +- c/src/lib/libbsp/i386/shared/irq/irq.c| 32 + c/src/lib/libbsp/i386/shared/irq/irq_init.c | 7 ++- c/src/libchip/network/if_fxp.c| 11 ++--- 12 files changed, 154 insertions(+), 81 deletions(-) -- 1.9.1 ___ devel mailing list devel@rtems.org http://lists.rtems.org/mailman/listinfo/devel
[PATCH 1/3] bsps/i386: replace global interrupt disable by SMP build supporting locking.
From: Pavel Pisa --- c/src/lib/libbsp/i386/pc386/clock/ckinit.c | 19 ++--- c/src/lib/libbsp/i386/pc386/console/inch.c | 10 +++-- c/src/lib/libbsp/i386/pc386/console/keyboard.c | 55 -- c/src/lib/libbsp/i386/pc386/console/vt.c | 13 +++--- c/src/lib/libbsp/i386/pc386/include/bsp.h | 5 +++ c/src/lib/libbsp/i386/pc386/timer/timer.c | 45 ++--- c/src/lib/libbsp/i386/shared/irq/idt.c | 34 ++-- c/src/lib/libbsp/i386/shared/irq/irq.c | 32 ++- c/src/lib/libbsp/i386/shared/irq/irq_init.c| 7 +++- 9 files changed, 148 insertions(+), 72 deletions(-) diff --git a/c/src/lib/libbsp/i386/pc386/clock/ckinit.c b/c/src/lib/libbsp/i386/pc386/clock/ckinit.c index 67f4bf7..e7fe50a 100644 --- a/c/src/lib/libbsp/i386/pc386/clock/ckinit.c +++ b/c/src/lib/libbsp/i386/pc386/clock/ckinit.c @@ -84,15 +84,18 @@ static uint32_t pc386_get_timecount_i8254(struct timecounter *tc) { uint32_t irqs; uint8_t lsb, msb; - rtems_interrupt_levellevel; + rtems_interrupt_lock_context lock_context; /* * Fetch all the data in an interrupt critical section. */ - rtems_interrupt_disable(level); + + rtems_interrupt_lock_acquire(&rtems_i386_i8254_access_lock, &lock_context); + READ_8254(lsb, msb); irqs = Clock_driver_ticks; - rtems_interrupt_enable(level); + + rtems_interrupt_lock_release(&rtems_i386_i8254_access_lock, &lock_context); return (irqs + 1) * pc386_microseconds_per_isr - ((msb << 8) | lsb); } @@ -141,6 +144,7 @@ static void calibrate_tsc(void) static void clockOn(void) { + rtems_interrupt_lock_context lock_context; pc386_isrs_per_tick= 1; pc386_microseconds_per_isr = rtems_configuration_get_microseconds_per_tick(); @@ -150,8 +154,6 @@ static void clockOn(void) } pc386_clock_click_count = US_TO_TICK(pc386_microseconds_per_isr); - bsp_interrupt_vector_enable( BSP_PERIODIC_TIMER - BSP_IRQ_VECTOR_BASE ); - #if 0 printk( "configured usecs per tick=%d \n", rtems_configuration_get_microseconds_per_tick() ); @@ -160,9 +162,13 @@ static void clockOn(void) printk( "final timer counts=%d\n", pc386_clock_click_count ); #endif + rtems_interrupt_lock_acquire(&rtems_i386_i8254_access_lock, &lock_context); outport_byte(TIMER_MODE, TIMER_SEL0|TIMER_16BIT|TIMER_RATEGEN); outport_byte(TIMER_CNTR0, pc386_clock_click_count >> 0 & 0xff); outport_byte(TIMER_CNTR0, pc386_clock_click_count >> 8 & 0xff); + rtems_interrupt_lock_release(&rtems_i386_i8254_access_lock, &lock_context); + + bsp_interrupt_vector_enable( BSP_PERIODIC_TIMER - BSP_IRQ_VECTOR_BASE ); /* * Now calibrate cycles per tick. Do this every time we @@ -174,10 +180,13 @@ static void clockOn(void) static void clockOff(void) { + rtems_interrupt_lock_context lock_context; + rtems_interrupt_lock_acquire(&rtems_i386_i8254_access_lock, &lock_context); /* reset timer mode to standard (BIOS) value */ outport_byte(TIMER_MODE, TIMER_SEL0 | TIMER_16BIT | TIMER_RATEGEN); outport_byte(TIMER_CNTR0, 0); outport_byte(TIMER_CNTR0, 0); + rtems_interrupt_lock_release(&rtems_i386_i8254_access_lock, &lock_context); } /* Clock_exit */ bool Clock_isr_enabled = false; diff --git a/c/src/lib/libbsp/i386/pc386/console/inch.c b/c/src/lib/libbsp/i386/pc386/console/inch.c index 047269e..f5d5079 100644 --- a/c/src/lib/libbsp/i386/pc386/console/inch.c +++ b/c/src/lib/libbsp/i386/pc386/console/inch.c @@ -260,13 +260,17 @@ int BSP_wait_polled_input(void) int rtems_kbpoll( void ) { intrc; - rtems_interrupt_level level; - rtems_interrupt_disable(level); + /* + * The locking or disable of interrupts does not help + * there because if interrupts are enabled after leave of this + * function the state can change without notice anyway. + */ + RTEMS_COMPILER_MEMORY_BARRIER(); rc = ( kbd_first != kbd_last ) ? TRUE : FALSE; - rtems_interrupt_enable(level); + RTEMS_COMPILER_MEMORY_BARRIER(); return rc; } diff --git a/c/src/lib/libbsp/i386/pc386/console/keyboard.c b/c/src/lib/libbsp/i386/pc386/console/keyboard.c index 3a33c54..0c8991b 100644 --- a/c/src/lib/libbsp/i386/pc386/console/keyboard.c +++ b/c/src/lib/libbsp/i386/pc386/console/keyboard.c @@ -9,6 +9,7 @@ #include #include #include +#include #define SIZE(x) (sizeof(x)/sizeof((x)[0])) @@ -28,59 +29,53 @@ #define KBD_DEFLOCK 0 #endif -static int set_bit(int nr, unsigned long * addr) +static int kbd_test_and_set_bit(int nr, atomic_uint_least32_t * addr) { - int mask; + uint_least32_tmask; int retval; - rtems_interrupt_level level; addr += nr >> 5; - mask = 1 << (nr & 0x1f); - rtems_interrupt_disable(level); -retval = (mask & *addr) != 0; -*addr |= mask; - rtems_interrupt_enable(level); + mask = 1UL << (nr & 0x1f); + + retval = (atomic_fetch_or(addr, mask) & ma
[PATCH 3/3] libchip/network/if_fxp.c: do not use rtems_interrupt_disable.
From: Pavel Pisa The single write to memory or ioport output are mostly atomic operations already. The proper memory synchronization barrier should be used around them to guarantee ordering (sync or eieio on PowerPC for example) but because I have not found settable portable primitive only compiler barrier is used. It should be enough on x86 because the externally visible order should be/is guaranteed to be preserved on x86 architecture. --- c/src/libchip/network/if_fxp.c | 11 --- 1 file changed, 4 insertions(+), 7 deletions(-) diff --git a/c/src/libchip/network/if_fxp.c b/c/src/libchip/network/if_fxp.c index 4d9d983..c2ca419 100644 --- a/c/src/libchip/network/if_fxp.c +++ b/c/src/libchip/network/if_fxp.c @@ -1130,7 +1130,6 @@ fxp_start(struct ifnet *ifp) { struct fxp_softc *sc = ifp->if_softc; struct fxp_cb_tx *txp; - rtems_interrupt_level level; DBGLVL_PRINTK(3,"fxp_start called\n"); @@ -1279,10 +1278,10 @@ tbdinit: /* * reenable interrupts */ - rtems_interrupt_disable (level); + RTEMS_COMPILER_MEMORY_BARRIER(); CSR_WRITE_1(sc, FXP_CSR_SCB_INTRCNTL,0); bsp_interrupt_vector_enable(sc->irq_num); - rtems_interrupt_enable (level); + RTEMS_COMPILER_MEMORY_BARRIER(); } /* @@ -1311,7 +1310,6 @@ static void fxp_daemon(void *xsc) struct ifnet *ifp = &sc->sc_if; u_int8_t statack; rtems_event_set events; - rtems_interrupt_level level; #ifdef NOTUSED if (sc->suspended) { @@ -1458,10 +1456,9 @@ rcvloop: /* * reenable interrupts */ - rtems_interrupt_disable (level); + RTEMS_COMPILER_MEMORY_BARRIER(); CSR_WRITE_1(sc, FXP_CSR_SCB_INTRCNTL,0); - bsp_interrupt_vector_enable(sc->irq_num); - rtems_interrupt_enable (level); + RTEMS_COMPILER_MEMORY_BARRIER(); } } -- 1.9.1 ___ devel mailing list devel@rtems.org http://lists.rtems.org/mailman/listinfo/devel
Re: [PATCH 2/3] bsps/i386: use Pentimum instructions for pc586 and pc686 builds.
On 12/10/16 10:26, p...@cmp.felk.cvut.cz wrote: SMP build is broken with i386 set because libatomic and GCC generate infinite loop for __atomic_fetch_add_4 used in rtems_interrupt_lock_acquire __atomic_fetch_add_4: push %ebp mov%esp,%ebp movl $0x5,0x10(%ebp) pop%ebp jmp__atomic_fetch_add_4 Do you have a test case for this compiler/RTEMS bug? The use of libatomic is inefficient, but it should work. -- Sebastian Huber, embedded brains GmbH Address : Dornierstr. 4, D-82178 Puchheim, Germany Phone : +49 89 189 47 41-16 Fax : +49 89 189 47 41-09 E-Mail : sebastian.hu...@embedded-brains.de PGP : Public key available on request. Diese Nachricht ist keine geschäftliche Mitteilung im Sinne des EHUG. ___ devel mailing list devel@rtems.org http://lists.rtems.org/mailman/listinfo/devel
[PATCH 2/2] score: More robust linker sets
Update #2408. Update #2790. --- cpukit/sapi/src/exinit.c | 7 ++- cpukit/score/include/rtems/linkersets.h | 50 +- testsuites/sptests/splinkersets01/init.c | 73 +++- 3 files changed, 80 insertions(+), 50 deletions(-) diff --git a/cpukit/sapi/src/exinit.c b/cpukit/sapi/src/exinit.c index 7988a5b..f4bea7c 100644 --- a/cpukit/sapi/src/exinit.c +++ b/cpukit/sapi/src/exinit.c @@ -131,8 +131,11 @@ RTEMS_SYSINIT_ITEM( void rtems_initialize_executive(void) { - const volatile rtems_sysinit_item *cur = RTEMS_LINKER_SET_BEGIN(_Sysinit ); - const volatile rtems_sysinit_item *end = RTEMS_LINKER_SET_END( _Sysinit ); + const rtems_sysinit_item *cur; + const rtems_sysinit_item *end; + + RTEMS_LINKER_SET_ASSIGN_BEGIN(_Sysinit, cur ); + RTEMS_LINKER_SET_ASSIGN_END( _Sysinit, end ); /* Invoke the registered system initialization handlers */ while ( cur != end ) { diff --git a/cpukit/score/include/rtems/linkersets.h b/cpukit/score/include/rtems/linkersets.h index 47c210d..b790fa5 100644 --- a/cpukit/score/include/rtems/linkersets.h +++ b/cpukit/score/include/rtems/linkersets.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2015 embedded brains GmbH. All rights reserved. + * Copyright (c) 2015, 2016 embedded brains GmbH. All rights reserved. * * embedded brains GmbH * Dornierstr. 4 @@ -21,40 +21,52 @@ extern "C" { #endif /* __cplusplus */ -#define RTEMS_LINKER_SET_BEGIN( set ) \ +#define _LINKER_SET_BEGIN( set ) \ _Linker_set_##set##_begin -#define RTEMS_LINKER_SET_END( set ) \ +#define _LINKER_SET_END( set ) \ _Linker_set_##set##_end +#define RTEMS_LINKER_SET_ASSIGN_BEGIN( set, item ) \ + do { \ +item = _LINKER_SET_BEGIN( set ); \ +RTEMS_OBFUSCATE_POINTER( item ); \ + } while ( 0 ) + +#define RTEMS_LINKER_SET_ASSIGN_END( set, item ) \ + do { \ +item = _LINKER_SET_END( set ); \ +RTEMS_OBFUSCATE_POINTER( item ); \ + } while ( 0 ) + #define RTEMS_LINKER_SET_SIZE( set ) \ ( (size_t) ( _Linker_set_##set##_end - _Linker_set_##set##_begin ) ) #define RTEMS_LINKER_ROSET_DECLARE( set, type ) \ - extern type volatile const RTEMS_LINKER_SET_BEGIN( set )[0]; \ - extern type volatile const RTEMS_LINKER_SET_END( set )[0] + extern type const _LINKER_SET_BEGIN( set )[0]; \ + extern type const _LINKER_SET_END( set )[0] #define RTEMS_LINKER_ROSET( set, type ) \ - type volatile const RTEMS_LINKER_SET_BEGIN( set )[0] \ + type const _LINKER_SET_BEGIN( set )[0] \ RTEMS_SECTION( ".rtemsroset." #set ".begin" ) RTEMS_USED; \ - type volatile const RTEMS_LINKER_SET_END( set )[0] \ + type const _LINKER_SET_END( set )[0] \ RTEMS_SECTION( ".rtemsroset." #set ".end" ) RTEMS_USED #define RTEMS_LINKER_ROSET_ITEM_DECLARE( set, type, item ) \ - extern type volatile const _Linker_set_##set##_##item + extern type const _Linker_set_##set##_##item #define RTEMS_LINKER_ROSET_ITEM_REFERENCE( set, type, item ) \ - static type volatile const * const _Set_reference_##set##_##item \ + static type const * const _Set_reference_##set##_##item \ RTEMS_SECTION( ".rtemsroset.reference" ) RTEMS_USED = \ &_Linker_set_##set##_##item #define RTEMS_LINKER_ROSET_ITEM_ORDERED( set, type, item, order ) \ - type volatile const _Linker_set_##set##_##item \ + type const _Linker_set_##set##_##item \ RTEMS_SECTION( ".rtemsroset." #set ".content.0." RTEMS_XSTRING( order ) ) \ RTEMS_USED #define RTEMS_LINKER_ROSET_ITEM( set, type, item ) \ - type volatile const _Linker_set_##set##_##item \ + type const _Linker_set_##set##_##item \ RTEMS_SECTION( ".rtemsroset." #set ".content.1" ) RTEMS_USED #define RTEMS_LINKER_ROSET_CONTENT( set, decl ) \ @@ -62,17 +74,17 @@ extern "C" { RTEMS_SECTION( ".rtemsroset." #set ".content" ) #define RTEMS_LINKER_RWSET_DECLARE( set, type ) \ - extern type volatile RTEMS_LINKER_SET_BEGIN( set )[0]; \ - extern type volatile RTEMS_LINKER_SET_END( set )[0] + extern type _LINKER_SET_BEGIN( set )[0]; \ + extern type _LINKER_SET_END( set )[0] #define RTEMS_LINKER_RWSET( set, type ) \ - type volatile RTEMS_LINKER_SET_BEGIN( set )[0] \ + type _LINKER_SET_BEGIN( set )[0] \ RTEMS_SECTION( ".rtemsrwset." #set ".begin" ) RTEMS_USED; \ - type volatile RTEMS_LINKER_SET_END( set )[0] \ + type _LINKER_SET_END( set )[0] \ RTEMS_SECTION( ".rtemsrwset." #set ".end" ) RTEMS_USED #define RTEMS_LINKER_RWSET_ITEM_DECLARE( set, type, item ) \ - extern type volatile _Linker_set_##set##_##item + extern type _Linker_set_##set##_##item /* * The .rtemsroset is here not a typo. We must ensure that the references are @@ -80,17 +92,17 @@ extern "C" { * in a dedicated area of the RTEMS read-only linker set section. */ #define RTEMS_LINKER_RWSET_ITEM_REFERENCE( set, type, item ) \ - static type volatile * const _Set_reference_##set##_##item \ + static type * const _Set_reference_##set##_##item \ RTEMS_SECTION( ".rtemsroset.reference" ) RTEMS_USED = \ &_Linker_set_##set##
[PATCH 1/2] score: Add RTEMS_OBFUSCATE_POINTER()
Update #2790. --- cpukit/score/include/rtems/score/basedefs.h | 12 +++- 1 file changed, 11 insertions(+), 1 deletion(-) diff --git a/cpukit/score/include/rtems/score/basedefs.h b/cpukit/score/include/rtems/score/basedefs.h index c378635..ea4d831 100644 --- a/cpukit/score/include/rtems/score/basedefs.h +++ b/cpukit/score/include/rtems/score/basedefs.h @@ -10,7 +10,7 @@ * COPYRIGHT (c) 1989-2007. * On-Line Applications Research Corporation (OAR). * - * Copyright (c) 2010-2015 embedded brains GmbH. + * Copyright (c) 2010, 2016 embedded brains GmbH. * * The license and distribution terms for this file may be * found in the file LICENSE in this distribution or at @@ -221,6 +221,16 @@ #define RTEMS_PRINTFLIKE( _format_pos, _ap_pos ) #endif +/** + * @brief Obfuscates the pointer so that the compiler cannot perform + * optimizations based on the pointer value. + */ +#if defined(__GNUC__) + #define RTEMS_OBFUSCATE_POINTER( _ptr ) __asm__("" : "+r" (_ptr)) +#else + #define RTEMS_OBFUSCATE_POINTER( _ptr ) (void) (_ptr) +#endif + #if __cplusplus >= 201103L #define RTEMS_STATIC_ASSERT(cond, msg) \ static_assert(cond, # msg) -- 1.8.4.5 ___ devel mailing list devel@rtems.org http://lists.rtems.org/mailman/listinfo/devel
Re: [PATCH 1/2] score: Add RTEMS_OBFUSCATE_POINTER()
On 12/10/16 11:13, Sebastian Huber wrote: Update #2790. --- cpukit/score/include/rtems/score/basedefs.h | 12 +++- 1 file changed, 11 insertions(+), 1 deletion(-) diff --git a/cpukit/score/include/rtems/score/basedefs.h b/cpukit/score/include/rtems/score/basedefs.h index c378635..ea4d831 100644 --- a/cpukit/score/include/rtems/score/basedefs.h +++ b/cpukit/score/include/rtems/score/basedefs.h @@ -10,7 +10,7 @@ * COPYRIGHT (c) 1989-2007. * On-Line Applications Research Corporation (OAR). * - * Copyright (c) 2010-2015 embedded brains GmbH. + * Copyright (c) 2010, 2016 embedded brains GmbH. * * The license and distribution terms for this file may be * found in the file LICENSE in this distribution or at @@ -221,6 +221,16 @@ #define RTEMS_PRINTFLIKE( _format_pos, _ap_pos ) #endif +/** + * @brief Obfuscates the pointer so that the compiler cannot perform + * optimizations based on the pointer value. + */ +#if defined(__GNUC__) + #define RTEMS_OBFUSCATE_POINTER( _ptr ) __asm__("" : "+r" (_ptr)) +#else + #define RTEMS_OBFUSCATE_POINTER( _ptr ) (void) (_ptr) +#endif + #if __cplusplus >= 201103L #define RTEMS_STATIC_ASSERT(cond, msg) \ static_assert(cond, # msg) Looks like this works for any variable that can reside in a register. So maybe change this to RTEMS_OBFUSCATE_VARIABLE( _var ) See also discussion here: https://gcc.gnu.org/ml/gcc/2016-09/msg00114.html -- Sebastian Huber, embedded brains GmbH Address : Dornierstr. 4, D-82178 Puchheim, Germany Phone : +49 89 189 47 41-16 Fax : +49 89 189 47 41-09 E-Mail : sebastian.hu...@embedded-brains.de PGP : Public key available on request. Diese Nachricht ist keine geschäftliche Mitteilung im Sinne des EHUG. ___ devel mailing list devel@rtems.org http://lists.rtems.org/mailman/listinfo/devel
Re: [PATCH 2/3] bsps/i386: use Pentimum instructions for pc586 and pc686 builds.
Hello Sebastian, On Wednesday 12 of October 2016 10:35:55 Sebastian Huber wrote: > On 12/10/16 10:26, p...@cmp.felk.cvut.cz wrote: > > SMP build is broken with i386 set because libatomic and GCC > > generate infinite loop for __atomic_fetch_add_4 used > > in rtems_interrupt_lock_acquire > > > > __atomic_fetch_add_4: > > push %ebp > > mov%esp,%ebp > > movl $0x5,0x10(%ebp) > > pop%ebp > > jmp__atomic_fetch_add_4 > > Do you have a test case for this compiler/RTEMS bug? The use of > libatomic is inefficient, but it should work. may be it is problem of my i386 toolchain build, I have not updated it from April. The next is a simple test #include atomic_uint atvar1; volatile unsigned int res1; volatile unsigned int res2; int main(void) { res1 = atomic_fetch_or(&atvar1, 0x55); res2 = atomic_fetch_add(&atvar1, 0xaa); return 0; } The next build commands are used i386-rtems4.12-gcc --pipe -B/opt/rtems4.12/i386-rtems4.12/pc686/lib/ -specs bsp_specs -qrtems-I /opt/rtems4.12/i386-rtems4.12/pc686/lib/include -march=i386 -Wall -O2 -g -ffunction-sections -fdata-sections -o libatomic-add-test.o -c libatomic-add-test.c i386-rtems4.12-gcc --pipe -B/opt/rtems4.12/i386-rtems4.12/pc686/lib/ -specs bsp_specs -qrtems -mtune=pentiumpro -march=pentium -Wall -O2 -g -ffunction-sections -fdata-sections -Wl,--gc-sections -Wl,-Ttext,0x0010 libatomic-add-test.o -o libatomic-test-add problem appears with and without -march=i386, when -march is something newer (pentium) then all is OK. Disassembly looks like 00120a76 <__atomic_fetch_add_4>: 120a76: 55 push %ebp 120a77: 89 e5 mov%esp,%ebp 120a79: c7 45 10 05 00 00 00movl $0x5,0x10(%ebp) 120a80: 5d pop%ebp 120a81: eb f3 jmp120a76 <__atomic_fetch_add_4> 00120a83 <__atomic_add_fetch_4>: 120a83: 55 push %ebp 120a84: 89 e5 mov%esp,%ebp 120a86: c7 45 10 05 00 00 00movl $0x5,0x10(%ebp) 120a8d: 5d pop%ebp 120a8e: eb e6 jmp120a76 <__atomic_fetch_add_4> 00120a90 <__atomic_fetch_or_4>: 120a90: 55 push %ebp 120a91: 89 e5 mov%esp,%ebp 120a93: 56 push %esi 120a94: 53 push %ebx 120a95: 83 ec 0csub$0xc,%esp 120a98: 8b 5d 08mov0x8(%ebp),%ebx 120a9b: 53 push %ebx 120a9c: e8 df 66 00 00 call 127180 <_Libatomic_Protect_start> 120aa1: 8b 33 mov(%ebx),%esi 120aa3: 8b 55 0cmov0xc(%ebp),%edx 120aa6: 09 f2 or %esi,%edx 120aa8: 89 13 mov%edx,(%ebx) 120aaa: 5a pop%edx 120aab: 59 pop%ecx 120aac: 50 push %eax 120aad: 53 push %ebx 120aae: e8 ed 66 00 00 call 1271a0 <_Libatomic_Protect_end> 120ab3: 8d 65 f8lea-0x8(%ebp),%esp 120ab6: 89 f0 mov%esi,%eax 120ab8: 5b pop%ebx 120ab9: 5e pop%esi 120aba: 5d pop%ebp 120abb: c3 ret _Libatomic_Protect_start is provided by RTEMS. 00127180 <_Libatomic_Protect_start>: __uint32_t _Libatomic_Protect_start( void *ptr ) { ISR_Level isr_level; (void) ptr; _ISR_Local_disable( isr_level ); 127180: 9c pushf 127181: fa cli 127182: 58 pop%eax static inline bool _CPU_atomic_Flag_test_and_set( CPU_atomic_Flag *obj, CPU_atomic_Order order ) { #if defined(_RTEMS_SCORE_CPUSTDATOMIC_USE_ATOMIC) return obj->test_and_set( order ); #elif defined(_RTEMS_SCORE_CPUSTDATOMIC_USE_STDATOMIC) return atomic_flag_test_and_set_explicit( obj, order ); 127183: b1 01 mov$0x1,%cl 127185: 8d 74 26 00 lea0x0(%esi,%eiz,1),%esi 127189: 8d bc 27 00 00 00 00lea0x0(%edi,%eiz,1),%edi 127190: 88 ca mov%cl,%dl 127192: 86 15 8c 85 13 00 xchg %dl,0x13858c #if defined(RTEMS_SMP) while ( 127198: 84 d2 test %dl,%dl 12719a: 75 f4 jne127190 <_Libatomic_Protect_start+0x10> --
Re: [PATCH 2/3] bsps/i386: use Pentimum instructions for pc586 and pc686 builds.
This looks like a compiler or libatomic configuration bug. I currently have no time to investigate this further. On 12/10/16 15:36, Pavel Pisa wrote: Hello Sebastian, On Wednesday 12 of October 2016 10:35:55 Sebastian Huber wrote: On 12/10/16 10:26, p...@cmp.felk.cvut.cz wrote: SMP build is broken with i386 set because libatomic and GCC generate infinite loop for __atomic_fetch_add_4 used in rtems_interrupt_lock_acquire __atomic_fetch_add_4: push %ebp mov%esp,%ebp movl $0x5,0x10(%ebp) pop%ebp jmp__atomic_fetch_add_4 Do you have a test case for this compiler/RTEMS bug? The use of libatomic is inefficient, but it should work. may be it is problem of my i386 toolchain build, I have not updated it from April. The next is a simple test #include atomic_uint atvar1; volatile unsigned int res1; volatile unsigned int res2; int main(void) { res1 = atomic_fetch_or(&atvar1, 0x55); res2 = atomic_fetch_add(&atvar1, 0xaa); return 0; } The next build commands are used i386-rtems4.12-gcc --pipe -B/opt/rtems4.12/i386-rtems4.12/pc686/lib/ -specs bsp_specs -qrtems-I /opt/rtems4.12/i386-rtems4.12/pc686/lib/include -march=i386 -Wall -O2 -g -ffunction-sections -fdata-sections -o libatomic-add-test.o -c libatomic-add-test.c i386-rtems4.12-gcc --pipe -B/opt/rtems4.12/i386-rtems4.12/pc686/lib/ -specs bsp_specs -qrtems -mtune=pentiumpro -march=pentium -Wall -O2 -g -ffunction-sections -fdata-sections -Wl,--gc-sections -Wl,-Ttext,0x0010 libatomic-add-test.o -o libatomic-test-add problem appears with and without -march=i386, when -march is something newer (pentium) then all is OK. Disassembly looks like 00120a76 <__atomic_fetch_add_4>: 120a76: 55 push %ebp 120a77: 89 e5 mov%esp,%ebp 120a79: c7 45 10 05 00 00 00movl $0x5,0x10(%ebp) 120a80: 5d pop%ebp 120a81: eb f3 jmp120a76 <__atomic_fetch_add_4> 00120a83 <__atomic_add_fetch_4>: 120a83: 55 push %ebp 120a84: 89 e5 mov%esp,%ebp 120a86: c7 45 10 05 00 00 00movl $0x5,0x10(%ebp) 120a8d: 5d pop%ebp 120a8e: eb e6 jmp120a76 <__atomic_fetch_add_4> 00120a90 <__atomic_fetch_or_4>: 120a90: 55 push %ebp 120a91: 89 e5 mov%esp,%ebp 120a93: 56 push %esi 120a94: 53 push %ebx 120a95: 83 ec 0csub$0xc,%esp 120a98: 8b 5d 08mov0x8(%ebp),%ebx 120a9b: 53 push %ebx 120a9c: e8 df 66 00 00 call 127180 <_Libatomic_Protect_start> 120aa1: 8b 33 mov(%ebx),%esi 120aa3: 8b 55 0cmov0xc(%ebp),%edx 120aa6: 09 f2 or %esi,%edx 120aa8: 89 13 mov%edx,(%ebx) 120aaa: 5a pop%edx 120aab: 59 pop%ecx 120aac: 50 push %eax 120aad: 53 push %ebx 120aae: e8 ed 66 00 00 call 1271a0 <_Libatomic_Protect_end> 120ab3: 8d 65 f8lea-0x8(%ebp),%esp 120ab6: 89 f0 mov%esi,%eax 120ab8: 5b pop%ebx 120ab9: 5e pop%esi 120aba: 5d pop%ebp 120abb: c3 ret _Libatomic_Protect_start is provided by RTEMS. 00127180 <_Libatomic_Protect_start>: __uint32_t _Libatomic_Protect_start( void *ptr ) { ISR_Level isr_level; (void) ptr; _ISR_Local_disable( isr_level ); 127180: 9c pushf 127181: fa cli 127182: 58 pop%eax static inline bool _CPU_atomic_Flag_test_and_set( CPU_atomic_Flag *obj, CPU_atomic_Order order ) { #if defined(_RTEMS_SCORE_CPUSTDATOMIC_USE_ATOMIC) return obj->test_and_set( order ); #elif defined(_RTEMS_SCORE_CPUSTDATOMIC_USE_STDATOMIC) return atomic_flag_test_and_set_explicit( obj, order ); 127183: b1 01 mov$0x1,%cl 127185: 8d 74 26 00 lea0x0(%esi,%eiz,1),%esi 127189: 8d bc 27 00 00 00 00lea0x0(%edi,%eiz,1),%edi 127190: 88 ca mov%cl,%dl 127192: 86 15 8c 85 13 00 xchg %dl,0x13858c #if defined(RTEMS_SMP) while (
Re: [PATCH 3/3] libchip/network/if_fxp.c: do not use rtems_interrupt_disable.
Hello Gedare, On Wednesday 12 of October 2016 18:10:19 Gedare Bloom wrote: > On Wed, Oct 12, 2016 at 4:26 AM, wrote: > > From: Pavel Pisa > > > > The single write to memory or ioport output are mostly > > atomic operations already. The proper memory synchronization barrier > > should be used around them to guarantee ordering (sync or eieio > > on PowerPC for example) but because I have not found settable > > portable primitive only compiler barrier is used. > > It should be enough on x86 because the externally visible order > > should be/is guaranteed to be preserved on x86 architecture. > > --- > > c/src/libchip/network/if_fxp.c | 11 --- > > 1 file changed, 4 insertions(+), 7 deletions(-) > > > > diff --git a/c/src/libchip/network/if_fxp.c > > b/c/src/libchip/network/if_fxp.c index 4d9d983..c2ca419 100644 > > --- a/c/src/libchip/network/if_fxp.c > > +++ b/c/src/libchip/network/if_fxp.c > > @@ -1130,7 +1130,6 @@ fxp_start(struct ifnet *ifp) > > { > > struct fxp_softc *sc = ifp->if_softc; > > struct fxp_cb_tx *txp; > > - rtems_interrupt_level level; > > > > DBGLVL_PRINTK(3,"fxp_start called\n"); > > > > @@ -1279,10 +1278,10 @@ tbdinit: > > /* > > * reenable interrupts > > */ > > - rtems_interrupt_disable (level); > > + RTEMS_COMPILER_MEMORY_BARRIER(); > > CSR_WRITE_1(sc, FXP_CSR_SCB_INTRCNTL,0); > > bsp_interrupt_vector_enable(sc->irq_num); > > Here you don't delete bsp_interrupt_vector_enable ... Good catch. The reason is that there should not be bsp_interrupt_vector_enable() in neither. The interrupt is enabled after attach and should stay that way for whole driver life. The disable at ISR level and enable in daemon is controlled on the board registers level for FXP which is how correct PCI driver with possibly shared interrupts should work. But RTEMS i8269 support has been broken to disable vector for level triggered interrupts in generic IRQ processing code. So I have introduced reenable bsp_interrupt_vector_enable to ensure that driver can work even with that setup. classic networking: adapt FXP driver to work with actual PCI and IRQ code. The hack is not required after bsps/i386: Separate variable for i8259 IRQs disable due to in progress state. so I have removed unneeded reenable from daemon hot path. I have left it in the setup to be sure that it is enabled after some driver stop start cycles. In theory, this occurrence should be deleted as well. Generally, I am not sure if/how much I have broken/I am breaking i386 support by all these changes. I believe only, hat it is the right direction. I would be happy to discus them with others. Thanks for review, Pavel > > - rtems_interrupt_enable (level); > > + RTEMS_COMPILER_MEMORY_BARRIER(); > > } > > > > /* > > @@ -1311,7 +1310,6 @@ static void fxp_daemon(void *xsc) > > struct ifnet *ifp = &sc->sc_if; > > u_int8_t statack; > > rtems_event_set events; > > - rtems_interrupt_level level; > > > > #ifdef NOTUSED > > if (sc->suspended) { > > @@ -1458,10 +1456,9 @@ rcvloop: > > /* > >* reenable interrupts > >*/ > > - rtems_interrupt_disable (level); > > + RTEMS_COMPILER_MEMORY_BARRIER(); > > CSR_WRITE_1(sc, FXP_CSR_SCB_INTRCNTL,0); > > - bsp_interrupt_vector_enable(sc->irq_num); > > ... here you do. Why are the cases different? > > > - rtems_interrupt_enable (level); > > + RTEMS_COMPILER_MEMORY_BARRIER(); > > } > > } > > > > -- > > 1.9.1 > > ___ devel mailing list devel@rtems.org http://lists.rtems.org/mailman/listinfo/devel
Re: [PATCH 3/3] libchip/network/if_fxp.c: do not use rtems_interrupt_disable.
On 13/10/2016 03:22, Pavel Pisa wrote: But RTEMS i8269 support has been broken to disable vector for level triggered interrupts in generic IRQ processing code. I am not sure where the blame should be placed. We need to disable at the PIC when using libbsd with shared PCI interrupts because an interrupt server is used that is common to a few architectures. Some legacy drivers like this one assume processing inside the interrupt context. It is not clear to me shared interrupts were ever supported with these drivers. I would assume it means some type of per driver interrupt chaining. So I have introduced reenable bsp_interrupt_vector_enable to ensure that driver can work even with that setup. I am not sure we can mix both models without some changes. classic networking: adapt FXP driver to work with actual PCI and IRQ code. The hack is not required after Which hack? bsps/i386: Separate variable for i8259 IRQs disable due to in progress state. so I have removed unneeded reenable from daemon hot path. I have left it in the setup to be sure that it is enabled after some driver stop start cycles. In theory, this occurrence should be deleted as well. Generally, I am not sure if/how much I have broken/I am breaking i386 support by all these changes. I have not testing the i386 with libbsd with your recent changes. I will see what I can do. I did not notice the enables/disables had been changed. I believe only, hat it is the right direction. I am sorry it is not clear to me what direction this is. Chris ___ devel mailing list devel@rtems.org http://lists.rtems.org/mailman/listinfo/devel
Re: [PATCH 3/3] libchip/network/if_fxp.c: do not use rtems_interrupt_disable.
Hello Chris, On Wednesday 12 of October 2016 23:05:30 Chris Johns wrote: > On 13/10/2016 03:22, Pavel Pisa wrote: > > But RTEMS i8269 support has been broken to disable > > vector for level triggered interrupts in generic > > IRQ processing code. > > I am not sure where the blame should be placed. We need to disable at > the PIC when using libbsd with shared PCI interrupts because an > interrupt server is used that is common to a few architectures. Some > legacy drivers like this one assume processing inside the interrupt > context. It is not clear to me shared interrupts were ever supported > with these drivers. I would assume it means some type of per driver > interrupt chaining. > > > So I have introduced reenable > > bsp_interrupt_vector_enable to ensure that driver > > can work even with that setup. > > I am not sure we can mix both models without some changes. I hope that interrupt server should work after the committed change. At least, I have feeling that it has been outcome of previous debate. The IRQ server bsp_interrupt_server_trigger() disables given IRQ vector on PIC level in hardware IRQ context by bsp_interrupt_vector_disable() See https://git.rtems.org/rtems/tree/c/src/lib/libbsp/shared/src/irq-server.c#n64 I would not push the changes if it has not be a case. > > classic networking: adapt FXP driver to work with actual PCI and IRQ > > code. > > > > The hack is not required after > > Which hack? The reenabling of PIC level ISR in driver code. Generally I consider the functions bsp_interrupt_vector_disable() and bsp_interrupt_vector_enable() should be used as paired and use should allow to use them even if implemented as counting disable clock. That is implementation where bsp_interrupt_vector_enable() enables vector only after same number of calls as was the number of calls bsp_interrupt_vector_enable() > > bsps/i386: Separate variable for i8259 IRQs disable due to in progress > > state. > > > > so I have removed unneeded reenable from daemon hot path. > > I have left it in the setup to be sure that it is enabled > > after some driver stop start cycles. > > > > In theory, this occurrence should be deleted as well. > > > > Generally, I am not sure if/how much I have broken/I am > > breaking i386 support by all these changes. > > I have not testing the i386 with libbsd with your recent changes. I will > see what I can do. I did not notice the enables/disables had been changed. > > > I believe only, hat it is the right direction. > > I am sorry it is not clear to me what direction this is. I have on mind changes required for i386 BSP SMP build and generally that all RTEMS code (not only x86) should eliminate constructs based on UP assumptions or directly incompatible with SMP. That is rtems_interrupt_lock_acquire should be used to protect low level operations which has to be serialized (short system level/hardware critical sections). i386 support needs to move forward. basic SMP support and LAPIC seems to be included. So it needs to enable its testing. The proposed changes allows the build. I have tested UP and SMP i386 builds only under QEMU. My test of networking, RTL and some others seems to work for both builds. UP and SMP build single core applications seems to run on real HW. SMP build with 1 CPU output on real HW - novaboot: Serial line interaction (press Ctrl-C to interrupt)... Scanning from 0x9D400 for 1024 bytes Scanning from 0xF for 65536 bytes Found MP Floating Structure Pointer at FDA40 Intel MultiProcessor Spec 1.4 BIOS support detected APIC config: "Virtual Wire mode"Local APIC address: 0xFEE0 OEM id: CBX3 Product id: DELL Bus id 0 is PCI Bus id 1 is PCI Bus id 2 is PCI Bus id 3 is PCI Bus id 4 is ISA I/O APIC id 2 ver 32, address: 0xFEC0 WARNING!! Found more CPUs (4) than configured for (1)!! RTEMS v 4.11.99 Starting application appfoo v 0.1.0 *** Starting up Task_1 *** Task_1 woken RTEMS Shell on /dev/console. Use 'help' to list commands. [/] # Task_1 woken Task_1 woken - When I try to enable two CPUs and try to run SMP build on QEMU and real HW then it breaks. REAL HW output - i386: isr=0 irr=1 Scanning from 0x9D400 for 1024 bytes Scanning from 0xF for 65536 bytes Found MP Floating Structure Pointer at FDA40 Intel MultiProcessor Spec 1.4 BIOS support detected APIC config: "Virtual Wire mode"Local APIC address: 0xFEE0 OEM id: CBX3 Product id: DELL Processor [APIC id 0 ver 21]: #0 BootStrap Processor (BSP) Processor [APIC id 2 ver 21]: i386: isr=0 irr=1 Scanning from 0x9D400 for 1024 bytes Scanning from 0xF for 65536 bytes Found MP Floating Structure Pointer at FDA40 Intel MultiProcessor Spec 1.4 BIOS support detected APIC config: "Virtual Wire mode"Local APIC address: 0xFEE0 OEM id: CBX
Re: [rtems commit] score: More robust linker sets
On 12/10/2016 20:13, Sebastian Huber wrote: Module:rtems Branch:master Commit:be573185e6d6ddafdd3612c7c2db04aa0f65a330 Changeset: http://git.rtems.org/rtems/commit/?id=be573185e6d6ddafdd3612c7c2db04aa0f65a330 Author:Sebastian Huber Date: Fri Sep 23 06:45:07 2016 +0200 score: More robust linker sets Update #2408. Update #2790. -#define RTEMS_LINKER_SET_BEGIN( set ) \ +#define _LINKER_SET_BEGIN( set ) \ _Linker_set_##set##_begin -#define RTEMS_LINKER_SET_END( set ) \ +#define _LINKER_SET_END( set ) \ _Linker_set_##set##_end This has broken libbsd here https://git.rtems.org/rtems-libbsd/tree/freebsd/contrib/pf/pfctl/pfctl.c#n2100 Chris ___ devel mailing list devel@rtems.org http://lists.rtems.org/mailman/listinfo/devel
Re: [rtems commit] score: More robust linker sets
On 13/10/2016 14:08, Chris Johns wrote: On 12/10/2016 20:13, Sebastian Huber wrote: Module:rtems Branch:master Commit:be573185e6d6ddafdd3612c7c2db04aa0f65a330 Changeset: http://git.rtems.org/rtems/commit/?id=be573185e6d6ddafdd3612c7c2db04aa0f65a330 Author:Sebastian Huber Date: Fri Sep 23 06:45:07 2016 +0200 score: More robust linker sets Update #2408. Update #2790. -#define RTEMS_LINKER_SET_BEGIN( set ) \ +#define _LINKER_SET_BEGIN( set ) \ _Linker_set_##set##_begin -#define RTEMS_LINKER_SET_END( set ) \ +#define _LINKER_SET_END( set ) \ _Linker_set_##set##_end This has broken libbsd here https://git.rtems.org/rtems-libbsd/tree/freebsd/contrib/pf/pfctl/pfctl.c#n2100 This patch OK? $ git diff diff --git a/freebsd/contrib/pf/pfctl/pfctl.c b/freebsd/contrib/pf/pfctl/pfctl.c index 8dc289e..357dcb6 100644 --- a/freebsd/contrib/pf/pfctl/pfctl.c +++ b/freebsd/contrib/pf/pfctl/pfctl.c @@ -2097,9 +2097,11 @@ int rtems_bsd_command_pfctl(int argc, char *argv[]) { int exit_code = EXIT_FAILURE; - const void *data_buf = RTEMS_LINKER_SET_BEGIN(bsd_prog_pfctl); + const void *data_buf; const size_t data_size = RTEMS_LINKER_SET_SIZE(bsd_prog_pfctl); + RTEMS_LINKER_SET_ASSIGN_BEGIN(bsd_prog_pfctl, data_buf); + rtems_bsd_program_lock(); exit_code = rtems_bsd_program_call_main_with_data_restore("pfctl", main, argc, argv, data_buf, data_size); Chris ___ devel mailing list devel@rtems.org http://lists.rtems.org/mailman/listinfo/devel
Re: [rtems commit] score: More robust linker sets
On 13/10/16 05:08, Chris Johns wrote: On 12/10/2016 20:13, Sebastian Huber wrote: Module:rtems Branch:master Commit:be573185e6d6ddafdd3612c7c2db04aa0f65a330 Changeset: http://git.rtems.org/rtems/commit/?id=be573185e6d6ddafdd3612c7c2db04aa0f65a330 Author:Sebastian Huber Date: Fri Sep 23 06:45:07 2016 +0200 score: More robust linker sets Update #2408. Update #2790. -#define RTEMS_LINKER_SET_BEGIN( set ) \ +#define _LINKER_SET_BEGIN( set ) \ _Linker_set_##set##_begin -#define RTEMS_LINKER_SET_END( set ) \ +#define _LINKER_SET_END( set ) \ _Linker_set_##set##_end This has broken libbsd here https://git.rtems.org/rtems-libbsd/tree/freebsd/contrib/pf/pfctl/pfctl.c#n2100 Sorry, I checked in this: https://git.rtems.org/rtems-libbsd/commit/?id=40f202da4e2ddb70bdc2d93c7535f9bf22ea070b -- Sebastian Huber, embedded brains GmbH Address : Dornierstr. 4, D-82178 Puchheim, Germany Phone : +49 89 189 47 41-16 Fax : +49 89 189 47 41-09 E-Mail : sebastian.hu...@embedded-brains.de PGP : Public key available on request. Diese Nachricht ist keine geschäftliche Mitteilung im Sinne des EHUG. ___ devel mailing list devel@rtems.org http://lists.rtems.org/mailman/listinfo/devel