diff options
-rw-r--r-- | .bzrignore | 9 | ||||
-rw-r--r-- | CMakeLists.txt | 121 | ||||
-rw-r--r-- | dma/ipe.c | 2 | ||||
-rw-r--r-- | dma/nwl_engine.c | 4 | ||||
-rw-r--r-- | dma/nwl_engine_buffers.h | 8 | ||||
-rw-r--r-- | docs/BUGS | 5 | ||||
-rw-r--r-- | driver/makefile (renamed from driver/Makefile) | 17 | ||||
-rw-r--r-- | misc/dkms.conf.in | 10 | ||||
-rw-r--r-- | misc/pcilib.in | 9 | ||||
-rw-r--r-- | misc/pcilib.sysconfig.in | 12 | ||||
-rw-r--r-- | misc/pcilib_api.service.in | 2 | ||||
-rw-r--r-- | misc/pcilib_html.service.in | 2 | ||||
-rw-r--r-- | misc/rpmlintrc | 8 | ||||
-rw-r--r-- | pcilib/kmem.c | 6 | ||||
-rw-r--r-- | pcilib/kmem.h | 6 | ||||
-rw-r--r-- | pcilib/locking.c | 6 | ||||
-rw-r--r-- | pcilib/py.c | 211 | ||||
-rw-r--r-- | pcitool.spec.in | 204 | ||||
-rw-r--r-- | pcitool/cli.c | 4 | ||||
-rw-r--r-- | protocols/software.c | 6 | ||||
-rw-r--r-- | pywrap/CMakeLists.txt | 1 | ||||
-rwxr-xr-x | tests/reload.sh | 21 |
22 files changed, 490 insertions, 184 deletions
@@ -37,3 +37,12 @@ build pcipywrap.py pcipywrapPYTHON_wrap.c apps/test_multithread +pcitool.spec +misc/dkms.conf +CPackConfig.cmake +CPackSourceConfig.cmake +_CPack_Packages +pcilib_api.service +pcilib_html.service +pcilib.conf +pcilib.sysconfig diff --git a/CMakeLists.txt b/CMakeLists.txt index 8b5e9ca..3db7ca9 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -1,5 +1,6 @@ -project(pcitool) +project(pcitool C) +set(RELEASE "0") set(PCILIB_VERSION "0.2.7") set(PCILIB_ABI_VERSION "2") @@ -9,15 +10,24 @@ cmake_minimum_required(VERSION 2.8) set(DISABLE_PCITOOL FALSE CACHE BOOL "Build only the library") set(DISABLE_PYTHON FALSE CACHE BOOL "Disable python scripting support") +set(DISABLE_SERVERS FALSE CACHE BOOL "Disable Web API support") #list(APPEND CMAKE_MODULE_PATH "${CMAKE_SOURCE_DIR}/cmake") +if(NOT DEFINED LIB_SUFFIX) + if (CMAKE_SIZEOF_VOID_P EQUAL 8) + set(LIB_SUFFIX "64") + else (CMAKE_SIZEOF_VOID_P EQUAL 8) + set(LIB_SUFFIX "") + endif (CMAKE_SIZEOF_VOID_P EQUAL 8) +endif(NOT DEFINED LIB_SUFFIX) + if(NOT DEFINED BIN_INSTALL_DIR) set(BIN_INSTALL_DIR "${CMAKE_INSTALL_PREFIX}/bin") endif(NOT DEFINED BIN_INSTALL_DIR) if(NOT DEFINED LIB_INSTALL_DIR) - set(LIB_INSTALL_DIR "${CMAKE_INSTALL_PREFIX}/lib") + set(LIB_INSTALL_DIR "${CMAKE_INSTALL_PREFIX}/lib${LIB_SUFFIX}") endif(NOT DEFINED LIB_INSTALL_DIR) if(NOT DEFINED INCLUDE_INSTALL_DIR) @@ -32,11 +42,35 @@ if(NOT DEFINED LOCALE_INSTALL_DIR) set(LOCALE_INSTALL_DIR "${DATA_INSTALL_DIR}/locale") endif(NOT DEFINED LOCALE_INSTALL_DIR) +if (NOT DEFINED PCILIB_PLUGIN_DIR) + set(PCILIB_PLUGIN_DIR "${LIB_INSTALL_DIR}/pcilib" CACHE PATH "Directory to install plugins") +endif (NOT DEFINED PCILIB_PLUGIN_DIR) + +if (NOT DEFINED PCILIB_DATA_DIR) + set(PCILIB_DATA_DIR "${DATA_INSTALL_DIR}/pcilib" CACHE PATH "Directory to install data files") +endif (NOT DEFINED PCILIB_DATA_DIR) + +if (NOT DEFINED PCILIB_MODEL_DIR) + set(PCILIB_MODEL_DIR "${PCILIB_DATA_DIR}/models" CACHE PATH "Directory to install XML models") +endif (NOT DEFINED PCILIB_MODEL_DIR) + +if (NOT DEFINED PCILIB_SERVER_DIR) + set(PCILIB_SERVER_DIR "${PCILIB_DATA_DIR}/pyserver" CACHE PATH "Directory to install python server") +endif (NOT DEFINED PCILIB_SERVER_DIR) + +if (NOT DEFINED PCILIB_DOC_DIR) + set(PCILIB_DOC_DIR "${CMAKE_CURRENT_BINARY_DIR}/docs/" CACHE PATH "Directory to install documentation") +endif (NOT DEFINED PCILIB_DOC_DIR) + +if (NOT DEFINED PCILIB_DEBUG_DIR) + set(PCILIB_DEBUG_DIR "." CACHE PATH "Directory to write debug information") +endif (NOT DEFINED PCILIB_DEBUG_DIR) SET(ENV{PKG_CONFIG_PATH} "${LIB_INSTALL_DIR}/pkgconfig:$ENV{PKG_CONFIG_PATH}") find_package(PkgConfig REQUIRED) find_package(Threads REQUIRED) +find_package(Doxygen) if (NOT DISABLE_PYTHON) set(PYTHON_VERSION 2.7 CACHE STRING "python version") @@ -51,19 +85,26 @@ if (NOT DISABLE_PYTHON) # execute_process (COMMAND ${PYTHON_EXECUTABLE} -c "from sysconfig import get_path; print get_path('platlib')" OUTPUT_VARIABLE PYTHON_INSTALL_DIR OUTPUT_STRIP_TRAILING_WHITESPACE) - execute_process (COMMAND ${PYTHON_EXECUTABLE} -c "import site; print (site.PREFIXES[-1])" OUTPUT_VARIABLE PYTHON_PREFIX OUTPUT_STRIP_TRAILING_WHITESPACE) - file (TO_CMAKE_PATH "${PYTHON_PREFIX}" PYTHON_PREFIX) - execute_process (COMMAND ${PYTHON_EXECUTABLE} -c "import site; print (site.getsitepackages()[0])" OUTPUT_VARIABLE PYTHON_SITE_DIR OUTPUT_STRIP_TRAILING_WHITESPACE) - file (TO_CMAKE_PATH "${PYTHON_SITE_DIR}" PYTHON_SITE_DIR) + if (NOT DEFINED PYTHON_INSTALL_DIR) + execute_process (COMMAND ${PYTHON_EXECUTABLE} -c "import site; print (site.PREFIXES[-1])" OUTPUT_VARIABLE PYTHON_PREFIX OUTPUT_STRIP_TRAILING_WHITESPACE) + file (TO_CMAKE_PATH "${PYTHON_PREFIX}" PYTHON_PREFIX) + execute_process (COMMAND ${PYTHON_EXECUTABLE} -c "import site; print (site.getsitepackages()[0])" OUTPUT_VARIABLE PYTHON_SITE_DIR OUTPUT_STRIP_TRAILING_WHITESPACE) + file (TO_CMAKE_PATH "${PYTHON_SITE_DIR}" PYTHON_SITE_DIR) - string (REGEX REPLACE "^${PYTHON_PREFIX}/" "${CMAKE_INSTALL_PREFIX}/" PYTHON_SITE_DIR "${PYTHON_SITE_DIR}") - set(PYTHON_INSTALL_DIR ${PYTHON_SITE_DIR} CACHE PATH "path to install python module") + string (REGEX REPLACE "^${PYTHON_PREFIX}/" "${CMAKE_INSTALL_PREFIX}/" PYTHON_SITE_DIR "${PYTHON_SITE_DIR}") + set(PYTHON_INSTALL_DIR ${PYTHON_SITE_DIR} CACHE PATH "path to install python module") + endif (NOT DEFINED PYTHON_INSTALL_DIR) set(HAVE_PYTHON TRUE) endif (NOT DISABLE_PYTHON) +if (NOT HAVE_PYTHON) + set(DISABLE_SERVERS TRUE) +endif (NOT HAVE_PYTHON) + set(EXTRA_SYSTEM_LIBS -lrt) +include(CheckIncludeFiles) check_include_files(stdatomic.h HAVE_STDATOMIC_H) find_path(UTHASH_INCLUDE_DIRS uthash.h PATH_SUFFIXES uthash) @@ -94,7 +135,6 @@ add_custom_command(TARGET build ) set_source_files_properties(${CMAKE_BINARY_DIR}/pcilib/build.h PROPERTIES GENERATED TRUE) - set(TARNAME "pcitool") set(PACKAGE_VERSION ${PCILIB_VERSION}) set(PACKAGE_NAME "${TARNAME}") @@ -102,12 +142,20 @@ set(PACKAGE_TARNAME "${TARNAME}") set(PACKAGE_STRING "${PACKAGE_NAME} ${PACKAGE_VERSION}") set(PACKAGE_BUGREPORT "http://ufo.kit.edu/ufo/newticket") -set(PCILIB_PLUGIN_DIR "${LIB_INSTALL_DIR}/pcilib" CACHE PATH "Directory to install plugins") -set(PCILIB_DATA_DIR "${DATA_INSTALL_DIR}/pcilib" CACHE PATH "Directory to install data files") -set(PCILIB_PY_SERVER_INSTALL_DIR "${PCILIB_DATA_DIR}/pyserver" CACHE PATH "Directory to install python server") -set(PCILIB_MODEL_DIR "${PCILIB_DATA_DIR}/models" CACHE PATH "Directory to install XML models") -set(PCILIB_DOC_DIR "${CMAKE_CURRENT_BINARY_DIR}/docs/" CACHE PATH "Directory to install documentation") -set(PCILIB_DEBUG_DIR "." CACHE PATH "Directory to write debug information") +set(CPACK_SOURCE_GENERATOR "TBZ2") +set(CPACK_PACKAGE_CONTACT "Suren A. Chilingaryan <csa@suren.me>") +if (${RELEASE} GREATER 0) + set(CPACK_PACKAGE_VERSION "${PACKAGE_VERSION}.${RELEASE}") +else (${RELEASE} GREATER 0) + set(CPACK_PACKAGE_VERSION "${PACKAGE_VERSION}") +endif (${RELEASE} GREATER 0) +set(CPACK_SOURCE_IGNORE_FILES "/.bzr/;CMakeFiles;_CPack_Packages;cmake_install.cmake;CPack.*.cmake;CMakeCache.txt;install_manifest.txt;config.h$;.pc$;Makefile;.tar.bz2$;~$;${CPACK_SOURCE_IGNORE_FILES}") +set(CPACK_SOURCE_PACKAGE_FILE_NAME "${CMAKE_PROJECT_NAME}-${CPACK_PACKAGE_VERSION}") +include(CPack) + +add_custom_target(dist_clean COMMAND ${CMAKE_MAKE_PROGRAM} clean WORKING_DIRECTORY ${CMAKE_CURRENT_DIR}) +add_custom_target(dist DEPENDS dist_clean COMMAND ${CMAKE_MAKE_PROGRAM} package_source) + add_subdirectory(dma) add_subdirectory(protocols) @@ -126,18 +174,25 @@ set_target_properties(pcilib PROPERTIES SOVERSION ${PCILIB_ABI_VERSION} ) +add_custom_target(docs + COMMAND ${DOXYGEN_EXECUTABLE} ${CMAKE_CURRENT_BINARY_DIR}/docs/Doxyfile + WORKING_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR}/docs + COMMENT "Generating API documentation with Doxygen" VERBATIM +) +set_directory_properties(PROPERTIES ADDITIONAL_MAKE_CLEAN_FILES "docs/html") + + +configure_file(${CMAKE_CURRENT_SOURCE_DIR}/pcitool.spec.in ${CMAKE_CURRENT_BINARY_DIR}/pcitool.spec) +configure_file(${CMAKE_CURRENT_SOURCE_DIR}/misc/dkms.conf.in ${CMAKE_CURRENT_BINARY_DIR}/misc/dkms.conf) configure_file(${CMAKE_CURRENT_SOURCE_DIR}/misc/pcitool.pc.in ${CMAKE_CURRENT_BINARY_DIR}/misc/pcitool.pc) configure_file(${CMAKE_CURRENT_SOURCE_DIR}/pcilib/config.h.in ${CMAKE_CURRENT_BINARY_DIR}/pcilib/config.h) configure_file(${CMAKE_CURRENT_SOURCE_DIR}/pcilib/version.h.in ${CMAKE_CURRENT_BINARY_DIR}/pcilib/version.h) configure_file(${CMAKE_CURRENT_SOURCE_DIR}/docs/Doxyfile.in ${CMAKE_CURRENT_BINARY_DIR}/docs/Doxyfile) -if (HAVE_PYTHON) - configure_file(${CMAKE_CURRENT_SOURCE_DIR}/misc/pcilib_api.service.in - ${CMAKE_CURRENT_BINARY_DIR}/misc/pcilib_api.service) - configure_file(${CMAKE_CURRENT_SOURCE_DIR}/misc/pcilib_html.service.in - ${CMAKE_CURRENT_BINARY_DIR}/misc/pcilib_html.service) - configure_file(${CMAKE_CURRENT_SOURCE_DIR}/misc/pcilib.in - ${CMAKE_CURRENT_BINARY_DIR}/misc/pcilib) -endif (HAVE_PYTHON) +if (NOT DISABLE_SERVERS) + configure_file(${CMAKE_CURRENT_SOURCE_DIR}/misc/pcilib_api.service.in ${CMAKE_CURRENT_BINARY_DIR}/misc/pcilib_api.service) + configure_file(${CMAKE_CURRENT_SOURCE_DIR}/misc/pcilib_html.service.in ${CMAKE_CURRENT_BINARY_DIR}/misc/pcilib_html.service) + configure_file(${CMAKE_CURRENT_SOURCE_DIR}/misc/pcilib.sysconfig.in ${CMAKE_CURRENT_BINARY_DIR}/misc/pcilib.sysconfig) +endif (NOT DISABLE_SERVERS) if (NOT CMAKE_SOURCE_DIR STREQUAL CMAKE_BINARY_DIR) file(COPY ${CMAKE_SOURCE_DIR}/xml DESTINATION ${CMAKE_BINARY_DIR}) @@ -157,18 +212,18 @@ install(FILES DESTINATION ${LIB_INSTALL_DIR}/pkgconfig ) -if (HAVE_PYTHON) +if (NOT DISABLE_SERVERS) #install Python servers file(GLOB DEPLOY_FILES_AND_DIRS "${CMAKE_SOURCE_DIR}/pyserver/*") foreach(ITEM ${DEPLOY_FILES_AND_DIRS}) - IF( IS_DIRECTORY "${ITEM}" ) - LIST( APPEND DIRS_TO_DEPLOY "${ITEM}" ) - ELSE() - LIST( APPEND FILES_TO_DEPLOY "${ITEM}" ) - ENDIF() - endforeach() - INSTALL( FILES ${FILES_TO_DEPLOY} DESTINATION ${PCILIB_PY_SERVER_INSTALL_DIR} ) - INSTALL( DIRECTORY ${DIRS_TO_DEPLOY} DESTINATION ${PCILIB_PY_SERVER_INSTALL_DIR} ) -endif (HAVE_PYTHON) + if( IS_DIRECTORY "${ITEM}" ) + list(APPEND DIRS_TO_DEPLOY "${ITEM}") + else() + list(APPEND FILES_TO_DEPLOY "${ITEM}") + endif() + endforeach() + install(FILES ${FILES_TO_DEPLOY} DESTINATION ${PCILIB_SERVER_DIR}) + install(DIRECTORY ${DIRS_TO_DEPLOY} DESTINATION ${PCILIB_SERVER_DIR}) +endif (NOT DISABLE_SERVERS) message("-- Configured pcitool ${PCILIB_VERSION_MAJOR}.${PCILIB_VERSION_MINOR}.${PCILIB_VERSION_MICRO} with public ABI ${PCILIB_ABI_VERSION}") @@ -651,7 +651,7 @@ int dma_ipe_stream_read(pcilib_dma_context_t *vctx, pcilib_dma_engine_t dma, uin if ((ctx->dma_flags&IPEDMA_FLAG_NOSYNC) == 0) pcilib_kmem_sync_block(ctx->dmactx.pcilib, ctx->pages, PCILIB_KMEM_SYNC_FROMDEVICE, cur_read); - void *buf = pcilib_kmem_get_block_ua(ctx->dmactx.pcilib, ctx->pages, cur_read); + void *buf = (void*)pcilib_kmem_get_block_ua(ctx->dmactx.pcilib, ctx->pages, cur_read); ret = cb(cbattr, packet_flags, ctx->page_size, buf); if (ret < 0) return -ret; diff --git a/dma/nwl_engine.c b/dma/nwl_engine.c index b098943..f8ae6ac 100644 --- a/dma/nwl_engine.c +++ b/dma/nwl_engine.c @@ -237,7 +237,7 @@ int dma_nwl_write_fragment(pcilib_dma_context_t *vctx, pcilib_dma_engine_t dma, return PCILIB_ERROR_TIMEOUT; } - void *buf = pcilib_kmem_get_block_ua(ctx->dmactx.pcilib, ectx->pages, bufnum); + void *buf = (void*)pcilib_kmem_get_block_ua(ctx->dmactx.pcilib, ectx->pages, bufnum); pcilib_kmem_sync_block(ctx->dmactx.pcilib, ectx->pages, PCILIB_KMEM_SYNC_FROMDEVICE, bufnum); memcpy(buf, data, block_size); @@ -293,7 +293,7 @@ int dma_nwl_stream_read(pcilib_dma_context_t *vctx, pcilib_dma_engine_t dma, uin if (ctx->ignore_eop) eop = 1; pcilib_kmem_sync_block(ctx->dmactx.pcilib, ectx->pages, PCILIB_KMEM_SYNC_FROMDEVICE, bufnum); - void *buf = pcilib_kmem_get_block_ua(ctx->dmactx.pcilib, ectx->pages, bufnum); + void *buf = (void*)pcilib_kmem_get_block_ua(ctx->dmactx.pcilib, ectx->pages, bufnum); ret = cb(cbattr, (eop?PCILIB_DMA_FLAG_EOP:0), bufsize, buf); if (ret < 0) return -ret; // DS: Fixme, it looks like we can avoid calling this for the sake of performance diff --git a/dma/nwl_engine_buffers.h b/dma/nwl_engine_buffers.h index 0cc5343..8d1185f 100644 --- a/dma/nwl_engine_buffers.h +++ b/dma/nwl_engine_buffers.h @@ -173,7 +173,7 @@ static size_t dma_nwl_clean_buffers(nwl_dma_t * ctx, pcilib_nwl_engine_context_t size_t res = 0; uint32_t status; - unsigned char *ring = pcilib_kmem_get_ua(ctx->dmactx.pcilib, ectx->ring); + volatile unsigned char *ring = pcilib_kmem_get_ua(ctx->dmactx.pcilib, ectx->ring); ring += ectx->tail * PCILIB_NWL_DMA_DESCRIPTOR_SIZE; next_buffer: @@ -250,7 +250,7 @@ static int dma_nwl_push_buffer(nwl_dma_t *ctx, pcilib_nwl_engine_context_t *ectx int flags = 0; uint32_t val; - unsigned char *ring = pcilib_kmem_get_ua(ctx->dmactx.pcilib, ectx->ring); + volatile unsigned char *ring = pcilib_kmem_get_ua(ctx->dmactx.pcilib, ectx->ring); uint32_t ring_pa = pcilib_kmem_get_ba(ctx->dmactx.pcilib, ectx->ring); ring += ectx->head * PCILIB_NWL_DMA_DESCRIPTOR_SIZE; @@ -282,7 +282,7 @@ static size_t dma_nwl_wait_buffer(nwl_dma_t *ctx, pcilib_nwl_engine_context_t *e struct timeval start, cur; uint32_t status_size, status; - unsigned char *ring = pcilib_kmem_get_ua(ctx->dmactx.pcilib, ectx->ring); + volatile unsigned char *ring = pcilib_kmem_get_ua(ctx->dmactx.pcilib, ectx->ring); ring += ectx->tail * PCILIB_NWL_DMA_DESCRIPTOR_SIZE; @@ -337,7 +337,7 @@ static int dma_nwl_is_overflown(nwl_dma_t *ctx, pcilib_nwl_engine_context_t *ect static int dma_nwl_return_buffer(nwl_dma_t *ctx, pcilib_nwl_engine_context_t *ectx) { uint32_t val; - unsigned char *ring = pcilib_kmem_get_ua(ctx->dmactx.pcilib, ectx->ring); + volatile unsigned char *ring = pcilib_kmem_get_ua(ctx->dmactx.pcilib, ectx->ring); uint32_t ring_pa = pcilib_kmem_get_ba(ctx->dmactx.pcilib, ectx->ring); size_t bufsz = pcilib_kmem_get_block_size(ctx->dmactx.pcilib, ectx->pages, ectx->tail); diff --git a/docs/BUGS b/docs/BUGS deleted file mode 100644 index 4b0c1cc..0000000 --- a/docs/BUGS +++ /dev/null @@ -1,5 +0,0 @@ -IPECamera Hardware Bugs -======================= - 1. Strange sequence writting CMOSIS registers - 2. Sometimes during DMA streaming register accesses fail - 3. The lower 12-bit of bus address are ignored by all hardware diff --git a/driver/Makefile b/driver/makefile index a55e7c7..ca44b94 100644 --- a/driver/Makefile +++ b/driver/makefile @@ -3,10 +3,11 @@ CONFIG_MODULE_SIG=n obj-m := pciDriver.o pciDriver-objs := base.o dev.o int.o umem.o kmem.o sysfs.o ioctl.o pcibus.o rdma.o -KERNELDIR ?= /lib/modules/$(shell uname -r)/build -INSTALLDIR ?= /lib/modules/$(shell uname -r)/extra -MAININSTALLDIR ?= /lib/modules/$(shell uname -r)/kernel/extra -HEADERDIR ?= /lib/modules/$(shell uname -r)/source/include +KERNELVER ?= $(shell uname -r) +KERNELDIR ?= /lib/modules/$(KERNELVER)/build +INSTALLDIR ?= /lib/modules/$(KERNELVER)/extra +MAININSTALLDIR ?= /lib/modules/$(KERNELVER)/kernel/extra +HEADERDIR ?= /lib/modules/$(KERNELVER)/source/include PWD := $(shell pwd) EXTRA_CFLAGS += -I$(M)/.. @@ -63,6 +64,14 @@ install: @mkdir -p /usr/include/linux @install -m 644 ioctl.h /usr/include/linux/pcidriver.h +install_symvers: + @mkdir -p $(INSTALLDIR) + @echo "INSTALL $(INSTALLDIR)/pciDriver.symvers" + @install -m 644 Module.symvers $(INSTALLDIR)/pciDriver.symvers + @echo "INSTALL $(HEADERDIR)/linux/pcidriver.h" + @install -m 644 pcidriver.h $(HEADERDIR)/linux/ + + uninstall: @echo "UNINSTALL $(INSTALLDIR)/pciDriver.ko" @rm -f $(INSTALLDIR)/pciDriver.ko diff --git a/misc/dkms.conf.in b/misc/dkms.conf.in new file mode 100644 index 0000000..2e647a9 --- /dev/null +++ b/misc/dkms.conf.in @@ -0,0 +1,10 @@ +POST_INSTALL="make -C driver/ install_symvers KERNELVER=$kernelver KERNELDIR=$kernel_source_dir" +MAKE="make -C driver/ KERNELDIR=/lib/modules/${kernelver}/build" +CLEAN="make -C driver/ clean" +BUILT_MODULE_NAME=pciDriver +BUILT_MODULE_LOCATION=driver/ +PACKAGE_NAME=${PACKAGE_NAME} +PACKAGE_VERSION=${CPACK_PACKAGE_VERSION} +DEST_MODULE_LOCATION[0]="/extra" +REMAKE_INITRD=no +AUTOINSTALL=yes diff --git a/misc/pcilib.in b/misc/pcilib.in deleted file mode 100644 index 9b7352c..0000000 --- a/misc/pcilib.in +++ /dev/null @@ -1,9 +0,0 @@ -# API server parameters -API_SERVER_DEVICE="/dev/fpga0" -API_SERVER_MODEL="test" - -# HTML server parameters -HTML_SERVER_PORT=5000 - -#Scripts directory -PCILIB_SCRIPTS_DIR="${PCILIB_PY_SERVER_INSTALL_DIR}/scripts" diff --git a/misc/pcilib.sysconfig.in b/misc/pcilib.sysconfig.in new file mode 100644 index 0000000..65edeb3 --- /dev/null +++ b/misc/pcilib.sysconfig.in @@ -0,0 +1,12 @@ +# Common parameters +SERVER_DEVICE="/dev/fpga0" +SERVER_MODEL="test" + +# API server parameters +API_SERVER_PORT=9000 + +# HTML server parameters +HTML_SERVER_PORT=5000 + +#Scripts directory +PCILIB_SCRIPTS_DIR="${PCILIB_SERVER_DIR}/scripts" diff --git a/misc/pcilib_api.service.in b/misc/pcilib_api.service.in index 291a3e0..297772b 100644 --- a/misc/pcilib_api.service.in +++ b/misc/pcilib_api.service.in @@ -6,7 +6,7 @@ After=network.target nss-lookup.target [Service] Type=simple EnvironmentFile=/etc/sysconfig/pcilib -ExecStart=${PYTHON_EXECUTABLE} ${PCILIB_PY_SERVER_INSTALL_DIR}/pcilib_api_server.py -d $API_SERVER_DEVICE -m $API_SERVER_MODEL +ExecStart=${PYTHON_EXECUTABLE} ${PCILIB_SERVER_DIR}/pcilib_api_server.py -d SERVER_DEVICE -m $SERVER_MODEL -p $API_SERVER_PORT [Install] WantedBy=multi-user.target diff --git a/misc/pcilib_html.service.in b/misc/pcilib_html.service.in index 634d9c7..7f03e77 100644 --- a/misc/pcilib_html.service.in +++ b/misc/pcilib_html.service.in @@ -8,7 +8,7 @@ After=pcilib_api.service [Service] Type=simple EnvironmentFile=/etc/sysconfig/pcilib -ExecStart=${PYTHON_EXECUTABLE} ${PCILIB_PY_SERVER_INSTALL_DIR}/pcilib_html_server.py -p $HTML_SERVER_PORT -e +ExecStart=${PYTHON_EXECUTABLE} ${PCILIB_SERVER_DIR}/pcilib_html_server.py -d $SERVER_DEVICE -m $SERVER_MODEL -p $HTML_SERVER_PORT -e --api-server-port $API_SERVER_PORT [Install] WantedBy=multi-user.target diff --git a/misc/rpmlintrc b/misc/rpmlintrc new file mode 100644 index 0000000..d79a8b5 --- /dev/null +++ b/misc/rpmlintrc @@ -0,0 +1,8 @@ +addFilter("devel-file-in-non-devel-package.*/usr/src/pciDriver") +addFilter("no-manual-page-for-binary") +addFilter("files-duplicate /usr/share/doc/packages/libpcilib-devel/html/") +addFilter("files-duplicate /usr/share/pcilib.*/pyserver/static/codebase/imgs/dhxtree_skyblue/") +addFilter("suse-filelist-forbidden-fhs23 /usr/src/pciDriver") + +# uthash +addFilter("libpcilib.* shared-lib-calls-exit /usr/lib.*/libpcilib") diff --git a/pcilib/kmem.c b/pcilib/kmem.c index b103126..e1d60c5 100644 --- a/pcilib/kmem.c +++ b/pcilib/kmem.c @@ -29,7 +29,7 @@ int pcilib_clean_kernel_memory(pcilib_t *ctx, pcilib_kmem_use_t use, pcilib_kmem static int pcilib_free_kernel_buffer(pcilib_t *ctx, pcilib_kmem_list_t *kbuf, size_t i, pcilib_kmem_flags_t flags) { kmem_handle_t kh = {0}; - if (kbuf->buf.blocks[i].ua) munmap(kbuf->buf.blocks[i].ua, kbuf->buf.blocks[i].size + kbuf->buf.blocks[i].alignment_offset); + if (kbuf->buf.blocks[i].ua) munmap((void*)kbuf->buf.blocks[i].ua, kbuf->buf.blocks[i].size + kbuf->buf.blocks[i].alignment_offset); kh.handle_id = kbuf->buf.blocks[i].handle_id; kh.pa = kbuf->buf.blocks[i].pa; kh.flags = flags; @@ -361,7 +361,7 @@ int pcilib_kmem_sync_block(pcilib_t *ctx, pcilib_kmem_handle_t *k, pcilib_kmem_s return 0; } -void* volatile pcilib_kmem_get_ua(pcilib_t *ctx, pcilib_kmem_handle_t *k) { +volatile void *pcilib_kmem_get_ua(pcilib_t *ctx, pcilib_kmem_handle_t *k) { pcilib_kmem_list_t *kbuf = (pcilib_kmem_list_t*)k; return kbuf->buf.addr.ua + kbuf->buf.addr.alignment_offset + kbuf->buf.addr.mmap_offset; } @@ -380,7 +380,7 @@ uintptr_t pcilib_kmem_get_ba(pcilib_t *ctx, pcilib_kmem_handle_t *k) { return 0; } -void* volatile pcilib_kmem_get_block_ua(pcilib_t *ctx, pcilib_kmem_handle_t *k, size_t block) { +volatile void *pcilib_kmem_get_block_ua(pcilib_t *ctx, pcilib_kmem_handle_t *k, size_t block) { pcilib_kmem_list_t *kbuf = (pcilib_kmem_list_t*)k; return kbuf->buf.blocks[block].ua + kbuf->buf.blocks[block].alignment_offset + kbuf->buf.blocks[block].mmap_offset; } diff --git a/pcilib/kmem.h b/pcilib/kmem.h index 1d63e3b..e8d2827 100644 --- a/pcilib/kmem.h +++ b/pcilib/kmem.h @@ -68,7 +68,7 @@ typedef struct { uintptr_t pa; /**< physical address of buffer */ uintptr_t ba; /**< bus address of buffer (if it is mapped for DMA operations) */ - void* volatile ua; /**< pointer to buffer in the process address space */ + volatile void *ua; /**< pointer to buffer in the process address space */ size_t size; /**< size of the buffer in bytes */ size_t alignment_offset; /**< we may request alignment of allocated buffers. To enusre proper alignment the larger buffer will be allocated and the offset will specify the first position in the buffer fullfilling alignment request */ @@ -205,7 +205,7 @@ int pcilib_kmem_sync_block(pcilib_t *ctx, pcilib_kmem_handle_t *k, pcilib_kmem_s * @param[in] k - kernel memory handle returned from pcilib_alloc_kernel_memory() call * @return - user-space pointer */ -void* volatile pcilib_kmem_get_ua(pcilib_t *ctx, pcilib_kmem_handle_t *k); +volatile void *pcilib_kmem_get_ua(pcilib_t *ctx, pcilib_kmem_handle_t *k); /** * Get a physical address of a single-buffer kernel memory @@ -233,7 +233,7 @@ uintptr_t pcilib_kmem_get_ba(pcilib_t *ctx, pcilib_kmem_handle_t *k); * @param[in] block - specifies the buffer within the kernel memory (buffers are numbered from 0) * @return - user-space pointer */ -void* volatile pcilib_kmem_get_block_ua(pcilib_t *ctx, pcilib_kmem_handle_t *k, size_t block); +volatile void *pcilib_kmem_get_block_ua(pcilib_t *ctx, pcilib_kmem_handle_t *k, size_t block); /** * Get a physical address of the specified kernel memory buffer diff --git a/pcilib/locking.c b/pcilib/locking.c index 71f204e..6ae4365 100644 --- a/pcilib/locking.c +++ b/pcilib/locking.c @@ -43,7 +43,7 @@ int pcilib_init_locking(pcilib_t* ctx) { if ((reused & PCILIB_KMEM_REUSE_REUSED) == 0) { for (i = 0; i < PCILIB_LOCK_PAGES; i++) { - void *addr = pcilib_kmem_get_block_ua(ctx, ctx->locks.kmem, i); + void *addr = (void*)pcilib_kmem_get_block_ua(ctx, ctx->locks.kmem, i); memset(addr, 0, PCILIB_KMEM_PAGE_SIZE); } } @@ -95,7 +95,7 @@ void pcilib_unlock_global(pcilib_t *ctx) { pcilib_lock_t *pcilib_get_lock_by_id(pcilib_t *ctx, pcilib_lock_id_t id) { int page = id / PCILIB_LOCKS_PER_PAGE; int offset = id - page * PCILIB_LOCKS_PER_PAGE; - void *addr = pcilib_kmem_get_block_ua(ctx, ctx->locks.kmem, page); + volatile void *addr = pcilib_kmem_get_block_ua(ctx, ctx->locks.kmem, page); pcilib_lock_t *lock = (pcilib_lock_t*)(addr + offset * PCILIB_LOCK_SIZE); return lock; @@ -308,7 +308,7 @@ int pcilib_destroy_all_locks(pcilib_t *ctx, int force) { } for (i = 0; i < PCILIB_LOCK_PAGES; i++) { - void *addr = pcilib_kmem_get_block_ua(ctx, ctx->locks.kmem, i); + void *addr = (void*)pcilib_kmem_get_block_ua(ctx, ctx->locks.kmem, i); memset(addr, 0, PCILIB_KMEM_PAGE_SIZE); } diff --git a/pcilib/py.c b/pcilib/py.c index 94d7ed8..03e9d8d 100644 --- a/pcilib/py.c +++ b/pcilib/py.c @@ -3,10 +3,9 @@ #ifdef HAVE_PYTHON # include <Python.h> -#if PY_MAJOR_VERSION >= 3 -#include <pthread.h> -#endif /* PY_MAJOR_VERSION >= 3 */ - +# if PY_MAJOR_VERSION >= 3 +# include <pthread.h> +# endif /* PY_MAJOR_VERSION >= 3 */ #endif /* HAVE_PYTHON */ #include <stdio.h> @@ -22,7 +21,7 @@ #include "error.h" #ifdef HAVE_PYTHON -#define PCILIB_PYTHON_WRAPPER "pcipywrap" +# define PCILIB_PYTHON_WRAPPER "pcipywrap" typedef struct pcilib_script_s pcilib_script_t; @@ -32,14 +31,6 @@ struct pcilib_script_s { UT_hash_handle hh; /**< hash */ }; -#if PY_MAJOR_VERSION >= 3 -typedef struct pcilib_py_s_thread_control { - pthread_t pth; - pthread_cond_t cond_finished; - pthread_mutex_t cond_finished_lock; -} pcilib_py_s_thread_control; -#endif /* PY_MAJOR_VERSION < 3 */ - struct pcilib_py_s { int finalyze; /**< Indicates, that we are initialized from wrapper and should not destroy Python resources in destructor */ PyObject *main_module; /**< Main interpreter */ @@ -47,9 +38,11 @@ struct pcilib_py_s { PyObject *pcilib_pywrap; /**< pcilib wrapper module */ pcilib_script_t *script_hash; /**< Hash with loaded scripts */ -#if PY_MAJOR_VERSION >= 3 - pcilib_py_s_thread_control *thr_ctl; /**< Controller for Python main loop thread for Python 3 */ -#endif /* PY_MAJOR_VERSION < 3 */ +# if PY_MAJOR_VERSION >= 3 + pthread_t pth; + pthread_cond_t cond; + pthread_mutex_t lock; +# endif /* PY_MAJOR_VERSION > 3 */ }; #endif /* HAVE_PYTHON */ @@ -72,7 +65,7 @@ void pcilib_log_python_error(const char *file, int line, pcilib_log_flags_t flag PyErr_NormalizeException(&pytype, &pyval, &pytraceback); if (pyval) pystr = PyObject_Str(pyval); -#if PY_MAJOR_VERSION >= 3 +# if PY_MAJOR_VERSION >= 3 if (pytype) { if (PyUnicode_Check(pytype)) type = PyUnicode_AsUTF8(pytype); @@ -82,7 +75,7 @@ void pcilib_log_python_error(const char *file, int line, pcilib_log_flags_t flag if (pystr) { val = PyUnicode_AsUTF8(pystr); } -#else /* PY_MAJOR_VERSION >= 3 */ +# else /* PY_MAJOR_VERSION >= 3 */ if (pytype) { if (PyString_Check(pytype)) type = PyString_AsString(pytype); @@ -92,7 +85,7 @@ void pcilib_log_python_error(const char *file, int line, pcilib_log_flags_t flag if (pystr) { val = PyString_AsString(pystr); } -#endif /*PY_MAJOR_VERSION >= 3*/ +# endif /*PY_MAJOR_VERSION >= 3*/ } PyGILState_Release(gstate); #endif /* HAVE_PYTHON */ @@ -133,26 +126,47 @@ void pcilib_log_python_error(const char *file, int line, pcilib_log_flags_t flag } #ifdef HAVE_PYTHON -#if PY_MAJOR_VERSION >= 3 -void *pcilib_py_run_side_thread(void *arg) { - pcilib_t *ctx = (pcilib_t*)(arg); - //Initializing python - Py_Initialize(); - PyEval_InitThreads(); - PyEval_ReleaseLock(); +# if PY_MAJOR_VERSION >= 3 +/** + * Python3 specially treats the main thread intializing Python. It crashes if + * the Lock is released and any Python code is executed under the GIL compaling + * that GIL is not locked. Python3 assumes that the main thread most of the time + * holds the Lock, only shortly giving it away to other threads and re-obtaining + * it hereafter. This is not possible to do with GILs, but instead (probably) + * PyEval_{Save,Restore}Thread() should be used. On other hand, the other threads + * are working fine with GILs. This makes things complicated as we need to know + * if we are running in main thread or not. + * To simplify matters, during initalization we start a new thread which will + * performa actual initialization of Python and, hence, act as main thread. + * We only intialize here. No python code is executed afterwards. So we don't + * need to care about special locking mechanisms in main thread. Instead all + * our user threads can use GILs normally. + * See more details here: + * http://stackoverflow.com/questions/24499393/cpython-locking-the-gil-in-the-main-thread + * http://stackoverflow.com/questions/15470367/pyeval-initthreads-in-python-3-how-when-to-call-it-the-saga-continues-ad-naus + */ +static void *pcilib_py_run_init_thread(void *arg) { + pcilib_py_t *py = (pcilib_py_t*)(arg); + + Py_Initialize(); + PyEval_InitThreads(); + PyEval_ReleaseLock(); + + // Ensure that main thread waiting for our signal + pthread_lock(&(py->lock)); - //send initialization finish signal - pthread_cond_signal(&(ctx->py->thr_ctl->cond_finished)); - pthread_mutex_unlock(&(ctx->py->thr_ctl->cond_finished_lock)); - pthread_mutex_destroy(&(ctx->py->thr_ctl->cond_finished_lock)); - - //wait untill finish signal - pthread_mutex_lock(&(ctx->py->thr_ctl->cond_finished_lock)); - pthread_cond_wait(&(ctx->py->thr_ctl->cond_finished), - &(ctx->py->thr_ctl->cond_finished_lock)); - return NULL; + // Inform the parent thread that initialization is finished + pthread_cond_signal(&(py->cond)); + + // Wait untill cleanup is requested + pthread_cond_wait(&(py->cond), &(py->lock)); + pthread_unlock(&(py->lock))); + + Py_Finalize(); + + return NULL; } -#endif /* PY_MAJOR_VERSION < 3 */ +# endif /* PY_MAJOR_VERSION < 3 */ #endif /* HAVE_PYTHON */ int pcilib_init_py(pcilib_t *ctx) { @@ -161,28 +175,42 @@ int pcilib_init_py(pcilib_t *ctx) { if (!ctx->py) return PCILIB_ERROR_MEMORY; memset(ctx->py, 0, sizeof(pcilib_py_t)); - if(!Py_IsInitialized()) { -#if PY_MAJOR_VERSION >= 3 - //create thread controller - ctx->py->thr_ctl = malloc(sizeof(pcilib_py_s_thread_control)); - if(!ctx->py->thr_ctl) return PCILIB_ERROR_MEMORY; - memset(ctx->py->thr_ctl, 0, sizeof(pcilib_py_s_thread_control)); - - //create side thread with python main loop - pthread_create(&(ctx->py->thr_ctl->pth), NULL, pcilib_py_run_side_thread, ctx); - pthread_mutex_lock(&(ctx->py->thr_ctl->cond_finished_lock)); - - //wait until Python initializes - pthread_cond_wait(&(ctx->py->thr_ctl->cond_finished), - &(ctx->py->thr_ctl->cond_finished_lock)); - -#else /* PY_MAJOR_VERSION < 3 */ - Py_Initialize(); - // Since python is being initializing from c programm, it needs to initialize threads to work properly with c threads - PyEval_InitThreads(); - PyEval_ReleaseLock(); -#endif /* PY_MAJOR_VERSION < 3 */ - ctx->py->finalyze = 1; + if (!Py_IsInitialized()) { +# if PY_MAJOR_VERSION < 3 + Py_Initialize(); + // Since python is being initializing from c programm, it needs to initialize threads to work properly with c threads + PyEval_InitThreads(); + PyEval_ReleaseLock(); +# else /* PY_MAJOR_VERSION < 3 */ + err = pthread_mutex_init(&(ctx->py.lock)); + if (err) return PCILIB_ERROR_FAILED; + + err = pthread_cond_init(&(ctx->py.cond)); + if (err) { + pthread_mutex_destroy(&(ctx->py.lock)); + return PCILIB_ERROR_FAILED; + } + + err = pthread_mutex_lock(&(ctx->py.lock)); + if (err) { + pthread_cond_destroy(&(ctx->py.lock)); + pthread_mutex_destroy(&(ctx->py.lock)); + return PCILIB_ERROR_FAILED; + } + + // Create initalizer thread and wait until it releases the Lock + err = pthread_create(&(ctx->py.pth), NULL, pcilib_py_run_init_thread, &(ctx->py)); + if (err) { + pthread_mutex_unlock(&(ctx->py.lock)); + pthread_cond_destroy(&(ctx->py.cond)); + pthread_mutex_destroy(&(ctx->py.lock)); + return PCILIB_ERROR_FAILED; + } + + // Wait until initialized and keep the lock afterwards until free executed + pthread_cond_wait(&(ctx->py.cond), (ctx->py.lock)); +# endif /* PY_MAJOR_VERSION < 3 */ + ctx->py->finalyze = 1; } @@ -190,22 +218,22 @@ int pcilib_init_py(pcilib_t *ctx) { ctx->py->main_module = PyImport_AddModule("__parser__"); if (!ctx->py->main_module) { - pcilib_python_warning("Error importing python parser"); PyGILState_Release(gstate); + pcilib_python_warning("Error importing python parser"); return PCILIB_ERROR_FAILED; } ctx->py->global_dict = PyModule_GetDict(ctx->py->main_module); if (!ctx->py->global_dict) { - pcilib_python_warning("Error locating global python dictionary"); PyGILState_Release(gstate); + pcilib_python_warning("Error locating global python dictionary"); return PCILIB_ERROR_FAILED; } PyObject *pywrap = PyImport_ImportModule(PCILIB_PYTHON_WRAPPER); if (!pywrap) { - pcilib_python_warning("Error importing pcilib python wrapper"); PyGILState_Release(gstate); + pcilib_python_warning("Error importing pcilib python wrapper"); return PCILIB_ERROR_FAILED; } @@ -216,8 +244,8 @@ int pcilib_init_py(pcilib_t *ctx) { Py_XDECREF(mod_name); if (!ctx->py->pcilib_pywrap) { - pcilib_python_warning("Error initializing python wrapper"); PyGILState_Release(gstate); + pcilib_python_warning("Error initializing python wrapper"); return PCILIB_ERROR_FAILED; } @@ -253,15 +281,15 @@ int pcilib_py_add_script_dir(pcilib_t *ctx, const char *dir) { pypath = PySys_GetObject("path"); if (!pypath) { - pcilib_python_warning("Can't get python path"); PyGILState_Release(gstate); + pcilib_python_warning("Can't get python path"); return PCILIB_ERROR_FAILED; } pynewdir = PyUnicode_FromString(script_dir); if (!pynewdir) { - pcilib_python_warning("Can't create python string"); PyGILState_Release(gstate); + pcilib_python_warning("Can't create python string"); return PCILIB_ERROR_MEMORY; } @@ -290,13 +318,12 @@ int pcilib_py_add_script_dir(pcilib_t *ctx, const char *dir) { if (pyret) Py_DECREF(pyret); Py_DECREF(pynewdir); + PyGILState_Release(gstate); + if (err) { pcilib_python_warning("Can't add directory (%s) to python path", script_dir); - PyGILState_Release(gstate); return err; } - - PyGILState_Release(gstate); #endif /* HAVE_PYTHON */ return 0; @@ -305,14 +332,13 @@ int pcilib_py_add_script_dir(pcilib_t *ctx, const char *dir) { void pcilib_free_py(pcilib_t *ctx) { #ifdef HAVE_PYTHON int finalyze = 0; - PyGILState_STATE gstate; -#if PY_MAJOR_VERSION >= 3 - pcilib_py_s_thread_control *thr_ctl = ctx->py->thr_ctl; -#endif /* PY_MAJOR_VERSION < 3 */ - if (ctx->py) { + PyGILState_STATE gstate; + if (ctx->py->finalyze) finalyze = 1; + + gstate = PyGILState_Ensure(); if (ctx->py->script_hash) { pcilib_script_t *script, *script_tmp; @@ -325,12 +351,11 @@ void pcilib_free_py(pcilib_t *ctx) { ctx->py->script_hash = NULL; } - if (ctx->py->pcilib_pywrap) { - gstate = PyGILState_Ensure(); + if (ctx->py->pcilib_pywrap) Py_DECREF(ctx->py->pcilib_pywrap); - PyGILState_Release(gstate); - } - + + PyGILState_Release(gstate); + free(ctx->py); ctx->py = NULL; @@ -339,26 +364,16 @@ void pcilib_free_py(pcilib_t *ctx) { if (finalyze) { #if PY_MAJOR_VERSION >= 3 - - //stop python side thread - pthread_cond_signal(&(thr_ctl->cond_finished)); - pthread_mutex_unlock(&(thr_ctl->cond_finished_lock)); - pthread_join(thr_ctl->pth, NULL); - - //free python - //must be finalized in main thread to correctly stop python threading - PyGILState_Ensure(); - Py_Finalize(); - - //destroy thread controllers - pthread_mutex_destroy(&(thr_ctl->cond_finished_lock)); - pthread_cond_destroy(&(thr_ctl->cond_finished)); - free(thr_ctl); + // singal python init thread to stop and wait it to finish + pthread_cond_signal(&(ctx->py.cond)); + pthread_mutex_unlock(&(ctx->py.lock)); + pthread_join(ctx->py.pth, NULL); + // destroy synchronization primitives + pthread_cond_destroy(&(ctx->py.cond)); + pthread_mutex_destroy(&(ctx->py.lock)); #else /* PY_MAJOR_VERSION < 3 */ - Py_Finalize(); - #endif /* PY_MAJOR_VERSION < 3 */ } @@ -388,14 +403,12 @@ int pcilib_py_load_script(pcilib_t *ctx, const char *script_name) { if (module) return 0; gstate = PyGILState_Ensure(); - pymodule = PyImport_ImportModule(module_name); if (!pymodule) { - pcilib_python_error("Error importing script (%s)", script_name); PyGILState_Release(gstate); + pcilib_python_error("Error importing script (%s)", script_name); return PCILIB_ERROR_FAILED; } - PyGILState_Release(gstate); module = (pcilib_script_t*)malloc(sizeof(pcilib_script_t)); @@ -433,8 +446,8 @@ int pcilib_py_get_transform_script_properties(pcilib_t *ctx, const char *script_ dict = PyModule_GetDict(module->module); if (!dict) { - pcilib_python_error("Error getting dictionary for script (%s)", script_name); PyGILState_Release(gstate); + pcilib_python_error("Error getting dictionary for script (%s)", script_name); return PCILIB_ERROR_FAILED; } diff --git a/pcitool.spec.in b/pcitool.spec.in new file mode 100644 index 0000000..a8b1d9b --- /dev/null +++ b/pcitool.spec.in @@ -0,0 +1,204 @@ +%define modname pciDriver + +%{!?__python2: %global __python2 /usr/bin/python2} +%{!?python2_sitelib: %global python2_sitelib %(%{__python2} -c "from distutils.sysconfig import get_python_lib; print(get_python_lib())")} +%{!?python2_sitearch: %global python2_sitearch %(%{__python2} -c "from distutils.sysconfig import get_python_lib; print(get_python_lib(1))")} + +Summary: Universal PCI driver +Name: pcitool +Version: ${CPACK_PACKAGE_VERSION} +Release: csa +License: GPL-3.0 +Group: Development/Libraries +Source: ${CPACK_SOURCE_PACKAGE_FILE_NAME}.tar.bz2 +BuildRoot: %{_tmppath}/%{name}-%{version}-root +URL: http://darksoft.org +Prefix: %{_prefix} +Docdir: %{_docdir} +BuildRequires: libfastwriter-devel libxml2-devel uthash +BuildRequires: python python-devel swig +BuildRequires: kernel-devel dkms +BuildRequires: doxygen +BuildRequires: pkg-config libtool cmake +Vendor: Institute for Data Processing and Electronics, KIT +Packager: Suren A. Chilingaryan <csa@suren.me> + +%description +pcitool is a command line tool to manipulate PCI hardware. It provides ability +to get/set registers, read/write data using DMA engine, and debug hardware +operation. + +%package -n libpcilib${PCILIB_ABI_VERSION} +Summary: User-space PCI library +Group: Development/Libraries +Requires: pcilib-python >= %{version} +Requires: pcilib-dkms >= %{version} + +%description -n libpcilib${PCILIB_ABI_VERSION} +pcilib is a user-space library providing structured access to the PCI hardware. +API exposes 4 API layers. + - PCI memory access - allows to map PCI bar memory into the address space of + user application and manipulate it directly. + - Register access - allows to read and write device registers. The register + model is defined using XML. Besides the direct hardware access, the register + values can be filtered using Python scripts. This allows to convert hardware + reading to standard units, make consistency checking, and create meta registers + setting multiple registers from a single parameter. + - DMA engine - allows high-speed reading and writting using DMA. The DMA + engines are implemented in user-space as plugins. + - Event engine - allows polling for hardware events and grabbing the data + associated with the event in multiple supported formats. The event engines + are implemented as plugins and are not part of this package. + +%package -n libpcilib-devel +Summary: Development files for pcilib +Group: Development/Libraries +Requires: libpcilib${PCILIB_ABI_VERSION} = %{version} + +%description -n libpcilib-devel +Development files for user-space PCI library + +%package -n pcilib-test +Summary: Testing files for pcilib +Group: Development/Libraries +Requires: libpcilib${PCILIB_ABI_VERSION} = %{version} + +%description -n pcilib-test +Sample XML register model and a few applications for testing pcilib + +%package -n pcilib-python +Summary: Python wrapper for pcilib +Group: Development/Libraries +Requires: libpcilib${PCILIB_ABI_VERSION} = %{version} + +%description -n pcilib-python +Python wrapper for pcilib. The python wrapper is used + - By register scripts which are used to convert hardware reading to standard + units, make consistency checking, and create meta registers setting multiple + registers from a single parameter. + - pcilib web api which used to provide register and dma access from remote + applications. + +%package -n pcilib-dkms +Summary: Kernel module providing low-level PCI access +Group: Development/Libraries +Requires: dkms bash gcc make + +%description -n pcilib-dkms +Minimalistic driver used by pcilib to + - Handle interrupts + - Map PCI regions into the user space + - Allocate persistent page-locked memory for DMA operations + and map it into the user-space + - Ensure access syncrhonization between multiple applications + +%package -n pcilib-server +Summary: Pcilib Web API +Group: Development/Libraries +Requires: pcilib-python = %{version} +Requires: python + +%description -n pcilib-server +Pcilib Web API and small demo web server. + +%prep +%setup -q -n pcitool-%{version} + +%build +cmake -DCMAKE_BUILD_TYPE=Release -DCMAKE_INSTALL_PREFIX=/usr \ + -DPCILIB_PLUGIN_DIR=%{_libdir}/pcilib${PCILIB_ABI_VERSION}/ -DPCILIB_DATA_DIR=%{_datadir}/pcilib${PCILIB_ABI_VERSION}/ \ + -DLIB_INSTALL_DIR=%{_libdir} -DBIN_INSTALL_DIR=%{_bindir} -DDATA_INSTALL_DIR=%{_datadir} -DINCLUDE_INSTALL_DIR=%{_includedir} -DPYTHON_INSTALL_DIR=%{python2_sitearch} . +make +make docs + +%install +rm -rf $RPM_BUILD_ROOT +make install DESTDIR=$RPM_BUILD_ROOT +mkdir -p $RPM_BUILD_ROOT/%{_libdir}/pcilib${PCILIB_ABI_VERSION}/ + +# scripts +install -m 755 tests/reload.sh $RPM_BUILD_ROOT/%{_bindir}/pci-reload + +# udev +mkdir -p $RPM_BUILD_ROOT/usr/lib/udev/rules.d +install -m 644 misc/50-pcidriver.rules $RPM_BUILD_ROOT/%{_udevrulesdir} + +# DKMS +mkdir -p $RPM_BUILD_ROOT/%{_includedir}/linux/ +install -m 644 driver/ioctl.h $RPM_BUILD_ROOT/%{_includedir}/linux/pcidriver.h +mkdir -p $RPM_BUILD_ROOT/usr/src/%{modname}-%{version}/pcilib/ +install -m 644 misc/dkms.conf $RPM_BUILD_ROOT/%{_prefix}/src/%{modname}-%{version}/ +install -m 644 pcilib/*.h $RPM_BUILD_ROOT/%{_prefix}/src/%{modname}-%{version}/pcilib/ +cp -r driver $RPM_BUILD_ROOT/usr/src/%{modname}-%{version}/ + +# Sample model +cp -r xml/test $RPM_BUILD_ROOT/%{_datadir}/pcilib${PCILIB_ABI_VERSION}/models/ + +# Servers +cp -r pyserver $RPM_BUILD_ROOT/%{_datadir}/pcilib${PCILIB_ABI_VERSION}/ + +%clean +rm -rf $RPM_BUILD_ROOT + +%post -n libpcilib${PCILIB_ABI_VERSION} -p /sbin/ldconfig + +%postun -n libpcilib${PCILIB_ABI_VERSION} -p /sbin/ldconfig + +%post -n pcilib-dkms +if [ -z "`dkms status -m %{modname} -v %{version}`" ]; then + echo "Add module source to dkms" + dkms add -m %{modname} -v %{version} --rpm_safe_upgrade + + echo "Build module with dkms" + dkms build -m %{modname} -v %{version} + dkms install -m %{modname} -v %{version} +fi +exit 0 + +%preun -n pcilib-dkms +/usr/sbin/dkms remove -m %{modname} -v %{version} --all --rpm_safe_upgrade +exit 0 + +%files +%defattr(-, root, root) +%{_bindir}/pci +%{_bindir}/pci-reload + +%files -n libpcilib${PCILIB_ABI_VERSION} +%defattr(-, root, root) +%doc docs/README +%doc docs/HARDWARE +%dir %{_libdir}/pcilib${PCILIB_ABI_VERSION}/ +%dir %{_datadir}/pcilib${PCILIB_ABI_VERSION}/models/ +%{_datadir}/pcilib${PCILIB_ABI_VERSION}/models/*.xsd +%{_libdir}/libpcilib.so.* + +%files -n libpcilib-devel +%defattr(-, root, root) +%doc docs/html +%{_includedir}/linux/pcidriver.h +%{_includedir}/pcilib.h +%{_includedir}/pcilib/ +%{_libdir}/lib*.so +%{_libdir}/pkgconfig/*.pc + +%files -n pcilib-test +%defattr(-, root, root) +%{_datadir}/pcilib${PCILIB_ABI_VERSION}/models/test + +%files -n pcilib-dkms +%defattr(-, root, root) +%{_udevrulesdir} +%{_prefix}/src/%{modname}-%{version}/ + +%files -n pcilib-python +%defattr(-, root, root) +%{python2_sitearch}/* + +%files -n pcilib-server +%defattr(-, root, root) +%{_datadir}/pcilib${PCILIB_ABI_VERSION}/pyserver + +%changelog +* Fri Mar 4 2016 Suren A. Chilingaryan <csa@suren.me> - ${CPACK_PACKAGE_VERSION} +- Added spec file to the sources diff --git a/pcitool/cli.c b/pcitool/cli.c index caa55a9..1fc2abb 100644 --- a/pcitool/cli.c +++ b/pcitool/cli.c @@ -2614,7 +2614,7 @@ int DetailKMEM(pcilib_t *handle, const char *device, const char *use, size_t blo printf("Buffer Address Hardware Address Bus Address\n"); printf("--------------------------------------------------------------------------------\n"); for (; i < n; i++) { - void *data = pcilib_kmem_get_block_ua(handle, kbuf, i); + volatile void *data = pcilib_kmem_get_block_ua(handle, kbuf, i); uintptr_t pa = pcilib_kmem_get_block_pa(handle, kbuf, i); uintptr_t ba = pcilib_kmem_get_block_ba(handle, kbuf, i); printf("%6lu %16p %16lx %16lx\n", i, data, pa, ba); @@ -2648,7 +2648,7 @@ int ReadKMEM(pcilib_t *handle, const char *device, pcilib_kmem_use_t useid, size return 0; } - data = pcilib_kmem_get_block_ua(handle, kbuf, block); + data = (void*)pcilib_kmem_get_block_ua(handle, kbuf, block); if (data) { size = pcilib_kmem_get_block_size(handle, kbuf, block); if ((max_size)&&(size > max_size)) size = max_size; diff --git a/protocols/software.c b/protocols/software.c index 5b217d4..ca15d8d 100644 --- a/protocols/software.c +++ b/protocols/software.c @@ -21,7 +21,7 @@ typedef struct pcilib_software_register_bank_context_s pcilib_software_register_ struct pcilib_software_register_bank_context_s { pcilib_register_bank_context_t bank_ctx; /**< the bank context associated with the software registers */ pcilib_kmem_handle_t *kmem; /**< the kernel memory for software registers */ - void *addr; /**< the virtual adress of the allocated kernel memory*/ + volatile void *addr; /**< the virtual adress of the allocated kernel memory*/ }; void pcilib_software_registers_close(pcilib_t *ctx, pcilib_register_bank_context_t *bank_ctx) { @@ -131,7 +131,7 @@ int pcilib_software_registers_read(pcilib_t *ctx, pcilib_register_bank_context_t return PCILIB_ERROR_INVALID_ADDRESS; } - pcilib_datacpy(&val, ((pcilib_software_register_bank_context_t*)bank_ctx)->addr + addr, access, 1, b->raw_endianess); + pcilib_datacpy(&val, (void*)((pcilib_software_register_bank_context_t*)bank_ctx)->addr + addr, access, 1, b->raw_endianess); *value = val; return 0; @@ -147,7 +147,7 @@ int pcilib_software_registers_write(pcilib_t *ctx, pcilib_register_bank_context_ } // we consider this atomic operation and, therefore, do no locking - pcilib_datacpy(((pcilib_software_register_bank_context_t*)bank_ctx)->addr + addr, &value, access, 1, b->raw_endianess); + pcilib_datacpy((void*)((pcilib_software_register_bank_context_t*)bank_ctx)->addr + addr, &value, access, 1, b->raw_endianess); return 0; } diff --git a/pywrap/CMakeLists.txt b/pywrap/CMakeLists.txt index 933d2ff..033298e 100644 --- a/pywrap/CMakeLists.txt +++ b/pywrap/CMakeLists.txt @@ -23,5 +23,4 @@ install(FILES ${CMAKE_CURRENT_BINARY_DIR}/pcilib.py DESTINATION ${PYTHON_INSTALL if (NOT CMAKE_SOURCE_DIR STREQUAL CMAKE_BINARY_DIR) file(COPY ${CMAKE_CURRENT_SOURCE_DIR}/test_pcilib.py DESTINATION ${CMAKE_CURRENT_BINARY_DIR}) - configure_file(pcilib.py pcilib.py) endif(NOT CMAKE_SOURCE_DIR STREQUAL CMAKE_BINARY_DIR) diff --git a/tests/reload.sh b/tests/reload.sh index 62c6e22..13a8c63 100755 --- a/tests/reload.sh +++ b/tests/reload.sh @@ -1,25 +1,26 @@ #! /bin/bash - -device=`lspci -n | grep -m 1 "10ee:" | awk '{print $1}'` -if [ -z "$device" ]; then +devdir=`ls -d /sys/bus/pci/devices/*/driver/module/drivers/pci:pciDriver` +if [ $? -ne 0 ]; then echo "Xilinx device doesn't exist, rescanning..." echo 1 > /sys/bus/pci/rescan exit else + device=`echo $devdir | head -n 1 | cut -c 27-33` echo "Xilinx is located at: " $device fi -echo "remove driver" -rmmod pciDriver echo "remove devices" echo 1 > /sys/bus/pci/devices/0000\:${device:0:2}\:${device:3:4}/remove sleep 1 echo "rescan" echo 1 > /sys/bus/pci/rescan sleep 1 +echo "remove driver" +rmmod pciDriver +sleep 1 echo "instantiate driver" modprobe pciDriver -# for devices with different ID -#echo "10ee 6028" > /sys/bus/pci/drivers/pciDriver/new_id -pci -i -#echo Enabling bus mastering on device $dev -#setpci -s $device 4.w=0x07 +sleep 1 +echo "set bus master dma" +dev=$device +echo Enabling bus mastering on device $dev +setpci -s $dev 4.w=0x07 |