diff --git a/.github/workflows/ci-scripts-build.yml b/.github/workflows/ci-scripts-build.yml index 75dc48c91..855569578 100644 --- a/.github/workflows/ci-scripts-build.yml +++ b/.github/workflows/ci-scripts-build.yml @@ -43,7 +43,9 @@ jobs: BCFG: ${{ matrix.configuration }} WINE: ${{ matrix.wine }} RTEMS: ${{ matrix.rtems }} + RTEMS_TARGET: ${{ matrix.rtems_target }} EXTRA: ${{ matrix.extra }} + TEST: ${{ matrix.test }} strategy: fail-fast: false matrix: @@ -78,17 +80,74 @@ jobs: extra: "CMD_CXXFLAGS=-std=c++11" name: "Ub-20 clang-10 C++11" + - os: ubuntu-20.04 + cmp: gcc + configuration: default + rtems: "5" + rtems_target: RTEMS-pc686-qemu + name: "Ub-20 gcc-9 + RT-5.1 pc686" + + - os: ubuntu-20.04 + cmp: gcc + configuration: default + rtems: "5" + rtems_target: RTEMS-beatnik + test: NO + name: "Ub-20 gcc-9 + RT-5.1 beatnik" + + # - os: ubuntu-20.04 + # cmp: gcc + # configuration: default + # rtems: "5" + # rtems_target: RTEMS-mvme2100 + # test: NO + # name: "Ub-20 gcc-9 + RT-5.1 mvme2100" + + - os: ubuntu-20.04 + cmp: gcc + configuration: default + rtems: "5" + rtems_target: RTEMS-mvme3100 + test: NO + name: "Ub-20 gcc-9 + RT-5.1 mvme3100" + + - os: ubuntu-20.04 + cmp: gcc + configuration: default + rtems: "5" + rtems_target: RTEMS-qoriq_e500 + test: NO + name: "Ub-20 gcc-9 + RT-5.1 qoriq_e500" + + - os: ubuntu-20.04 + cmp: gcc + configuration: default + rtems: "5" + rtems_target: RTEMS-xilinx_zynq_a9_qemu + test: NO + name: "Ub-20 gcc-9 + RT-5.1 xilinx_zynq_a9_qemu" + + - os: ubuntu-20.04 + cmp: gcc + configuration: default + rtems: "5" + rtems_target: RTEMS-uC5282 + test: NO + name: "Ub-20 gcc-9 + RT-5.1 uC5282" + - os: ubuntu-20.04 cmp: gcc configuration: default rtems: "4.10" name: "Ub-20 gcc-9 + RT-4.10" + rtems_target: RTEMS-pc386-qemu - os: ubuntu-20.04 cmp: gcc configuration: default rtems: "4.9" name: "Ub-20 gcc-9 + RT-4.9" + rtems_target: RTEMS-pc386-qemu - os: ubuntu-16.04 cmp: gcc-4.8 diff --git a/configure/CONFIG b/configure/CONFIG index fab3c245f..1c1242858 100644 --- a/configure/CONFIG +++ b/configure/CONFIG @@ -62,6 +62,9 @@ include $(CONFIG)/os/CONFIG.$(EPICS_HOST_ARCH).Common RELEASE_TOPS := $(shell $(CONVERTRELEASE) -T $(TOP) releaseTops) ifdef T_A + # Information from the target's compiler + # + -include $(EPICS_BASE)/cfg/TOOLCHAIN.$(EPICS_HOST_ARCH).$(T_A) # Cross compile specific definitions # diff --git a/configure/CONFIG_COMMON b/configure/CONFIG_COMMON index 825725973..61e85904c 100644 --- a/configure/CONFIG_COMMON +++ b/configure/CONFIG_COMMON @@ -142,9 +142,10 @@ BUILDLIB_SUFFIX = $(BUILDLIB_SUFFIX_$(SHARED_LIBRARIES)) #-------------------------------------------------- # vpath directories POSIX_YES = os/posix +OS_IMPL_DIRS = $(if $(OS_API),os/$(OS_CLASS)-$(OS_API),) os/$(OS_CLASS) GENERIC_SRC_DIRS = .. $(SRC_DIRS) OS_SRC_DIRS += . $(foreach dir, .. $(SRC_DIRS), \ - $(addprefix $(dir)/, os/$(OS_CLASS) $(POSIX_$(POSIX)) os/default )) + $(addprefix $(dir)/, $(OS_IMPL_DIRS) $(POSIX_$(POSIX)) os/default )) CMPLR_SRC_DIRS += . $(foreach dir, .. $(SRC_DIRS), \ $(addprefix $(dir)/, compiler/$(CMPLR_CLASS) compiler/default )) ALL_SRC_DIRS = $(CMPLR_SRC_DIRS) $(OS_SRC_DIRS) $(GENERIC_SRC_DIRS) diff --git a/configure/CONFIG_SITE b/configure/CONFIG_SITE index a575c61bf..49dfcab98 100644 --- a/configure/CONFIG_SITE +++ b/configure/CONFIG_SITE @@ -86,6 +86,7 @@ # vxWorks-mpc8540 # vxWorks-mpc8548 # RTEMS-at91rm9200ek +# RTEMS-beagleboneblack # RTEMS-beatnik # RTEMS-gen68360 # RTEMS-mcp750 @@ -95,8 +96,12 @@ # RTEMS-mvme3100 # RTEMS-mvme5500 # RTEMS-pc386 +# RTEMS-pc686 # RTEMS-psim +# RTEMS-qoriq_e500 # RTEMS-uC5282 +# RTEMS-xilinx-zynq_a9_qemu +# RTEMS-xilinx_zynq_zedboad # win32-x86-mingw (linux-x86 or -x86_64 host) # @@ -104,7 +109,6 @@ # Definitions in configure/os/CONFIG_SITE..Common # may override this setting. CROSS_COMPILER_TARGET_ARCHS= -#CROSS_COMPILER_TARGET_ARCHS=vxWorks-ppc32 # If only some of your host architectures can compile the # above CROSS_COMPILER_TARGET_ARCHS specify those host diff --git a/configure/Makefile b/configure/Makefile index f48278dd3..ba77d5089 100644 --- a/configure/Makefile +++ b/configure/Makefile @@ -15,7 +15,8 @@ include $(TOP)/configure/CONFIG TOOLS = $(TOP)/src/tools CONFIGS += $(subst ../,,$(wildcard ../CONFIG*)) -CONFIGS += $(subst ../,,$(wildcard ../os/CONFIG*)) +CONFIGS += $(subst ../,,$(wildcard ../os/CONFIG.*)) +CONFIGS += $(subst ../,,$(wildcard ../os/CONFIG_SITE.*)) CONFIGS += $(subst ../,,$(wildcard ../RELEASE*)) CONFIGS += $(subst ../,,$(wildcard ../RULES*)) @@ -29,5 +30,9 @@ CFG += CONFIG_CA_VERSION CFG += CONFIG_DATABASE_MODULE CFG += CONFIG_DATABASE_VERSION +CFG += TOOLCHAIN.$(EPICS_HOST_ARCH).$(T_A) + include $(TOP)/configure/RULES +TOOLCHAIN.$(EPICS_HOST_ARCH).$(T_A): toolchain.c + $(PREPROCESS.cpp) diff --git a/configure/os/CONFIG.Common.RTEMS b/configure/os/CONFIG.Common.RTEMS index 1319a7b50..1cfe0fe56 100644 --- a/configure/os/CONFIG.Common.RTEMS +++ b/configure/os/CONFIG.Common.RTEMS @@ -28,12 +28,13 @@ ifneq ($(CONFIG),$(TOP)/configure) endif #-------------------------------------------------- -# Set RTEMS_BSP from T_A if not already done +# Set RTEMS_BSP and GNU_TARGET if not already done RTEMS_BSP ?= $(subst RTEMS-,,$(T_A)) +GNU_TARGET ?= $(RTEMS_TARGET_CPU)-rtems #------------------------------------------------------- # Pick up the RTEMS tool/path definitions from the RTEMS BSP directory. -include $(RTEMS_BASE)/$(RTEMS_TARGET_CPU)-rtems$(RTEMS_VERSION)/$(RTEMS_BSP)/Makefile.inc +include $(RTEMS_BASE)/$(GNU_TARGET)$(RTEMS_VERSION)/$(RTEMS_BSP)/Makefile.inc include $(RTEMS_CUSTOM) include $(CONFIG.CC) @@ -41,7 +42,7 @@ include $(CONFIG.CC) # RTEMS cross-development tools CC = $(RTEMS_TOOLS)/bin/$(CC_FOR_TARGET) $(GCCSPECS) -fasm CCC = $(RTEMS_TOOLS)/bin/$(CXX) -CPP = $(RTEMS_TOOLS)/bin/$(CC_FOR_TARGET) -x c -E +CPP = $(RTEMS_TOOLS)/bin/$(CC_FOR_TARGET) -x c -E $(GCCSPECS) AR = $(RTEMS_TOOLS)/bin/$(AR_FOR_TARGET) LD = $(RTEMS_TOOLS)/bin/$(LD_FOR_TARGET) -r @@ -95,20 +96,39 @@ MODEXT=.obj OS_CLASS = RTEMS #-------------------------------------------------- -# Operating system flags -OP_SYS_LDLIBS += -lrtemsCom -lc -lrtemscpu -lCom -lnfs -lm -OP_SYS_LDFLAGS += $(CPU_CFLAGS) -u Init \ +# Operating system compile & link flags +OP_SYS_CFLAGS += -D__LINUX_ERRNO_EXTENSIONS__ + +OP_SYS_CFLAGS_NET_yes = -DRTEMS_LEGACY_STACK +OP_SYS_CFLAGS += $(OP_SYS_CFLAGS_NET_$(RTEMS_HAS_NETWORKING)) + +ifeq ($(RTEMS_HAS_POSIX_API),yes) +POSIX_CPPFLAGS = -D_GNU_SOURCE -D_DEFAULT_SOURCE +endif + +OP_SYS_LDLIBS_posix_NET_yes = -ltftpfs -lnfs -lz -ltelnetd +OP_SYS_LDLIBS_posix_NET_no = -ltftpfs -lbsd -lz +OP_SYS_LDLIBS_kernel_NET_yes = -lnfs +OP_SYS_LDLIBS_kernel_NET_no = -lnfs +OP_SYS_LDLIBS += -lrtemsCom -lCom +OP_SYS_LDLIBS += $(OP_SYS_LDLIBS_$(OS_API)_NET_$(RTEMS_HAS_NETWORKING)) +OP_SYS_LDLIBS += -lrtemscpu -lc -lm + +OP_SYS_LDFLAGS_posix = -u POSIX_Init +OP_SYS_LDFLAGS_kernel = -u Init \ $(PROJECT_RELEASE)/lib/no-dpmem.rel \ $(PROJECT_RELEASE)/lib/no-mp.rel \ $(PROJECT_RELEASE)/lib/no-part.rel \ $(PROJECT_RELEASE)/lib/no-signal.rel \ $(PROJECT_RELEASE)/lib/no-rtmon.rel +OP_SYS_LDFLAGS += $(CPU_CFLAGS) $(OP_SYS_LDFLAGS_$(OS_API)) +# Settings for GeSys MOD_SYS_LDFLAGS += $(CPU_CFLAGS) -Wl,-r -nostdlib # Do not link against libraries which are part of the Generic Image GESYS_LIBS += -lgcc -GESYS_LIBS += -lc -lm -lrtemscpu -lrtemsbsp -lrtems++ -lbspExt +GESYS_LIBS += -lc -lm -lrtemscpu -lrtemsbsp -lrtems++ GESYS_LIBS += -lcexp -ltecla_r -lspencer_regexp -lpmelf -lpmbfd GESYS_LIBS += -lnfs -ltelnetd -lrtems-gdb-stub diff --git a/configure/os/CONFIG.Common.RTEMS-beagleboneblack b/configure/os/CONFIG.Common.RTEMS-beagleboneblack new file mode 100644 index 000000000..4b6107b05 --- /dev/null +++ b/configure/os/CONFIG.Common.RTEMS-beagleboneblack @@ -0,0 +1,18 @@ +# +# CONFIG.Common.RTEMS-beaglebineblack +# Author: Heinz Junkes +# +# All RTEMS targets use the same Makefile fragment +# +#EXE = .elf +RTEMS_BSP = beagleboneblack +RTEMS_TARGET_CPU = arm +GNU_TARGET = arm-rtems + +OP_SYS_LDLIBS += -Wl,--gc-sections +ARCH_DEP_LDFLAGS = -L$(RTEMS_BASE)/$(GNU_TARGET)$(RTEMS_VERSION)/beagleboneblack/lib/ + +include $(CONFIG)/os/CONFIG.Common.RTEMS + + + diff --git a/configure/os/CONFIG.Common.RTEMS-beatnik b/configure/os/CONFIG.Common.RTEMS-beatnik index aaa45e4c9..b133fd489 100644 --- a/configure/os/CONFIG.Common.RTEMS-beatnik +++ b/configure/os/CONFIG.Common.RTEMS-beatnik @@ -8,14 +8,16 @@ EXE = .elf RTEMS_BSP = beatnik RTEMS_TARGET_CPU = powerpc GNU_TARGET = powerpc-rtems -ARCH_DEP_CFLAGS += -DMY_DO_BOOTP=NULL +# optimization trouble in postfix.c +ARCH_DEP_CFLAGS += -DRTEMS_HAS_ALTIVEC +#will use bootp +#ARCH_DEP_CFLAGS += -DMY_DO_BOOTP=NULL ARCH_DEP_CFLAGS += -DHAVE_MOTLOAD ARCH_DEP_CFLAGS += -DRTEMS_NETWORK_CONFIG_MBUF_SPACE=2048 ARCH_DEP_CFLAGS += -DRTEMS_NETWORK_CONFIG_CLUSTER_SPACE=5120 -OP_SYS_LDLIBS += -lbspExt - MUNCH_SUFFIX = .boot +MUNCHNAME = $(PRODNAME:%$(EXE)=%$(MUNCH_SUFFIX)) define MUNCH_CMD $(RTEMS_TOOLS)/bin/$(OBJCOPY_FOR_TARGET) -O binary $< $@ endef diff --git a/configure/os/CONFIG.Common.RTEMS-mvme2100 b/configure/os/CONFIG.Common.RTEMS-mvme2100 index a8e8bf76e..1e222b5ab 100644 --- a/configure/os/CONFIG.Common.RTEMS-mvme2100 +++ b/configure/os/CONFIG.Common.RTEMS-mvme2100 @@ -11,8 +11,6 @@ GNU_TARGET = powerpc-rtems ARCH_DEP_CFLAGS += -DMY_DO_BOOTP=NULL ARCH_DEP_CFLAGS += -DHAVE_PPCBUG -OP_SYS_LDLIBS += -lbspExt - MUNCH_SUFFIX = .boot define MUNCH_CMD $(RTEMS_TOOLS)/bin/$(OBJCOPY_FOR_TARGET) -O binary -R .comment -S $< rtems diff --git a/configure/os/CONFIG.Common.RTEMS-mvme2700 b/configure/os/CONFIG.Common.RTEMS-mvme2700 index a5ad7fbf5..655e0a5b0 100644 --- a/configure/os/CONFIG.Common.RTEMS-mvme2700 +++ b/configure/os/CONFIG.Common.RTEMS-mvme2700 @@ -20,6 +20,4 @@ define MUNCH_CMD rm -f rtems.gz endef -OP_SYS_LDLIBS += -lbspExt - include $(CONFIG)/os/CONFIG.Common.RTEMS diff --git a/configure/os/CONFIG.Common.RTEMS-mvme3100 b/configure/os/CONFIG.Common.RTEMS-mvme3100 index 283e7d680..2cbf49a84 100644 --- a/configure/os/CONFIG.Common.RTEMS-mvme3100 +++ b/configure/os/CONFIG.Common.RTEMS-mvme3100 @@ -13,8 +13,6 @@ ARCH_DEP_CFLAGS += -DHAVE_MOTLOAD ARCH_DEP_CFLAGS += -DRTEMS_NETWORK_CONFIG_MBUF_SPACE=2048 ARCH_DEP_CFLAGS += -DRTEMS_NETWORK_CONFIG_CLUSTER_SPACE=5120 -OP_SYS_LDLIBS += -lbspExt - MUNCH_SUFFIX = .boot define MUNCH_CMD $(RTEMS_TOOLS)/bin/$(OBJCOPY_FOR_TARGET) -O binary $< $@ diff --git a/configure/os/CONFIG.Common.RTEMS-mvme5500 b/configure/os/CONFIG.Common.RTEMS-mvme5500 index 0329185bb..a240a298a 100644 --- a/configure/os/CONFIG.Common.RTEMS-mvme5500 +++ b/configure/os/CONFIG.Common.RTEMS-mvme5500 @@ -14,13 +14,9 @@ ARCH_DEP_CFLAGS += -DRTEMS_NETWORK_CONFIG_MBUF_SPACE=2048 ARCH_DEP_CFLAGS += -DRTEMS_NETWORK_CONFIG_CLUSTER_SPACE=5120 ARCH_DEP_CFLAGS += -DBSP_NVRAM_BASE_ADDR=0xf1110000 -OP_SYS_LDLIBS += -lbspExt - MUNCH_SUFFIX = .boot define MUNCH_CMD $(RTEMS_TOOLS)/bin/$(OBJCOPY_FOR_TARGET) -O binary $< $@ endef -OP_SYS_LDLIBS += -lbspExt - include $(CONFIG)/os/CONFIG.Common.RTEMS diff --git a/configure/os/CONFIG.Common.RTEMS-pc386 b/configure/os/CONFIG.Common.RTEMS-pc386 index 8dfa7d2ba..9fc518d6b 100644 --- a/configure/os/CONFIG.Common.RTEMS-pc386 +++ b/configure/os/CONFIG.Common.RTEMS-pc386 @@ -1,12 +1,13 @@ +# CONFIG.Common.RTEMS-pc386 # -# Author: W. Eric Norum -# Canadian Light Source -# eric@cls.usask.ca -# -# All RTEMS targets use the same Makefile fragment +# Definitions for the RTEMS-pc386 target, RTEMS 4.x only +# Site-specific overrides go in CONFIG_SITE.Common.RTEMS-pc386 # +#------------------------------------------------------- + RTEMS_BSP = pc386 RTEMS_TARGET_CPU = i386 +GNU_TARGET = i386-rtems MUNCH_SUFFIX = .boot define MUNCH_CMD @@ -22,3 +23,10 @@ include $(CONFIG)/os/CONFIG.Common.RTEMS # Put text segment where it will work with etherboot # OP_SYS_LDFLAGS += -Wl,-Ttext,0x100000 + +# This check must appear after the above include +ifeq ($(RTEMS_VERSION),5) + $(info *** This target is not compatible with the configured RTEMS version.) + $(info *** Build the RTEMS-pc686 (-qemu) target for RTEMS 5.x) + $(error Can't continue) +endif diff --git a/configure/os/CONFIG.Common.RTEMS-pc386-qemu b/configure/os/CONFIG.Common.RTEMS-pc386-qemu index 684f01a19..07bf30e7c 100644 --- a/configure/os/CONFIG.Common.RTEMS-pc386-qemu +++ b/configure/os/CONFIG.Common.RTEMS-pc386-qemu @@ -6,6 +6,7 @@ #------------------------------------------------------- # Include definitions from RTEMS-pc386 +# For Tests overwrite it with pc686 include $(CONFIG)/os/CONFIG.Common.RTEMS-pc386 RTEMS_QEMU_FIXUPS = YES diff --git a/configure/os/CONFIG.Common.RTEMS-pc686 b/configure/os/CONFIG.Common.RTEMS-pc686 new file mode 100644 index 000000000..882a2f3cb --- /dev/null +++ b/configure/os/CONFIG.Common.RTEMS-pc686 @@ -0,0 +1,39 @@ +# CONFIG.Common.RTEMS-pc686 +# +# Definitions for the RTEMS-pc686 target, RTEMS 5.x only +# Site-specific overrides go in CONFIG_SITE.Common.RTEMS-pc686 +# +#------------------------------------------------------- +# +# Author: W. Eric Norum +# Canadian Light Source +# eric@cls.usask.ca +# +# All RTEMS targets use the same Makefile fragment +# +RTEMS_BSP = pc686 +RTEMS_TARGET_CPU = i386 +GNU_TARGET = i386-rtems + +MUNCH_SUFFIX = .boot +define MUNCH_CMD + $(RTEMS_TOOLS)/bin/$(OBJCOPY_FOR_TARGET) -O binary -R .comment -S $< $@ +endef + +OP_SYS_LDLIBS += -Wl,--gc-sections +ARCH_DEP_LDFLAGS = -L$(RTEMS_BASE)/$(GNU_TARGET)$(RTEMS_VERSION)/pc686/lib/ + +include $(CONFIG)/os/CONFIG.Common.RTEMS + +# +# Put text segment where it will work with etherboot +# +OP_SYS_LDFLAGS += -Wl,-Ttext,0x100000 + + +# This check must appear after the above include +ifneq ($(RTEMS_VERSION),5) + $(info *** This target is not compatible with the configured RTEMS version.) + $(info *** Build the RTEMS-pc386 (-qemu) target for RTEMS 4.x) + $(error Can't continue) +endif diff --git a/configure/os/CONFIG.Common.RTEMS-pc686-qemu b/configure/os/CONFIG.Common.RTEMS-pc686-qemu new file mode 100644 index 000000000..1de543a30 --- /dev/null +++ b/configure/os/CONFIG.Common.RTEMS-pc686-qemu @@ -0,0 +1,11 @@ +# CONFIG.Common.RTEMS-pc686-qemu +# +# Definitions for the RTEMS-pc686-qemu target +# Site-specific overrides go in CONFIG_SITE.Common.RTEMS-pc686-qemu +# +#------------------------------------------------------- + +# Include definitions from RTEMS-pc686 +include $(CONFIG)/os/CONFIG.Common.RTEMS-pc686 + +RTEMS_QEMU_FIXUPS = YES diff --git a/configure/os/CONFIG.Common.RTEMS-qoriq_e500 b/configure/os/CONFIG.Common.RTEMS-qoriq_e500 new file mode 100644 index 000000000..7f5c42e8e --- /dev/null +++ b/configure/os/CONFIG.Common.RTEMS-qoriq_e500 @@ -0,0 +1,48 @@ +# +# CONFIG.Common.RTEMS-qoriq_e500 +# Author: Heinz Junkes +# +# All RTEMS targets use the same Makefile fragment +# +EXE = .elf +RTEMS_BSP = qoriq_e500 +RTEMS_TARGET_CPU = powerpc +GNU_TARGET = powerpc-rtems +# optimization trouble in postfix.c +ARCH_DEP_CFLAGS += -DRTEMS_HAS_ALTIVEC +#will use bootp +#ARCH_DEP_CFLAGS += -DMY_DO_BOOTP=NULL + +#ARCH_DEP_CFLAGS += -DRTEMS_NETWORK_CONFIG_MBUF_SPACE=2048 +#ARCH_DEP_CFLAGS += -DRTEMS_NETWORK_CONFIG_CLUSTER_SPACE=5120 + +#netbsdlib +#ARCH_DEP_CFLAGS += -I$(RTEMS_BASE)/powerpc-rtems5/qoriq_e500/lib/include + +#OP_SYS_LDLIBS += -lbspExt #does not use posix stuff ... want to ignore +OP_SYS_LDLIBS += -Wl,--gc-sections +#ARCH_DEP_LDFLAGS = -mcpu=8540 -meabi -msdata=sysv -mstrict-align -mspe -mabi=spe -mfloat-gprs=double +ARCH_DEP_LDFLAGS = -L$(RTEMS_BASE)/powerpc-rtems5/qoriq_e500/lib + +MUNCH_SUFFIX = .img +MUNCHNAME = $(PRODNAME:%$(EXE)=%$(MUNCH_SUFFIX)) +define MUNCH_CMD + $(RTEMS_TOOLS)/bin/$(OBJCOPY_FOR_TARGET) -O binary $< $@ + gzip -9 -f $@ + $(RTEMS_TOOLS)/bin/mkimage.py -A ppc -O linux -T kernel -a 0x4000 -e 0x4000 -n $* -d $@.gz $*.img +endef + +include $(CONFIG)/os/CONFIG.Common.RTEMS + +RTEMSSYMS=$(PRODNAME:%$(EXE)=%.sym) +RTEMSIMGS=$(PRODNAME:%$(EXE)=%.bin) +INSTALL_RTEMSSYMS=$(RTEMSSYMS:%=$(INSTALL_BIN)/%) +INSTALL_RTEMSIMGS=$(RTEMSIMGS:%=$(INSTALL_BIN)/%) + +%.sym: %$(EXE) + $(XSYMS) $^ $@ + +%.bin: %$(EXE) + $(OBJCOPY) -Obinary $^ $@ + +#PRODTARGETS+=$(INSTALL_RTEMSSYMS) $(INSTALL_RTEMSIMGS) diff --git a/configure/os/CONFIG.Common.RTEMS-uC5282 b/configure/os/CONFIG.Common.RTEMS-uC5282 index 2cb215aca..c0cdaff74 100644 --- a/configure/os/CONFIG.Common.RTEMS-uC5282 +++ b/configure/os/CONFIG.Common.RTEMS-uC5282 @@ -9,6 +9,10 @@ RTEMS_BSP = uC5282 RTEMS_TARGET_CPU = m68k ARCH_DEP_CFLAGS += -DMY_DO_BOOTP=NULL +# Hopefully a temporary fix: +ARCH_DEP_CXXFLAGS_5 = -std=c++98 +ARCH_DEP_CXXFLAGS += $(ARCH_DEP_CXXFLAGS_$(RTEMS_VERSION)) + MUNCH_SUFFIX = .boot define MUNCH_CMD $(RTEMS_TOOLS)/bin/$(OBJCOPY_FOR_TARGET) -O binary -R .comment -S $< $@ diff --git a/configure/os/CONFIG.Common.RTEMS-xilinx_zynq_a9_qemu b/configure/os/CONFIG.Common.RTEMS-xilinx_zynq_a9_qemu new file mode 100644 index 000000000..83b518b69 --- /dev/null +++ b/configure/os/CONFIG.Common.RTEMS-xilinx_zynq_a9_qemu @@ -0,0 +1,20 @@ +# +# CONFIG.Common.RTEMS-xilinx_zynq_a9_qemu +# Author: Heinz Junkes +# +# All RTEMS targets use the same Makefile fragment +# +#EXE = .elf +RTEMS_BSP = xilinx_zynq_a9_qemu +RTEMS_TARGET_CPU = arm +GNU_TARGET = arm-rtems + +#use dhcp/bootp +ARCH_DEP_CFLAGS += -DMY_DO_BOOTP=NULL + +OP_SYS_LDLIBS += -Wl,--gc-sections +ARCH_DEP_LDFLAGS = -L$(RTEMS_BASE)/$(GNU_TARGET)$(RTEMS_VERSION)/xilinx_zynq_a9_qemu/lib/ + + +include $(CONFIG)/os/CONFIG.Common.RTEMS + diff --git a/configure/os/CONFIG.Common.RTEMS-xilinx_zynq_zedboard b/configure/os/CONFIG.Common.RTEMS-xilinx_zynq_zedboard new file mode 100644 index 000000000..bac33eb91 --- /dev/null +++ b/configure/os/CONFIG.Common.RTEMS-xilinx_zynq_zedboard @@ -0,0 +1,19 @@ +# +# CONFIG.Common.RTEMS-xilinx_zynq_zedboard +# Author: Heinz Junkes +# +# All RTEMS targets use the same Makefile fragment +# +#EXE = .elf +RTEMS_BSP = xilinx_zynq_zedboard +RTEMS_TARGET_CPU = arm +GNU_TARGET = arm-rtems + +OP_SYS_LDLIBS += -Wl,--gc-sections +ARCH_DEP_LDFLAGS = -L$(RTEMS_BASE)/$(GNU_TARGET)$(RTEMS_VERSION)/xilinx_zynq_zedboard/lib/ + + +include $(CONFIG)/os/CONFIG.Common.RTEMS + + + diff --git a/configure/os/CONFIG.darwin-x86.Common b/configure/os/CONFIG.darwin-x86.Common index e779f7dc1..c88d8f7ea 100644 --- a/configure/os/CONFIG.darwin-x86.Common +++ b/configure/os/CONFIG.darwin-x86.Common @@ -3,6 +3,6 @@ # Definitions for darwin-x86 host builds # Sites may override these definitions in CONFIG_SITE.darwin-x86.Common #------------------------------------------------------- - +#support for IPv6 etc. #Include definitions common to unix hosts include $(CONFIG)/os/CONFIG.UnixCommon.Common diff --git a/configure/os/CONFIG.darwinCommon.darwinCommon b/configure/os/CONFIG.darwinCommon.darwinCommon index bfd61830d..3ee6fd5f9 100644 --- a/configure/os/CONFIG.darwinCommon.darwinCommon +++ b/configure/os/CONFIG.darwinCommon.darwinCommon @@ -30,6 +30,7 @@ ARCH_DEP_LDFLAGS += $(ARCH_DEP_FLAGS) # # Special flags for Darwin # No common blocks (as required when using shared libraries) +# OS provides socket address length # OP_SYS_CFLAGS += -fno-common diff --git a/configure/os/CONFIG_SITE.Common.RTEMS b/configure/os/CONFIG_SITE.Common.RTEMS index 0b5d227ee..6857dc9a9 100644 --- a/configure/os/CONFIG_SITE.Common.RTEMS +++ b/configure/os/CONFIG_SITE.Common.RTEMS @@ -3,11 +3,26 @@ # Site-specific information for all RTEMS targets #------------------------------------------------------- -# Where to find RTEMS +# Where to find RTEMS, and what version is it # +# RTEMS_BASE must point to the specific installation of RTEMS to +# build the target code with. +# RTEMS_VERSION is used in the path to the toolsets inside that +# installation. For RTEMS 5 only the major version number is +# used, but for RTEMS 4.10.2 say all 3 components are required. +# + +# FHI: +#RTEMS_VERSION = 5 +#RTEMS_BASE = /home/h1/DBG/rtems +#RTEMS_BASE = /home/ad/MVME6100/rtems/$(RTEMS_VERSION) +#RTEMS_BASE = /opt/RTEMS/qoriq/rtems/$(RTEMS_VERSION) + # APS: -RTEMS_VERSION = 4.10.2 -RTEMS_BASE = /usr/local/vw/rtems/rtems-$(RTEMS_VERSION) +#RTEMS_VERSION = 4.10.2 +#RTEMS_BASE = /usr/local/vw/rtems/rtems-4.10.2 +#RTEMS_VERSION = 5 +#RTEMS_BASE = /usr/local/vw/rtems/rtems-5.1 # Cross-compile toolchain in $(RTEMS_TOOLS)/bin # diff --git a/configure/os/CONFIG_SITE.Common.RTEMS-pc386-qemu b/configure/os/CONFIG_SITE.Common.RTEMS-pc386-qemu index 027dcf4ab..0f930c5d9 100644 --- a/configure/os/CONFIG_SITE.Common.RTEMS-pc386-qemu +++ b/configure/os/CONFIG_SITE.Common.RTEMS-pc386-qemu @@ -6,4 +6,4 @@ # If you're building this architecture you _probably_ want to # run the tests for it under QEMU, but if not you can turn # them off here by commenting out this line: -CROSS_COMPILER_RUNTEST_ARCHS += RTEMS-pc386-qemu +CROSS_COMPILER_RUNTEST_ARCHS += $(T_A) diff --git a/configure/os/CONFIG_SITE.Common.RTEMS-pc686-qemu b/configure/os/CONFIG_SITE.Common.RTEMS-pc686-qemu new file mode 100644 index 000000000..4ed2ed36c --- /dev/null +++ b/configure/os/CONFIG_SITE.Common.RTEMS-pc686-qemu @@ -0,0 +1,9 @@ +# CONFIG_SITE.Common.RTEMS-pc686-qemu +# +# Site-specific overrides for the RTEMS-pc686-qemu target +# + +# If you're building this architecture you _probably_ want to +# run the tests for it under QEMU, but if not you can turn +# them off here by commenting out this line: +CROSS_COMPILER_RUNTEST_ARCHS += $(T_A) diff --git a/configure/toolchain.c b/configure/toolchain.c new file mode 100644 index 000000000..3120d4fdc --- /dev/null +++ b/configure/toolchain.c @@ -0,0 +1,37 @@ +#ifdef _COMMENT_ +/* Extract compiler pre-defined macros as Make variables + * + * Expanded as $(INSTALL_CFG)/TOOLCHAIN.$(EPICS_HOST_ARCH).$(T_A) + * + * Must be careful not to #include any C definitions + * into what is really a Makefile snippet + * + * cf. https://sourceforge.net/p/predef/wiki/Home/ + */ +/* GCC preprocessor drops C comments from output. + * MSVC preprocessor emits C comments in output + */ +#endif + +#if defined(__GNUC__) && !defined(__clang__) +GCC_MAJOR = __GNUC__ +GCC_MINOR = __GNUC_MINOR__ +GCC_PATCH = __GNUC_PATCHLEVEL__ + +#elif defined(__clang__) +CLANG_MAJOR = __clang_major__ +CLANG_MINOR = __clang_minor__ +CLANG_PATCH = __clang_patchlevel__ + +#elif defined(_MSC_VER) +MSVC_VER = _MSC_VER +#endif + +#ifdef __rtems__ +#include +# if __RTEMS_MAJOR__>=5 +OS_API = posix +# else +OS_API = kernel +# endif +#endif diff --git a/documentation/RELEASE_NOTES.md b/documentation/RELEASE_NOTES.md index 6c6699e7a..610992ba3 100644 --- a/documentation/RELEASE_NOTES.md +++ b/documentation/RELEASE_NOTES.md @@ -133,6 +133,44 @@ Test programs written directly in Perl as a `.plt` script should implement a similar timeout for themselves. The "netget" test in Base does this in a way that works on Windows as well as Unix-like hosts. +### Experimental Support for RTEMS 5 +The new major release of the RTEMS real-time OS contains many changes +including the ability to support SMP systems and support for several +new targets: + +- RTEMS-beagleboneblack +- RTEMS-pc686 +- RTEMS-qoriq_e500 +- RTEMS-xilinx-zynq-a9_qemu +- RTEMS-xilinx_zynq_zedboard + +The earlier EPICS support for RTEMS made use of various +RTEMS-specific kernel APIs which cannot be used on an SMP system, so +the changes here required a completely new port to the Posix +real-time APIs that RTEMS-5 now recommends. + +A new RTEMS configuration variable RTEMS_VERSION has been added which +should be set to the OS version number, e.g. 4.9. When this is 4.12 +or greater, true for 5.1 as well, the new libCom/osi/os/RTEMS-posix +source files will be used; the older API source files can now be +found in libCom/osi/os/RTEMS-kernel, and those which are common to +both installations are in libCom/osi/os/RTEMS. The compiler options +are read from the Makefile.inc of the corresponding BSP and set in +the configuration files. It checks that the BSP was also built with +the --enable-posix option. It also checks if the BSP was built with +the legacy stack or libbsd. + +The dependency on bspExt has been removed. RTEMS 5 provides the bus +support natively now. + +Known Issues: +- MVME2100, MVME167, and uC5282 have not yet been updated to compile for RTEMS 5. +- VMEBus support is not available for all powerpc BSPs. +- There are some known issues with floating point on MVME2500 +- Changed network driver for beatnik to work with libbsd. Some + issues with DHCP, but network stack usable. Can load env from + NVRAM. + ----- ## EPICS Release 7.0.5 diff --git a/modules/ca/src/client/caProto.h b/modules/ca/src/client/caProto.h index 1af7ec298..397b1edaf 100644 --- a/modules/ca/src/client/caProto.h +++ b/modules/ca/src/client/caProto.h @@ -17,6 +17,9 @@ #ifndef INC_caProto_H #define INC_caProto_H +// Pick up definition of IPPORT_USERRESERVED +#include + #define capStrOf(A) #A #define capStrOfX(A) capStrOf ( A ) diff --git a/modules/database/test/ioc/db/callbackParallelTest.c b/modules/database/test/ioc/db/callbackParallelTest.c index 731ed361b..7955fb6a1 100644 --- a/modules/database/test/ioc/db/callbackParallelTest.c +++ b/modules/database/test/ioc/db/callbackParallelTest.c @@ -54,7 +54,7 @@ typedef struct myPvt { int resultFail; } myPvt; -epicsEventId finished; +static epicsEventId finished; static void myCallback(epicsCallback *pCallback) { diff --git a/modules/database/test/ioc/db/callbackTest.c b/modules/database/test/ioc/db/callbackTest.c index e83943b4a..2863720f0 100644 --- a/modules/database/test/ioc/db/callbackTest.c +++ b/modules/database/test/ioc/db/callbackTest.c @@ -54,7 +54,7 @@ typedef struct myPvt { int resultFail; } myPvt; -epicsEventId finished; +static epicsEventId finished; static void myCallback(epicsCallback *pCallback) diff --git a/modules/libcom/RTEMS/Makefile b/modules/libcom/RTEMS/Makefile index b46889db1..c939563fc 100644 --- a/modules/libcom/RTEMS/Makefile +++ b/modules/libcom/RTEMS/Makefile @@ -11,10 +11,14 @@ TOP = ../../.. include $(TOP)/configure/CONFIG include $(TOP)/configure/CONFIG_LIBCOM_VERSION +# check check +SRC_DIRS += ../$(OS_API) + PERL_SCRIPTS += epicsMakeMemFs.pl INC += epicsRtemsInitHooks.h INC += epicsMemFs.h +INC += epicsNtp.h ifeq ($(RTEMS_QEMU_FIXUPS),YES) rtems_init_CPPFLAGS += -DQEMU_FIXUPS @@ -27,11 +31,14 @@ rtemsCom_SRCS += setBootConfigFromNVRAM.c rtemsCom_SRCS += epicsRtemsInitHookPre.c rtemsCom_SRCS += epicsRtemsInitHookPost.c rtemsCom_SRCS += epicsMemFs.c +rtemsCom_SRCS += epicsNtp.c -ifeq ($(RTEMS_BSP),pc386) +ifeq ($(RTEMS_TARGET_CPU),i386) rtemsCom_SRCS += ne2kpci.c endif +rtems_config_CPPFLAGS += -DBSP_$(RTEMS_BSP) + LIBRARY_RTEMS = rtemsCom # shared library ABI version. diff --git a/modules/libcom/RTEMS/epicsNtp.c b/modules/libcom/RTEMS/epicsNtp.c new file mode 100644 index 000000000..760d62610 --- /dev/null +++ b/modules/libcom/RTEMS/epicsNtp.c @@ -0,0 +1,85 @@ +/*************************************************************************\ +* (C) 2014 David Lettier. +* http://www.lettier.com/ +* SPDX-License-Identifier: BSD-3-Clause +\*************************************************************************/ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include "epicsNtp.h" + +int epicsNtpGetTime(char *ntpIp, struct timespec *now) +{ + + int sockfd, n; // Socket file descriptor and the n return result from writing/reading from the socket. + int portno = 123; // NTP UDP port number. + + // Create and zero out the packet. All 48 bytes worth. + ntp_packet packet = { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }; + memset( &packet, 0, sizeof( ntp_packet ) ); + // Set the first byte's bits to 00,011,011 for li = 0, vn = 3, and mode = 3. The rest will be left set to zero. + *( ( char * ) &packet + 0 ) = 0x1b; // Represents 27 in base 10 or 00011011 in base 2. + + // Create a UDP socket, convert the host-name to an IP address, set the port number, + // connect to the server, send the packet, and then read in the return packet. + struct sockaddr_in serv_addr; // Server address data structure. + + sockfd = socket( AF_INET, SOCK_DGRAM, IPPROTO_UDP ); // Create a UDP socket. + + if ( sockfd < 0 ) { + perror( "epicsNtpGetTime" ); + return -1; + } + + // Zero out the server address structure. + memset( ( char* ) &serv_addr, 0, sizeof( serv_addr ) ); + + serv_addr.sin_family = AF_INET; + serv_addr.sin_addr.s_addr = inet_addr(ntpIp); + + serv_addr.sin_port = htons( portno ); + + // Call up the server using its IP address and port number. + if ( connect( sockfd, ( struct sockaddr * ) &serv_addr, sizeof( serv_addr) ) < 0 ) { + perror( "epicsNtpGetTime" ); + return -1; + } + + // Send it the NTP packet it wants. If n == -1, it failed. + n = write( sockfd, ( char* ) &packet, sizeof( ntp_packet ) ); + if ( n < 0 ) { + perror( "epicsNtpGetTime" ); + return -1; + } + +// Wait and receive the packet back from the server. If n == -1, it failed. + n = read( sockfd, ( char* ) &packet, sizeof( ntp_packet ) ); + if ( n < 0 ) { + perror( "epicsNtpGetTime" ); + return -1; + } + + // These two fields contain the time-stamp seconds as the packet left the NTP server. + // The number of seconds correspond to the seconds passed since 1900. + // ntohl() converts the bit/byte order from the network's to host's "endianness". + packet.txTm_s = ntohl( packet.txTm_s ); // Time-stamp seconds. + packet.txTm_f = ntohl( packet.txTm_f ); // Time-stamp fraction of a second. + + // Extract the 32 bits that represent the time-stamp seconds (since NTP epoch) from when the packet left the server. + // Subtract 70 years worth of seconds from the seconds since 1900. + // This leaves the seconds since the UNIX epoch of 1970. + // (1900)------------------(1970)**************************************(Time Packet Left the Server) + time_t txTm = ( time_t ) ( packet.txTm_s - NTP_TIMESTAMP_DELTA ); + now->tv_sec = txTm; + return 0; +} diff --git a/modules/libcom/RTEMS/epicsNtp.h b/modules/libcom/RTEMS/epicsNtp.h new file mode 100644 index 000000000..062970f30 --- /dev/null +++ b/modules/libcom/RTEMS/epicsNtp.h @@ -0,0 +1,42 @@ +/*************************************************************************\ +* (C) 2014 David Lettier. +* http://www.lettier.com/ +* SPDX-License-Identifier: BSD-3-Clause +\*************************************************************************/ +#ifndef EPICSNTP_H +#define EPICSNTP_H + +#define NTP_TIMESTAMP_DELTA 2208988800ull + +int epicsNtpGetTime(char *ntpIp, struct timespec *now); + +typedef struct +{ + + uint8_t li_vn_mode; // Eight bits. li, vn, and mode. + // li. Two bits. Leap indicator. + // vn. Three bits. Version number of the protocol. + // mode. Three bits. Client will pick mode 3 for client. + + uint8_t stratum; // Eight bits. Stratum level of the local clock. + uint8_t poll; // Eight bits. Maximum interval between successive messages. + uint8_t precision; // Eight bits. Precision of the local clock. + + uint32_t rootDelay; // 32 bits. Total round trip delay time. + uint32_t rootDispersion; // 32 bits. Max error aloud from primary clock source. + uint32_t refId; // 32 bits. Reference clock identifier. + + uint32_t refTm_s; // 32 bits. Reference time-stamp seconds. + uint32_t refTm_f; // 32 bits. Reference time-stamp fraction of a second. + + uint32_t origTm_s; // 32 bits. Originate time-stamp seconds. + uint32_t origTm_f; // 32 bits. Originate time-stamp fraction of a second. + + uint32_t rxTm_s; // 32 bits. Received time-stamp seconds. + uint32_t rxTm_f; // 32 bits. Received time-stamp fraction of a second. + + uint32_t txTm_s; // 32 bits and the most important field the client cares about. Transmit time-stamp seconds. + uint32_t txTm_f; // 32 bits. Transmit time-stamp fraction of a second. + +} ntp_packet; // Total: 384 bits or 48 bytes. +#endif // EPICSNTP_H diff --git a/modules/libcom/RTEMS/epicsRtemsInitHookPost.c b/modules/libcom/RTEMS/epicsRtemsInitHookPost.c index ba14aae4c..674c32662 100644 --- a/modules/libcom/RTEMS/epicsRtemsInitHookPost.c +++ b/modules/libcom/RTEMS/epicsRtemsInitHookPost.c @@ -10,9 +10,10 @@ * Dummy version -- use if application does not provide its own version */ #include "epicsRtemsInitHooks.h" - +#ifdef RTEMS_LEGACY_STACK int epicsRtemsInitPostSetBootConfigFromNVRAM(struct rtems_bsdnet_config *config) { return 0; } +#endif diff --git a/modules/libcom/RTEMS/epicsRtemsInitHookPre.c b/modules/libcom/RTEMS/epicsRtemsInitHookPre.c index 4c8544745..b84fa7ac3 100644 --- a/modules/libcom/RTEMS/epicsRtemsInitHookPre.c +++ b/modules/libcom/RTEMS/epicsRtemsInitHookPre.c @@ -10,9 +10,10 @@ * Dummy version -- use if application does not provide its own version */ #include "epicsRtemsInitHooks.h" - +#ifdef RTEMS_LEGACY_STACK int epicsRtemsInitPreSetBootConfigFromNVRAM(struct rtems_bsdnet_config *config) { return 0; } +#endif diff --git a/modules/libcom/RTEMS/epicsRtemsInitHooks.h b/modules/libcom/RTEMS/epicsRtemsInitHooks.h index cdbc74315..e08b7fa35 100644 --- a/modules/libcom/RTEMS/epicsRtemsInitHooks.h +++ b/modules/libcom/RTEMS/epicsRtemsInitHooks.h @@ -10,7 +10,9 @@ * Hooks into RTEMS startup code */ #include +#ifdef RTEMS_LEGACY_STACK #include +#endif extern char *env_nfsServer; extern char *env_nfsPath; @@ -23,8 +25,10 @@ extern "C" { /* * Return 0 for success, non-zero for failure (will cause panic) */ +#ifdef RTEMS_LEGACY_STACK int epicsRtemsInitPreSetBootConfigFromNVRAM(struct rtems_bsdnet_config *config); int epicsRtemsInitPostSetBootConfigFromNVRAM(struct rtems_bsdnet_config *config); +#endif /* Return 0 if local file system was setup, or non-zero (will fall back to network */ int epicsRtemsMountLocalFilesystem(char **argv); diff --git a/modules/libcom/RTEMS/rtems_config.c b/modules/libcom/RTEMS/kernel/rtems_config.c similarity index 100% rename from modules/libcom/RTEMS/rtems_config.c rename to modules/libcom/RTEMS/kernel/rtems_config.c diff --git a/modules/libcom/RTEMS/rtems_init.c b/modules/libcom/RTEMS/kernel/rtems_init.c similarity index 100% rename from modules/libcom/RTEMS/rtems_init.c rename to modules/libcom/RTEMS/kernel/rtems_init.c diff --git a/modules/libcom/RTEMS/posix/rtems_config.c b/modules/libcom/RTEMS/posix/rtems_config.c new file mode 100644 index 000000000..d0a123b6d --- /dev/null +++ b/modules/libcom/RTEMS/posix/rtems_config.c @@ -0,0 +1,172 @@ +/*************************************************************************\ +* Copyright (c) 2002 The University of Saskatchewan +* EPICS BASE Versions 3.13.7 +* and higher are distributed subject to a Software License Agreement found +* in file LICENSE that is included with this distribution. +\*************************************************************************/ +/* + * RTEMS configuration for EPICS + * Author: W. Eric Norum + * norume@aps.anl.gov + * (630) 252-4793 + */ + +#include + +/* + *********************************************************************** + * RTEMS CONFIGURATION * + *********************************************************************** + */ + +extern void *POSIX_Init(void *argument); + +#define CONFIGURE_POSIX_INIT_THREAD_TABLE +#define CONFIGURE_POSIX_INIT_THREAD_ENTRY_POINT POSIX_Init +#define CONFIGURE_POSIX_INIT_THREAD_STACK_SIZE (64*1024) + +#define CONFIGURE_MAXIMUM_PERIODS 5 +#define CONFIGURE_MICROSECONDS_PER_TICK 10000 +#define CONFIGURE_MALLOC_STATISTICS 1 +/* MINIMUM_STACK_SIZE == 8K */ +#define CONFIGURE_EXTRA_TASK_STACKS (4000 * RTEMS_MINIMUM_STACK_SIZE) + +#if __RTEMS_MAJOR__ > 4 +#define CONFIGURE_FILESYSTEM_DEVFS +#define CONFIGURE_FILESYSTEM_TFTPFS +#endif +#define CONFIGURE_FILESYSTEM_NFS +#define CONFIGURE_FILESYSTEM_IMFS + +#ifndef RTEMS_LEGACY_STACK +#define CONFIGURE_USE_IMFS_AS_BASE_FILESYSTEM +/* + * Configure LibBSD. + */ +//#define RTEMS_BSD_CONFIG_NET_PF_UNIX +//#define RTEMS_BSD_CONFIG_NET_IF_BRIDGE +//#define RTEMS_BSD_CONFIG_NET_IF_LAGG +//#define RTEMS_BSD_CONFIG_NET_IF_VLAN +#define RTEMS_BSD_CONFIG_BSP_CONFIG +#define RTEMS_BSD_CONFIG_INIT +#include +#endif // not LEGACY_STACK + +/* + * Configure RTEMS. + */ +#define CONFIGURE_APPLICATION_NEEDS_CLOCK_DRIVER +#define CONFIGURE_APPLICATION_NEEDS_CONSOLE_DRIVER +#define CONFIGURE_APPLICATION_NEEDS_STUB_DRIVER +#define CONFIGURE_APPLICATION_NEEDS_ZERO_DRIVER + +#define CONFIGURE_MAXIMUM_FILE_DESCRIPTORS 150 +#define CONFIGURE_IMFS_ENABLE_MKFIFO 2 + +#define CONFIGURE_MAXIMUM_NFS_MOUNTS 3 +#define CONFIGURE_MAXIMUM_USER_EXTENSIONS 5 + +#define CONFIGURE_UNLIMITED_ALLOCATION_SIZE 32 +#define CONFIGURE_UNLIMITED_OBJECTS +#define CONFIGURE_UNIFIED_WORK_AREAS + +#define CONFIGURE_STACK_CHECKER_ENABLED + +#define CONFIGURE_APPLICATION_NEEDS_LIBBLOCK +#define CONFIGURE_BDBUF_BUFFER_MAX_SIZE (64 * 1024) +#define CONFIGURE_BDBUF_MAX_READ_AHEAD_BLOCKS 4 +#define CONFIGURE_BDBUF_CACHE_MEMORY_SIZE (1 * 1024 * 1024) + +/* we are using POSIX_INIT needed by V4 +#define CONFIGURE_RTEMS_INIT_TASKS_TABLE +#define CONFIGURE_INIT_TASK_STACK_SIZE (32 * 1024) +#define CONFIGURE_INIT_TASK_INITIAL_MODES RTEMS_DEFAULT_MODES +#define CONFIGURE_INIT_TASK_ATTRIBUTES RTEMS_FLOATING_POINT +#endif +*/ + +//#define RTEMS_PCI_CONFIG_LIB +//#define CONFIGURE_PCI_LIB PCI_LIB_AUTO + +#if __RTEMS_MAJOR__ > 4 +#define CONFIGURE_SHELL_COMMANDS_INIT + +#include + +#ifndef RTEMS_LEGACY_STACK +#include + +#define CONFIGURE_SHELL_USER_COMMANDS \ + &bsp_interrupt_shell_command, \ + &rtems_shell_HOSTNAME_Command, \ + &rtems_shell_PING_Command, \ + &rtems_shell_ROUTE_Command, \ + &rtems_shell_NETSTAT_Command, \ + &rtems_shell_IFCONFIG_Command, \ + &rtems_shell_TCPDUMP_Command, \ + &rtems_shell_PFCTL_Command, \ + &rtems_shell_SYSCTL_Command +#else // LEGACY_STACK: +#define CONFIGURE_SHELL_USER_COMMANDS \ + &bsp_interrupt_shell_command, \ + &rtems_shell_PING_Command, \ + &rtems_shell_ROUTE_Command, \ + &rtems_shell_IFCONFIG_Command +#endif + +#define CONFIGURE_SHELL_COMMAND_CPUUSE +#define CONFIGURE_SHELL_COMMAND_PERIODUSE +#define CONFIGURE_SHELL_COMMAND_STACKUSE +#define CONFIGURE_SHELL_COMMAND_PROFREPORT + +#define CONFIGURE_SHELL_COMMAND_CP +#define CONFIGURE_SHELL_COMMAND_PWD +#define CONFIGURE_SHELL_COMMAND_LS +#define CONFIGURE_SHELL_COMMAND_LN +#define CONFIGURE_SHELL_COMMAND_LSOF +#define CONFIGURE_SHELL_COMMAND_CHDIR +#define CONFIGURE_SHELL_COMMAND_CD +#define CONFIGURE_SHELL_COMMAND_MKDIR +#define CONFIGURE_SHELL_COMMAND_RMDIR +#define CONFIGURE_SHELL_COMMAND_CAT +#define CONFIGURE_SHELL_COMMAND_MV +#define CONFIGURE_SHELL_COMMAND_RM +#define CONFIGURE_SHELL_COMMAND_MALLOC_INFO +#define CONFIGURE_SHELL_COMMAND_SHUTDOWN + +#include +#define RTEMS_BSD_CONFIG_BSP_CONFIG +#define RTEMS_BSD_CONFIG_SERVICE_TELNETD +#define RTEMS_BSD_CONFIG_TELNETD_STACK_SIZE (16 * 1024) +#define RTEMS_BSD_CONFIG_SERVICE_FTPD +#define RTEMS_BSD_CONFIG_FIREWALL_PF +#else +#include +#endif // not LEGACY_STACK + +#if __RTEMS_MAJOR__ < 5 // still needed in Version 4? +#define CONFIGURE_MAXIMUM_TASKS rtems_resource_unlimited(30) +#endif + +#define CONFIGURE_MAXIMUM_DRIVERS 40 + +/* + * This should be made BSP dependent, not CPU dependent but I know of no + * appropriate conditionals to use. + * The new general time support makes including the RTC driver less important. + */ +#if !defined(mpc604) && !defined(__mc68040__) && !defined(__mcf5200__) && \ + !defined(mpc7455) && !defined(__arm__) && !defined(__nios2__) + /* don't have RTC code */ +#define CONFIGURE_APPLICATION_NEEDS_RTC_DRIVER +#endif + +#if defined(BSP_pc386) || defined(BSP_pc686) +#define RTEMS_BSD_CONFIG_DOMAIN_PAGE_MBUFS_SIZE (64 * 1024 * 1024) +#elif defined(BSP_qoriq_e500) +#define RTEMS_BSD_CONFIG_DOMAIN_PAGE_MBUFS_SIZE (32 * 1024 * 1024) +#endif + +#define CONFIGURE_INIT + +#include diff --git a/modules/libcom/RTEMS/posix/rtems_init.c b/modules/libcom/RTEMS/posix/rtems_init.c new file mode 100644 index 000000000..d8a836a64 --- /dev/null +++ b/modules/libcom/RTEMS/posix/rtems_init.c @@ -0,0 +1,1186 @@ +/*************************************************************************\ +* Copyright (c) 2002 The University of Saskatchewan +* EPICS BASE Versions 3.13.7 +* and higher are distributed subject to a Software License Agreement found +* in file LICENSE that is included with this distribution. +\*************************************************************************/ +/* + * RTEMS startup task for EPICS + * Author: W. Eric Norum + * eric.norum@usask.ca + * (306) 966-5394 + */ + +/* + * This is the first implementation with posix and rtems5. + * Currently only dhcp is supported with libbsd. The reading of the + * environment variables from e.g. u-boot environment is still missing. + * Extensive tests so far only with qemu. + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#if __RTEMS_MAJOR__ > 4 +#include +#else +#include +#endif + +#ifdef RTEMS_LEGACY_STACK +#include +#include +#else // libbsd stack +#include +#include +#include +#include +#endif + +#include +#if __RTEMS_MAJOR__ > 4 +#include +#endif +#include "epicsVersion.h" +#include "epicsThread.h" +#include "epicsTime.h" +#include "epicsExit.h" +#include "envDefs.h" +#include "errlog.h" +#include "logClient.h" +#include "osiUnistd.h" +#include "iocsh.h" +#include "osdTime.h" +#include "epicsMemFs.h" +#include "epicsEvent.h" +#include "errlog.h" + +#include "epicsRtemsInitHooks.h" + +#ifdef RTEMS_LEGACY_STACK +#pragma message "RTEMS uses legacy stack" +#else +#pragma message "RTEMS uses libbsd stack" +// setup own ntp-client to get time +#include "epicsNtp.h" +epicsEventId dhcpDone; +#endif + +/* these settings are needed by the rtems startup + * may provide by dhcp/bootp + * or environments from the "BIOS" like u-boot, motboot etc. + */ +char rtemsInit_NTP_server_ip[16] = "10.0.5.1"; +char bootp_server_name_init[128] = "1001.1001@10.0.5.1:/epics"; +char bootp_boot_file_name_init[128] = "/epics/myExample/bin/RTEMS-beatnik/myExample.boot"; +char bootp_cmdline_init[128] = "/epics/myExample/iocBoot/iocmyExample/st.cmd"; + +struct in_addr rtems_bsdnet_bootp_server_address; +/* TODO check rtems_bsdnet_bootp_cmdline */ +#ifndef RTEMS_LEGACY_STACK +char *rtems_bsdnet_bootp_server_name = bootp_server_name_init; +char *rtems_bsdnet_bootp_boot_file_name = bootp_boot_file_name_init; +char *rtems_bsdnet_bootp_cmdline = bootp_cmdline_init; +#endif // not LEGACY Stack + +/* + * Prototypes for some functions not in header files + */ +//void tzset(void); +int fileno(FILE *); +int main(int argc, char **argv); + +static void +logReset (void) +{ + void rtems_bsp_reset_cause(char *buf, size_t capacity) __attribute__((weak)); + void (*fp)(char *buf, size_t capacity) = rtems_bsp_reset_cause; + + if (fp) { + char buf[80]; + fp(buf, sizeof buf); + errlogPrintf ("Startup after %s.\n", buf); + } + else { + errlogPrintf ("Startup.\n"); + } +} + +/* + *********************************************************************** + * FATAL ERROR REPORTING * + *********************************************************************** + */ +/* + * Delay for a while, then terminate + */ +static void +delayedPanic (const char *msg) +{ + rtems_task_wake_after (rtems_clock_get_ticks_per_second()); + rtems_task_wake_after (rtems_clock_get_ticks_per_second()); + rtems_panic ("%s", msg); +} + +/* + * Log error and terminate + */ +void +LogFatal (const char *msg, ...) +{ + va_list ap; + + va_start (ap, msg); + errlogVprintf (msg, ap); + va_end (ap); + delayedPanic (msg); +} + +/* + * Log RTEMS error and terminate + */ +void +LogRtemsFatal (const char *msg, rtems_status_code sc) +{ + errlogPrintf ("%s: %s\n", msg, rtems_status_text (sc)); + delayedPanic (msg); +} + +/* + * Log network error and terminate + */ +void +LogNetFatal (const char *msg, int err) +{ + errlogPrintf ("%s: %d\n", msg, err); + delayedPanic (msg); +} + +void * +mustMalloc(int size, const char *msg) +{ + void *p; + + if ((p = malloc (size)) == NULL) + LogFatal ("Can't allocate space for %s.\n", msg); + return p; +} + +/* + *********************************************************************** + * REMOTE FILE ACCESS * + *********************************************************************** + */ +#ifdef OMIT_NFS_SUPPORT +# include +#endif + +const epicsMemFS *epicsRtemsFSImage __attribute__((weak)); +const epicsMemFS *epicsRtemsFSImage = (void*)&epicsRtemsFSImage; + +/* hook to allow app specific FS setup */ +int +epicsRtemsMountLocalFilesystem(char **argv) __attribute__((weak)); +int +epicsRtemsMountLocalFilesystem(char **argv) +{ + if(epicsRtemsFSImage==(void*)&epicsRtemsFSImage) + return -1; /* no FS image provided. */ + else if(epicsRtemsFSImage==NULL) + return 0; /* no FS image provided, but none is needed. */ + else { + printf("***** Using compiled in file data *****\n"); + if (epicsMemFsLoad(epicsRtemsFSImage) != 0) { + printf("Can't unpack tar filesystem\n"); + return -1; + } else { + argv[1] = "/"; + return 0; + } + } +} + +static int +initialize_local_filesystem(char **argv) +{ + extern char _DownloadLocation[] __attribute__((weak)); + extern char _FlashBase[] __attribute__((weak)); + extern char _FlashSize[] __attribute__((weak)); + + argv[0] = rtems_bsdnet_bootp_boot_file_name; + if (epicsRtemsMountLocalFilesystem(argv)==0) { + return 1; /* FS setup successful */ +#ifdef RTEMS_LEGACY_STACK + } else if (_FlashSize && (_DownloadLocation || _FlashBase)) { + extern char _edata[]; + size_t flashIndex = _edata - _DownloadLocation; + char *header = _FlashBase + flashIndex; + + if (memcmp(header + 257, "ustar ", 8) == 0) { + int fd; + printf ("***** Unpack in-memory file system (IMFS) *****\n"); + if (rtems_tarfs_load("/", (unsigned char *)header, (size_t)_FlashSize - flashIndex) != 0) { + printf("Can't unpack tar filesystem\n"); + return 0; + } + if ((fd = open(rtems_bsdnet_bootp_cmdline, 0)) >= 0) { + close(fd); + printf ("***** Found startup script (%s) in IMFS *****\n", rtems_bsdnet_bootp_cmdline); + argv[1] = rtems_bsdnet_bootp_cmdline; + return 1; + } + printf ("***** Startup script (%s) not in IMFS *****\n", rtems_bsdnet_bootp_cmdline); + } +#endif /* only with old stack, check check libbsd dependency! */ + } + return 0; +} + +#ifndef OMIT_NFS_SUPPORT +int +nfsMount(char *uidhost, char *path, char *mntpoint) +{ + int devl = strlen(uidhost) + strlen(path) + 2; + char *dev; + int rval = -1; + + if ((dev = malloc(devl)) == NULL) { + fprintf(stderr,"nfsMount: out of memory\n"); + return -1; + } + sprintf(dev, "%s:%s", uidhost, path); + printf("Mount %s on %s\n", dev, mntpoint); + rval = mount_and_make_target_path ( + dev, mntpoint, RTEMS_FILESYSTEM_TYPE_NFS, + RTEMS_FILESYSTEM_READ_WRITE, NULL ); + if(rval) + perror("mount failed"); + free(dev); + return rval; +} +#define NFS_INIT +#endif + + +static void +initialize_remote_filesystem(char **argv, int hasLocalFilesystem) +{ +#ifdef OMIT_NFS_SUPPORT + printf ("***** Initializing TFTP *****\n"); + mount_and_make_target_path(NULL, + "/TFTP", + RTEMS_FILESYSTEM_TYPE_TFTPFS, + RTEMS_FILESYSTEM_READ_WRITE, + NULL); + if (!hasLocalFilesystem) { + char *path; + int pathsize = 200; + int l; + + path = mustMalloc(pathsize, "Command path name "); + strcpy (path, "/TFTP/BOOTP_HOST/epics/"); + l = strlen (path); + if (gethostname (&path[l], pathsize - l - 10) || (path[l] == '\0')) + { + LogFatal ("Can't get host name"); + } + strcat (path, "/st.cmd"); + argv[1] = path; + } +#else + char *server_name; + char *server_path; + char *mount_point; + char *cp; + int l = 0; + + printf ("***** Initializing NFS *****\n"); + NFS_INIT + if (env_nfsServer && env_nfsPath && env_nfsMountPoint) { + server_name = env_nfsServer; + server_path = env_nfsPath; + mount_point = env_nfsMountPoint; + cp = mount_point; + while ((cp = strchr(cp+1, '/')) != NULL) { + *cp = '\0'; + if ((mkdir (mount_point, 0755) != 0) + && (errno != EEXIST)) + LogFatal("Can't create directory \"%s\": %s.\n", + mount_point, strerror(errno)); + *cp = '/'; + } + argv[1] = rtems_bsdnet_bootp_cmdline; + } + else if (hasLocalFilesystem) { + return; + } + else { + /* + * Use first component of nvram/bootp command line pathname + * to set up initial NFS mount. A "/tftpboot/" is prepended + * if the pathname does not begin with a '/'. This allows + * NFS and TFTP to have a similar view of the remote system. + */ + if (rtems_bsdnet_bootp_cmdline[0] == '/') + cp = rtems_bsdnet_bootp_cmdline + 1; + else + cp = rtems_bsdnet_bootp_cmdline; + cp = strchr(cp, '/'); + if ((cp == NULL) + || ((l = cp - rtems_bsdnet_bootp_cmdline) == 0)) + LogFatal("\"%s\" is not a valid command pathname.\n", rtems_bsdnet_bootp_cmdline); + cp = mustMalloc(l + 20, "NFS mount paths"); + server_path = cp; + server_name = rtems_bsdnet_bootp_server_name; + if (rtems_bsdnet_bootp_cmdline[0] == '/') { + mount_point = server_path; + strncpy(mount_point, rtems_bsdnet_bootp_cmdline, l); + mount_point[l] = '\0'; + argv[1] = rtems_bsdnet_bootp_cmdline; + /* + * Its probably common to embed the mount point in the server + * name so, when this is occurring, dont clobber the mount point + * by appending the first node from the command path. This allows + * the mount point to be a different path then the server's mount + * path. + * + * This allows for example a line similar to as follows the DHCP + * configuration file. + * + * server-name "159.233@192.168.0.123:/vol/vol0/bootRTEMS"; + */ + if ( server_name ) { + const size_t allocSize = strlen ( server_name ) + 2; + char * const pServerName = mustMalloc( allocSize, + "NFS mount paths"); + char * const pServerPath = mustMalloc ( allocSize, + "NFS mount paths"); + const int scanfStatus = sscanf ( + server_name, + "%[^:] : / %s", + pServerName, + pServerPath + 1u ); + if ( scanfStatus == 2 ) { + pServerPath[0u]= '/'; + server_name = pServerName; + // is this a general solution? + server_path = mount_point = pServerPath; + } + else { + free ( pServerName ); + free ( pServerPath ); + } + } + } + else { + char *abspath = mustMalloc(strlen(rtems_bsdnet_bootp_cmdline)+2,"Absolute command path"); + strcpy(server_path, "/tftpboot/"); + mount_point = server_path + strlen(server_path); + strncpy(mount_point, rtems_bsdnet_bootp_cmdline, l); + mount_point[l] = '\0'; + mount_point--; + strcpy(abspath, "/"); + strcat(abspath, rtems_bsdnet_bootp_cmdline); + argv[1] = abspath; + } + } + errlogPrintf("nfsMount(\"%s\", \"%s\", \"%s\")\n", + server_name, server_path, mount_point); + nfsMount(server_name, server_path, mount_point); +#endif +} + +static +char rtems_etc_hosts[] = "127.0.0.1 localhost\n"; + +/* If it doesn't already exist, create /etc/hosts with an entry for 'localhost' */ +static +void fixup_hosts(void) +{ + FILE *fp; + int ret; + struct stat STAT; + + ret=stat("/etc/hosts", &STAT); + if(ret==0) + { + return; /* already exists, assume file */ + } else if(errno!=ENOENT) { + perror("error: fixup_hosts stat /etc/hosts"); + return; + } + + ret = mkdir("/etc", 0775); + if(ret!=0 && errno!=EEXIST) + { + perror("error: fixup_hosts create /etc"); + return; + } + + if((fp=fopen("/etc/hosts", "w"))==NULL) + { + perror("error: fixup_hosts create /etc/hosts"); + } + + if(fwrite(rtems_etc_hosts, 1, sizeof(rtems_etc_hosts)-1, fp)!=sizeof(rtems_etc_hosts)-1) + { + perror("error: failed to write /etc/hosts"); + } + + fclose(fp); +} + +/* + * Get to the startup script directory + * The TFTP filesystem requires a trailing '/' on chdir arguments. + */ +static void +set_directory (const char *commandline) +{ + const char *cp; + char *directoryPath; + int l; + + cp = strrchr(commandline, '/'); + if (cp == NULL) { + l = 0; + cp = "/"; + } + else { + l = cp - commandline; + cp = commandline; + } + directoryPath = mustMalloc(l + 2, "Command path directory "); + strncpy(directoryPath, cp, l); + directoryPath[l] = '/'; + directoryPath[l+1] = '\0'; + if (chdir (directoryPath) < 0) + LogFatal ("Can't set initial directory(%s): %s\n", directoryPath, strerror(errno)); + else + errlogPrintf("chdir(\"%s\")\n", directoryPath); + free(directoryPath); +} + +/* + *********************************************************************** + * RTEMS/EPICS COMMANDS * + *********************************************************************** + */ + +static const iocshArg rtshellArg0 = { "cmd", iocshArgString}; +static const iocshArg rtshellArg1 = { "args", iocshArgArgv}; +static const iocshArg * rtshellArgs[2] = { &rtshellArg0, &rtshellArg1}; +static const iocshFuncDef rtshellFuncDef = { "rt",2, rtshellArgs +#ifdef IOCSHFUNCDEF_HAS_USAGE + , "run rtems shell command" +#endif + }; + +static void rtshellCallFunc(const iocshArgBuf *args) +{ + rtems_shell_cmd_t *cmd = rtems_shell_lookup_cmd(args[0].sval); + int ret; + + if (!cmd) { + fprintf(stderr, "ERR: No such command\n"); + + } else { + fflush(stdout); + fflush(stderr); + ret = (*cmd->command)(args[1].aval.ac,args[1].aval.av); + fflush(stdout); + fflush(stderr); + if(ret) + fprintf(stderr, "ERR: %d\n",ret); + } +} + +/* + * RTEMS status + */ +static void +rtems_netstat (unsigned int level) +{ +#ifndef RTEMS_LEGACY_STACK + printf ("***** Sorry not implemented yet with the new network stack (bsdlib)\n"); +#else + rtems_bsdnet_show_if_stats (); + rtems_bsdnet_show_mbuf_stats (); + if (level >= 1) { + rtems_bsdnet_show_inet_routes (); + } + if (level >= 2) { + rtems_bsdnet_show_ip_stats (); + rtems_bsdnet_show_icmp_stats (); + rtems_bsdnet_show_udp_stats (); + rtems_bsdnet_show_tcp_stats (); + } +#endif +} + +static const iocshArg netStatArg0 = { "level",iocshArgInt}; +static const iocshArg * const netStatArgs[1] = {&netStatArg0}; +static const iocshFuncDef netStatFuncDef = {"netstat",1,netStatArgs +#ifdef IOCSHFUNCDEF_HAS_USAGE + , "show network status" +#endif + }; +static void netStatCallFunc(const iocshArgBuf *args) +{ + rtems_netstat(args[0].ival); +} + +static const iocshFuncDef heapSpaceFuncDef = {"heapSpace",0,NULL +#ifdef IOCSHFUNCDEF_HAS_USAGE + , "show malloc statistic" +#endif + }; +static void heapSpaceCallFunc(const iocshArgBuf *args) +{ +#if __RTEMS_MAJOR__ > 4 + Heap_Information_block info; + double x; + + malloc_info (&info); + x = info.Stats.size - (unsigned long) + (info.Stats.lifetime_allocated - info.Stats.lifetime_freed); + if (x >= 1024*1024) + printf("Heap space: %.1f MB\n", x / (1024 * 1024)); + else + printf("Heap space: %.1f kB\n", x / 1024); +#else + rtems_malloc_statistics_t s; + double x; + + malloc_get_statistics(&s); + x = s.space_available - (unsigned long)(s.lifetime_allocated - s.lifetime_freed); + if (x >= 1024*1024) + printf("Heap space: %.1f MB\n", x / (1024 * 1024)); + else + printf("Heap space: %.1f kB\n", x / 1024); +#endif // RTEMS < 5 +} + +#ifndef OMIT_NFS_SUPPORT +static const iocshArg nfsMountArg0 = { "[uid.gid@]host",iocshArgString}; +static const iocshArg nfsMountArg1 = { "server path",iocshArgString}; +static const iocshArg nfsMountArg2 = { "mount point",iocshArgString}; +static const iocshArg * const nfsMountArgs[3] = {&nfsMountArg0,&nfsMountArg1, + &nfsMountArg2}; +static const iocshFuncDef nfsMountFuncDef = {"nfsMount",3,nfsMountArgs +#ifdef IOCSHFUNCDEF_HAS_USAGE + , "mount nfs drive" +#endif + }; +static void nfsMountCallFunc(const iocshArgBuf *args) +{ + char *cp = args[2].sval; + while ((cp = strchr(cp+1, '/')) != NULL) { + *cp = '\0'; + if ((mkdir (args[2].sval, 0755) != 0) && (errno != EEXIST)) { + printf("Can't create directory \"%s\": %s.\n", + args[2].sval, strerror(errno)); + return; + } + *cp = '/'; + } + nfsMount(args[0].sval, args[1].sval, args[2].sval); +} +#endif + + +void zoneset(const char *zone) +{ + if(zone) + setenv("TZ", zone, 1); + else + unsetenv("TZ"); + tzset(); +} + +static const iocshArg zonesetArg0 = {"zone string", iocshArgString}; +static const iocshArg * const zonesetArgs[1] = {&zonesetArg0}; +static const iocshFuncDef zonesetFuncDef = {"zoneset",1,zonesetArgs +#ifdef IOCSHFUNCDEF_HAS_USAGE + , "set timezone (obsolete?)" +#endif + }; +static void zonesetCallFunc(const iocshArgBuf *args) +{ + zoneset(args[0].sval); +} + + +/* + * Register RTEMS-specific commands + */ +static void iocshRegisterRTEMS (void) +{ + iocshRegister(&netStatFuncDef, netStatCallFunc); + iocshRegister(&heapSpaceFuncDef, heapSpaceCallFunc); +#ifndef OMIT_NFS_SUPPORT + iocshRegister(&nfsMountFuncDef, nfsMountCallFunc); +#endif + iocshRegister(&zonesetFuncDef, &zonesetCallFunc); + iocshRegister(&rtshellFuncDef, &rtshellCallFunc); +#if __RTEMS_MAJOR__ > 4 + rtems_shell_init_environment(); +#endif +} + +/* + * Set up the console serial line (no handshaking) + */ +static void +initConsole (void) +{ + struct termios t; + +printf("\n initConsole --- Info ---\n"); +printf("stdin: fileno: %d, ttyname: %s\n", fileno(stdin), ttyname(fileno(stdin))); +printf("stdout: fileno: %d, ttyname: %s\n", fileno(stdout), ttyname(fileno(stdout))); +printf("stderr: fileno: %d, ttyname: %s\n", fileno(stderr), ttyname(fileno(stderr))); + + if (tcgetattr (fileno (stdin), &t) < 0) { + printf ("tcgetattr failed: %s\n", strerror (errno)); + return; + } + t.c_iflag &= ~(IXOFF | IXON | IXANY); + if (tcsetattr (fileno (stdin), TCSANOW, &t) < 0) { + printf ("tcsetattr failed: %s\n", strerror (errno)); + return; + } +} + +/* + * Hook to ensure that BSP cleanup code gets run on exit + */ +static void +exitHandler(void) +{ + rtems_shutdown_executive(0); +} + +#ifndef RTEMS_LEGACY_STACK +static char* getPrimaryNetworkInterface(void) +{ + // lookup available network interfaces + char ifnamebuf[IF_NAMESIZE]; + char *ifname; + // get primary network interface + ifname = if_indextoname(1, &ifnamebuf[0]); + if (ifname == NULL) return (NULL); + printf("\n***** Primary Network interface : %s *****\n", ifname); + return (ifname); +} + +static void +dhcpcd_hook_handler(rtems_dhcpcd_hook *hook, char *const *env) +{ + int bound = 0; + char iName[16]; + char *name; + char *value; + char * env_position; + + (void)hook; + + char ifnamebuf[IF_NAMESIZE]; + sprintf(ifnamebuf, "%s", getPrimaryNetworkInterface()); + + while (*env != NULL) { + char const * interface = "interface"; + char const * reason = "reason"; + char const * bound_str = "BOUND"; + + name = strtok_r(*env,"=", &env_position); + value = strtok_r(NULL,"=", &env_position); + printf("all out ---> %s = %s\n", name, value); + + if (!strncmp(name, interface, strlen(interface)) && + !strcmp(value, ifnamebuf)) { + snprintf(iName, sizeof(iName), "%s", value); + } + + if (!strncmp(name, reason, strlen(reason)) && + !strncmp(value, bound_str, strlen(bound_str))) { + printf ("Interface %s bounded\n", iName); + bound = 1; + } + + if (bound) { + // as there is no ntp-support in rtems-libbsd, we call our own client + char const * new_ntp_servers = "new_ntp_servers"; + char const * new_host_name = "new_host_name"; + char const * new_tftp_server_name = "new_tftp_server_name"; + + if (!strncmp(name, new_ntp_servers, strlen(new_ntp_servers))) + snprintf(rtemsInit_NTP_server_ip, + sizeof(rtemsInit_NTP_server_ip), + "%s", value); + + if (!strncmp(name, new_host_name, strlen(new_host_name))) + sethostname (value, strlen (value)); + + if (!strncmp(name, new_tftp_server_name, strlen(new_tftp_server_name))){ + snprintf(rtems_bsdnet_bootp_server_name, + sizeof(bootp_server_name_init), + "%s", value); + printf(" rtems_bsdnet_bootp_server_name : %s\n", rtems_bsdnet_bootp_server_name); + } + if(!strncmp(name, "new_bootfile_name", 20)){ + snprintf(rtems_bsdnet_bootp_boot_file_name, + sizeof(bootp_boot_file_name_init), + "%s", value); + printf(" rtems_bsdnet_bootp_boot_file_name : %s\n", rtems_bsdnet_bootp_boot_file_name); + } + if(!strncmp(name, "new_rtems_cmdline", 20)){ + snprintf(rtems_bsdnet_bootp_cmdline, + sizeof(bootp_cmdline_init), + "%s", value); + printf(" rtems_bsdnet_bootp_cmdline : %s\n", rtems_bsdnet_bootp_cmdline); + } + } + ++env; + } + if (bound) + epicsEventSignal(dhcpDone); +} + +static rtems_dhcpcd_hook dhcpcd_hook = { + .name = "ioc boot", + .handler = dhcpcd_hook_handler +}; + +static void +default_network_on_exit(int exit_code, void *arg) +{ + rtems_printer printer; + + (void)arg; + + rtems_print_printer_printf(&printer); + rtems_stack_checker_report_usage_with_plugin(&printer); +} + +static void +default_network_set_self_prio(rtems_task_priority prio) +{ + rtems_status_code sc; + + sc = rtems_task_set_priority(RTEMS_SELF, prio, &prio); + assert(sc == RTEMS_SUCCESSFUL); +} + +static void +default_network_dhcpcd(void) +{ + static const char default_cfg[] = "clientid test client\n"; + rtems_status_code sc; + int fd; + int rv; + ssize_t n; + struct stat statbuf; + + if (ENOENT == stat("/etc/dhcpcd.conf", &statbuf)) { + fd = open("/etc/dhcpcd.conf", O_CREAT | O_WRONLY, + S_IRWXU | S_IRWXG | S_IRWXO); + assert(fd >= 0); + + n = write(fd, default_cfg, sizeof(default_cfg) - 1); + assert(n == (ssize_t) sizeof(default_cfg) - 1); + + static const char fhi_cfg[] = + "nodhcp6\n" + "ipv4only\n" + "option ntp_servers\n" + "option rtems_cmdline\n" + "option tftp_server_name\n" + "option bootfile_name\n" + "define 129 string rtems_cmdline\n" + "timeout 0"; + + n = write(fd, fhi_cfg, sizeof(fhi_cfg) - 1); + assert(n == (ssize_t) sizeof(fhi_cfg) - 1); + + rv = close(fd); + assert(rv == 0); + } + + sc = rtems_dhcpcd_start(NULL); + assert(sc == RTEMS_SUCCESSFUL); +} +#endif // not RTEMS_LEGACY_STACK + +#if __RTEMS_MAJOR__>4 +/* + *********************************************************************** + * TELNET DAEMON * + *********************************************************************** + */ +#define LINE_SIZE 256 +static void +telnet_pseudoIocsh(char *name, __attribute__((unused))void *arg) +{ + char line[LINE_SIZE]; + int fid[3], save_fid[3]; + + printf("info: pty dev name = %s\n", name); + + save_fid[1] = dup2(1,1); + fid[1] = dup2( fileno(stdout), 1); + if (fid[1] == -1 ) printf("Can't dup stdout\n"); + save_fid[2] = dup2(2,2); + fid[2] = dup2( fileno(stderr), 2); + if (fid[2] == -1 ) printf("Can't dup stderr\n"); + + const char *prompt = "tIocSh> "; + + while (1) { + fputs(prompt, stdout); + fflush(stdout); + /* telnet close not detected ??? tbd */ + if (fgets(line, LINE_SIZE, stdin) == NULL) { + dup2(save_fid[1],1); + dup2(save_fid[2],2); + return; + } + if (line[strlen(line)-1] == '\n') line[strlen(line)-1] = 0; + if (!strncmp( line, "bye",3)) { + printf( "%s", "Will end session\n"); + dup2(save_fid[1],1); + dup2(save_fid[2],2); + return; + } + iocshCmd(line); + } +} + +#define SHELL_ENTRY telnet_pseudoIocsh + +/* + * Telnet daemon configuration + * 0 or NULL for most fields in thsi struct indicate default values to RTEMS. + */ +rtems_telnetd_config_table rtems_telnetd_config = { + .command = SHELL_ENTRY, + .arg = NULL, + .priority = 0, + .stack_size = 0, + .client_maximum = 0, + .login_check = NULL, + .keep_stdio = false +}; + +#endif + + +/* + * RTEMS Startup task + */ +void * +POSIX_Init ( void *argument __attribute__((unused))) +{ + int result; + char *argv[3] = { NULL, NULL, NULL }; + rtems_status_code sc; + struct timespec now; + char timeBuff[100]; + + initConsole (); + + /* + * Use BSP-supplied time of day if available otherwise supply default time. + * It is very likely that other time synchronization facilities in EPICS + * will soon override this value. + */ + /* check for RTC ... unfortunately seems to be missing with libbsd and qemu ? + if (checkRealtime() >= 0) { + setRealTimeToRTEMS(); + } else + */ + { + // set time to 14.4.2014 + now.tv_sec = 1397460606; + now.tv_nsec = 0; + sc = clock_settime(CLOCK_REALTIME, &now); + if (sc < 0) + printf ("***** Can't set time: %s\n", rtems_status_text (sc)); + } + sc = clock_gettime( CLOCK_REALTIME, &now); + if ( sc < 0) { + printf ("***** Can't get time: %s\n", rtems_status_text (sc)); + } else { + strftime(timeBuff, sizeof timeBuff, "%D %T", gmtime(&now.tv_sec)); + printf("time set to : %s.%09ld UTC\n", timeBuff, now.tv_nsec); + } + + /* + * Explain why we're here + */ + logReset(); + + /* TBD ... + * Architecture-specific hooks + */ +#ifdef RTEMS_LEGACY_STACK + if (epicsRtemsInitPreSetBootConfigFromNVRAM(&rtems_bsdnet_config) != 0) + delayedPanic("epicsRtemsInitPreSetBootConfigFromNVRAM"); + if (rtems_bsdnet_config.bootp == NULL) { + extern void setBootConfigFromNVRAM(void); + setBootConfigFromNVRAM(); + } + if (epicsRtemsInitPostSetBootConfigFromNVRAM(&rtems_bsdnet_config) != 0) + delayedPanic("epicsRtemsInitPostSetBootConfigFromNVRAM"); +#endif + /* + * Override RTEMS Posix configuration, it gets started with posix prio 2 + */ + epicsThreadSetPriority(epicsThreadGetIdSelf(), epicsThreadPriorityIocsh); + + /* + * Create a reasonable environment + */ + + putenv ("TERM=xterm"); + putenv ("IOCSH_HISTSIZE=20"); + + /* + * Display some OS information + */ + printf("\n***** RTEMS Version: %s *****\n", + rtems_get_version_string()); + +#ifndef RTEMS_LEGACY_STACK + /* + * Start network (libbsd) + * + * start qemu like this + * qemu-system-i386 -m 64 -no-reboot -serial stdio -display none \ + * -net nic,model=rtl8139,macaddr=0e:b0:ba:5e:ba:11 -net user,restrict=yes \ + * -append "--video=off --console=/dev/com1" -kernel libComTestHarness + */ + printf("\n***** Initializing network (libbsd, dhcpcd) *****\n"); + rtems_bsd_setlogpriority("debug"); + on_exit(default_network_on_exit, NULL); + + /* Let other tasks run to complete background work */ + default_network_set_self_prio(RTEMS_MAXIMUM_PRIORITY - 1U); + + /* supress all output from bsd network initialization */ + rtems_bsd_set_vprintf_handler(rtems_bsd_vprintf_handler_mute); + + sc = rtems_bsd_initialize(); + assert(sc == RTEMS_SUCCESSFUL); + + /* Let the callout timer allocate its resources */ + sc = rtems_task_wake_after(2); + assert(sc == RTEMS_SUCCESSFUL); + + printf("\n***** ifconfig lo0 *****\n"); + rtems_bsd_ifconfig_lo0(); + + printf("\n***** add dhcpcd hook *****\n"); + dhcpDone = epicsEventMustCreate(epicsEventEmpty); + rtems_dhcpcd_add_hook(&dhcpcd_hook); + + printf("\n***** Start default network dhcpcd *****\n"); + // if MY_BOOTP??? + default_network_dhcpcd(); + + /* this seems to be hard coded in the BSP -> Sebastian Huber ? */ + printf("\n--Info (hpj)-- bsd task prio IRQS: %d -----\n", rtems_bsd_get_task_priority("IRQS")); + printf("\n--Info (hpj)-- bsd task prio TIME: %d -----\n", rtems_bsd_get_task_priority("TIME")); + + + // wait for dhcp done ... should be if SYNCDHCP is used + epicsEventWaitStatus stat; + printf("\n ---- Waiting for DHCP ...\n"); + stat = epicsEventWaitWithTimeout(dhcpDone, 600); + if (stat == epicsEventOK) + epicsEventDestroy(dhcpDone); + else if (stat == epicsEventWaitTimeout) + printf("\n ---- DHCP timed out!\n"); + else + printf("\n ---- dhcpDone Event Unknown state %d\n", stat); + + const char* ifconfg_args[] = { + "ifconfig", NULL + }; + const char* netstat_args[] = { + "netstat", "-rn", NULL + }; + + printf("-------------- IFCONFIG -----------------\n"); + rtems_bsd_command_ifconfig(1, (char**) ifconfg_args); + printf("-------------- NETSTAT ------------------\n"); + rtems_bsd_command_netstat(2, (char**) netstat_args); + + /* until now there is no NTP support in libbsd -> Sebastian Huber ... */ + printf("\n***** Until now no NTP support in RTEMS 5 with rtems-libbsd *****\n"); + printf("\n***** Ask ntp server once... *****\n"); + if (epicsNtpGetTime(rtemsInit_NTP_server_ip, &now) < 0) { + printf ("***** Can't get time from ntp ...\n"); + } else { + if (clock_settime(CLOCK_REALTIME, &now) < 0){ + printf ("***** Can't set time: %s\n", rtems_status_text (sc)); + } else { + strftime(timeBuff, sizeof timeBuff, "%D %T", gmtime(&now.tv_sec)); + printf("time from ntp : %s.%09ld UTC\n", timeBuff, now.tv_nsec); + } + } +#else // Legacy stack, old network initialization + char *cp; + if ((cp = getenv("EPICS_TS_NTP_INET")) != NULL) + rtems_bsdnet_config.ntp_server[0] = cp; + + int rtems_bsdnet_ntpserver_count = 1; + struct in_addr rtems_bsdnet_ntpserver[rtems_bsdnet_ntpserver_count]; + memcpy(rtems_bsdnet_ntpserver, rtems_bsdnet_config.ntp_server, sizeof(struct in_addr)); + + if (rtems_bsdnet_config.network_task_priority == 0) + { + unsigned int p; + if (epicsThreadHighestPriorityLevelBelow(epicsThreadPriorityScanLow, &p) + == epicsThreadBooleanStatusSuccess) + { + rtems_bsdnet_config.network_task_priority = p; + } + } + printf("\n***** Initializing network (Legacy Stack) *****\n"); + rtems_bsdnet_initialize_network(); + printf("\n***** Network Status *****\n"); + rtems_netstat(3); + rtems_bsdnet_synchronize_ntp (0, 0); +#endif // not RTEMS_LEGACY_STACK + + /* show messages from network after initialization ? good idea? */ + //rtems_bsd_set_vprintf_handler(bsd_vprintf_handler_old); + + printf("\n***** Setting up file system *****\n"); + initialize_remote_filesystem(argv, initialize_local_filesystem(argv)); + fixup_hosts(); + + /* + * More environment: iocsh prompt and hostname + */ + { + char hostname[1024]; + gethostname(hostname, 1023); + char *cp = mustMalloc(strlen(hostname)+3, "iocsh prompt"); + sprintf(cp, "%s> ", hostname); + epicsEnvSet ("IOCSH_PS1", cp); + epicsEnvSet("IOC_NAME", hostname); + } + + if (getenv("") == NULL) { + const char *tzp = envGetConfigParamPtr(&EPICS_TZ); + if (tzp == NULL) { + printf("Warning -- no timezone information available -- times will be displayed as GMT.\n"); + } + + } + tzset(); + printf(" check for time registered , C++ initialization ...\n"); + //osdTimeRegister(); + /*/Volumes/Epics/myExample/bin/RTEMS-xilinx_zynq_a9_qemu + * Run the EPICS startup script + */ +#if __RTEMS_MAJOR__>4 + // if telnetd is requested ... + // printf(" Will try to start telnetd with prio %d ...\n", rtems_telnetd_config.priority); + // result = rtems_telnetd_initialize(); + // printf (" telnetd initialized with result %d\n", result); +#endif + + printf ("***** Preparing EPICS application *****\n"); + iocshRegisterRTEMS (); + set_directory (argv[1]); + epicsEnvSet ("IOC_STARTUP_SCRIPT", argv[1]); + atexit(exitHandler); + errlogFlush(); + printf ("***** Starting EPICS application *****\n"); + +#if 0 +// Start an rtems shell before main, for debugging RTEMS system issues + rtems_shell_init("SHLL", RTEMS_MINIMUM_STACK_SIZE * 4, + 100, "/dev/console", + false, true, + NULL); +#endif + + result = main ((sizeof argv / sizeof argv[0]) - 1, argv); + printf ("***** IOC application terminating *****\n"); + epicsThreadSleep(1.0); + epicsExit(result); + +#if defined(__rtems__) + delayedPanic("will reset rtems ... end of POSIX_Init"); +#endif + exit(0); +} + +#if defined(QEMU_FIXUPS) +/* Override some hooks (weak symbols) + * if BSP defaults aren't configured for running tests. + */ + + +/* Ensure that stdio goes to serial (so it can be captured) */ +#if defined(__i386__) && !USE_COM1_AS_CONSOLE +#include +#if __RTEMS_MAJOR__ > 4 +#include +#endif + +extern int BSPPrintkPort; +void bsp_predriver_hook(void) +{ +#if __RTEMS_MAJOR__ > 4 + Console_Port_Minor = BSP_CONSOLE_PORT_COM1; +#else + BSPConsolePort = BSP_CONSOLE_PORT_COM1; + +#endif + BSPPrintkPort = BSP_CONSOLE_PORT_COM1; +} +#endif + +/* reboot immediately when done. */ +#if defined(__i386__) && BSP_PRESS_KEY_FOR_RESET +void bsp_cleanup(void) +{ + void bsp_reset(); + bsp_reset(); +} +#endif + +#endif /* QEMU_FIXUPS */ + +int cexpdebug __attribute__((weak)); diff --git a/modules/libcom/RTEMS/rtems_netconfig.c b/modules/libcom/RTEMS/rtems_netconfig.c index 4f7a84149..0207512c7 100644 --- a/modules/libcom/RTEMS/rtems_netconfig.c +++ b/modules/libcom/RTEMS/rtems_netconfig.c @@ -15,8 +15,24 @@ */ #include #include +#include + +#define RTEMS_VERSION_INT VERSION_INT(__RTEMS_MAJOR__, __RTEMS_MINOR__, 0, 0) + +#ifdef RTEMS_LEGACY_STACK // old non libbsd stack #include +/* + * Comment (by sebastian.huber): + * + * This rtems_bsdnet_loopattach() was a hack and is no longer needed in RTEMS + * 4.11. + * + * -- + * Ticket URL: + */ + +#if RTEMS_VERSION_INT<=VERSION_INT(4,10,0,0) extern void rtems_bsdnet_loopattach(); static struct rtems_bsdnet_ifconfig loopback_config = { "lo0", /* name */ @@ -25,7 +41,7 @@ static struct rtems_bsdnet_ifconfig loopback_config = { "127.0.0.1", /* IP address */ "255.0.0.0", /* IP net mask */ }; - +#endif /* * The following conditionals select the network interface card. * @@ -37,19 +53,23 @@ static struct rtems_bsdnet_ifconfig loopback_config = { * application directory and make the appropriate changes. */ #if defined(__i386__) - extern int rtems_ne2kpci_driver_attach (struct rtems_bsdnet_ifconfig *config, int attach); static struct rtems_bsdnet_ifconfig ne2k_driver_config = { "ne2", /* name */ rtems_ne2kpci_driver_attach, /* attach function */ +#if RTEMS_VERSION_INT<=VERSION_INT(4,10,0,0) &loopback_config, /* link to next interface */ +#else + NULL, +#endif }; + extern int rtems_fxp_attach (struct rtems_bsdnet_ifconfig *, int); static struct rtems_bsdnet_ifconfig fxp_driver_config = { "fxp1", /* name */ rtems_fxp_attach, /* attach function */ - &ne2k_driver_config, /* link to next interface */ + &ne2k_driver_config, /* link to next interface */ }; extern int rtems_3c509_driver_attach (struct rtems_bsdnet_ifconfig *, int); static struct rtems_bsdnet_ifconfig e3c509_driver_config = { @@ -73,12 +93,14 @@ static struct rtems_bsdnet_ifconfig e3c509_driver_config = { # endif # endif -static struct rtems_bsdnet_ifconfig bsp_driver_config = { +static struct rtems_bsdnet_ifconfig netdriver_config = { RTEMS_BSP_NETWORK_DRIVER_NAME, /* name */ RTEMS_BSP_NETWORK_DRIVER_ATTACH, /* attach function */ +#if RTEMS_VERSION_INT<=VERSION_INT(4,10,0,0) &loopback_config, /* link to next interface */ +#endif }; -#define FIRST_DRIVER_CONFIG &bsp_driver_config +#define FIRST_DRIVER_CONFIG &netdriver_config #endif @@ -127,3 +149,11 @@ struct rtems_bsdnet_config rtems_bsdnet_config = { NULL, /* Host name */ MY_DOMAINNAME, /* Domain name */ }; +#else // libbsd "new" stack +// nothing to do?? +#endif // RTEMS_LEGACY_STACK + + + + + diff --git a/modules/libcom/RTEMS/setBootConfigFromNVRAM.c b/modules/libcom/RTEMS/setBootConfigFromNVRAM.c index 6fcca54b2..deb9f0654 100644 --- a/modules/libcom/RTEMS/setBootConfigFromNVRAM.c +++ b/modules/libcom/RTEMS/setBootConfigFromNVRAM.c @@ -12,7 +12,9 @@ #include #include #include +#ifdef RTEMS_LEGACY_STACK #include +#endif #include #include #include @@ -26,6 +28,7 @@ char *env_nfsServer; char *env_nfsPath; char *env_nfsMountPoint; +extern char* rtems_bsdnet_bootp_cmdline; /* * Split argument string of form nfs_server:nfs_export: * The nfs_export component will be used as: diff --git a/modules/libcom/src/calc/postfix.c b/modules/libcom/src/calc/postfix.c index 6519d9a39..b3a99e08b 100644 --- a/modules/libcom/src/calc/postfix.c +++ b/modules/libcom/src/calc/postfix.c @@ -27,6 +27,10 @@ #include "postfixPvt.h" #include "libComAPI.h" +#ifdef RTEMS_HAS_ALTIVEC +#pragma GCC push_options +#pragma GCC optimize ("O0") +#endif /* declarations for postfix */ @@ -626,3 +630,6 @@ LIBCOM_API void } } } +#ifdef RTEMS_HAS_ALTIVEC +#pragma GCC pop_options +#endif diff --git a/modules/libcom/src/osi/os/RTEMS/devLibVMEOSD.c b/modules/libcom/src/osi/os/RTEMS-kernel/devLibVMEOSD.c similarity index 85% rename from modules/libcom/src/osi/os/RTEMS/devLibVMEOSD.c rename to modules/libcom/src/osi/os/RTEMS-kernel/devLibVMEOSD.c index f8b05421c..ed310eebc 100644 --- a/modules/libcom/src/osi/os/RTEMS/devLibVMEOSD.c +++ b/modules/libcom/src/osi/os/RTEMS-kernel/devLibVMEOSD.c @@ -19,12 +19,16 @@ #include #include "devLibVME.h" #include +#include +#include #if defined(__PPC__) || defined(__mcf528x__) +/* EPICS VME support requires various routines to be provided by the + * BSP. Most MVME PowerPC BSPs provide them, plus the uC5282. + */ #if defined(__PPC__) #include -#include #endif @@ -126,8 +130,7 @@ static long rtemsDevInit(void) { /* assume the vme bridge has been initialized by bsp */ - /* init BSP extensions [memProbe etc.] */ - return bspExtInit(); + return 0; } /* @@ -245,18 +248,70 @@ static long rtemsDevMapAddr (epicsAddressType addrType, unsigned options, return 0; } +#if defined(__m68k__) +/* All RTEMS m68k BSPs define this, m68k/shared/[misc/]memProbe.c */ +extern +rtems_status_code bspExtMemProbe(void *addr, int write, int size, void *pval); +#else + +static +rtems_status_code bspExtMemProbe(void *addr, int write, int size, void *pval) +{ + rtems_interrupt_level flags; + rtems_status_code ret = RTEMS_SUCCESSFUL; + epicsUInt32 val; + + /* bspExt allows caller to write uninitialized values, we don't */ + if(write && !pval) + return RTEMS_INVALID_NUMBER; + + switch(size) { + case 1: + case 2: + case 4: + break; + default: + return RTEMS_INVALID_SIZE; + } + + if(write) + memcpy(&val, pval, size); + + rtems_interrupt_disable(flags); + _BSP_clear_hostbridge_errors(0,1); + + if(!write) { + switch(size) { + case 1: val = ioread8(addr)<<24; break; + case 2: val = nat_ioread16(addr)<<16; break; + case 4: val = nat_ioread32(addr); break; + } + } else { + switch(size) { + case 1: iowrite8(addr, val>>24); break; + case 2: nat_iowrite16(addr, val>>16); break; + case 4: nat_iowrite32(addr, val); break; + } + } + + ret = _BSP_clear_hostbridge_errors(0,1); + rtems_interrupt_enable(flags); + + if(!write && pval) + memcpy(pval, &val, size); + + return ret; +} +#endif + /* * a bus error safe "wordSize" read at the specified address which returns * unsuccessful status if the device isnt present */ -rtems_status_code bspExtMemProbe(void *addr, int write, int size, void *pval); static long rtemsDevReadProbe (unsigned wordSize, volatile const void *ptr, void *pValue) { long status; - /* - * this global variable exists in the nivxi library - */ status = bspExtMemProbe ((void*)ptr, 0/*read*/, wordSize, pValue); if (status!=RTEMS_SUCCESSFUL) { return S_dev_noDevice; @@ -273,9 +328,6 @@ static long rtemsDevWriteProbe (unsigned wordSize, volatile void *ptr, const voi { long status; - /* - * this global variable exists in the nivxi library - */ status = bspExtMemProbe ((void*)ptr, 1/*write*/, wordSize, (void*)pValue); if (status!=RTEMS_SUCCESSFUL) { return S_dev_noDevice; @@ -359,7 +411,7 @@ devLibVME *pdevLibVME; #endif /* defined(__PPC__) || defined(__mcf528x__) */ /* - * Some vxWorks convenience routines + * Some convenience routines */ void bcopyLongs(char *source, char *destination, int nlongs) diff --git a/modules/libcom/src/osi/os/RTEMS/epicsAtomicOSD.cpp b/modules/libcom/src/osi/os/RTEMS-kernel/epicsAtomicOSD.cpp similarity index 100% rename from modules/libcom/src/osi/os/RTEMS/epicsAtomicOSD.cpp rename to modules/libcom/src/osi/os/RTEMS-kernel/epicsAtomicOSD.cpp diff --git a/modules/libcom/src/osi/os/RTEMS/epicsAtomicOSD.h b/modules/libcom/src/osi/os/RTEMS-kernel/epicsAtomicOSD.h similarity index 100% rename from modules/libcom/src/osi/os/RTEMS/epicsAtomicOSD.h rename to modules/libcom/src/osi/os/RTEMS-kernel/epicsAtomicOSD.h diff --git a/modules/libcom/src/osi/os/RTEMS/epicsMath.h b/modules/libcom/src/osi/os/RTEMS-kernel/epicsMath.h similarity index 100% rename from modules/libcom/src/osi/os/RTEMS/epicsMath.h rename to modules/libcom/src/osi/os/RTEMS-kernel/epicsMath.h diff --git a/modules/libcom/src/osi/os/RTEMS/osdEvent.c b/modules/libcom/src/osi/os/RTEMS-kernel/osdEvent.c similarity index 100% rename from modules/libcom/src/osi/os/RTEMS/osdEvent.c rename to modules/libcom/src/osi/os/RTEMS-kernel/osdEvent.c diff --git a/modules/libcom/src/osi/os/RTEMS/osdEvent.h b/modules/libcom/src/osi/os/RTEMS-kernel/osdEvent.h similarity index 100% rename from modules/libcom/src/osi/os/RTEMS/osdEvent.h rename to modules/libcom/src/osi/os/RTEMS-kernel/osdEvent.h diff --git a/modules/libcom/src/osi/os/RTEMS/osdFindSymbol.c b/modules/libcom/src/osi/os/RTEMS-kernel/osdFindSymbol.c similarity index 100% rename from modules/libcom/src/osi/os/RTEMS/osdFindSymbol.c rename to modules/libcom/src/osi/os/RTEMS-kernel/osdFindSymbol.c diff --git a/modules/libcom/src/osi/os/RTEMS/osdMutex.c b/modules/libcom/src/osi/os/RTEMS-kernel/osdMutex.c similarity index 100% rename from modules/libcom/src/osi/os/RTEMS/osdMutex.c rename to modules/libcom/src/osi/os/RTEMS-kernel/osdMutex.c diff --git a/modules/libcom/src/osi/os/RTEMS/osdMutex.h b/modules/libcom/src/osi/os/RTEMS-kernel/osdMutex.h similarity index 100% rename from modules/libcom/src/osi/os/RTEMS/osdMutex.h rename to modules/libcom/src/osi/os/RTEMS-kernel/osdMutex.h diff --git a/modules/libcom/src/osi/os/RTEMS/osdPoolStatus.c b/modules/libcom/src/osi/os/RTEMS-kernel/osdPoolStatus.c similarity index 100% rename from modules/libcom/src/osi/os/RTEMS/osdPoolStatus.c rename to modules/libcom/src/osi/os/RTEMS-kernel/osdPoolStatus.c diff --git a/modules/libcom/src/osi/os/RTEMS/osdProcess.c b/modules/libcom/src/osi/os/RTEMS-kernel/osdProcess.c similarity index 100% rename from modules/libcom/src/osi/os/RTEMS/osdProcess.c rename to modules/libcom/src/osi/os/RTEMS-kernel/osdProcess.c diff --git a/modules/libcom/src/osi/os/RTEMS/osdReadline.c b/modules/libcom/src/osi/os/RTEMS-kernel/osdReadline.c similarity index 100% rename from modules/libcom/src/osi/os/RTEMS/osdReadline.c rename to modules/libcom/src/osi/os/RTEMS-kernel/osdReadline.c diff --git a/modules/libcom/src/osi/os/RTEMS/osdSignal.cpp b/modules/libcom/src/osi/os/RTEMS-kernel/osdSignal.cpp similarity index 100% rename from modules/libcom/src/osi/os/RTEMS/osdSignal.cpp rename to modules/libcom/src/osi/os/RTEMS-kernel/osdSignal.cpp diff --git a/modules/libcom/src/osi/os/RTEMS/osdSock.h b/modules/libcom/src/osi/os/RTEMS-kernel/osdSock.h similarity index 97% rename from modules/libcom/src/osi/os/RTEMS/osdSock.h rename to modules/libcom/src/osi/os/RTEMS-kernel/osdSock.h index 49023fe78..3090234af 100644 --- a/modules/libcom/src/osi/os/RTEMS/osdSock.h +++ b/modules/libcom/src/osi/os/RTEMS-kernel/osdSock.h @@ -37,6 +37,10 @@ int select(int n, fd_set *readfds, fd_set *writefds, fd_set *exceptfds, str } #endif +#ifndef IPPORT_USERRESERVED +#define IPPORT_USERRESERVED 5000 +#endif + typedef int SOCKET; #define INVALID_SOCKET (-1) #define SOCKERRNO errno @@ -68,7 +72,6 @@ typedef unsigned char osiSockOptMcastTTL_t; #define SOCK_ENOTSOCK ENOTSOCK #define SOCK_EBADF EBADF -#define bzero(p,n) memset(p,0,n) #include #include #include diff --git a/modules/libcom/src/osi/os/RTEMS/osdSpin.c b/modules/libcom/src/osi/os/RTEMS-kernel/osdSpin.c similarity index 100% rename from modules/libcom/src/osi/os/RTEMS/osdSpin.c rename to modules/libcom/src/osi/os/RTEMS-kernel/osdSpin.c diff --git a/modules/libcom/src/osi/os/RTEMS/osdStrtod.h b/modules/libcom/src/osi/os/RTEMS-kernel/osdStrtod.h similarity index 100% rename from modules/libcom/src/osi/os/RTEMS/osdStrtod.h rename to modules/libcom/src/osi/os/RTEMS-kernel/osdStrtod.h diff --git a/modules/libcom/src/osi/os/RTEMS/osdThread.c b/modules/libcom/src/osi/os/RTEMS-kernel/osdThread.c similarity index 100% rename from modules/libcom/src/osi/os/RTEMS/osdThread.c rename to modules/libcom/src/osi/os/RTEMS-kernel/osdThread.c diff --git a/modules/libcom/src/osi/os/RTEMS/osdThread.h b/modules/libcom/src/osi/os/RTEMS-kernel/osdThread.h similarity index 100% rename from modules/libcom/src/osi/os/RTEMS/osdThread.h rename to modules/libcom/src/osi/os/RTEMS-kernel/osdThread.h diff --git a/modules/libcom/src/osi/os/RTEMS/osdThreadExtra.c b/modules/libcom/src/osi/os/RTEMS-kernel/osdThreadExtra.c similarity index 100% rename from modules/libcom/src/osi/os/RTEMS/osdThreadExtra.c rename to modules/libcom/src/osi/os/RTEMS-kernel/osdThreadExtra.c diff --git a/modules/libcom/src/osi/os/RTEMS/osdTime.cpp b/modules/libcom/src/osi/os/RTEMS-kernel/osdTime.cpp similarity index 100% rename from modules/libcom/src/osi/os/RTEMS/osdTime.cpp rename to modules/libcom/src/osi/os/RTEMS-kernel/osdTime.cpp diff --git a/modules/libcom/src/osi/os/RTEMS/osdTime.h b/modules/libcom/src/osi/os/RTEMS-kernel/osdTime.h similarity index 100% rename from modules/libcom/src/osi/os/RTEMS/osdTime.h rename to modules/libcom/src/osi/os/RTEMS-kernel/osdTime.h diff --git a/modules/libcom/src/osi/os/RTEMS/osiUnistd.h b/modules/libcom/src/osi/os/RTEMS-kernel/osiUnistd.h similarity index 100% rename from modules/libcom/src/osi/os/RTEMS/osiUnistd.h rename to modules/libcom/src/osi/os/RTEMS-kernel/osiUnistd.h diff --git a/modules/libcom/src/osi/os/RTEMS-posix/devLibVMEOSD.c b/modules/libcom/src/osi/os/RTEMS-posix/devLibVMEOSD.c new file mode 100644 index 000000000..c83c338d9 --- /dev/null +++ b/modules/libcom/src/osi/os/RTEMS-posix/devLibVMEOSD.c @@ -0,0 +1,6 @@ +#ifdef RTEMS_LEGACY_STACK +#include "../RTEMS-kernel/devLibVMEOSD.c" +#else +#pragma message "\n VME-Support only with RTEMS Legacy stack\n" +#include "../default/devLibVMEOSD.c" +#endif diff --git a/modules/libcom/src/osi/os/RTEMS-posix/osdMessageQueue.c b/modules/libcom/src/osi/os/RTEMS-posix/osdMessageQueue.c new file mode 100644 index 000000000..7c7ea8aad --- /dev/null +++ b/modules/libcom/src/osi/os/RTEMS-posix/osdMessageQueue.c @@ -0,0 +1,160 @@ +/*************************************************************************\ +* Copyright (c) 2002 The University of Chicago, as Operator of Argonne +* National Laboratory. +* Copyright (c) 2002 The Regents of the University of California, as +* Operator of Los Alamos National Laboratory. +* SPDX-License-Identifier: EPICS +* EPICS Base is distributed subject to a Software License Agreement found +* in file LICENSE that is included with this distribution. +\*************************************************************************/ +/* + * Author W. Eric Norum + * norume@aps.anl.gov + * 630 252 4793 + */ + +/* + * We want to access information which is + * normally hidden from application programs. + */ +#define __RTEMS_VIOLATE_KERNEL_VISIBILITY__ 1 + +#define epicsExportSharedSymbols +#include +#include +#include +#include +#include +#include +#include "epicsMessageQueue.h" +#include "errlog.h" +#include + +#include +#include +#include + +static int idCnt; + +LIBCOM_API epicsMessageQueueId epicsStdCall +epicsMessageQueueCreate(unsigned int capacity, unsigned int maximumMessageSize) +{ + struct mq_attr the_attr; + epicsMessageQueueId id = (epicsMessageQueueId)calloc(1, sizeof(*id)); + sprintf(id->name, "MQ_%0d", epicsAtomicIncrIntT(&idCnt)); + the_attr.mq_maxmsg = capacity; + the_attr.mq_msgsize = maximumMessageSize; + id->id = mq_open(id->name, O_RDWR | O_CREAT | O_EXCL, 0644, &the_attr); + if (id->id <0) { + fprintf (stderr, "Can't create message queue: %s\n", strerror (errno)); + return NULL; + } + return id; +} + +LIBCOM_API void epicsStdCall epicsMessageQueueDestroy( + epicsMessageQueueId id) +{ + int rv; + rv = mq_close(id->id); + if( rv ) { + fprintf(stderr, "epicsMessageQueueDestroy mq_close failed: %s\n", + strerror(rv)); + } + rv = mq_unlink(id->name); + if( rv ) { + fprintf(stderr,"epicsMessageQueueDestroy mq_unlink %s failed: %s\n", + id->name, strerror(rv)); + } + free(id); +} + + +LIBCOM_API int epicsStdCall epicsMessageQueueTrySend( + epicsMessageQueueId id, + void *message, + unsigned int messageSize) +{ + struct timespec ts; + clock_gettime(CLOCK_REALTIME, &ts); + return mq_timedsend(id->id, (char const *)message, messageSize, 0, &ts); +} + +LIBCOM_API int epicsStdCall epicsMessageQueueSendWithTimeout( + epicsMessageQueueId id, + void *message, + unsigned int messageSize, + double timeout) +{ + struct timespec ts; + unsigned long micros; + + // assume timeout in sec + micros = (unsigned long)(timeout * 1000000.0); + clock_gettime(CLOCK_REALTIME, &ts); + ts.tv_sec += micros / 1000000L; + ts.tv_nsec += (micros % 1000000L) * 1000L; + + return mq_timedsend (id->id, (const char *)message, messageSize, 0, &ts); +} + +LIBCOM_API int epicsStdCall epicsMessageQueueTryReceive( + epicsMessageQueueId id, + void *message, + unsigned int size) +{ + struct timespec ts; + clock_gettime(CLOCK_REALTIME, &ts); + return mq_timedreceive(id->id, (char *)message, size, NULL, &ts); +} + +LIBCOM_API int epicsStdCall epicsMessageQueueReceiveWithTimeout( + epicsMessageQueueId id, + void *message, + unsigned int size, + double timeout) +{ + unsigned long micros; + struct timespec ts; + + micros = (unsigned long)(timeout * 1000000.0); + clock_gettime(CLOCK_REALTIME, &ts); + ts.tv_sec += micros / 1000000L; + ts.tv_nsec += (micros % 1000000L) * 1000L; + + return mq_timedreceive(id->id, (char *)message, size, NULL, &ts); +} + +LIBCOM_API int epicsStdCall epicsMessageQueuePending( + epicsMessageQueueId id) +{ + int rv; + struct mq_attr the_attr; + + rv = mq_getattr(id->id, &the_attr); + if (rv) { + fprintf(stderr, "Epics Message queue %x (%s) get attr failed: %s\n", + (unsigned int)id->id, id->name, strerror(rv)); + return -1; + } + return the_attr.mq_curmsgs; +} +LIBCOM_API void epicsStdCall epicsMessageQueueShow( + epicsMessageQueueId id, + int level) +{ + int rv; + struct mq_attr the_attr; + + rv = mq_getattr(id->id, &the_attr); + if (rv) { + fprintf(stderr, "Epics Message queue %x (%s) get attr failed: %s\n", + (unsigned int)id->id, id->name, strerror(rv)); + } + + printf("Message Queue Used:%ld Max Msg:%lu", the_attr.mq_curmsgs, the_attr.mq_maxmsg); + if (level >= 1) + printf(" Maximum size:%lu", the_attr.mq_msgsize); + + printf("\n"); +} diff --git a/modules/libcom/src/osi/os/RTEMS-posix/osdMessageQueue.h b/modules/libcom/src/osi/os/RTEMS-posix/osdMessageQueue.h new file mode 100644 index 000000000..95e66e73e --- /dev/null +++ b/modules/libcom/src/osi/os/RTEMS-posix/osdMessageQueue.h @@ -0,0 +1,28 @@ +/*************************************************************************\ +* Copyright (c) 2002 The University of Chicago, as Operator of Argonne +* National Laboratory. +* Copyright (c) 2002 The Regents of the University of California, as +* Operator of Los Alamos National Laboratory. +* EPICS BASE Versions 3.13.7 +* and higher are distributed subject to a Software License Agreement found +* in file LICENSE that is included with this distribution. +\*************************************************************************/ +/* + * Author W. Eric Norum + * norume@aps.anl.gov + * 630 252 4793 + */ + +/* + * Very thin shims around RTEMS routines + */ +#include +#include + +struct epicsMessageQueueOSD { + mqd_t id; + char name[24]; +}; +#define epicsMessageQueueSend(q,m,l) (mq_send((q)->id, (const char*)(m), (l), 0)) +#define epicsMessageQueueReceive(q,m,s) (mq_receive((q)->id, (char*)(m), (s), NULL)) + diff --git a/modules/libcom/src/osi/os/RTEMS-posix/osdMutex.c b/modules/libcom/src/osi/os/RTEMS-posix/osdMutex.c new file mode 100644 index 000000000..2ee16bf88 --- /dev/null +++ b/modules/libcom/src/osi/os/RTEMS-posix/osdMutex.c @@ -0,0 +1,8 @@ +#include +#include +#include +#ifndef RTEMS_LEGACY_STACK +#include +#endif + +#include "../posix/osdMutex.c" diff --git a/modules/libcom/src/osi/os/RTEMS-posix/osdPoolStatus.c b/modules/libcom/src/osi/os/RTEMS-posix/osdPoolStatus.c new file mode 100644 index 000000000..5b202fd1d --- /dev/null +++ b/modules/libcom/src/osi/os/RTEMS-posix/osdPoolStatus.c @@ -0,0 +1,43 @@ +/*************************************************************************\ +* Copyright (c) 2002 The University of Chicago, as Operator of Argonne +* National Laboratory. +* Copyright (c) 2002 The Regents of the University of California, as +* Operator of Los Alamos National Laboratory. +* EPICS BASE Versions 3.13.7 +* and higher are distributed subject to a Software License Agreement found +* in file LICENSE that is included with this distribution. +\*************************************************************************/ +#include +#include +#include +#define epicsExportSharedSymbols +#include "osiPoolStatus.h" + +#if __RTEMS_MAJOR__<5 +/* + * * osiSufficentSpaceInPool () + * */ +LIBCOM_API int epicsStdCall osiSufficentSpaceInPool ( size_t contiguousBlockSize ) +{ + rtems_malloc_statistics_t s; + unsigned long n; + + malloc_get_statistics(&s); + n = s.space_available - (unsigned long)(s.lifetime_allocated - s.lifetime_freed); + return (n > (50000 + contiguousBlockSize)); +} + +#else +/* + * osiSufficentSpaceInPool () + */ +LIBCOM_API int epicsStdCall osiSufficentSpaceInPool ( size_t contiguousBlockSize ) +{ + unsigned long n; + Heap_Information_block info; + + malloc_info( &info ); + n = info.Stats.size - (unsigned long)(info.Stats.lifetime_allocated - info.Stats.lifetime_freed); + return (n > (50000 + contiguousBlockSize)); +} +#endif diff --git a/modules/libcom/src/osi/os/RTEMS-posix/osdSock.h b/modules/libcom/src/osi/os/RTEMS-posix/osdSock.h new file mode 100644 index 000000000..5d765b3a7 --- /dev/null +++ b/modules/libcom/src/osi/os/RTEMS-posix/osdSock.h @@ -0,0 +1,80 @@ +/*************************************************************************\ +* Copyright (c) 2002 The University of Chicago, as Operator of Argonne +* National Laboratory. +* Copyright (c) 2002 The Regents of the University of California, as +* Operator of Los Alamos National Laboratory. +* EPICS BASE is distributed subject to a Software License Agreement found +* in file LICENSE that is included with this distribution. +\*************************************************************************/ + +/* + * Linux specific socket include + */ + +#ifndef osdSockH +#define osdSockH + +#include + +#include +#include /* for MAXHOSTNAMELEN */ +#include +#include +#include +#include +#include +#include +#include +#include +#include /* close() and others */ + +typedef int SOCKET; +#define INVALID_SOCKET (-1) +#define SOCKERRNO errno +#define socket_ioctl(A,B,C) ioctl(A,B,C) +typedef int osiSockIoctl_t; +typedef socklen_t osiSocklen_t; +typedef char osiSockOptMcastLoop_t; +typedef char osiSockOptMcastTTL_t; + +#define FD_IN_FDSET(FD) ((FD)ifr_addr.sa_len + sizeof(pifreq->ifr_name)) + +#ifndef IPPORT_USERRESERVED +#define IPPORT_USERRESERVED 5000 +#endif + +#endif /*osdSockH*/ diff --git a/modules/libcom/src/osi/os/posix/osdFindSymbol.c b/modules/libcom/src/osi/os/posix/osdFindSymbol.c index 6c26696c8..fc175fc60 100644 --- a/modules/libcom/src/osi/os/posix/osdFindSymbol.c +++ b/modules/libcom/src/osi/os/posix/osdFindSymbol.c @@ -7,9 +7,10 @@ \*************************************************************************/ /* osi/os/posix/osdFindSymbol.c */ +#include "epicsFindSymbol.h" + #include -#include "epicsFindSymbol.h" /* non-POSIX extension available on Linux (glibc at least) and OSX. */ diff --git a/modules/libcom/src/osi/os/posix/osdThread.c b/modules/libcom/src/osi/os/posix/osdThread.c index 0eb5f5fd2..8690afad4 100644 --- a/modules/libcom/src/osi/os/posix/osdThread.c +++ b/modules/libcom/src/osi/os/posix/osdThread.c @@ -24,8 +24,9 @@ #include #include -#if defined(_POSIX_MEMLOCK) && _POSIX_MEMLOCK > 0 -#include +#define USE_MEMLOCK (defined(_POSIX_MEMLOCK) && (_POSIX_MEMLOCK > 0) && !defined(__rtems__)) +#if USE_MEMLOCK +#include #endif #include "epicsStdio.h" @@ -426,7 +427,8 @@ static void epicsThreadInit(void) LIBCOM_API void epicsThreadRealtimeLock(void) { -#if defined(_POSIX_MEMLOCK) && _POSIX_MEMLOCK > 0 +#if USE_MEMLOCK +#ifndef RTEMS_LEGACY_STACK // seems to be part of libbsd? if (pcommonAttr->maxPriority > pcommonAttr->minPriority) { int status = mlockall(MCL_CURRENT | MCL_FUTURE); @@ -451,6 +453,7 @@ void epicsThreadRealtimeLock(void) } } } +#endif // LEGACY STACK #endif } diff --git a/modules/libcom/src/osi/os/posix/osdTime.cpp b/modules/libcom/src/osi/os/posix/osdTime.cpp index 6d7b86048..b3bb84725 100644 --- a/modules/libcom/src/osi/os/posix/osdTime.cpp +++ b/modules/libcom/src/osi/os/posix/osdTime.cpp @@ -125,3 +125,15 @@ extern "C" LIBCOM_API void ++wakeTime->tv_sec; } } + +#ifdef __rtems__ +int osdTickGet() +{ + return epicsMonotonicGet(); // ns +} +int osdTickRateGet() +{ + return 1000000000; +} +void osdNTPReport() {} +#endif diff --git a/modules/libcom/src/osi/os/posix/osdTime.h b/modules/libcom/src/osi/os/posix/osdTime.h index 807b6d682..2aab01f3e 100644 --- a/modules/libcom/src/osi/os/posix/osdTime.h +++ b/modules/libcom/src/osi/os/posix/osdTime.h @@ -31,6 +31,14 @@ extern "C" { LIBCOM_API void epicsStdCall convertDoubleToWakeTime(double timeout,struct timespec *wakeTime); +#ifdef __rtems__ +void osdNTPInit(void); +int osdNTPGet(struct timespec *now); +int osdTickGet(void); +int osdTickRateGet(void); +void osdNTPReport(void); +#endif + #ifdef __cplusplus } #endif /* __cplusplus */ diff --git a/src/tools/makeTestfile.pl b/src/tools/makeTestfile.pl index 455bd7f69..9bfb46f4f 100644 --- a/src/tools/makeTestfile.pl +++ b/src/tools/makeTestfile.pl @@ -6,7 +6,7 @@ # Operator of Los Alamos National Laboratory. # SPDX-License-Identifier: EPICS # EPICS BASE is distributed subject to a Software License Agreement found -# in file LICENSE that is included with this distribution. +# in file LICENSE that is included with this distribution. #************************************************************************* # The makeTestfile.pl script generates a file $target.t which is needed @@ -36,29 +36,37 @@ my $tool = basename($0); my $timeout = $ENV{EPICS_UNITTEST_TIMEOUT} // 500; # 8 min 20 sec my ($TA, $HA, $target, $exe) = @ARGV; -my $exec; +my ($exec, $error); -# Use WINE to run windows target executables on non-windows host -if( $TA =~ /^win32-x86/ && $HA !~ /^win/ ) { - # new deb. derivatives have wine32 and wine64 - # older have wine and wine64 - # prefer wine32 if present - my $wine32 = "/usr/bin/wine32"; - $wine32 = "/usr/bin/wine" if ! -x $wine32; - $exec = "$wine32 $exe"; -} elsif( $TA =~ /^windows-x64/ && $HA !~ /^win/ ) { - $exec = "wine64 $exe"; - -# Run pc386 test harness w/ QEMU -} elsif( $TA =~ /^RTEMS-pc386-qemu$/ ) { - $exec = "qemu-system-i386 -m 64 -no-reboot -serial stdio -display none -net nic,model=ne2k_pci -net user,restrict=yes -kernel $exe"; - -# Explicitly fail for other RTEMS targets -} elsif( $TA =~ /^RTEMS-/ ) { - die "$tool: I don't know how to create scripts for testing $TA on $HA\n"; - -} else { - $exec = "./$exe"; +if ($TA =~ /^win32-x86/ && $HA !~ /^win/) { + # Use WINE to run win32-x86 executables on non-windows hosts. + # New Debian derivatives have wine32 and wine64, older ones have + # wine and wine64. We prefer wine32 if present. + my $wine32 = "/usr/bin/wine32"; + $wine32 = "/usr/bin/wine" if ! -x $wine32; + $error = $exec = "$wine32 $exe"; +} +elsif ($TA =~ /^windows-x64/ && $HA !~ /^win/) { + # Use WINE to run windows-x64 executables on non-windows hosts. + $error = $exec = "wine64 $exe"; +} +elsif ($TA =~ /^RTEMS-pc[36]86-qemu$/) { + # Run the pc386 and pc686 test harness w/ QEMU + $exec = "qemu-system-i386 -m 64 -no-reboot " + . "-serial stdio -display none " + . "-net nic,model=e1000 -net nic,model=ne2k_pci " + . "-net user,restrict=yes " + . "-append --console=/dev/com1 " + . "-kernel $exe"; + $error = "qemu-system-i386 ... -kernel $exe"; +} +elsif ($TA =~ /^RTEMS-/) { + # Explicitly fail for other RTEMS targets + die "$tool: I don't know how to create scripts for testing $TA on $HA\n"; +} +else { + # Assume it's directly executable on other targets + $error = $exec = "./$exe"; } # Create the $target.t file @@ -114,12 +122,12 @@ my \$proc; if (! Win32::Process::Create(\$proc, abs_path('$exec'), '$exec', 1, NORMAL_PRIORITY_CLASS, '.')) { my \$err = Win32::FormatMessage(Win32::GetLastError()); - die "\$tool: Can't create Process for '$exec': \$err\\n"; + die "\$tool: Can't create Process for '$error': \$err\\n"; } if (! \$proc->Wait(1000 * \$timeout)) { \$proc->Kill(1); print "\\n#### Test stopped by \$tool after \$timeout seconds\\n"; - die "\$tool: Timed out '$exec' after \$timeout seconds\\n"; + die "\$tool: Timed out '$error' after \$timeout seconds\\n"; } my \$status; \$proc->GetExitCode(\$status); @@ -132,7 +140,7 @@ else { print $OUT <<__UNIX__; my \$pid = fork(); -die "\$tool: Can't fork for '$exec': \$!\\n" +die "\$tool: Can't fork for '$error': \$!\\n" unless defined \$pid; if (\$pid) { @@ -141,7 +149,7 @@ if (\$pid) { # Time's up, kill the child kill 9, \$pid; print "\\n#### Test stopped by \$tool after \$timeout seconds\\n"; - die "\$tool: Timed out '$exec' after \$timeout seconds\\n"; + die "\$tool: Timed out '$error' after \$timeout seconds\\n"; }; alarm \$timeout; @@ -152,7 +160,7 @@ if (\$pid) { else { # Child process exec '$exec' - or die "\$tool: Can't run '$exec': \$!\\n"; + or die "\$tool: Can't run '$error': \$!\\n"; } __UNIX__ }