Commit a4fa5915 authored by Federico Vaga's avatar Federico Vaga

Merge branch 'release/v4.0.0.beta2'

parents c87ca048 533062b6
GPATH
GRTAGS
GTAGS
Makefile.specific
OBJS = fw-ac.o
OBJS += # add other object files that you need
OUTPUT = fw-ac
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_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_SW = $(TRTL)/software
EXTRA_CFLAGS += -I../../include
EXTRA_CFLAGS += -I../common
EXTRA_CFLAGS += -DFPGA_APPLICATION_ID=APPLICATION_ID
EXTRA_CFLAGS += -DRT_APPLICATION_ID=$(RT_APPLICATION_ID_CPU1)
TRTL_FW = $(TRTL)/software/firmware
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_SW = $(TRTL)/software
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
TRTL_FW = $(TRTL)/software/firmware
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_SW = $(TRTL)/software
EXTRA_CFLAGS += -I../../include
EXTRA_CFLAGS += -I../common
EXTRA_CFLAGS += -DFPGA_APPLICATION_ID=APPLICATION_ID
EXTRA_CFLAGS += -DRT_APPLICATION_ID=$(RT_APPLICATION_ID_CPU1)
TRTL_FW = $(TRTL)/software/firmware
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_SW = $(TRTL)/software
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
TRTL_FW = $(TRTL)/software/firmware
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_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_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.
#. *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;
......
......@@ -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
``/path/to/mockturtle/software/firmware/``.
Mock Turtle has a generic ``Makefile`` that you should include in your
``Makefile`` in order to import all the Mock Turtle building rules.::
TRTL ?= /path/to/mcokturtle/
TRTL_SW = $(TRTL)/software
Mock Turtle has a generic building system which can be used to produce
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
you have to specify what to build, for example::
# Mandatory
OBJS = source1.o
......@@ -56,15 +55,10 @@ Mock Turtle has a generic ``Makefile`` that you should include in your
OUTPUT = firmware-name
# Optional (prefer default when possible)
CFLAGS_OPT := -O1
CFLAGS_DBG := -ggdb
EXTRA_CFLGAS :=
EXTRA_CFLAGS :=
MOCKTURTLE_LDSCRIPT := myfirmware.ld
# INCLUDE GENERIC Makefile
include $(TRTL_SW)/firmware/Makefile
Here the list of supported Makefile environment variables
Here the list of supported TBuild variables
OBJS
(Mandatory) List of object files to generate from sources with
......@@ -74,10 +68,33 @@ OBJS
OUTPUT
(Mandatory) Final binary name (the firmware).
EXTRA_CFLAGS
(Optional) Additional compiler options.
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.
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
may take more space than needed. For this reason Mock Turtle has
*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.
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``
(trtl-<device-id>-<cpu-index>-<hmq-index>). The main purpose of this
interface is to exchange messages and configure filters. These devices
are bidirectional, so you can: ``write(2)`` to send messaged;
``read(2)`` to receive messages; ``poll(2)`` or ``select(2)`` to wait
for the interface to become accessible.
interface is to exchange messages. These devices are bidirectional,
so you can: ``write(2)`` to send messaged; ``read(2)`` to receive messages;
``poll(2)`` or ``select(2)`` to wait for the interface to become accessible.
This *char device* provides a set of ``ioctl(2)`` commands:
.. doxygendefine:: TRTL_IOCTL_MSG_FILTER_ADD
.. doxygendefine:: TRTL_IOCTL_MSG_FILTER_CLEAN
.. doxygendefine:: TRTL_IOCTL_HMQ_SYNC_SET
.. doxygendefine:: TRTL_IOCTL_MSG_SYNC_ABORT
You can find the HMQ *sysfs* attributes at::
......
......@@ -153,21 +153,6 @@ side so that the complete flush happens synchronously.
.. 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
running on Mock Turtle. This API offers a minimum set of function
to allow users to send/receive synchronous/asynchronous messages.
......
-include Makefile.specific
# include parent_common.mk for buildsystem's defines
# use absolute path for REPO_PARENT
CURDIR:=$(shell /bin/pwd)
......
-include Makefile.specific
-include $(CURDIR)/.config
src := $(M)/
-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.
INSTALL_PREFIX ?= .
......@@ -7,11 +22,12 @@ PATH_COMMON_RT ?= .
PATH_COMMON_H ?= ../include
TRTL ?= ../../
TRTL_SW ?= $(TRTL)/software
TRTL_FW ?= $(TRTL_SW)/firmware
TRTL_HDL ?= $(TRTL)/hdl/rtl
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
AUTOCONF = $(CURDIR)/$(BUILDDIR)/include/generated/autoconf.h
AUTOCONF = $(src)/$(BUILDDIR)/include/generated/autoconf.h
CROSS_COMPILE_TARGET ?= riscv32-elf-
# 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
LDFLAGS += -lgcc -lc -Wl,--gc-sections
# provide search patch for sources
vpath %.c $(TRTL)/software/firmware
vpath %.S $(TRTL)/software/firmware
vpath %.c $(TRTL_FW)
vpath %.S $(TRTL_FW)
vpath %.c $(src)
vpath %.S $(src)
BUILDDIR := build
BUILDDIR := $(src)/build
# auto dependency generation from
# http://make.mad-scientist.net/papers/advanced-auto-dependency-generation/
......@@ -42,10 +60,10 @@ STRIP = $(CROSS_COMPILE_TARGET)strip
CFLAGS += -Wall -D__TRTL_FIRMWARE__ -DARCH=urv
CFLAGS += -I.
CFLAGS += -I$(BUILDDIR)/include
CFLAGS += -I$(TRTL)/software/firmware
CFLAGS += -I$(TRTL)/software/firmware/lib
CFLAGS += -I$(TRTL)/software/firmware/framework
CFLAGS += -I$(TRTL)/software/include
CFLAGS += -I$(TRTL_FW)
CFLAGS += -I$(TRTL_FW)/lib
CFLAGS += -I$(TRTL_FW)/framework
CFLAGS += -I$(TRTL_SW)/include
CFLAGS += -DGIT_VERSION=$(RT_GIT_VERSION)
# used for firmware by trtl-project-creator
......@@ -76,11 +94,11 @@ OBJS_BUILD = $(addprefix $(BUILDDIR)/, $(OBJS))
OBJDIR_BUILD = $(addprefix $(BUILDDIR)/, $(OBJDIR))
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_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
$(TRTL_SW)/include/hw/mockturtle_cpu_lr.h: $(TRTL_HDL)/cpu/mt_cpu_lr.wb
# 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
# check needed env variables
check-def:
ifndef OUTPUT
@echo "OUTPUT variable is mandatory"
@exit 1
endif
# create dirs for object files
$(OBJDIR_BUILD):
mkdir -p $@
......@@ -112,12 +123,13 @@ $(OBJDIR_BUILD):
$(OBJS_BUILD): | $(AUTOCONF)
$(OBJS_BUILD): | $(OBJDIR_BUILD)
$(OUTPUT).elf: $(addprefix $(TRTL_SW)/include/hw/,$(WBGEN_HEADERS)) $(MOCKTURTLE_LDSCRIPT) $(OBJS_BUILD) | check-def
${CC} $(CFLAGS) $(LDFLAGS) -o $(OUTPUT).elf -nostartfiles $(OBJS_BUILD) -T $(MOCKTURTLE_LDSCRIPT)
$(build_output).elf: $(addprefix $(TRTL_SW)/include/hw/,$(WBGEN_HEADERS)) $(MOCKTURTLE_LDSCRIPT) $(OBJS_BUILD)
$(warning $(OBJS_BUILD))
${CC} $(CFLAGS) $(LDFLAGS) -o $(build_output).elf -nostartfiles $(OBJS_BUILD) -T $(MOCKTURTLE_LDSCRIPT)
$(OUTPUT).bin: $(OUTPUT).elf | check-def
${OBJCOPY} --remove-section .smem -O binary $(OUTPUT).elf $(OUTPUT).bin
$(SIZE) $(OUTPUT).elf
$(build_output).bin: $(build_output).elf
${OBJCOPY} --remove-section .smem -O binary $(build_output).elf $(build_output).bin
$(SIZE) $(build_output).elf
$(BUILDDIR)/urv/emulate.o: urv/emulate.c
${CC} $(DEPFLAGS) $(CFLAGS) -march=rv32i -c $< -o $@
......@@ -126,13 +138,15 @@ $(BUILDDIR)/urv/emulate.o: urv/emulate.c
$(BUILDDIR)/%.o: %.c
${CC} $(DEPFLAGS) $(CFLAGS) $(LDFLAGS) -c $< -o $@
$(POSTCOMPILE)
$(warning $< ---- $@)
@echo ""
$(BUILDDIR)/%.o: %.S
${CC} $(DEPFLAGS) $(CFLAGS) $(LDFLAGS) -c $< -o $@
$(POSTCOMPILE)
clean:
rm -f $(OUTPUT).bin $(OUTPUT).elf
rm -f $(build_output).bin $(build_output).elf
rm -rf $(BUILDDIR)
clean-dot-config:
......@@ -141,7 +155,7 @@ clean-dot-config:
cleanall: clean clean-dot-config
install:
@cp $(OUTPUT).bin $(INSTALL_PREFIX)
@cp $(build_output).bin $(INSTALL_PREFIX)
# inlude *.d files from the build directory
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
# this one is used to generate autoconf.h file
$(AUTOCONF) silentoldconfig: .config | $(BUILDDIR)
export KCONFIG_CONFIG=$(CURDIR)/.config; \
$(MAKE) quiet=quiet_ KBUILD_KCONFIG=$(CURDIR)/Kconfig projtree=$(CURDIR)/$(BUILDDIR) -C $(TRTL)/software/firmware -f Makefile.kconfig silentoldconfig
export KCONFIG_CONFIG=$(src)/.config; \
$(MAKE) quiet=quiet_ KBUILD_KCONFIG=$(src)/Kconfig projtree=$(BUILDDIR) -C $(TRTL_FW) -f Makefile.kconfig silentoldconfig
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:
$(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:
$(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: ;
# Explicit rule for .config
# 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,
msg_out.header->msg_id = 0;
msg_out.header->len = 0;
msg_out.header->sync_id = msg->header->sync_id;
msg_out.header->seq = app.seq++;
err = action(msg, &msg_out);
if (err)
......@@ -408,7 +407,6 @@ int trtl_fw_mq_send_uint32(enum trtl_mq_type type,
msg.header->flags = 0;
msg.header->msg_id = msg_id;
msg.header->len = n;
msg.header->seq = app.seq++;
va_start(ap, n);
for (i = 0; i < msg.header->len;++i)
......@@ -455,7 +453,6 @@ int trtl_fw_mq_send_buf(enum trtl_mq_type type,
msg.header->flags = 0;
msg.header->msg_id = msg_id;
msg.header->len = n / 4;
msg.header->seq = app.seq++;
memcpy(msg.payload, data, n);
mq_send(type, idx_mq);
......@@ -603,7 +600,6 @@ int trtl_fw_init(void)
{
int err;
app.seq = 0;
app.cfgrom = trtl_config_rom_get();
err = trtl_fw_init_action(&app);
......
......@@ -88,7 +88,6 @@ struct trtl_fw_application {
trtl_fw_action_t **actions; /**< list 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 */
/* Operations */
......
......@@ -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] slot slot number
* @return pointer to the input buffer
*
* Note: uninitialized memory
*/
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)
* @param[in] type MQ type to use
* @param[in] slot slot number
* @return pointer to the output header
*
* Note: uninitialized memory
*/
static inline void *mq_map_out_header(enum trtl_mq_type type, int slot)
{
......
HEADERS := mockturtle_cpu_csr.h
HEADERS += mockturtle_cpu_lr.h
TRTL = ../../..
TRTL ?= ../../..
TRTL_HDL = $(TRTL)/hdl/rtl/
WBGEN2 ?= wbgen2
......
......@@ -6,6 +6,8 @@
/* Host addresses. */
#define TRTL_ADDR_OFFSET_HMQ 0x00000000
#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_SHM 0x00010000
......
......@@ -179,35 +179,6 @@ enum trtl_smem_modifier {
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
*/
......@@ -225,8 +196,8 @@ struct trtl_smem_io {
*/
enum trtl_ioctl_commands {
TRTL_SMEM_IO, /**< access to shared memory */
TRTL_MSG_FILTER_ADD, /**< add a message filter */
TRTL_MSG_FILTER_CLEAN, /**< remove all filters */
TRTL_MSG_SYNC_ABORT, /**< abort sync message*/
TRTL_HMQ_SYNC_SET, /**< Mark HMQ user context as synchronous */
};
......@@ -235,19 +206,19 @@ enum trtl_ioctl_commands {
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, \
TRTL_MSG_FILTER_ADD, \
struct trtl_msg_filter)
#define TRTL_IOCTL_HMQ_SYNC_SET _IOW(TRTL_IOCTL_MAGIC, \
TRTL_HMQ_SYNC_SET, \
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, \
TRTL_MSG_FILTER_CLEAN, \
struct trtl_msg_filter)
#define TRTL_IOCTL_MSG_SYNC_ABORT _IOW(TRTL_IOCTL_MAGIC, \
TRTL_MSG_SYNC_ABORT, \
unsigned int)
/**
* Messages descriptor for host
......
......@@ -26,6 +26,8 @@ mockturtle-y += mockturtle-cpu.o
mockturtle-y += mockturtle-hmq.o
mockturtle-y += mockturtle-tty.o
mockturtle-y += mockturtle-dbg.o
mockturtle-y += mockturtle-dbg.o
mockturtle-y += mockturtle-compat.o
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 @@
#include <linux/kernel.h>
#include <linux/module.h>
#include <linux/device.h>
#include <linux/moduleparam.h>
#include <linux/idr.h>
#include <linux/init.h>
......@@ -29,6 +30,7 @@
#include <hw/mockturtle_queue.h>
#include "mockturtle-drv.h"
#include "mockturtle-compat.h"
static DEFINE_IDA(trtl_ida);
......@@ -497,7 +499,7 @@ static unsigned int trtl_max_irq_loop(struct trtl_dev *trtl)
int i, k;
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);
if (size > max)
max = size;
......@@ -529,7 +531,7 @@ int trtl_probe(struct platform_device *pdev)
platform_set_drvdata(pdev, trtl);
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)
return -EADDRNOTAVAIL;
trtl->base_csr = trtl->base_core + TRTL_ADDR_OFFSET_CSR;
......
......@@ -8,9 +8,11 @@
#include <linux/debugfs.h>
#include <linux/device.h>
#include <linux/seq_file.h>
#include <linux/mm.h>
#include <hw/mockturtle_cpu_csr.h>
#include "mockturtle-drv.h"
#include "mockturtle-compat.h"
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);
seq_printf(s, " name: %s\n",
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) {
seq_printf(s, " buf-in-r: %d (user %p)\n",
usr->idx_r, usr);
}
seq_printf(s, " buf-in-w: %d\n",
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",
hmq->buf_out.idx_r);
seq_printf(s, " buf-out-w: %d\n",
......@@ -83,6 +89,47 @@ static const struct file_operations trtl_dbg_info_ops = {
.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
......@@ -90,6 +137,8 @@ static const struct file_operations trtl_dbg_info_ops = {
*/
void trtl_debugfs_init(struct trtl_dev *trtl)
{
char name[20];
trtl->dbg_dir = debugfs_create_dir(dev_name(&trtl->dev), NULL);
if (IS_ERR_OR_NULL(trtl->dbg_dir)) {
dev_err(&trtl->dev, "Cannot create debugfs\n");
......@@ -106,6 +155,16 @@ void trtl_debugfs_init(struct trtl_dev *trtl)
PTR_ERR(trtl->dbg_info));
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)
return msg->data[1];
}
struct trtl_msg_filter_element {
struct trtl_msg_filter filter;
struct list_head list;
};
struct trtl_memory_ops {
u32 (*read)(void *addr);
void (*write)(u32 value, void *addr);
......@@ -117,6 +112,7 @@ struct mturtle_hmq_buffer {
spinlock_t lock;
unsigned int idx_w;
unsigned int idx_r;
unsigned int entries;
struct trtl_msg *msg;
struct trtl_msg msg_tmp;
unsigned int count;
......@@ -177,13 +173,22 @@ struct trtl_hmq {
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
* @list: to keep it in our local queue
* @hmq: reference to opened HMQ
* @lock: to protect filters
* @list_filters: list of filters to apply
* @n_filters: number of filters
* @lock: to protect flags, wait_id
* @idx_r: index read pointer for the message circular buffer. This is
* 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
......@@ -194,9 +199,9 @@ struct trtl_hmq_user {
struct list_head list;
struct trtl_hmq *hmq;
spinlock_t lock;
struct list_head list_filters;
unsigned int n_filters;
unsigned long flags;
unsigned int idx_r;
uint16_t wait_id;
};
......@@ -244,7 +249,8 @@ struct trtl_cpu {
* @irq_mask: IRQ mask in use
* @message_sequence: message sequence number
* @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
* @tty_driver:
* @memops:
......@@ -252,6 +258,9 @@ struct trtl_cpu {
* @dbg_info: information
* @max_irq_loop: maximum number of messages that can be retrieved with a
* 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 device dev;
......@@ -272,6 +281,8 @@ struct trtl_dev {
struct dentry *dbg_dir;
struct dentry *dbg_info;
unsigned int max_irq_loop;
uint32_t last_seq;
struct dentry *debugger;
};
static inline u32 trtl_ioread(struct trtl_dev *trtl, void *addr)
......
This diff is collapsed.
......@@ -8,7 +8,8 @@ REPO_PARENT ?= ../..
-include $(REPO_PARENT)/parent_common.mk
TRTL ?= ../
TRTL ?= ../../
TRTL_SW = $(TRTL)/software
LIBS = libmockturtle.so
LIB = libmockturtle.a
......@@ -16,7 +17,7 @@ LOBJ := libmockturtle.o
LOBJ += libmockturtle-rt-msg.o
CFLAGS += -Wall -Werror -ggdb -fPIC
CFLAGS += -I. -I$(TRTL)/include $(EXTRACFLAGS)
CFLAGS += -I. -I$(TRTL_SW)/include $(EXTRACFLAGS)
LDFLAGS = -L. -lmockturtle
ARFLAGS = rc
......
......@@ -15,6 +15,7 @@ TRTL_CONFIG_ROM_MAX_CPU = 8
TRTL_CONFIG_ROM_MAX_HMQ = 8
TRTL_CONFIG_ROM_MAX_RMQ = 8
ETRTL_MSG_SYNC_FAILED_RECV_TIMEOUT = 83638
class TrtlConfigMq(Structure):
"""
......@@ -109,6 +110,8 @@ class TrtlHmqHeader(Structure):
return False
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):
"""
......@@ -135,6 +138,9 @@ class TrtlMessage(Structure):
break
return True
def __str__(self):
return "{:s}, payload: ##".format(str(self.header))
class TrtlFirmwareVersion(Structure):
"""
......@@ -309,15 +315,6 @@ class TrtlDevice(object):
self.libtrtl.trtl_fw_variable_set.restype = c_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):
"""Generic error handler for functions returning pointers"""
if ret is None:
......@@ -555,16 +552,16 @@ class TrtlHmq(object):
:param timeout: time to wait before returning
:type timeout: int
:return: an asynchronous message
:return: an asynchronous message or None
:rtype: TrtlMessage
:raises OSError: from C library errors
"""
set_errno(0)
msg = TrtlMessage()
self.libtrtl.trtl_msg_async_recv(self.trtl_dev.tkn,
self.idx_cpu, self.idx_hmq,
pointer(msg), 1)
return msg
ret = self.libtrtl.trtl_msg_async_recv(self.trtl_dev.tkn,
self.idx_cpu, self.idx_hmq,
pointer(msg), 1)
return None if ret == 0 else msg
def sync_msg(self, msg_s, timeout=1000):
"""
......@@ -578,6 +575,7 @@ class TrtlHmq(object):
:rtype: TrtlMessage
:raises OSError: from C library errors
"""
set_errno(0)
msg_r = TrtlMessage()
self.libtrtl.trtl_msg_sync(self.trtl_dev.tkn,
self.idx_cpu, self.idx_hmq,
......
......@@ -13,7 +13,8 @@ from .PyMockTurtle import TrtlHmqHeader, TrtlMessage, TrtlConfig, \
TrtlFirmwareVariable, \
TRTL_CONFIG_ROM_MAX_CPU, \
TRTL_CONFIG_ROM_MAX_HMQ, \
TRTL_CONFIG_ROM_MAX_RMQ
TRTL_CONFIG_ROM_MAX_RMQ, \
ETRTL_MSG_SYNC_FAILED_RECV_TIMEOUT
__all__ = (
"TrtlDevice",
......@@ -29,4 +30,5 @@ __all__ = (
"TRTL_CONFIG_ROM_MAX_CPU",
"TRTL_CONFIG_ROM_MAX_HMQ",
"TRTL_CONFIG_ROM_MAX_RMQ",
"ETRTL_MSG_SYNC_FAILED_RECV_TIMEOUT",
)
......@@ -9,7 +9,7 @@ setup(name='PyMockTurtle',
author_email='federico.vaga@cern.ch',
maintainer="Federico Vaga",
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'],
license='LGPLv2',
)
......@@ -31,9 +31,8 @@ struct trtl_desc {
int fd_dev; /**< File Descriptor of the device */
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_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_dev *trtl_sync; /**< token for synchronous operations */
};
#endif
This diff is collapsed.
......@@ -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,
unsigned int idx_cpu,
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,
unsigned int idx_cpu,
unsigned int idx_hmq,
......
......@@ -7,3 +7,4 @@ mockturtle-smem
mockturtle-ping
mockturtle-variable
mockturtle-buffer
mockturtle-gdbserver
\ No newline at end of file
......@@ -8,14 +8,15 @@ REPO_PARENT ?= ../..
-include $(REPO_PARENT)/parent_common.mk
DESTDIR ?= /usr/local
TRTL ?= ../
TRTL ?= ../../
TRTL_SW = $(TRTL)/software
GIT_VERSION := $(shell git describe --dirty --long --tags)
CFLAGS += -Wall -Werror -ggdb -I$(TRTL)/lib
CFLAGS += -I$(TRTL)/include
CFLAGS += -Wall -Werror -ggdb -I$(TRTL_SW)/lib
CFLAGS += -I$(TRTL_SW)/include
CFLAGS += $(EXTRACFLAGS)
LDLIBS += -Wl,-Bstatic -L$(TRTL)/lib -lmockturtle
LDLIBS += -Wl,-Bstatic -L$(TRTL_SW)/lib -lmockturtle
LDLIBS += -Wl,-Bdynamic -lpthread
PROGS := mockturtle-count
PROGS += lsmockturtle
......@@ -26,6 +27,7 @@ PROGS += mockturtle-smem
PROGS += mockturtle-ping
PROGS += mockturtle-variable
PROGS += mockturtle-buffer
PROGS += mockturtle-gdbserver
all: $(PROGS)
......@@ -33,7 +35,7 @@ install:
install -d $(DESTDIR)/bin
install -D $(PROGS) $(DESTDIR)/bin
%: %.c $(TRTL)/libmockturtle.a
%: %.c $(TRTL_SW)/lib/libmockturtle.a
$(CC) $(CFLAGS) $^ -o $@ $(LDLIBS)
# make nothing for modules_install, but avoid errors
......
This diff is collapsed.
......@@ -7,6 +7,7 @@ DIRS += config_rom
DIRS += sim-verif
DIRS += hmq-async-recv
DIRS += hmq-async-send
DIRS += hmq-sync
DIRS += hmq-purge
DIRS += rmq-udp-send
DIRS += rt-frm
......
OBJS = config_rom.o
OBJS += # add other object files that you need
OUTPUT = fw-config-rom
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_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_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_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_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()
mq_claim(TRTL_HMQ, hmq);
hdr = mq_map_out_header(TRTL_HMQ, hmq);
memset(hdr, 0, sizeof(*hdr));
msg = mq_map_out_buffer(TRTL_HMQ, hmq);
hdr->len = n_word;
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_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_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_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_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_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_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):
def test_valid_host(self, trtl_device, cfg):
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
def test_valid_softcpu(self, trtl_cpu, cfg, firmware_file_config):
......@@ -27,5 +27,5 @@ class TestConfig(object):
msg = trtl_cpu.hmq[0].recv_msg()
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
......@@ -3,6 +3,8 @@ import PyMockTurtle
import pytest
import serial
import time
import multiprocessing
import errno
@pytest.fixture
def trtl_binary_hmq_purge(trtl_firmware_dir):
......@@ -25,6 +27,25 @@ def trtl_binary_hmq_sync(trtl_firmware_dir):
"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):
confirm = 'OK\r\n'
......@@ -98,20 +119,103 @@ class TestHmq(object):
trtl_cpu.load_application_file(trtl_binary_hmq_async_recv)
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:
tot = trtl_cpu.trtl_dev.rom.hmq[trtl_cpu.idx_cpu][hmq.idx_hmq].entries
for n in range(tot):
msg = hmq.recv_msg()
assert msg is not None
payload = list(msg.payload)
for i, val in enumerate(payload):
if i >= msg.header.len:
break
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()
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):
"""It sends the test messages on all available HMQ.
......@@ -131,8 +235,9 @@ class TestHmq(object):
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.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
for v1, v2 in zip(msg.payload, msg_r.payload):
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