Commit 82e09058 authored by Jaco Hofmann's avatar Jaco Hofmann
Browse files

Adds support for MPSoC and specifially the ZCU102 dev board

parent 571a4137
...@@ -30,6 +30,7 @@ namespace eval tapasco { ...@@ -30,6 +30,7 @@ namespace eval tapasco {
namespace export createRegisterSlice namespace export createRegisterSlice
namespace export createIntCtrl namespace export createIntCtrl
namespace export createInterconnect namespace export createInterconnect
namespace export createSmartConnect
namespace export createMIG namespace export createMIG
namespace export createOLEDController namespace export createOLEDController
namespace export createPCIeBridge namespace export createPCIeBridge
...@@ -69,10 +70,10 @@ namespace eval tapasco { ...@@ -69,10 +70,10 @@ namespace eval tapasco {
return "2017.1" return "2017.1"
} }
# Instantiates an AXI4 Interconnect IP. # Instantiates an AXI Interconnect IP.
# @param name Name of the instance. # @param name Name of the instance.
# @param no_slaves Number of AXI4 Slave interfaces. # @param no_slaves Number of AXI Slave interfaces.
# @param no_masters Number of AXI4 Master interfaces. # @param no_masters Number of AXI Master interfaces.
# @return bd_cell of the instance. # @return bd_cell of the instance.
proc createInterconnect {name no_slaves no_masters} { proc createInterconnect {name no_slaves no_masters} {
variable stdcomps variable stdcomps
...@@ -93,6 +94,23 @@ namespace eval tapasco { ...@@ -93,6 +94,23 @@ namespace eval tapasco {
return $ic return $ic
} }
# Instantiates an AXI4 SmartConnect IP.
# @param name Name of the instance.
# @param no_slaves Number of AXI4 Slave interfaces.
# @param no_masters Number of AXI4 Master interfaces.
# @param reset If 1 a dedicated reset port is added to the block.
# @return bd_cell of the instance.
proc createSmartConnect {name no_slaves no_masters {reset 0}} {
variable stdcomps
puts "Creating AXI SmartConnect $name with $no_slaves slaves and $no_masters masters..."
puts " VLNV: [dict get $stdcomps axi_ic vlnv]"
set ic [create_bd_cell -type ip -vlnv [dict get $stdcomps axi_sc vlnv] $name]
set props [list CONFIG.NUM_SI $no_slaves CONFIG.NUM_MI $no_masters CONFIG.HAS_ARESETN $reset]
set_property -dict $props $ic
return $ic
}
# Instantiates a Zynq-7000 Processing System IP core. # Instantiates a Zynq-7000 Processing System IP core.
# @param name Name of the instance (default: ps7). # @param name Name of the instance (default: ps7).
# @param preset Name of board preset to apply (default: tapasco::get_board_preset). # @param preset Name of board preset to apply (default: tapasco::get_board_preset).
...@@ -115,6 +133,24 @@ namespace eval tapasco { ...@@ -115,6 +133,24 @@ namespace eval tapasco {
return $ps return $ps
} }
# Instantiates a Zynq Ultra Scale MPSoC Processing System IP core.
# @param name Name of the instance (default: ps7).
# @param preset Name of board preset to apply (default: tapasco::get_board_preset).
# @param freq_mhz FCLK_0 frequency in MHz (default: tapasco::get_design_frequency).
# @return bd_cell of the instance.
proc createMPSoCPS {{name mpsoc} {preset [tapasco::get_board_preset]} {freq_mhz [tapasco::get_design_frequency]}} {
variable stdcomps
puts "Creating Zynq-Ultra Scale series IP core ..."
puts " VLNV: [dict get $stdcomps psmpsoc vlnv]"
puts " Preset: $preset"
puts " PL0 : $freq_mhz"
set ps [create_bd_cell -type ip -vlnv [dict get $stdcomps psmpsoc vlnv] $name]
apply_bd_automation -rule xilinx.com:bd_rule:zynq_ultra_ps_e -config {apply_board_preset "1" Master "Disable" Slave "Disable" } $ps
set_property -dict [list CONFIG.PSU__CRL_APB__PL0_REF_CTRL__FREQMHZ $freq_mhz] $ps
return $ps
}
# Instantiates a Zynq-7000 Processing System IP BFM simulation core. # Instantiates a Zynq-7000 Processing System IP BFM simulation core.
# @param name Name of the instance (default: ps7). # @param name Name of the instance (default: ps7).
# @param preset Name of board preset to apply (default: tapasco::get_board_preset). # @param preset Name of board preset to apply (default: tapasco::get_board_preset).
...@@ -787,7 +823,7 @@ namespace eval tapasco { ...@@ -787,7 +823,7 @@ namespace eval tapasco {
# @param freqs list of name frequency (MHz) pairs, e.g., [list design 100 memory 250] # @param freqs list of name frequency (MHz) pairs, e.g., [list design 100 memory 250]
# @param name Name of the subsystem group # @param name Name of the subsystem group
# @return Subsystem group # @return Subsystem group
proc create_subsystem_clocks_and_resets {{freqs {}} {name ClockResets}} { proc create_subsystem_clocks_and_resets {{freqs {}} {name ClockResets} {sys_clock_name sys_diff_clock}} {
if {$freqs == {}} { set freqs [get_frequencies] } if {$freqs == {}} { set freqs [get_frequencies] }
puts "Creating clock and reset subsystem ..." puts "Creating clock and reset subsystem ..."
puts " frequencies: $freqs" puts " frequencies: $freqs"
...@@ -798,10 +834,10 @@ namespace eval tapasco { ...@@ -798,10 +834,10 @@ namespace eval tapasco {
set reset_in [create_bd_pin -dir I -type rst "reset_in"] set reset_in [create_bd_pin -dir I -type rst "reset_in"]
set clk [createClockingWizard "clk_wiz"] set clk [createClockingWizard "clk_wiz"]
set_property -dict [list CONFIG.USE_LOCKED {false} CONFIG.USE_RESET {false} CONFIG.NUM_OUT_CLKS [expr "[llength $freqs] / 2"]] $clk set_property -dict [list CONFIG.USE_LOCKED {false} CONFIG.USE_RESET {false} CONFIG.NUM_OUT_CLKS [expr "[llength $freqs] / 2"]] $clk
set clk_mode "sys_diff_clock" set clk_mode "$sys_clock_name"
if {[catch {set_property CONFIG.CLK_IN1_BOARD_INTERFACE {sys_diff_clock} $clk}]} { if {[catch {set_property CONFIG.CLK_IN1_BOARD_INTERFACE $sys_clock_name $clk}]} {
puts " sys_diff_clock is not supported, trying sys_clock instead" puts " $sys_clock_name is not supported, trying sys_clock instead"
set clk_mode "sys_clock" set clk_mode "sys_clock"
} }
# check if external port already exists, re-use # check if external port already exists, re-use
...@@ -812,7 +848,7 @@ namespace eval tapasco { ...@@ -812,7 +848,7 @@ namespace eval tapasco {
set_property -dict [list CONFIG.PRIMITIVE {PLL} CONFIG.USE_MIN_POWER {true}] $clk set_property -dict [list CONFIG.PRIMITIVE {PLL} CONFIG.USE_MIN_POWER {true}] $clk
} { } {
# apply board automation to create top-level port # apply board automation to create top-level port
if {$clk_mode == "sys_diff_clock"} { if {$clk_mode == "$sys_clock_name"} {
set cport [get_bd_intf_pins -of_objects $clk] set cport [get_bd_intf_pins -of_objects $clk]
} { } {
set cport [get_bd_pins -filter {DIR == I} -of_objects $clk] set cport [get_bd_pins -filter {DIR == I} -of_objects $clk]
......
# create a dictionary of compatible VLNVs # create a dictionary of compatible VLNVs
dict set stdcomps axi_ic vlnv "xilinx.com:ip:axi_interconnect:2.1" dict set stdcomps axi_ic vlnv "xilinx.com:ip:axi_interconnect:2.1"
dict set stdcomps axi_sc vlnv "xilinx.com:ip:smartconnect:1.0"
dict set stdcomps ps vlnv "xilinx.com:ip:processing_system7:5.5" dict set stdcomps ps vlnv "xilinx.com:ip:processing_system7:5.5"
dict set stdcomps psmpsoc vlnv "xilinx.com:ip:zynq_ultra_ps_e:3.0"
dict set stdcomps ps_bfm vlnv "xilinx.com:ip:processing_system7_bfm:2.0" dict set stdcomps ps_bfm vlnv "xilinx.com:ip:processing_system7_bfm:2.0"
dict set stdcomps axi_irqc vlnv "xilinx.com:ip:axi_intc:4.1" dict set stdcomps axi_irqc vlnv "xilinx.com:ip:axi_intc:4.1"
dict set stdcomps axi_cache vlnv "xilinx.com:ip:system_cache:3.0" dict set stdcomps axi_cache vlnv "xilinx.com:ip:system_cache:3.0"
......
...@@ -18,10 +18,10 @@ ...@@ -18,10 +18,10 @@
# along with Tapasco. If not, see <http://www.gnu.org/licenses/>. # along with Tapasco. If not, see <http://www.gnu.org/licenses/>.
# #
# @file hls_patch_supported_families.sh # @file hls_patch_supported_families.sh
# @brief Patches the run_ippack.tcl generated by Vivado HLS to include # @brief Patches the run_ippack.tcl generated by Vivado HLS to include
# all Zynq, Virtex7, Artix7 and Kintex7 FPGAs in the supported # all Zynq, Virtex7, Artix7 and Kintex7 FPGAs in the supported
# device families for the IP cores. # device families for the IP cores.
# @authors J. Korinth (jk@esa.cs.tu-darmstadt.de # @authors J. Korinth (jk@esa.cs.tu-darmstadt.de
# #
sed -i 's/set_property supported_families .*$/set_property supported_families [list zynq Pre-Production virtex7 Pre-Production kintex7 Pre-Production artix7 Pre-Production] $core/g' run_ippack.tcl sed -i 's/set_property supported_families .*$/set_property supported_families [list zynq Pre-Production virtex7 Pre-Production kintex7 Pre-Production artix7 Pre-Production zynquplus Pre-Production] $core/g' run_ippack.tcl
sed -i 's/\(set DisplayName.*\)$/\1\nset IPName $DisplayName/g' run_ippack.tcl sed -i 's/\(set DisplayName.*\)$/\1\nset IPName $DisplayName/g' run_ippack.tcl
cmake_minimum_required(VERSION 2.6)
project(platform-zynq)
set(CMAKE_INSTALL_PREFIX "..")
set(CMAKE_SKIP_RPATH true)
if (NOT EXISTS "$ENV{TAPASCO_HOME}")
message(FATAL_ERROR "Please set TAPASCO_HOME environment variable to root directory of Tapasco")
endif (NOT EXISTS "$ENV{TAPASCO_HOME}")
include ("$ENV{TAPASCO_HOME}/cmake/Tapasco.cmake")
set(SRCDIR "src")
set(CMNDIR "../common")
set(GCMNDIR "${TAPASCO_HOME}/common")
set(COMPFLAGS "-Wall -Werror -g -O3 -std=gnu11")
set(CMNSRCS "${CMNDIR}/src/platform_logging.c"
"${CMNDIR}/src/platform_errors.c"
"${SRCDIR}/platform_address_map.c"
"${CMNDIR}/src/platform_version.c"
"${GCMNDIR}/src/gen_queue.c")
set(SRCS "${SRCDIR}/platform_zynq.c")
set(PLATFORM_LIBS_DIR "${TAPASCO_HOME}/platform/lib")
include_directories("." "include" "${CMNDIR}/include" "${GCMNDIR}/include")
set_source_files_properties(${CMNSRCS} ${SRCS} PROPERTIES COMPILE_FLAGS ${COMPFLAGS})
add_library(platform SHARED ${CMNSRCS} ${SRCS})
add_library(platform-static STATIC ${CMNSRCS} ${SRCS})
set_target_properties(platform-static PROPERTIES OUTPUT_NAME platform)
set_target_properties(platform PROPERTIES COMPILE_FLAGS ${COMPFLAGS})
set_target_properties(platform-static PROPERTIES COMPILE_FLAGS ${COMPFLAGS})
if ("armv71" STREQUAL ${TAPASCO_TARGET})
target_link_libraries(platform atomic)
target_link_libraries(platform-static atomic)
endif ()
install(TARGETS platform platform-static
LIBRARY DESTINATION "lib/${TAPASCO_TARGET}"
ARCHIVE DESTINATION "lib/${TAPASCO_TARGET}/static")
get_filename_component(LIBSDIR "lib" REALPATH)
add_custom_command(OUTPUT ${PLATFORM_LIBS_DIR}
COMMAND ln;-fs;${LIBSDIR};${PLATFORM_LIBS_DIR})
add_custom_target(install_libs ALL DEPENDS platform platform-static ${PLATFORM_LIBS_DIR})
#!/usr/bin/python
import sys
import subprocess
clean = len(sys.argv) > 1 and sys.argv[1] == "clean"
debug = len(sys.argv) > 1 and (sys.argv[1] == "debug" or sys.argv[1] == "driver_debug")
driver_debug = len(sys.argv) > 1 and sys.argv[1] == "driver_debug"
moddir = "$TAPASCO_HOME/platform/zynq/module"
pdir = "$TAPASCO_HOME/platform/zynq/build"
adir = "$TAPASCO_HOME/arch/axi4mm/build"
if clean:
subprocess.call(["rm -rf " + pdir], shell=True)
subprocess.call(["rm -rf " + adir], shell=True)
subprocess.call(["cd " + moddir + " && make clean"], shell=True)
else:
if debug:
print("Building debug mode libraries...")
else:
print("Building release mode libraries, pass 'debug' as first argument to build debug libs...")
subprocess.call(["cd " + moddir + " && make " + ("" if driver_debug else "release ")], shell=True)
subprocess.call(["mkdir -p " + pdir + " && cd " + pdir + " && cmake " + ("" if debug else "-DCMAKE_BUILD_TYPE=Release") + " .. && make && make install"], shell=True)
subprocess.call(["mkdir -p " + adir + " && cd " + adir + " && cmake " + ("" if debug else "-DCMAKE_BUILD_TYPE=Release") + " .. && make && make install"], shell=True)
KERNEL=="tapasco_platform*" OWNER="tapasco" GROUP="tapasco"
KERNEL=="tapasco_platform*" RUN+="/bin/chown tapasco:tapasco /sys/class/misc/tapasco_platform_zynq_tapasco_status/pending_ev" RUN+="/bin/chown tapasco:tapasco /sys/class/misc/tapasco_platform_zynq_tapasco_status/total_ev" RUN+="/bin/chown tapasco:tapasco /sys/class/misc/tapasco_platform_zynq_tapasco_status/wait"
SUBSYSTEM=="tapasco_memory" OWNER="tapasco" GROUP="tapasco"
LINUX_HOME ?= /lib/modules/$(shell uname -r)/build
ifeq ($(ARCH), arm)
CROSS_COMPILE ?= arm-unknown-linux-gnueabihf-
endif
obj-m += tapasco-platform-zynq.o
tapasco-platform-zynq-objs := zynq_module.o zynq_device.o zynq_dmamgmt.o zynq_irq.o zynq_ioctl.o
.PHONY: all clean
all:
make -C $(LINUX_HOME) M=$(PWD) modules
release:
KCPPFLAGS="-DNDEBUG -O3" make -C $(LINUX_HOME) M=$(PWD) modules
clean:
make -C $(LINUX_HOME) M=$(PWD) clean
rm -rf test-alloc-dealloc
#!/bin/bash
#
# Copyright (C) 2014 Jens Korinth, TU Darmstadt
#
# This file is part of Tapasco (TPC).
#
# Tapasco is free software: you can redistribute it and/or modify
# it under the terms of the GNU Lesser General Public License as published by
# the Free Software Foundation, either version 3 of the License, or
# (at your option) any later version.
#
# Tapasco is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU Lesser General Public License for more details.
#
# You should have received a copy of the GNU Lesser General Public License
# along with Tapasco. If not, see <http://www.gnu.org/licenses/>.
#
show_usage() {
cat << EOF
Usage: ${0##*/} [-v|--verbose] [--d|--drv-reload] BITSTREAM
Program FPGA via /dev/xdevcfg.
-v enable verbose output
-d reload device driver
EOF
}
# init vars
BITSTREAM=""
VERBOSE=0
RELOADD=1
OPTIND=1
while getopts vd opt; do
case $opt in
v)
VERBOSE=1
;;
d)
RELOADD=1
;;
*)
echo "unknown option: $opt"
show_usage
exit 1
;;
esac
done
shift "$((OPTIND-1))"
BITSTREAM="$1"
if [ -n $BITSTREAM ] && [[ $BITSTREAM == *.bit ]] && [[ -e $BITSTREAM ]]
then
pushd $TAPASCO_HOME/platform/zynq/module &> /dev/null
if [[ `lsmod | grep tapasco | wc -l` -eq 1 ]]; then
sudo ./unload.sh
fi
popd &> /dev/null
echo "Loading bitstream $BITSTREAM ..."
sudo sh -c "cat $BITSTREAM > /dev/xdevcfg"
echo "Done!"
pushd $TAPASCO_HOME/platform/zynq/module &> /dev/null
echo "Loading kernel module ..."
sudo ./load.sh
popd &> /dev/null
echo "Done."
else
show_usage
exit 1
fi
//
// Copyright (C) 2014 Jens Korinth, TU Darmstadt
//
// This file is part of Tapasco (TPC).
//
// Tapasco is free software: you can redistribute it and/or modify
// it under the terms of the GNU Lesser General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
//
// Tapasco is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU Lesser General Public License for more details.
//
// You should have received a copy of the GNU Lesser General Public License
// along with Tapasco. If not, see <http://www.gnu.org/licenses/>.
//
/*
This file is part of gen_fixed_size_pool.
(C) Copyright 2015 Jens Korinth
gen_fixed_size_pool is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
gen_fixed_size_pool is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with gen_fixed_size_pool. If not, see <http://www.gnu.org/licenses/>.
*/
//! @file gen_stack.h
//! @brief Generic, header-only, lock-free implementation of a fixed size
//! pool of things based on statically allocated array.
//! @authors J. Korinth, TU Darmstadt (jk@esa.cs.tu-darmstadt.de)
//!
#ifndef __GEN_FIXED_SIZE_POOL_H__
#define __GEN_FIXED_SIZE_POOL_H__
#ifdef USE_ASSERTIONS
#ifndef __cplusplus
#include <assert.h>
#else
#include <cassert>
#endif
#else /* !USE_ASSERTIONS */
#define assert(...)
#endif
/** Index type: external id of pool element. */
typedef uint32_t fsp_idx_t;
#define INVALID_IDX ((fsp_idx_t)(-1))
// define a pool: PRE = prefix, SZ = size, T = type, IF = initializer function
#define MAKE_FIXED_SIZE_POOL(PRE, SZ, T, IF) \
struct PRE##_fsp_t { \
T elems[SZ]; \
int locked[SZ]; \
int refcnt[SZ]; \
fsp_idx_t curr; \
}; \
\
static inline void PRE##_fsp_init(struct PRE##_fsp_t *fsp) \
{ \
int i; \
memset(fsp, 0, sizeof(*fsp)); \
for (i = 0; i < SZ; ++i) { \
__atomic_clear(&fsp->locked[i], __ATOMIC_SEQ_CST); \
IF(&fsp->elems[i], i); \
} \
} \
\
static inline fsp_idx_t PRE##_fsp_get(struct PRE##_fsp_t *fsp) \
{ \
fsp_idx_t ret; \
do { ret = __atomic_fetch_add(&fsp->curr, 1, __ATOMIC_SEQ_CST); } \
while (ret < SZ && __atomic_test_and_set(&fsp->locked[ret], __ATOMIC_SEQ_CST)); \
if (ret < SZ) { \
assert(__atomic_add_fetch(&fsp->refcnt[ret], 1, __ATOMIC_SEQ_CST) < 2); \
return ret; \
} \
return INVALID_IDX; \
} \
\
static inline void PRE##_fsp_put(struct PRE##_fsp_t *fsp, fsp_idx_t const idx) \
{ \
if (idx < SZ) { \
fsp_idx_t old; \
__atomic_sub_fetch(&fsp->refcnt[idx], 1, __ATOMIC_SEQ_CST); \
__atomic_clear(&fsp->locked[idx], __ATOMIC_SEQ_CST); \
do { old = fsp->curr; } \
while (idx < old && ! __atomic_compare_exchange(&fsp->curr, &old, \
&idx, 0, __ATOMIC_SEQ_CST, __ATOMIC_SEQ_CST)); \
} \
} \
#endif /* __GEN_FIXED_SIZE_POOL_H__ */
#!/bin/bash
#
# Copyright (C) 2014 Jens Korinth, TU Darmstadt
#
# This file is part of Tapasco (TPC).
#
# Tapasco is free software: you can redistribute it and/or modify
# it under the terms of the GNU Lesser General Public License as published by
# the Free Software Foundation, either version 3 of the License, or
# (at your option) any later version.
#
# Tapasco is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU Lesser General Public License for more details.
#
# You should have received a copy of the GNU Lesser General Public License
# along with Tapasco. If not, see <http://www.gnu.org/licenses/>.
#
# Helper script to load zynq TPC Platform device driver.
# Must be run as superuser.
# insmod tapasco-platform-zynq.ko logging_level=132
# insmod tapasco-platform-zynq.ko logging_level=0x7fffffff
insmod tapasco-platform-zynq.ko
//
// Copyright (C) 2014 Jens Korinth, TU Darmstadt
//
// This file is part of Tapasco (TPC).
//
// Tapasco is free software: you can redistribute it and/or modify
// it under the terms of the GNU Lesser General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
//
// Tapasco is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU Lesser General Public License for more details.
//
// You should have received a copy of the GNU Lesser General Public License
// along with Tapasco. If not, see <http://www.gnu.org/licenses/>.
//
//! @file logging.h
//! @brief Kernel logging helper functions:
//! Declares module parameter 'logging_level' which determines the
//! amount of printk output; errors are signaled using level 0 and
//! are always output, warnings are level 1, the other levels are
//! bitfield indicators and can be defined by the user.
//! @authors J. Korinth, TU Darmstadt (jk@esa.cs.tu-darmstadt.de)
//!
#ifndef __TAPASCO_PLATFORM_LOGGING_H__
#define __TAPASCO_PLATFORM_LOGGING_H__
#include <linux/printk.h>
#ifdef LOGGING_MODULE_INCLUDE
unsigned int logging_level = 0x7fffffff;
module_param(logging_level, uint, S_IRUGO|S_IWUSR|S_IWGRP);
#else
extern int logging_level;
#endif
#ifndef NDEBUG
#define ERR(msg, ...) tapasco_platform_log(0, msg, ##__VA_ARGS__)
#define WRN(msg, ...) tapasco_platform_log(1, msg, ##__VA_ARGS__)
#define LOG(l, msg, ...) tapasco_platform_log((l), msg, ##__VA_ARGS__)
#define tapasco_platform_log(level, fmt, ...) do { \
switch ((int)level) { \
case 0: \
printk(KERN_ERR "tapasco-platform-zynq: [%s] " \
fmt "\n", __func__, \
##__VA_ARGS__); \
break; \
case 1: \
printk(KERN_WARNING "tapasco-platform-zynq: [%s] " \
fmt "\n", __func__, \
##__VA_ARGS__); \
break; \
default: \
if (logging_level & level) \
printk(KERN_NOTICE "tapasco_platform_zynq: [%s] " \
fmt "\n", __func__, \
##__VA_ARGS__); \
break; \
} \
} while(0)
#else
/* only errors and warnings, no other messages */
#define ERR(fmt, ...) printk(KERN_ERR "tapasco-platform-zynq: [%s] " \
fmt "\n", __func__, \
##__VA_ARGS__)
#define WRN(fmt, ...) printk(KERN_WARNING "tapasco-platform-zynq: [%s] " \
fmt "\n", __func__, \
##__VA_ARGS__)
#define LOG(l, msg, ...)
#define tapasco_platform_log(level, fmt, ...)
#endif
#endif /* __TAPASCO_PLATFORM_LOGGING_H__ */
cmake_minimum_required(VERSION 2.7)
project(platform-zynq-module-tests)
include_directories("..")
find_library(NCURSESLIB ncurses)
add_executable(stress-alloc stress-alloc.c)
target_link_libraries(stress-alloc pthread m)
add_executable(stress-ioctl stress-ioctl.c)
target_link_libraries(stress-ioctl pthread ncurses)
//
// Copyright (C) 2014 Jens Korinth, TU Darmstadt
//
// This file is part of Tapasco (TPC).
//
// Tapasco is free software: you can redistribute it and/or modify
// it under the terms of the GNU Lesser General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
//
// Tapasco is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU Lesser General Public License for more details.
//
// You should have received a copy of the GNU Lesser General Public License
// along with Tapasco. If not, see <http://www.gnu.org/licenses/>.
//
#include <fcntl.h>
#include <unistd.h>
#include <stdlib.h>
#include <stdio.h>
#include <errno.h>
#include <string.h>
#include <time.h>
#include <math.h>
#include <pthread.h>
#define UPPER_BND (25)
static char const *const fn[] = {
"/sys/class/misc/tapasco_platform_zynq_gp0/alloc",
"/sys/class/misc/tapasco_platform_zynq_gp0/dealloc",
"/sys/class/misc/tapasco_platform_zynq_gp0/bufferid",
};
static int fd[sizeof(fn) / sizeof(*fn)] = { -1 };
static int stop = 0;
void *stress(void *p)
{
ssize_t res, dma;
unsigned long runs = (unsigned long)p;
printf("Starting %lu runs ...\n", runs);
while (runs && ! stop) {
size_t const sz = pow(2, (rand() % UPPER_BND));
dma = write(fd[0], &sz, sizeof(sz));
if (dma < 0) {
stop = 1;
fprintf(stderr, "error during allocation of size 0x%zu byte: %s\n",
sz, strerror(errno));
return NULL;
}
usleep(rand() % 1000);
res = write(fd[2], &res, sizeof(res));
if (res < 0) {
stop = 1;
fprintf(stderr, "could not find buffer for address 0x%08lx: %s\n",
sz, (unsigned long)dma, strerror(errno));
return NULL;
}
usleep(rand() % 1000);