Commit a4fa5915 authored by Federico Vaga's avatar Federico Vaga

Merge branch 'release/v4.0.0.beta2'

parents c87ca048 533062b6
GPATH GPATH
GRTAGS GRTAGS
GTAGS GTAGS
Makefile.specific
OBJS = fw-ac.o
OBJS += # add other object files that you need
OUTPUT = fw-ac
TRTL ?= ../../../../ TRTL ?= ../../../../
TRTL_SW = $(TRTL)/software TRTL_FW = $(TRTL)/software/firmware
include $(TRTL_SW)/firmware/Makefile all:
# Redirect all rules to MockTurtle
%:
$(MAKE) -C $(TRTL_FW) M=$(shell /bin/pwd) $@
OBJS = fw-ac.o
OBJS += # add other object files that you need
OUTPUT = fw-ac
OBJS = fw-dg.o
OBJS += # add other object files that you need
OUTPUT = fw-dg
TRTL ?= ../../../../ TRTL ?= ../../../../
TRTL_SW = $(TRTL)/software TRTL_FW = $(TRTL)/software/firmware
include $(TRTL_SW)/firmware/Makefile all:
# Redirect all rules to MockTurtle
%:
$(MAKE) -C $(TRTL_FW) M=$(shell /bin/pwd) $@
OBJS = fw-dg.o
OBJS += # add other object files that you need
OUTPUT = fw-dg
include ../../../project.mk
OBJS = fw-spec.o
OBJS += common/fw-spec-smem-code.o
OBJDIR += common
OUTPUT = fw-spec-1
TRTL ?= ../../../../../ TRTL ?= ../../../../../
TRTL_SW = $(TRTL)/software TRTL_FW = $(TRTL)/software/firmware
EXTRA_CFLAGS += -I../../include
EXTRA_CFLAGS += -I../common
EXTRA_CFLAGS += -DFPGA_APPLICATION_ID=APPLICATION_ID
EXTRA_CFLAGS += -DRT_APPLICATION_ID=$(RT_APPLICATION_ID_CPU1)
vpath %.c ../ all:
include $(TRTL_SW)/firmware/Makefile # Redirect all rules to MockTurtle
%:
$(MAKE) -C $(TRTL_FW) M=$(shell /bin/pwd) $@
include $(src)/../../../project.mk
OBJS = fw-spec.o
OBJS += common/fw-spec-smem-code.o
OBJDIR += common
OUTPUT = fw-spec-1
EXTRA_CFLAGS += -I$(src)/../../include
EXTRA_CFLAGS += -I$(src)/../common
EXTRA_CFLAGS += -DFPGA_APPLICATION_ID=APPLICATION_ID
EXTRA_CFLAGS += -DRT_APPLICATION_ID=$(RT_APPLICATION_ID_CPU1)
vpath %.c $(src)../
include ../../../project.mk
OBJS = fw-spec.o
OBJS += common/fw-spec-smem-code.o
OBJDIR += common
OUTPUT = fw-spec-2
TRTL ?= ../../../../../ TRTL ?= ../../../../../
TRTL_SW = $(TRTL)/software TRTL_FW = $(TRTL)/software/firmware
EXTRA_CFLAGS += -I../../include
EXTRA_CFLAGS += -I../common
EXTRA_CFLAGS += -DFPGA_APPLICATION_ID=$(APPLICATION_ID)
EXTRA_CFLAGS += -DRT_APPLICATION_ID=$(RT_APPLICATION_ID_CPU2)
EXTRA_CFLAGS += -DLIBRT_DEBUG_VERBOSE -DLIBRT_DEBUG
vpath %.c ../ all:
include $(TRTL_SW)/firmware/Makefile # Redirect all rules to MockTurtle
%:
$(MAKE) -C $(TRTL_FW) M=$(shell /bin/pwd) $@
include $(src)../../../project.mk
OBJS = fw-spec.o
OBJS += common/fw-spec-smem-code.o
OBJDIR += common
OUTPUT = fw-spec-2
EXTRA_CFLAGS += -I$(src)/../../include
EXTRA_CFLAGS += -I$(src)/../common
EXTRA_CFLAGS += -DFPGA_APPLICATION_ID=$(APPLICATION_ID)
EXTRA_CFLAGS += -DRT_APPLICATION_ID=$(RT_APPLICATION_ID_CPU2)
EXTRA_CFLAGS += -DLIBRT_DEBUG_VERBOSE -DLIBRT_DEBUG
vpath %.c $(src)/../
include ../../../project.mk
OBJS = fw-svec.o
OBJS += common/fw-svec-smem-code.o
OBJDIR += common
OUTPUT = fw-svec-1
TRTL ?= ../../../../../ TRTL ?= ../../../../../
TRTL_SW = $(TRTL)/software TRTL_FW = $(TRTL)/software/firmware
EXTRA_CFLAGS += -I../../include
EXTRA_CFLAGS += -I../common
EXTRA_CFLAGS += -DFPGA_APPLICATION_ID=APPLICATION_ID
EXTRA_CFLAGS += -DRT_APPLICATION_ID=$(RT_APPLICATION_ID_CPU1)
vpath %.c ../ all:
include $(TRTL_SW)/firmware/Makefile # Redirect all rules to MockTurtle
%:
$(MAKE) -C $(TRTL_FW) M=$(shell /bin/pwd) $@
include $(src)/../../../project.mk
OBJS = fw-svec.o
OBJS += common/fw-svec-smem-code.o
OBJDIR += common
OUTPUT = fw-svec-1
EXTRA_CFLAGS += -I$(src)/../../include
EXTRA_CFLAGS += -I$(src)/../common
EXTRA_CFLAGS += -DFPGA_APPLICATION_ID=APPLICATION_ID
EXTRA_CFLAGS += -DRT_APPLICATION_ID=$(RT_APPLICATION_ID_CPU1)
vpath %.c $(src)/../
include ../../../project.mk
OBJS = fw-svec.o
OBJS += common/fw-svec-smem-code.o
OBJDIR += common
OUTPUT = fw-svec-2
TRTL ?= ../../../../../ TRTL ?= ../../../../../
TRTL_SW = $(TRTL)/software TRTL_FW = $(TRTL)/software/firmware
EXTRA_CFLAGS += -I../../include
EXTRA_CFLAGS += -I../common
EXTRA_CFLAGS += -DFPGA_APPLICATION_ID=$(APPLICATION_ID)
EXTRA_CFLAGS += -DRT_APPLICATION_ID=$(RT_APPLICATION_ID_CPU2)
EXTRA_CFLAGS += -DLIBRT_DEBUG_VERBOSE -DLIBRT_DEBUG
vpath %.c ../ all:
include $(TRTL_SW)/firmware/Makefile # Redirect all rules to MockTurtle
%:
$(MAKE) -C $(TRTL_FW) M=$(shell /bin/pwd) $@
include $(src)/../../../project.mk
OBJS = fw-svec.o
OBJS += common/fw-svec-smem-code.o
OBJDIR += common
OUTPUT = fw-svec-2
EXTRA_CFLAGS += -I$(src)/../../include
EXTRA_CFLAGS += -I$(src)/../common
EXTRA_CFLAGS += -DFPGA_APPLICATION_ID=$(APPLICATION_ID)
EXTRA_CFLAGS += -DRT_APPLICATION_ID=$(RT_APPLICATION_ID_CPU2)
EXTRA_CFLAGS += -DLIBRT_DEBUG_VERBOSE -DLIBRT_DEBUG
vpath %.c $(src)/../
OBJS = fw-hello.o
OBJS += # add other object files that you need
OUTPUT = fw-hello
TRTL ?= ../../../../ TRTL ?= ../../../../
TRTL_SW = $(TRTL)/software TRTL_FW = $(TRTL)/software/firmware
include $(TRTL_SW)/firmware/Makefile all:
# Redirect all rules to MockTurtle
%:
$(MAKE) -C $(TRTL_FW) M=$(shell /bin/pwd) $@
OBJS = fw-hello.o
OBJS += # add other object files that you need
OUTPUT = fw-hello
OBJS = fw-hellofrm.o
OBJS += # add other object files that you need
OUTPUT = fw-hellofrm
TRTL ?= ../../../../ TRTL ?= ../../../../
TRTL_SW = $(TRTL)/software TRTL_FW = $(TRTL)/software/firmware
include $(TRTL_SW)/firmware/Makefile all:
# Redirect all rules to MockTurtle
%:
$(MAKE) -C $(TRTL_FW) M=$(shell /bin/pwd) $@
OBJS = fw-hellofrm.o
OBJS += # add other object files that you need
OUTPUT = fw-hellofrm
...@@ -132,7 +132,9 @@ The typical procedure to send (output) messages over is the following. ...@@ -132,7 +132,9 @@ The typical procedure to send (output) messages over is the following.
#. *claim* a mq in order to get exclusive access to it; #. *claim* a mq in order to get exclusive access to it;
#. *map* the claimed mq slot in order to get the buffer where to write; #. *map* the claimed mq slot in order to get the buffer where to write. Keep
in mind that the memory is not initialized, so you probably need to set
correctly all header fields;
#. *write* your message; #. *write* your message;
......
...@@ -43,11 +43,10 @@ memory) or you need much better performances: don't use this framework. ...@@ -43,11 +43,10 @@ memory) or you need much better performances: don't use this framework.
All the Mock Turtle firmware source code can be found in the directory All the Mock Turtle firmware source code can be found in the directory
``/path/to/mockturtle/software/firmware/``. ``/path/to/mockturtle/software/firmware/``.
Mock Turtle has a generic ``Makefile`` that you should include in your Mock Turtle has a generic building system which can be used to produce
``Makefile`` in order to import all the Mock Turtle building rules.:: Mock Turtle firmware applications. What you have to do is to prepare a
file named ``TBuild`` next to your firmware source files. In this file
TRTL ?= /path/to/mcokturtle/ you have to specify what to build, for example::
TRTL_SW = $(TRTL)/software
# Mandatory # Mandatory
OBJS = source1.o OBJS = source1.o
...@@ -56,15 +55,10 @@ Mock Turtle has a generic ``Makefile`` that you should include in your ...@@ -56,15 +55,10 @@ Mock Turtle has a generic ``Makefile`` that you should include in your
OUTPUT = firmware-name OUTPUT = firmware-name
# Optional (prefer default when possible) # Optional (prefer default when possible)
CFLAGS_OPT := -O1 EXTRA_CFLAGS :=
CFLAGS_DBG := -ggdb
EXTRA_CFLGAS :=
MOCKTURTLE_LDSCRIPT := myfirmware.ld MOCKTURTLE_LDSCRIPT := myfirmware.ld
# INCLUDE GENERIC Makefile Here the list of supported TBuild variables
include $(TRTL_SW)/firmware/Makefile
Here the list of supported Makefile environment variables
OBJS OBJS
(Mandatory) List of object files to generate from sources with (Mandatory) List of object files to generate from sources with
...@@ -74,10 +68,33 @@ OBJS ...@@ -74,10 +68,33 @@ OBJS
OUTPUT OUTPUT
(Mandatory) Final binary name (the firmware). (Mandatory) Final binary name (the firmware).
EXTRA_CFLAGS
(Optional) Additional compiler options.
MOCKTURTLE_LDSCRIPT MOCKTURTLE_LDSCRIPT
(Optional ) Local path to the linker script. (Optional) Local path to the linker script.
The default is the standard Mock Turtle linker script. The default is the standard Mock Turtle linker script.
You can build such firmware application by calling ``make`` from the
application directory (where the ``TBuild`` file is) like this::
make -C <path-to-mockturtle-project>/software/firmware M=$PWD
Or alternatively, you can copy the following lines in a Makefile::
TRTL_FW = $(TRTL)/software/firmware
all:
# Redirect all rules to MockTurtle
%:
$(MAKE) -C $(TRTL_FW) M=$(shell /bin/pwd) $@
Then, you will compile your application with the following command
from the application directory (where the ``TBuild`` file is)::
make TRTL=<path-to-mockturtle-project>
Memory resources on Mock Turtle are very limited and the full framework Memory resources on Mock Turtle are very limited and the full framework
may take more space than needed. For this reason Mock Turtle has may take more space than needed. For this reason Mock Turtle has
*Kconfig* support which allows you to interactivly enable/disable both *Kconfig* support which allows you to interactivly enable/disable both
......
...@@ -207,17 +207,15 @@ The Mock Turtle driver exports a *char device* for each Mock Turtle HMQ. ...@@ -207,17 +207,15 @@ The Mock Turtle driver exports a *char device* for each Mock Turtle HMQ.
All HMQ instances will appear as child of a :ref:`sw:drv:core`; in All HMQ instances will appear as child of a :ref:`sw:drv:core`; in
*/dev/mockturtle/* you will have devices named ``trtl-%04x-%02d-%02d`` */dev/mockturtle/* you will have devices named ``trtl-%04x-%02d-%02d``
(trtl-<device-id>-<cpu-index>-<hmq-index>). The main purpose of this (trtl-<device-id>-<cpu-index>-<hmq-index>). The main purpose of this
interface is to exchange messages and configure filters. These devices interface is to exchange messages. These devices are bidirectional,
are bidirectional, so you can: ``write(2)`` to send messaged; so you can: ``write(2)`` to send messaged; ``read(2)`` to receive messages;
``read(2)`` to receive messages; ``poll(2)`` or ``select(2)`` to wait ``poll(2)`` or ``select(2)`` to wait for the interface to become accessible.
for the interface to become accessible.
This *char device* provides a set of ``ioctl(2)`` commands: This *char device* provides a set of ``ioctl(2)`` commands:
.. doxygendefine:: TRTL_IOCTL_MSG_FILTER_ADD .. doxygendefine:: TRTL_IOCTL_HMQ_SYNC_SET
.. doxygendefine:: TRTL_IOCTL_MSG_FILTER_CLEAN
.. doxygendefine:: TRTL_IOCTL_MSG_SYNC_ABORT
You can find the HMQ *sysfs* attributes at:: You can find the HMQ *sysfs* attributes at::
......
...@@ -153,21 +153,6 @@ side so that the complete flush happens synchronously. ...@@ -153,21 +153,6 @@ side so that the complete flush happens synchronously.
.. doxygenfunction:: trtl_hmq_flush .. doxygenfunction:: trtl_hmq_flush
The Mock Turtle driver has a basic message filtering mechanism. Each
user can add a set of filters on any host message queue. Mock Turtle
will deliver to the user only those messages which pass the filter.
Rembember that this is a user filter, this means that on the same
host message queue, different users can have different filters.
.. doxygenfunction:: trtl_hmq_filter_add
.. doxygenfunction:: trtl_hmq_filter_clean
.. doxygenenum:: trtl_msg_filter_operation_type
.. doxygenstruct:: trtl_msg_filter
:members:
Then, there are the functions to exchange messages with firmware Then, there are the functions to exchange messages with firmware
running on Mock Turtle. This API offers a minimum set of function running on Mock Turtle. This API offers a minimum set of function
to allow users to send/receive synchronous/asynchronous messages. to allow users to send/receive synchronous/asynchronous messages.
......
-include Makefile.specific
# include parent_common.mk for buildsystem's defines # include parent_common.mk for buildsystem's defines
# use absolute path for REPO_PARENT # use absolute path for REPO_PARENT
CURDIR:=$(shell /bin/pwd) CURDIR:=$(shell /bin/pwd)
......
-include Makefile.specific src := $(M)/
-include $(CURDIR)/.config
-include $(src)/Makefile.specific
-include $(src)/.config
include $(src)/TBuild
# Validation
ifndef OUTPUT
$(error Missing variable OUTPUT)
else
build_output=$(src)/$(OUTPUT)
endif
ifndef OBJS
$(error Missing variable OBJS)
endif
# and don't touch the rest unless you know what you're doing. # and don't touch the rest unless you know what you're doing.
INSTALL_PREFIX ?= . INSTALL_PREFIX ?= .
...@@ -7,11 +22,12 @@ PATH_COMMON_RT ?= . ...@@ -7,11 +22,12 @@ PATH_COMMON_RT ?= .
PATH_COMMON_H ?= ../include PATH_COMMON_H ?= ../include
TRTL ?= ../../ TRTL ?= ../../
TRTL_SW ?= $(TRTL)/software TRTL_SW ?= $(TRTL)/software
TRTL_FW ?= $(TRTL_SW)/firmware
TRTL_HDL ?= $(TRTL)/hdl/rtl TRTL_HDL ?= $(TRTL)/hdl/rtl
RT_GIT_VERSION = 0x$(shell git rev-parse --short=8 HEAD || echo "0") # empty if git is not there RT_GIT_VERSION = 0x$(shell git rev-parse --short=8 HEAD || echo "0") # empty if git is not there
# header file generated from the .config # header file generated from the .config
AUTOCONF = $(CURDIR)/$(BUILDDIR)/include/generated/autoconf.h AUTOCONF = $(src)/$(BUILDDIR)/include/generated/autoconf.h
CROSS_COMPILE_TARGET ?= riscv32-elf- CROSS_COMPILE_TARGET ?= riscv32-elf-
# FIXME the mult/div is broken, for the time being remove it completely # FIXME the mult/div is broken, for the time being remove it completely
...@@ -21,10 +37,12 @@ CFLAGS += -mabi=ilp32 -march=rv32im -ffunction-sections -fdata-sections ...@@ -21,10 +37,12 @@ CFLAGS += -mabi=ilp32 -march=rv32im -ffunction-sections -fdata-sections
LDFLAGS += -lgcc -lc -Wl,--gc-sections LDFLAGS += -lgcc -lc -Wl,--gc-sections
# provide search patch for sources # provide search patch for sources
vpath %.c $(TRTL)/software/firmware vpath %.c $(TRTL_FW)
vpath %.S $(TRTL)/software/firmware vpath %.S $(TRTL_FW)
vpath %.c $(src)
vpath %.S $(src)
BUILDDIR := build BUILDDIR := $(src)/build
# auto dependency generation from # auto dependency generation from
# http://make.mad-scientist.net/papers/advanced-auto-dependency-generation/ # http://make.mad-scientist.net/papers/advanced-auto-dependency-generation/
...@@ -42,10 +60,10 @@ STRIP = $(CROSS_COMPILE_TARGET)strip ...@@ -42,10 +60,10 @@ STRIP = $(CROSS_COMPILE_TARGET)strip
CFLAGS += -Wall -D__TRTL_FIRMWARE__ -DARCH=urv CFLAGS += -Wall -D__TRTL_FIRMWARE__ -DARCH=urv
CFLAGS += -I. CFLAGS += -I.
CFLAGS += -I$(BUILDDIR)/include CFLAGS += -I$(BUILDDIR)/include
CFLAGS += -I$(TRTL)/software/firmware CFLAGS += -I$(TRTL_FW)
CFLAGS += -I$(TRTL)/software/firmware/lib CFLAGS += -I$(TRTL_FW)/lib
CFLAGS += -I$(TRTL)/software/firmware/framework CFLAGS += -I$(TRTL_FW)/framework
CFLAGS += -I$(TRTL)/software/include CFLAGS += -I$(TRTL_SW)/include
CFLAGS += -DGIT_VERSION=$(RT_GIT_VERSION) CFLAGS += -DGIT_VERSION=$(RT_GIT_VERSION)
# used for firmware by trtl-project-creator # used for firmware by trtl-project-creator
...@@ -76,11 +94,11 @@ OBJS_BUILD = $(addprefix $(BUILDDIR)/, $(OBJS)) ...@@ -76,11 +94,11 @@ OBJS_BUILD = $(addprefix $(BUILDDIR)/, $(OBJS))
OBJDIR_BUILD = $(addprefix $(BUILDDIR)/, $(OBJDIR)) OBJDIR_BUILD = $(addprefix $(BUILDDIR)/, $(OBJDIR))
OBJDIR_BUILD += $(BUILDDIR) OBJDIR_BUILD += $(BUILDDIR)
MOCKTURTLE_LDSCRIPT ?= $(TRTL)/software/firmware/urv/mockturtle.ld MOCKTURTLE_LDSCRIPT ?= $(TRTL_FW)/urv/mockturtle.ld
.PHONY: all clean cleanall check-def .PHONY: all clean cleanall
all: $(OUTPUT).bin all: $(build_output).bin
WBGEN_FILES = mt_cpu_csr.wb mt_cpu_lr.wb WBGEN_FILES = mt_cpu_csr.wb mt_cpu_lr.wb
WBGEN_HEADERS = mockturtle_cpu_csr.h mockturtle_cpu_lr.h WBGEN_HEADERS = mockturtle_cpu_csr.h mockturtle_cpu_lr.h
...@@ -93,16 +111,9 @@ $(TRTL_SW)/include/hw/mockturtle_cpu_csr.h: $(TRTL_HDL)/cpu/mt_cpu_csr.wb ...@@ -93,16 +111,9 @@ $(TRTL_SW)/include/hw/mockturtle_cpu_csr.h: $(TRTL_HDL)/cpu/mt_cpu_csr.wb
$(TRTL_SW)/include/hw/mockturtle_cpu_lr.h: $(TRTL_HDL)/cpu/mt_cpu_lr.wb $(TRTL_SW)/include/hw/mockturtle_cpu_lr.h: $(TRTL_HDL)/cpu/mt_cpu_lr.wb
# target to let wbgen2 to generate headers # target to let wbgen2 to generate headers
$(addprefix $(TRTL_SW)/include/hw/,$(WBGEN_HEADERS)): | check-def $(addprefix $(TRTL_SW)/include/hw/,$(WBGEN_HEADERS)):
make -C $(TRTL_SW) headers make -C $(TRTL_SW) headers
# check needed env variables
check-def:
ifndef OUTPUT
@echo "OUTPUT variable is mandatory"
@exit 1
endif
# create dirs for object files # create dirs for object files
$(OBJDIR_BUILD): $(OBJDIR_BUILD):
mkdir -p $@ mkdir -p $@
...@@ -112,12 +123,13 @@ $(OBJDIR_BUILD): ...@@ -112,12 +123,13 @@ $(OBJDIR_BUILD):
$(OBJS_BUILD): | $(AUTOCONF) $(OBJS_BUILD): | $(AUTOCONF)
$(OBJS_BUILD): | $(OBJDIR_BUILD) $(OBJS_BUILD): | $(OBJDIR_BUILD)
$(OUTPUT).elf: $(addprefix $(TRTL_SW)/include/hw/,$(WBGEN_HEADERS)) $(MOCKTURTLE_LDSCRIPT) $(OBJS_BUILD) | check-def $(build_output).elf: $(addprefix $(TRTL_SW)/include/hw/,$(WBGEN_HEADERS)) $(MOCKTURTLE_LDSCRIPT) $(OBJS_BUILD)
${CC} $(CFLAGS) $(LDFLAGS) -o $(OUTPUT).elf -nostartfiles $(OBJS_BUILD) -T $(MOCKTURTLE_LDSCRIPT) $(warning $(OBJS_BUILD))
${CC} $(CFLAGS) $(LDFLAGS) -o $(build_output).elf -nostartfiles $(OBJS_BUILD) -T $(MOCKTURTLE_LDSCRIPT)
$(OUTPUT).bin: $(OUTPUT).elf | check-def $(build_output).bin: $(build_output).elf
${OBJCOPY} --remove-section .smem -O binary $(OUTPUT).elf $(OUTPUT).bin ${OBJCOPY} --remove-section .smem -O binary $(build_output).elf $(build_output).bin
$(SIZE) $(OUTPUT).elf $(SIZE) $(build_output).elf
$(BUILDDIR)/urv/emulate.o: urv/emulate.c $(BUILDDIR)/urv/emulate.o: urv/emulate.c
${CC} $(DEPFLAGS) $(CFLAGS) -march=rv32i -c $< -o $@ ${CC} $(DEPFLAGS) $(CFLAGS) -march=rv32i -c $< -o $@
...@@ -126,13 +138,15 @@ $(BUILDDIR)/urv/emulate.o: urv/emulate.c ...@@ -126,13 +138,15 @@ $(BUILDDIR)/urv/emulate.o: urv/emulate.c
$(BUILDDIR)/%.o: %.c $(BUILDDIR)/%.o: %.c
${CC} $(DEPFLAGS) $(CFLAGS) $(LDFLAGS) -c $< -o $@ ${CC} $(DEPFLAGS) $(CFLAGS) $(LDFLAGS) -c $< -o $@
$(POSTCOMPILE) $(POSTCOMPILE)
$(warning $< ---- $@)
@echo ""
$(BUILDDIR)/%.o: %.S $(BUILDDIR)/%.o: %.S
${CC} $(DEPFLAGS) $(CFLAGS) $(LDFLAGS) -c $< -o $@ ${CC} $(DEPFLAGS) $(CFLAGS) $(LDFLAGS) -c $< -o $@
$(POSTCOMPILE) $(POSTCOMPILE)
clean: clean:
rm -f $(OUTPUT).bin $(OUTPUT).elf rm -f $(build_output).bin $(build_output).elf
rm -rf $(BUILDDIR) rm -rf $(BUILDDIR)
clean-dot-config: clean-dot-config:
...@@ -141,7 +155,7 @@ clean-dot-config: ...@@ -141,7 +155,7 @@ clean-dot-config:
cleanall: clean clean-dot-config cleanall: clean clean-dot-config
install: install:
@cp $(OUTPUT).bin $(INSTALL_PREFIX) @cp $(build_output).bin $(INSTALL_PREFIX)
# inlude *.d files from the build directory # inlude *.d files from the build directory
include $(wildcard $(patsubst %,%/.d/*.d,$(basename $(OBJDIR_BUILD)))) include $(wildcard $(patsubst %,%/.d/*.d,$(basename $(OBJDIR_BUILD))))
...@@ -150,20 +164,20 @@ include $(wildcard $(patsubst %,%/.d/*.d,$(basename $(OBJDIR_BUILD)))) ...@@ -150,20 +164,20 @@ include $(wildcard $(patsubst %,%/.d/*.d,$(basename $(OBJDIR_BUILD))))
# following targets from Makefile.kconfig # following targets from Makefile.kconfig
# this one is used to generate autoconf.h file # this one is used to generate autoconf.h file
$(AUTOCONF) silentoldconfig: .config | $(BUILDDIR) $(AUTOCONF) silentoldconfig: .config | $(BUILDDIR)
export KCONFIG_CONFIG=$(CURDIR)/.config; \ export KCONFIG_CONFIG=$(src)/.config; \
$(MAKE) quiet=quiet_ KBUILD_KCONFIG=$(CURDIR)/Kconfig projtree=$(CURDIR)/$(BUILDDIR) -C $(TRTL)/software/firmware -f Makefile.kconfig silentoldconfig $(MAKE) quiet=quiet_ KBUILD_KCONFIG=$(src)/Kconfig projtree=$(BUILDDIR) -C $(TRTL_FW) -f Makefile.kconfig silentoldconfig
scripts_basic config: scripts_basic config:
$(MAKE) quiet=quiet_ KBUILD_KCONFIG=$(CURDIR)/Kconfig projtree=$(CURDIR) -C $(TRTL)/software/firmware -f Makefile.kconfig $@ $(MAKE) quiet=quiet_ KBUILD_KCONFIG=$(src)/Kconfig projtree=$(src) -C $(TRTL_FW) -f Makefile.kconfig $@
%config: %config:
$(MAKE) quiet=quiet_ KBUILD_KCONFIG=$(CURDIR)/Kconfig projtree=$(CURDIR) -C $(TRTL)/software/firmware -f Makefile.kconfig $@ $(MAKE) quiet=quiet_ KBUILD_KCONFIG=$(src)/Kconfig projtree=$(src) -C $(TRTL_FW) -f Makefile.kconfig $@
defconfig: defconfig:
$(MAKE) quiet=quiet_ KBUILD_KCONFIG=$(CURDIR)/Kconfig projtree=$(CURDIR) -C $(TRTL)/software/firmware -f Makefile.kconfig mt_defconfig $(MAKE) quiet=quiet_ KBUILD_KCONFIG=$(src)/Kconfig projtree=$(src) -C $(TRTL_FW) -f Makefile.kconfig mt_defconfig
.config: ; .config: ;
# Explicit rule for .config # Explicit rule for .config
# needed since -include XXX triggers build for XXX # needed since -include XXX triggers build for XXX
$(CURDIR)/.config: ; $(src)/.config: ;
...@@ -303,7 +303,6 @@ static inline int rt_action_run(enum trtl_mq_type type, ...@@ -303,7 +303,6 @@ static inline int rt_action_run(enum trtl_mq_type type,
msg_out.header->msg_id = 0; msg_out.header->msg_id = 0;
msg_out.header->len = 0; msg_out.header->len = 0;
msg_out.header->sync_id = msg->header->sync_id; msg_out.header->sync_id = msg->header->sync_id;
msg_out.header->seq = app.seq++;
err = action(msg, &msg_out); err = action(msg, &msg_out);
if (err) if (err)
...@@ -408,7 +407,6 @@ int trtl_fw_mq_send_uint32(enum trtl_mq_type type, ...@@ -408,7 +407,6 @@ int trtl_fw_mq_send_uint32(enum trtl_mq_type type,
msg.header->flags = 0; msg.header->flags = 0;
msg.header->msg_id = msg_id; msg.header->msg_id = msg_id;
msg.header->len = n; msg.header->len = n;
msg.header->seq = app.seq++;
va_start(ap, n); va_start(ap, n);
for (i = 0; i < msg.header->len;++i) for (i = 0; i < msg.header->len;++i)
...@@ -455,7 +453,6 @@ int trtl_fw_mq_send_buf(enum trtl_mq_type type, ...@@ -455,7 +453,6 @@ int trtl_fw_mq_send_buf(enum trtl_mq_type type,
msg.header->flags = 0; msg.header->flags = 0;
msg.header->msg_id = msg_id; msg.header->msg_id = msg_id;
msg.header->len = n / 4; msg.header->len = n / 4;
msg.header->seq = app.seq++;
memcpy(msg.payload, data, n); memcpy(msg.payload, data, n);
mq_send(type, idx_mq); mq_send(type, idx_mq);
...@@ -603,7 +600,6 @@ int trtl_fw_init(void) ...@@ -603,7 +600,6 @@ int trtl_fw_init(void)
{ {
int err; int err;
app.seq = 0;
app.cfgrom = trtl_config_rom_get(); app.cfgrom = trtl_config_rom_get();
err = trtl_fw_init_action(&app); err = trtl_fw_init_action(&app);
......
...@@ -88,7 +88,6 @@ struct trtl_fw_application { ...@@ -88,7 +88,6 @@ struct trtl_fw_application {
trtl_fw_action_t **actions; /**< list of custum actions */ trtl_fw_action_t **actions; /**< list of custum actions */
unsigned int n_actions; /**< number of custum actions */ unsigned int n_actions; /**< number of custum actions */
unsigned int seq; /** sequence number reference */
const struct trtl_config_rom *cfgrom; /**< configuration ROM */ const struct trtl_config_rom *cfgrom; /**< configuration ROM */
/* Operations */ /* Operations */
......
...@@ -400,6 +400,8 @@ static inline uint32_t mq_readl(enum trtl_mq_type type, uint32_t reg) ...@@ -400,6 +400,8 @@ static inline uint32_t mq_readl(enum trtl_mq_type type, uint32_t reg)
* @param[in] type MQ type to use * @param[in] type MQ type to use
* @param[in] slot slot number * @param[in] slot slot number
* @return pointer to the input buffer * @return pointer to the input buffer
*
* Note: uninitialized memory
*/ */
static inline void *mq_map_out_buffer(enum trtl_mq_type type, int slot) static inline void *mq_map_out_buffer(enum trtl_mq_type type, int slot)
{ {
...@@ -426,6 +428,8 @@ static inline void *mq_map_in_buffer(enum trtl_mq_type type, int slot) ...@@ -426,6 +428,8 @@ static inline void *mq_map_in_buffer(enum trtl_mq_type type, int slot)
* @param[in] type MQ type to use * @param[in] type MQ type to use
* @param[in] slot slot number * @param[in] slot slot number
* @return pointer to the output header * @return pointer to the output header
*
* Note: uninitialized memory
*/ */
static inline void *mq_map_out_header(enum trtl_mq_type type, int slot) static inline void *mq_map_out_header(enum trtl_mq_type type, int slot)
{ {
......
HEADERS := mockturtle_cpu_csr.h HEADERS := mockturtle_cpu_csr.h
HEADERS += mockturtle_cpu_lr.h HEADERS += mockturtle_cpu_lr.h
TRTL = ../../.. TRTL ?= ../../..
TRTL_HDL = $(TRTL)/hdl/rtl/ TRTL_HDL = $(TRTL)/hdl/rtl/
WBGEN2 ?= wbgen2 WBGEN2 ?= wbgen2
......
...@@ -6,6 +6,8 @@ ...@@ -6,6 +6,8 @@
/* Host addresses. */ /* Host addresses. */
#define TRTL_ADDR_OFFSET_HMQ 0x00000000 #define TRTL_ADDR_OFFSET_HMQ 0x00000000
#define TRTL_ADDR_OFFSET_CSR 0x0000C000 #define TRTL_ADDR_OFFSET_CSR 0x0000C000
/* FIXME update memorymap to have DBG PAGE_ALIGNED */
#define TRTL_ADDR_OFFSET_DBG TRTL_ADDR_OFFSET_CSR
#define TRTL_ADDR_OFFSET_CONFIG_ROM 0x0000E000 #define TRTL_ADDR_OFFSET_CONFIG_ROM 0x0000E000
#define TRTL_ADDR_OFFSET_SHM 0x00010000 #define TRTL_ADDR_OFFSET_SHM 0x00010000
......
...@@ -179,35 +179,6 @@ enum trtl_smem_modifier { ...@@ -179,35 +179,6 @@ enum trtl_smem_modifier {
TRTL_SMEM_TYPE_TST_SET, /**< atomic test and set */ TRTL_SMEM_TYPE_TST_SET, /**< atomic test and set */
}; };
/**
* @enum trtl_msg_filter_operation_type
* List of available filter's operations
*/
enum trtl_msg_filter_operation_type {
TRTL_MSG_FILTER_AND,
TRTL_MSG_FILTER_OR,
TRTL_MSG_FILTER_EQ,
TRTL_MSG_FILTER_NEQ,
__TRTL_MSG_FILTER_MAX,
};
#define TRTL_MSG_FILTER_FLAG_HEADER (0)
#define TRTL_MSG_FILTER_FLAG_PAYLOAD (1 << 0)
/**
* It describe a filter to apply to messages
*/
struct trtl_msg_filter {
unsigned long flags; /**< options for the filter */
uint32_t operation; /**< kind of operation to perform */
uint32_t word_offset; /**< offset of the word to check */
uint32_t mask; /**< mask to apply before the operation */
uint32_t value; /**< second operand of the operation */
};
/** /**
* Descriptor of the IO operation on Shared Memory * Descriptor of the IO operation on Shared Memory
*/ */
...@@ -225,8 +196,8 @@ struct trtl_smem_io { ...@@ -225,8 +196,8 @@ struct trtl_smem_io {
*/ */
enum trtl_ioctl_commands { enum trtl_ioctl_commands {
TRTL_SMEM_IO, /**< access to shared memory */ TRTL_SMEM_IO, /**< access to shared memory */
TRTL_MSG_FILTER_ADD, /**< add a message filter */ TRTL_MSG_SYNC_ABORT, /**< abort sync message*/
TRTL_MSG_FILTER_CLEAN, /**< remove all filters */ TRTL_HMQ_SYNC_SET, /**< Mark HMQ user context as synchronous */
}; };
...@@ -235,19 +206,19 @@ enum trtl_ioctl_commands { ...@@ -235,19 +206,19 @@ enum trtl_ioctl_commands {
struct trtl_smem_io) struct trtl_smem_io)
/** /**
* The IOCTL command to add a filter to an HMQ * The IOCTL command to set HMQ user context to SYNC
*/ */
#define TRTL_IOCTL_MSG_FILTER_ADD _IOW(TRTL_IOCTL_MAGIC, \ #define TRTL_IOCTL_HMQ_SYNC_SET _IOW(TRTL_IOCTL_MAGIC, \
TRTL_MSG_FILTER_ADD, \ TRTL_HMQ_SYNC_SET, \
struct trtl_msg_filter) unsigned int)
/** /**
* The IOCTL command to remove all filters from an HMQ * The IOCTL command to abort a sync message. Usefull when the answer is
* not coming
*/ */
#define TRTL_IOCTL_MSG_FILTER_CLEAN _IOW(TRTL_IOCTL_MAGIC, \ #define TRTL_IOCTL_MSG_SYNC_ABORT _IOW(TRTL_IOCTL_MAGIC, \
TRTL_MSG_FILTER_CLEAN, \ TRTL_MSG_SYNC_ABORT, \
struct trtl_msg_filter) unsigned int)
/** /**
* Messages descriptor for host * Messages descriptor for host
......
...@@ -26,6 +26,8 @@ mockturtle-y += mockturtle-cpu.o ...@@ -26,6 +26,8 @@ mockturtle-y += mockturtle-cpu.o
mockturtle-y += mockturtle-hmq.o mockturtle-y += mockturtle-hmq.o
mockturtle-y += mockturtle-tty.o mockturtle-y += mockturtle-tty.o
mockturtle-y += mockturtle-dbg.o mockturtle-y += mockturtle-dbg.o
mockturtle-y += mockturtle-dbg.o
mockturtle-y += mockturtle-compat.o
all modules: all modules:
......
// SPDX-License-Identifier: GPL-2.0-or-later
/*
* Copyright (C) 2014-2019 CERN (www.cern.ch)
* Author: Federico Vaga <federico.vaga@cern.ch>
*/
#include <linux/version.h>
#include <linux/mm.h>
#include "mockturtle-compat.h"
#if KERNEL_VERSION(3, 9, 0) > LINUX_VERSION_CODE
/* Copied from v3.10 */
int vm_iomap_memory(struct vm_area_struct *vma, phys_addr_t start,
unsigned long len)
{
unsigned long vm_len, pfn, pages;
/* Check that the physical memory area passed in looks valid */
if (start + len < start)
return -EINVAL;
/*
* You *really* shouldn't map things that aren't page-aligned,
* but we've historically allowed it because IO memory might
* just have smaller alignment.
*/
len += start & ~PAGE_MASK;
pfn = start >> PAGE_SHIFT;
pages = (len + ~PAGE_MASK) >> PAGE_SHIFT;
if (pfn + pages < pfn)
return -EINVAL;
/* We start the mapping 'vm_pgoff' pages into the area */
if (vma->vm_pgoff > pages)
return -EINVAL;
pfn += vma->vm_pgoff;
pages -= vma->vm_pgoff;
/* Can we fit all of the mapping? */
vm_len = vma->vm_end - vma->vm_start;
if (vm_len >> PAGE_SHIFT > pages)
return -EINVAL;
/* Ok, let it rip */
return io_remap_pfn_range(vma, vma->vm_start, pfn, vm_len, vma->vm_page_prot);
}
void __iomem *devm_ioremap_resource(struct device *dev, struct resource *res)
{
return devm_request_and_ioremap(dev, res);
}
#endif
// SPDX-License-Identifier: GPL-2.0-or-later
/*
* Copyright (C) 2014-2016 CERN (www.cern.ch)
* Author: Federico Vaga <federico.vaga@cern.ch>
*/
#ifndef __TRTL_COMPAT_H__
#define __TRTL_COMPAT_H__
#include <linux/version.h>
#include <linux/device.h>
#include <linux/ioport.h>
#if KERNEL_VERSION(3, 9, 0) > LINUX_VERSION_CODE
int vm_iomap_memory(struct vm_area_struct *vma, phys_addr_t start,
unsigned long len);
void __iomem *devm_ioremap_resource(struct device *dev, struct resource *res);
#endif
#endif
...@@ -7,6 +7,7 @@ ...@@ -7,6 +7,7 @@
#include <linux/kernel.h> #include <linux/kernel.h>
#include <linux/module.h> #include <linux/module.h>
#include <linux/device.h>
#include <linux/moduleparam.h> #include <linux/moduleparam.h>
#include <linux/idr.h> #include <linux/idr.h>
#include <linux/init.h> #include <linux/init.h>
...@@ -29,6 +30,7 @@ ...@@ -29,6 +30,7 @@
#include <hw/mockturtle_queue.h> #include <hw/mockturtle_queue.h>
#include "mockturtle-drv.h" #include "mockturtle-drv.h"
#include "mockturtle-compat.h"
static DEFINE_IDA(trtl_ida); static DEFINE_IDA(trtl_ida);
...@@ -497,7 +499,7 @@ static unsigned int trtl_max_irq_loop(struct trtl_dev *trtl) ...@@ -497,7 +499,7 @@ static unsigned int trtl_max_irq_loop(struct trtl_dev *trtl)
int i, k; int i, k;
for (i = 0; i < trtl->cfgrom.n_cpu; ++i) { for (i = 0; i < trtl->cfgrom.n_cpu; ++i) {
for (k = 0; k < trtl->cfgrom.n_cpu; ++k) { for (k = 0; k < trtl->cfgrom.n_hmq[i]; ++k) {
size = TRTL_CONFIG_ROM_MQ_SIZE_ENTRIES(trtl->cfgrom.hmq[i][k].sizes); size = TRTL_CONFIG_ROM_MQ_SIZE_ENTRIES(trtl->cfgrom.hmq[i][k].sizes);
if (size > max) if (size > max)
max = size; max = size;
...@@ -529,7 +531,7 @@ int trtl_probe(struct platform_device *pdev) ...@@ -529,7 +531,7 @@ int trtl_probe(struct platform_device *pdev)
platform_set_drvdata(pdev, trtl); platform_set_drvdata(pdev, trtl);
r = platform_get_resource(pdev, IORESOURCE_MEM, TRTL_MEM_BASE); r = platform_get_resource(pdev, IORESOURCE_MEM, TRTL_MEM_BASE);
trtl->base_core = devm_request_and_ioremap(&pdev->dev, r); trtl->base_core = devm_ioremap_resource(&pdev->dev, r);
if (!trtl->base_core) if (!trtl->base_core)
return -EADDRNOTAVAIL; return -EADDRNOTAVAIL;
trtl->base_csr = trtl->base_core + TRTL_ADDR_OFFSET_CSR; trtl->base_csr = trtl->base_core + TRTL_ADDR_OFFSET_CSR;
......
...@@ -8,9 +8,11 @@ ...@@ -8,9 +8,11 @@
#include <linux/debugfs.h> #include <linux/debugfs.h>
#include <linux/device.h> #include <linux/device.h>
#include <linux/seq_file.h> #include <linux/seq_file.h>
#include <linux/mm.h>
#include <hw/mockturtle_cpu_csr.h> #include <hw/mockturtle_cpu_csr.h>
#include "mockturtle-drv.h" #include "mockturtle-drv.h"
#include "mockturtle-compat.h"
static int trtl_dbg_info_seq_read(struct seq_file *s, void *data) static int trtl_dbg_info_seq_read(struct seq_file *s, void *data)
{ {
...@@ -54,12 +56,16 @@ static int trtl_dbg_info_seq_read(struct seq_file *s, void *data) ...@@ -54,12 +56,16 @@ static int trtl_dbg_info_seq_read(struct seq_file *s, void *data)
hmq->index); hmq->index);
seq_printf(s, " name: %s\n", seq_printf(s, " name: %s\n",
dev_name(&hmq->dev)); dev_name(&hmq->dev));
seq_printf(s, " buf-in-max: %d\n",
hmq->buf_in.entries);
list_for_each_entry(usr, &hmq->list_usr, list) { list_for_each_entry(usr, &hmq->list_usr, list) {
seq_printf(s, " buf-in-r: %d (user %p)\n", seq_printf(s, " buf-in-r: %d (user %p)\n",
usr->idx_r, usr); usr->idx_r, usr);
} }
seq_printf(s, " buf-in-w: %d\n", seq_printf(s, " buf-in-w: %d\n",
hmq->buf_in.idx_w); hmq->buf_in.idx_w);
seq_printf(s, " buf-out-max: %d\n",
hmq->buf_out.entries);
seq_printf(s, " buf-out-r: %d\n", seq_printf(s, " buf-out-r: %d\n",
hmq->buf_out.idx_r); hmq->buf_out.idx_r);
seq_printf(s, " buf-out-w: %d\n", seq_printf(s, " buf-out-w: %d\n",
...@@ -83,6 +89,47 @@ static const struct file_operations trtl_dbg_info_ops = { ...@@ -83,6 +89,47 @@ static const struct file_operations trtl_dbg_info_ops = {
.release = single_release, .release = single_release,
}; };
#define TRTL_DBG_PORT_SIZE PAGE_SIZE /* FIXME */
static int trtl_dbg_debugger_mmap(struct file *file,
struct vm_area_struct *vma)
{
struct trtl_dev *trtl = file->private_data;
unsigned long vsize;
int ret;
struct platform_device *pdev = to_platform_device(trtl->dev.parent);
struct resource *r;
if (vma->vm_pgoff > 0) {
dev_err(&trtl->dev,
"Debug Port mapping does not accept offsets\n");
return -EINVAL;
}
vsize = vma->vm_end - vma->vm_start;
if (vsize > TRTL_DBG_PORT_SIZE) {
dev_err(&trtl->dev,
"Debug Port mapping can't map more that %lu bytes (%lu)\n",
TRTL_DBG_PORT_SIZE, vsize);
return -EINVAL;
}
vma->vm_flags |= VM_IO | VM_DONTCOPY | VM_DONTEXPAND;
vma->vm_page_prot = pgprot_noncached(vma->vm_page_prot);
r = platform_get_resource(pdev, IORESOURCE_MEM, TRTL_MEM_BASE);
return vm_iomap_memory(vma,
r->start + TRTL_ADDR_OFFSET_DBG,
TRTL_DBG_PORT_SIZE);
return ret;
}
static const struct file_operations trtl_dbg_debugger_ops = {
.owner = THIS_MODULE,
.open = simple_open,
.mmap = trtl_dbg_debugger_mmap,
};
/** /**
* It creates the debug info file * It creates the debug info file
...@@ -90,6 +137,8 @@ static const struct file_operations trtl_dbg_info_ops = { ...@@ -90,6 +137,8 @@ static const struct file_operations trtl_dbg_info_ops = {
*/ */
void trtl_debugfs_init(struct trtl_dev *trtl) void trtl_debugfs_init(struct trtl_dev *trtl)
{ {
char name[20];
trtl->dbg_dir = debugfs_create_dir(dev_name(&trtl->dev), NULL); trtl->dbg_dir = debugfs_create_dir(dev_name(&trtl->dev), NULL);
if (IS_ERR_OR_NULL(trtl->dbg_dir)) { if (IS_ERR_OR_NULL(trtl->dbg_dir)) {
dev_err(&trtl->dev, "Cannot create debugfs\n"); dev_err(&trtl->dev, "Cannot create debugfs\n");
...@@ -106,6 +155,16 @@ void trtl_debugfs_init(struct trtl_dev *trtl) ...@@ -106,6 +155,16 @@ void trtl_debugfs_init(struct trtl_dev *trtl)
PTR_ERR(trtl->dbg_info)); PTR_ERR(trtl->dbg_info));
trtl->dbg_info = NULL; trtl->dbg_info = NULL;
} }
snprintf(name, 20, "%s-dbg", dev_name(&trtl->dev));
trtl->debugger = debugfs_create_file(name, 0664, trtl->dbg_dir,
trtl, &trtl_dbg_debugger_ops);
if (IS_ERR_OR_NULL(trtl->debugger)) {
dev_err(&trtl->dev,
"Cannot create debugfs file: %ld\n",
PTR_ERR(trtl->debugger));
trtl->debugger = NULL;
}
} }
......
...@@ -75,11 +75,6 @@ static inline uint32_t trtl_get_sequence(struct trtl_msg *msg) ...@@ -75,11 +75,6 @@ static inline uint32_t trtl_get_sequence(struct trtl_msg *msg)
return msg->data[1]; return msg->data[1];
} }
struct trtl_msg_filter_element {
struct trtl_msg_filter filter;
struct list_head list;
};
struct trtl_memory_ops { struct trtl_memory_ops {
u32 (*read)(void *addr); u32 (*read)(void *addr);
void (*write)(u32 value, void *addr); void (*write)(u32 value, void *addr);
...@@ -117,6 +112,7 @@ struct mturtle_hmq_buffer { ...@@ -117,6 +112,7 @@ struct mturtle_hmq_buffer {
spinlock_t lock; spinlock_t lock;
unsigned int idx_w; unsigned int idx_w;
unsigned int idx_r; unsigned int idx_r;
unsigned int entries;
struct trtl_msg *msg; struct trtl_msg *msg;
struct trtl_msg msg_tmp; struct trtl_msg msg_tmp;
unsigned int count; unsigned int count;
...@@ -177,13 +173,22 @@ struct trtl_hmq { ...@@ -177,13 +173,22 @@ struct trtl_hmq {
struct mturtle_hmq_buffer buf_out; struct mturtle_hmq_buffer buf_out;
}; };
/**
* User do only sync messages
*/
#define TRTL_HMQ_USER_FLAG_SYNC BIT(0)
/**
* User is waiting for a sync answer message
*/
#define TRTL_HMQ_USER_FLAG_SYNC_WAIT BIT(1)
/** /**
* It describes the consumer of the output slot * It describes the consumer of the output slot
* @list: to keep it in our local queue * @list: to keep it in our local queue
* @hmq: reference to opened HMQ * @hmq: reference to opened HMQ
* @lock: to protect filters * @lock: to protect flags, wait_id
* @list_filters: list of filters to apply
* @n_filters: number of filters
* @idx_r: index read pointer for the message circular buffer. This is * @idx_r: index read pointer for the message circular buffer. This is
* protected by the input buffer lock. Accessing this field means that * protected by the input buffer lock. Accessing this field means that
* you are accessing the buffer input, and in order to do that you need * you are accessing the buffer input, and in order to do that you need
...@@ -194,9 +199,9 @@ struct trtl_hmq_user { ...@@ -194,9 +199,9 @@ struct trtl_hmq_user {
struct list_head list; struct list_head list;
struct trtl_hmq *hmq; struct trtl_hmq *hmq;
spinlock_t lock; spinlock_t lock;
struct list_head list_filters; unsigned long flags;
unsigned int n_filters;
unsigned int idx_r; unsigned int idx_r;
uint16_t wait_id;
}; };
...@@ -244,7 +249,8 @@ struct trtl_cpu { ...@@ -244,7 +249,8 @@ struct trtl_cpu {
* @irq_mask: IRQ mask in use * @irq_mask: IRQ mask in use
* @message_sequence: message sequence number * @message_sequence: message sequence number
* @lock_cpu_sel: * @lock_cpu_sel:
* @lock_hmq_sel: * @lock_hmq_sel: protects the HMQ usage which is based on selection. It
* protects also last_seq which is related to HMQ messages
* @cfgrom: synthesis configuration ROM * @cfgrom: synthesis configuration ROM
* @tty_driver: * @tty_driver:
* @memops: * @memops:
...@@ -252,6 +258,9 @@ struct trtl_cpu { ...@@ -252,6 +258,9 @@ struct trtl_cpu {
* @dbg_info: information * @dbg_info: information
* @max_irq_loop: maximum number of messages that can be retrieved with a * @max_irq_loop: maximum number of messages that can be retrieved with a
* single IRQ. It regulates the HMQ IRQ handler * single IRQ. It regulates the HMQ IRQ handler
* @last_seq: last sequence number used. The same seq number cannot be used
* on different HMQ on the same CPU
* @debugger: debugfs interface for gdbserver
*/ */
struct trtl_dev { struct trtl_dev {
struct device dev; struct device dev;
...@@ -272,6 +281,8 @@ struct trtl_dev { ...@@ -272,6 +281,8 @@ struct trtl_dev {
struct dentry *dbg_dir; struct dentry *dbg_dir;
struct dentry *dbg_info; struct dentry *dbg_info;
unsigned int max_irq_loop; unsigned int max_irq_loop;
uint32_t last_seq;
struct dentry *debugger;
}; };
static inline u32 trtl_ioread(struct trtl_dev *trtl, void *addr) static inline u32 trtl_ioread(struct trtl_dev *trtl, void *addr)
......
This diff is collapsed.
...@@ -8,7 +8,8 @@ REPO_PARENT ?= ../.. ...@@ -8,7 +8,8 @@ REPO_PARENT ?= ../..
-include $(REPO_PARENT)/parent_common.mk -include $(REPO_PARENT)/parent_common.mk
TRTL ?= ../ TRTL ?= ../../
TRTL_SW = $(TRTL)/software
LIBS = libmockturtle.so LIBS = libmockturtle.so
LIB = libmockturtle.a LIB = libmockturtle.a
...@@ -16,7 +17,7 @@ LOBJ := libmockturtle.o ...@@ -16,7 +17,7 @@ LOBJ := libmockturtle.o
LOBJ += libmockturtle-rt-msg.o LOBJ += libmockturtle-rt-msg.o
CFLAGS += -Wall -Werror -ggdb -fPIC CFLAGS += -Wall -Werror -ggdb -fPIC
CFLAGS += -I. -I$(TRTL)/include $(EXTRACFLAGS) CFLAGS += -I. -I$(TRTL_SW)/include $(EXTRACFLAGS)
LDFLAGS = -L. -lmockturtle LDFLAGS = -L. -lmockturtle
ARFLAGS = rc ARFLAGS = rc
......
...@@ -15,6 +15,7 @@ TRTL_CONFIG_ROM_MAX_CPU = 8 ...@@ -15,6 +15,7 @@ TRTL_CONFIG_ROM_MAX_CPU = 8
TRTL_CONFIG_ROM_MAX_HMQ = 8 TRTL_CONFIG_ROM_MAX_HMQ = 8
TRTL_CONFIG_ROM_MAX_RMQ = 8 TRTL_CONFIG_ROM_MAX_RMQ = 8
ETRTL_MSG_SYNC_FAILED_RECV_TIMEOUT = 83638
class TrtlConfigMq(Structure): class TrtlConfigMq(Structure):
""" """
...@@ -109,6 +110,8 @@ class TrtlHmqHeader(Structure): ...@@ -109,6 +110,8 @@ class TrtlHmqHeader(Structure):
return False return False
return True return True
def __str__(self):
return "rt_app_id: 0x{:x}, flags: 0x{:x}, msg_id: 0x{:x}, len: {:d}, sync_id: {:d}, seq: {:d}".format(self.rt_app_id,self.flags, self.msg_id, self.len, self.sync_id, self.seq)
class TrtlMessage(Structure): class TrtlMessage(Structure):
""" """
...@@ -135,6 +138,9 @@ class TrtlMessage(Structure): ...@@ -135,6 +138,9 @@ class TrtlMessage(Structure):
break break
return True return True
def __str__(self):
return "{:s}, payload: ##".format(str(self.header))
class TrtlFirmwareVersion(Structure): class TrtlFirmwareVersion(Structure):
""" """
...@@ -309,15 +315,6 @@ class TrtlDevice(object): ...@@ -309,15 +315,6 @@ class TrtlDevice(object):
self.libtrtl.trtl_fw_variable_set.restype = c_int self.libtrtl.trtl_fw_variable_set.restype = c_int
self.libtrtl.trtl_fw_variable_set.errcheck = self.__errcheck_int self.libtrtl.trtl_fw_variable_set.errcheck = self.__errcheck_int
# self.libtrtl.trtl_hmq_filter_add.argtypes = [c_void_p]
# self.libtrtl.trtl_hmq_filter_clean.argtypes = [c_void_p]
# # Return
# self.libtrtl.trtl_hmq_filter_add.restype = c_int
# self.libtrtl.trtl_hmq_filter_clean.restype = c_int
# # Error
# self.libtrtl.trtl_hmq_filter_add.errcheck = self.__errcheck_int
# self.libtrtl.trtl_hmq_filter_clean.errcheck = self.__errcheck_int
def __errcheck_pointer(self, ret, func, args): def __errcheck_pointer(self, ret, func, args):
"""Generic error handler for functions returning pointers""" """Generic error handler for functions returning pointers"""
if ret is None: if ret is None:
...@@ -555,16 +552,16 @@ class TrtlHmq(object): ...@@ -555,16 +552,16 @@ class TrtlHmq(object):
:param timeout: time to wait before returning :param timeout: time to wait before returning
:type timeout: int :type timeout: int
:return: an asynchronous message :return: an asynchronous message or None
:rtype: TrtlMessage :rtype: TrtlMessage
:raises OSError: from C library errors :raises OSError: from C library errors
""" """
set_errno(0) set_errno(0)
msg = TrtlMessage() msg = TrtlMessage()
self.libtrtl.trtl_msg_async_recv(self.trtl_dev.tkn, ret = self.libtrtl.trtl_msg_async_recv(self.trtl_dev.tkn,
self.idx_cpu, self.idx_hmq, self.idx_cpu, self.idx_hmq,
pointer(msg), 1) pointer(msg), 1)
return msg return None if ret == 0 else msg
def sync_msg(self, msg_s, timeout=1000): def sync_msg(self, msg_s, timeout=1000):
""" """
...@@ -578,6 +575,7 @@ class TrtlHmq(object): ...@@ -578,6 +575,7 @@ class TrtlHmq(object):
:rtype: TrtlMessage :rtype: TrtlMessage
:raises OSError: from C library errors :raises OSError: from C library errors
""" """
set_errno(0)
msg_r = TrtlMessage() msg_r = TrtlMessage()
self.libtrtl.trtl_msg_sync(self.trtl_dev.tkn, self.libtrtl.trtl_msg_sync(self.trtl_dev.tkn,
self.idx_cpu, self.idx_hmq, self.idx_cpu, self.idx_hmq,
......
...@@ -13,7 +13,8 @@ from .PyMockTurtle import TrtlHmqHeader, TrtlMessage, TrtlConfig, \ ...@@ -13,7 +13,8 @@ from .PyMockTurtle import TrtlHmqHeader, TrtlMessage, TrtlConfig, \
TrtlFirmwareVariable, \ TrtlFirmwareVariable, \
TRTL_CONFIG_ROM_MAX_CPU, \ TRTL_CONFIG_ROM_MAX_CPU, \
TRTL_CONFIG_ROM_MAX_HMQ, \ TRTL_CONFIG_ROM_MAX_HMQ, \
TRTL_CONFIG_ROM_MAX_RMQ TRTL_CONFIG_ROM_MAX_RMQ, \
ETRTL_MSG_SYNC_FAILED_RECV_TIMEOUT
__all__ = ( __all__ = (
"TrtlDevice", "TrtlDevice",
...@@ -29,4 +30,5 @@ __all__ = ( ...@@ -29,4 +30,5 @@ __all__ = (
"TRTL_CONFIG_ROM_MAX_CPU", "TRTL_CONFIG_ROM_MAX_CPU",
"TRTL_CONFIG_ROM_MAX_HMQ", "TRTL_CONFIG_ROM_MAX_HMQ",
"TRTL_CONFIG_ROM_MAX_RMQ", "TRTL_CONFIG_ROM_MAX_RMQ",
"ETRTL_MSG_SYNC_FAILED_RECV_TIMEOUT",
) )
...@@ -9,7 +9,7 @@ setup(name='PyMockTurtle', ...@@ -9,7 +9,7 @@ setup(name='PyMockTurtle',
author_email='federico.vaga@cern.ch', author_email='federico.vaga@cern.ch',
maintainer="Federico Vaga", maintainer="Federico Vaga",
maintainer_email="federico.vaga@cern.ch", maintainer_email="federico.vaga@cern.ch",
url='http://www.ohwr.org/projects/mock-turtle-sw', url='http://www.ohwr.org/projects/mock-turtle',
packages=['PyMockTurtle'], packages=['PyMockTurtle'],
license='LGPLv2', license='LGPLv2',
) )
...@@ -31,9 +31,8 @@ struct trtl_desc { ...@@ -31,9 +31,8 @@ struct trtl_desc {
int fd_dev; /**< File Descriptor of the device */ int fd_dev; /**< File Descriptor of the device */
int fd_cpu[TRTL_MAX_CPU]; /**< File Descriptor of the CPUs */ int fd_cpu[TRTL_MAX_CPU]; /**< File Descriptor of the CPUs */
int fd_hmq[TRTL_MAX_CPU][TRTL_MAX_MQ_CHAN]; /**< File Descriptors for the HMQ */ int fd_hmq[TRTL_MAX_CPU][TRTL_MAX_MQ_CHAN]; /**< File Descriptors for the HMQ */
int fd_hmq_sync[TRTL_MAX_CPU][TRTL_MAX_MQ_CHAN]; /**< File Descriptors for the HMQ in sync mode */
struct trtl_config_rom cfgrom;/**< synthesis configuration */ struct trtl_config_rom cfgrom;/**< synthesis configuration */
struct trtl_dev *trtl_sync; /**< token for synchronous operations */
}; };
#endif #endif
This diff is collapsed.
...@@ -151,16 +151,12 @@ static inline int trtl_cpu_restart(struct trtl_dev *trtl, unsigned int index) ...@@ -151,16 +151,12 @@ static inline int trtl_cpu_restart(struct trtl_dev *trtl, unsigned int index)
* @{ * @{
*/ */
extern int trtl_hmq_filter_add(struct trtl_dev *trtl,
unsigned int idx_cpu,
unsigned int idx_hmq,
struct trtl_msg_filter *filter);
extern int trtl_hmq_filter_clean(struct trtl_dev *trtl,
unsigned int idx_cpu,
unsigned int idx_hmq);
extern int trtl_hmq_fd(struct trtl_dev *trtl, extern int trtl_hmq_fd(struct trtl_dev *trtl,
unsigned int idx_cpu, unsigned int idx_cpu,
unsigned int idx_hmq); unsigned int idx_hmq);
extern int trtl_hmq_fd_sync(struct trtl_dev *trtl,
unsigned int idx_cpu,
unsigned int idx_hmq);
extern int trtl_msg_async_send(struct trtl_dev *trtl, extern int trtl_msg_async_send(struct trtl_dev *trtl,
unsigned int idx_cpu, unsigned int idx_cpu,
unsigned int idx_hmq, unsigned int idx_hmq,
......
...@@ -7,3 +7,4 @@ mockturtle-smem ...@@ -7,3 +7,4 @@ mockturtle-smem
mockturtle-ping mockturtle-ping
mockturtle-variable mockturtle-variable
mockturtle-buffer mockturtle-buffer
mockturtle-gdbserver
\ No newline at end of file
...@@ -8,14 +8,15 @@ REPO_PARENT ?= ../.. ...@@ -8,14 +8,15 @@ REPO_PARENT ?= ../..
-include $(REPO_PARENT)/parent_common.mk -include $(REPO_PARENT)/parent_common.mk
DESTDIR ?= /usr/local DESTDIR ?= /usr/local
TRTL ?= ../ TRTL ?= ../../
TRTL_SW = $(TRTL)/software
GIT_VERSION := $(shell git describe --dirty --long --tags) GIT_VERSION := $(shell git describe --dirty --long --tags)
CFLAGS += -Wall -Werror -ggdb -I$(TRTL)/lib CFLAGS += -Wall -Werror -ggdb -I$(TRTL_SW)/lib
CFLAGS += -I$(TRTL)/include CFLAGS += -I$(TRTL_SW)/include
CFLAGS += $(EXTRACFLAGS) CFLAGS += $(EXTRACFLAGS)
LDLIBS += -Wl,-Bstatic -L$(TRTL)/lib -lmockturtle LDLIBS += -Wl,-Bstatic -L$(TRTL_SW)/lib -lmockturtle
LDLIBS += -Wl,-Bdynamic -lpthread LDLIBS += -Wl,-Bdynamic -lpthread
PROGS := mockturtle-count PROGS := mockturtle-count
PROGS += lsmockturtle PROGS += lsmockturtle
...@@ -26,6 +27,7 @@ PROGS += mockturtle-smem ...@@ -26,6 +27,7 @@ PROGS += mockturtle-smem
PROGS += mockturtle-ping PROGS += mockturtle-ping
PROGS += mockturtle-variable PROGS += mockturtle-variable
PROGS += mockturtle-buffer PROGS += mockturtle-buffer
PROGS += mockturtle-gdbserver
all: $(PROGS) all: $(PROGS)
...@@ -33,7 +35,7 @@ install: ...@@ -33,7 +35,7 @@ install:
install -d $(DESTDIR)/bin install -d $(DESTDIR)/bin
install -D $(PROGS) $(DESTDIR)/bin install -D $(PROGS) $(DESTDIR)/bin
%: %.c $(TRTL)/libmockturtle.a %: %.c $(TRTL_SW)/lib/libmockturtle.a
$(CC) $(CFLAGS) $^ -o $@ $(LDLIBS) $(CC) $(CFLAGS) $^ -o $@ $(LDLIBS)
# make nothing for modules_install, but avoid errors # make nothing for modules_install, but avoid errors
......
This diff is collapsed.
...@@ -7,6 +7,7 @@ DIRS += config_rom ...@@ -7,6 +7,7 @@ DIRS += config_rom
DIRS += sim-verif DIRS += sim-verif
DIRS += hmq-async-recv DIRS += hmq-async-recv
DIRS += hmq-async-send DIRS += hmq-async-send
DIRS += hmq-sync
DIRS += hmq-purge DIRS += hmq-purge
DIRS += rmq-udp-send DIRS += rmq-udp-send
DIRS += rt-frm DIRS += rt-frm
......
OBJS = config_rom.o
OBJS += # add other object files that you need
OUTPUT = fw-config-rom
TRTL ?= ../../../ TRTL ?= ../../../
TRTL_SW = $(TRTL)/software TRTL_FW = $(TRTL)/software/firmware
include $(TRTL_SW)/firmware/Makefile all:
# Redirect all rules to MockTurtle
%:
$(MAKE) -C $(TRTL_FW) M=$(shell /bin/pwd) $@
OBJS = config_rom.o
OBJS += # add other object files that you need
OUTPUT = fw-config-rom
OBJS = byte-addressing.o
OBJS += # add other object files that you need
OUTPUT = fw-byte-addressing
TRTL ?= ../../../ TRTL ?= ../../../
TRTL_SW = $(TRTL)/software TRTL_FW = $(TRTL)/software/firmware
include $(TRTL_SW)/firmware/Makefile all:
# Redirect all rules to MockTurtle
%:
$(MAKE) -C $(TRTL_FW) M=$(shell /bin/pwd) $@
OBJS = byte-addressing.o
OBJS += # add other object files that you need
OUTPUT = fw-byte-addressing
OBJS = cpu-loop.o
OBJS += # add other object files that you need
OUTPUT = fw-loop
TRTL ?= ../../../ TRTL ?= ../../../
TRTL_SW = $(TRTL)/software TRTL_FW = $(TRTL)/software/firmware
include $(TRTL_SW)/firmware/Makefile all:
# Redirect all rules to MockTurtle
%:
$(MAKE) -C $(TRTL_FW) M=$(shell /bin/pwd) $@
OBJS = cpu-loop.o
OBJS += # add other object files that you need
OUTPUT = fw-loop
OBJS = notify.o
OBJS += # add other object files that you need
OUTPUT = fw-notify
TRTL ?= ../../../ TRTL ?= ../../../
TRTL_SW = $(TRTL)/software TRTL_FW = $(TRTL)/software/firmware
include $(TRTL_SW)/firmware/Makefile all:
# Redirect all rules to MockTurtle
%:
$(MAKE) -C $(TRTL_FW) M=$(shell /bin/pwd) $@
OBJS = notify.o
OBJS += # add other object files that you need
OUTPUT = fw-notify
OBJS = hmq-async-recv.o
OBJS += # add other object files that you need
OUTPUT = fw-hmq-async-recv
TRTL ?= ../../../ TRTL ?= ../../../
TRTL_SW = $(TRTL)/software TRTL_FW = $(TRTL)/software/firmware
include $(TRTL_SW)/firmware/Makefile all:
# Redirect all rules to MockTurtle
%:
$(MAKE) -C $(TRTL_FW) M=$(shell /bin/pwd) $@
OBJS = hmq-async-recv.o
OBJS += # add other object files that you need
OUTPUT = fw-hmq-async-recv
...@@ -23,6 +23,7 @@ int main() ...@@ -23,6 +23,7 @@ int main()
mq_claim(TRTL_HMQ, hmq); mq_claim(TRTL_HMQ, hmq);
hdr = mq_map_out_header(TRTL_HMQ, hmq); hdr = mq_map_out_header(TRTL_HMQ, hmq);
memset(hdr, 0, sizeof(*hdr));
msg = mq_map_out_buffer(TRTL_HMQ, hmq); msg = mq_map_out_buffer(TRTL_HMQ, hmq);
hdr->len = n_word; hdr->len = n_word;
for (i = 0; i < hdr->len; i++) for (i = 0; i < hdr->len; i++)
......
OBJS = hmq-async-send.o
OBJS += # add other object files that you need
OUTPUT = fw-hmq-async-send
TRTL ?= ../../../ TRTL ?= ../../../
TRTL_SW = $(TRTL)/software TRTL_FW = $(TRTL)/software/firmware
include $(TRTL_SW)/firmware/Makefile all:
# Redirect all rules to MockTurtle
%:
$(MAKE) -C $(TRTL_FW) M=$(shell /bin/pwd) $@
OBJS = hmq-async-send.o
OBJS += # add other object files that you need
OUTPUT = fw-hmq-async-send
OBJS = hmq-purge.o
OBJS += # add other object files that you need
OUTPUT = fw-hmq-purge
TRTL ?= ../../../ TRTL ?= ../../../
TRTL_SW = $(TRTL)/software TRTL_FW = $(TRTL)/software/firmware
include $(TRTL_SW)/firmware/Makefile all:
# Redirect all rules to MockTurtle
%:
$(MAKE) -C $(TRTL_FW) M=$(shell /bin/pwd) $@
OBJS = hmq-purge.o
OBJS += # add other object files that you need
OUTPUT = fw-hmq-purge
mainmenu "hmq_async_send test configuration"
comment "Project specific configuration"
config FPGA_APPLICATION_ID
int "FPGA application ID"
default 0
help
Help text
config RT_APPLICATION_ID
int "RT application ID"
default 0
help
Help text
# include Mock Turtle's Kconfig
source "Kconfig.mt"
TRTL ?= ../../../
TRTL_FW = $(TRTL)/software/firmware
all:
# Redirect all rules to MockTurtle
%:
$(MAKE) -C $(TRTL_FW) M=$(shell /bin/pwd) $@
OBJS = hmq-sync.o
OBJS += # add other object files that you need
OUTPUT = fw-hmq-sync
#
# Automatically generated file; DO NOT EDIT.
# hmq_async_send test configuration
#
#
# Project specific configuration
#
CONFIG_FPGA_APPLICATION_ID=0
CONFIG_RT_APPLICATION_ID=0
#
# Mock Turtle configuration
#
CONFIG_CFLAGS_OPT="-O0"
CONFIG_CFLAGS_EXTRA="-ggdb"
# CONFIG_MOCKTURTLE_SIMULATION is not set
#
# Mock Turtle framework configuration
#
# CONFIG_MOCKTURTLE_FRAMEWORK_ENABLE is not set
CONFIG_MOCKTURTLE_FRAMEWORK_ACTION_ENABLE=y
# CONFIG_MOCKTURTLE_FRAMEWORK_VARIABLE_ENABLE is not set
# CONFIG_MOCKTURTLE_FRAMEWORK_BUFFER_ENABLE is not set
CONFIG_MOCKTURTLE_FRAMEWORK_PING_ENABLE=y
CONFIG_MOCKTURTLE_FRAMEWORK_VERSION_ENABLE=y
#
# Mock Turtle library configuration
#
CONFIG_MOCKTURTLE_LIBRARY_PRINT_ENABLE=y
# CONFIG_MOCKTURTLE_LIBRARY_PRINT_DEBUG_ENABLE is not set
CONFIG_MOCKTURTLE_LIBRARY_PRINT_ERROR_ENABLE=y
# CONFIG_MOCKTURTLE_LIBRARY_PRINT_MESSAGE_ENABLE is not set
#include <mockturtle-rt.h>
int main()
{
int cpu, hmq;
const struct trtl_config_rom *cfgrom = trtl_config_rom_get();
struct trtl_fw_msg msg, msg_s;
struct payload *p;
uint32_t status;
pr_debug("TEST for: async send, sync\r\n");
cpu = trtl_get_core_id();
while (1) {
for (hmq = 0; hmq < cfgrom->n_hmq[cpu]; ++hmq) {
mq_map_in_message(TRTL_HMQ, hmq, &msg);
mq_map_out_message(TRTL_HMQ, hmq, &msg_s);
status = mq_poll_in_wait(TRTL_HMQ, 1 << hmq, 1);
if (!status)
continue;
if (!(msg.header->flags & TRTL_HMQ_HEADER_FLAG_SYNC))
continue;
/* For sync answer test */
pr_debug("SEND MESSAGES SYNC ANSWER\r\n");
mq_claim(TRTL_HMQ, hmq);
memcpy(msg_s.header, msg.header,
sizeof(struct trtl_hmq_header));
msg_s.header->flags &= ~TRTL_HMQ_HEADER_FLAG_SYNC;
msg_s.header->flags |= TRTL_HMQ_HEADER_FLAG_ACK;
memcpy(msg_s.payload, msg.payload, msg.header->len * 4);
mq_send(TRTL_HMQ, hmq);
mq_discard(TRTL_HMQ, hmq);
}
}
pp_printf("OK\r\n");
return 0;
}
-include ../Makefile.specific
OBJS = rmq-udp-send.o
OBJS += # add other object files that you need
OUTPUT = fw-rmq-udp-send
TRTL ?= ../../../ TRTL ?= ../../../
TRTL_SW = $(TRTL)/software TRTL_FW = $(TRTL)/software/firmware
CFLAGS_OPT = -O0 # disable optimization all:
include $(TRTL_SW)/firmware/Makefile # Redirect all rules to MockTurtle
%:
$(MAKE) -C $(TRTL_FW) M=$(shell /bin/pwd) $@
OBJS = rmq-udp-send.o
OBJS += # add other object files that you need
OUTPUT = fw-rmq-udp-send
CFLAGS_OPT = -O0 # disable optimization
OBJS = rt-frm.o
OBJS += # add other object files that you need
OUTPUT = fw-rt-frm
TRTL ?= ../../../ TRTL ?= ../../../
TRTL_SW = $(TRTL)/software TRTL_FW = $(TRTL)/software/firmware
include $(TRTL_SW)/firmware/Makefile all:
# Redirect all rules to MockTurtle
%:
$(MAKE) -C $(TRTL_FW) M=$(shell /bin/pwd) $@
OBJS = rt-frm.o
OBJS += # add other object files that you need
OUTPUT = fw-rt-frm
-include ../Makefile.specific
OBJS = serial.o
OBJS += # add other object files that you need
OUTPUT = fw-serial
TRTL ?= ../../../ TRTL ?= ../../../
TRTL_SW = $(TRTL)/software TRTL_FW = $(TRTL)/software/firmware
all:
include $(TRTL_SW)/firmware/Makefile # Redirect all rules to MockTurtle
%:
$(MAKE) -C $(TRTL_FW) M=$(shell /bin/pwd) $@
OBJS = serial.o
OBJS += # add other object files that you need
OUTPUT = fw-serial
OBJS = sim-verif.o
OBJS += # add other object files that you need
OUTPUT = sim-verif
TRTL ?= ../../../ TRTL ?= ../../../
TRTL_SW = $(TRTL)/software TRTL_FW = $(TRTL)/software/firmware
include $(TRTL_SW)/firmware/Makefile all:
# Redirect all rules to MockTurtle
%:
$(MAKE) -C $(TRTL_FW) M=$(shell /bin/pwd) $@
OBJS = sim-verif.o
OBJS += # add other object files that you need
OUTPUT = sim-verif
...@@ -14,7 +14,7 @@ class TestConfig(object): ...@@ -14,7 +14,7 @@ class TestConfig(object):
def test_valid_host(self, trtl_device, cfg): def test_valid_host(self, trtl_device, cfg):
assert trtl_device.rom.signature == cfg.signature assert trtl_device.rom.signature == cfg.signature
assert trtl_device.rom.app_id == cfg.app_id assert ((trtl_device.rom.app_id == cfg.app_id) or (trtl_device.rom.app_id == cfg.app_id | 0x10001)) # SVEC or SPEC DEMO
assert trtl_device.rom.n_cpu == cfg.n_cpu assert trtl_device.rom.n_cpu == cfg.n_cpu
def test_valid_softcpu(self, trtl_cpu, cfg, firmware_file_config): def test_valid_softcpu(self, trtl_cpu, cfg, firmware_file_config):
...@@ -27,5 +27,5 @@ class TestConfig(object): ...@@ -27,5 +27,5 @@ class TestConfig(object):
msg = trtl_cpu.hmq[0].recv_msg() msg = trtl_cpu.hmq[0].recv_msg()
assert msg.payload[0] == cfg.signature assert msg.payload[0] == cfg.signature
assert msg.payload[5] == cfg.app_id assert ((msg.payload[5] == cfg.app_id) or (msg.payload[5] == cfg.app_id | 0x10001))
assert msg.payload[6] == cfg.n_cpu assert msg.payload[6] == cfg.n_cpu
...@@ -3,6 +3,8 @@ import PyMockTurtle ...@@ -3,6 +3,8 @@ import PyMockTurtle
import pytest import pytest
import serial import serial
import time import time
import multiprocessing
import errno
@pytest.fixture @pytest.fixture
def trtl_binary_hmq_purge(trtl_firmware_dir): def trtl_binary_hmq_purge(trtl_firmware_dir):
...@@ -25,6 +27,25 @@ def trtl_binary_hmq_sync(trtl_firmware_dir): ...@@ -25,6 +27,25 @@ def trtl_binary_hmq_sync(trtl_firmware_dir):
"firmware/hmq-sync/fw-hmq-sync.bin") "firmware/hmq-sync/fw-hmq-sync.bin")
def do_sync_mult(q, hmq_orig, msg):
try:
dev = PyMockTurtle.TrtlDevice(hmq_orig.trtl_dev.device_id)
hmq = dev.cpu[hmq_orig.idx_cpu].hmq[hmq_orig.idx_hmq]
q.put(hmq.sync_msg(msg))
except Exception as e:
print(e)
q.put(None)
def do_sync_no_multone(q, hmq):
try:
msg_r = hmq.sync_msg(PyMockTurtle.TrtlMessage())
q.put(0)
except OSError as err:
q.put(err.errno)
except Exception as e:
print(e)
q.put(None)
class TestHmq(object): class TestHmq(object):
confirm = 'OK\r\n' confirm = 'OK\r\n'
...@@ -98,20 +119,103 @@ class TestHmq(object): ...@@ -98,20 +119,103 @@ class TestHmq(object):
trtl_cpu.load_application_file(trtl_binary_hmq_async_recv) trtl_cpu.load_application_file(trtl_binary_hmq_async_recv)
trtl_cpu.enable() trtl_cpu.enable()
time.sleep(0.1) time.sleep(0.5)
for hmq in trtl_cpu.hmq:
tot = trtl_cpu.trtl_dev.rom.hmq[trtl_cpu.idx_cpu][hmq.idx_hmq].entries
sa = hmq.get_stats()
assert sb[hmq]["message_received"] + tot == sa["message_received"]
for hmq in trtl_cpu.hmq: for hmq in trtl_cpu.hmq:
tot = trtl_cpu.trtl_dev.rom.hmq[trtl_cpu.idx_cpu][hmq.idx_hmq].entries tot = trtl_cpu.trtl_dev.rom.hmq[trtl_cpu.idx_cpu][hmq.idx_hmq].entries
for n in range(tot): for n in range(tot):
msg = hmq.recv_msg() msg = hmq.recv_msg()
assert msg is not None
payload = list(msg.payload) payload = list(msg.payload)
for i, val in enumerate(payload): for i, val in enumerate(payload):
if i >= msg.header.len: if i >= msg.header.len:
break break
assert i == val assert i == val
def __do_sync_msg(self, hmq, trtl_msg):
msg_r_a = []
# I do not understand why I can't make Pool() working.
# it complains about hmq
# with multiprocessing.Pool(processes=len(trtl_msg)) as p:
# msg_r_a = p.starmap(do_sync_msg,
# [(hmq, msg) for msg in trtl_msg])
proc = []
for msg in trtl_msg:
q = multiprocessing.Queue()
proc.append((q, multiprocessing.Process(target=do_sync_msg,
args=(q, hmq, msg))))
for q, p in proc:
p.start()
for q, p in proc:
msg_r_a.append(q.get())
p.join()
return msg_r_a
@pytest.mark.parametrize("nproc", range(1, 5))
def test_sync_no_multone(self, trtl_cpu, nproc):
"""The driver should not accept more than 1 sync message at time
from the same user. The test is successful when the driver refused
a second message"""
trtl_cpu.disable();
for hmq in trtl_cpu.hmq:
proc = []
for n in range(nproc):
q = multiprocessing.Queue()
p = multiprocessing.Process(target=do_sync_no_multone,
args=(q, hmq))
proc.append((q, p))
p.start()
count_busy = 0
count_timeout = 0
for q, p in proc:
err = q.get()
p.join()
assert err != 0
if err == errno.EBUSY:
count_busy = count_busy + 1
if err == PyMockTurtle.ETRTL_MSG_SYNC_FAILED_RECV_TIMEOUT:
count_timeout = count_timeout + 1
assert count_timeout == 1
assert count_busy == nproc - 1
assert count_timeout + count_busy == nproc
def test_sync_mult(self, trtl_cpu, trtl_msg, trtl_binary_hmq_sync):
"""Test Multiprocess sync messages. The firmware will copy back
the message as answer"""
trtl_cpu.load_application_file(trtl_binary_hmq_sync)
trtl_cpu.enable()
for hmq in trtl_cpu.hmq:
proc = []
sb = hmq.get_stats()
for msg in trtl_msg:
q = multiprocessing.Queue()
p = multiprocessing.Process(target=do_sync_mult,
args=(q, hmq, msg))
proc.append((q, p, msg))
p.start()
for q, p, msg in proc:
msg_r = q.get()
p.join()
assert msg_r is not None
assert msg_r.header.rt_app_id == msg.header.rt_app_id
assert msg_r.header.msg_id == msg.header.msg_id
assert msg_r.header.len == msg.header.len
assert msg_r.header.flags == PyMockTurtle.TrtlHmqHeader.TRTL_HMQ_HEADER_FLAG_ACK
for v1, v2 in zip(msg.payload, msg_r.payload):
assert v1 == v2
sa = hmq.get_stats() sa = hmq.get_stats()
assert sb[hmq]["message_received"] + tot == sa["message_received"] assert sb["message_sent"] + len(trtl_msg) == sa["message_sent"]
assert sb["message_received"] + len(trtl_msg) == sa["message_received"]
def test_sync(self, trtl_cpu, trtl_msg, trtl_binary_hmq_async_send): def test_sync(self, trtl_cpu, trtl_msg, trtl_binary_hmq_async_send):
"""It sends the test messages on all available HMQ. """It sends the test messages on all available HMQ.
...@@ -131,8 +235,9 @@ class TestHmq(object): ...@@ -131,8 +235,9 @@ class TestHmq(object):
assert msg_r.header.rt_app_id == msg.header.rt_app_id assert msg_r.header.rt_app_id == msg.header.rt_app_id
assert msg_r.header.msg_id == msg.header.msg_id assert msg_r.header.msg_id == msg.header.msg_id
assert msg_r.header.len == msg.header.len assert msg_r.header.len == msg.header.len
assert msg_r.header.sync_id == msg.header.sync_id
assert msg.header.flags == PyMockTurtle.TrtlHmqHeader.TRTL_HMQ_HEADER_FLAG_SYNC
assert msg_r.header.flags == PyMockTurtle.TrtlHmqHeader.TRTL_HMQ_HEADER_FLAG_ACK assert msg_r.header.flags == PyMockTurtle.TrtlHmqHeader.TRTL_HMQ_HEADER_FLAG_ACK
for v1, v2 in zip(msg.payload, msg_r.payload): for v1, v2 in zip(msg.payload, msg_r.payload):
assert v1 == v2 assert v1 == v2
msg_r = hmq.recv_msg()
assert msg_r is None
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment