diff options
author | Suren A. Chilingaryan <csa@suren.me> | 2015-04-27 02:28:57 +0200 |
---|---|---|
committer | Suren A. Chilingaryan <csa@suren.me> | 2015-04-27 02:28:57 +0200 |
commit | e1265fa32837f457ee2c2fa259d12c9545af4bbf (patch) | |
tree | 64b8d5f1c81c14f019047b0cb00cb77c2dcecf55 | |
parent | a37beb44d59cca329d0d9345c21505af81030688 (diff) | |
download | ipecamera-e1265fa32837f457ee2c2fa259d12c9545af4bbf.tar.gz ipecamera-e1265fa32837f457ee2c2fa259d12c9545af4bbf.tar.bz2 ipecamera-e1265fa32837f457ee2c2fa259d12c9545af4bbf.tar.xz ipecamera-e1265fa32837f457ee2c2fa259d12c9545af4bbf.zip |
First stand-alone ipecamera implementation
132 files changed, 206 insertions, 17046 deletions
@@ -1,27 +1,5 @@ -*.cmd -pciDriver.ko -pciDriver.mod.c -pci.d -tools.d -modules.order -Module.symvers -./pci -.tmp_versions -cli.d -ipecamera.d -pci.d -tools.d -*.d -CMakeCache.txt CMakeFiles -cmake_install.cmake Makefile -*.so.* +cmake_install.cmake +CMakeCache.txt install_manifest.txt -apps/xilinx -apps/pio_test -apps/compare_to_value -apps/heb_strip_bad_values -*.out -apps/check_counter -apps/lorenzo_ipedma_test @@ -1,18 +0,0 @@ -IPECamera Hardware Bugs -======================= - 1. Strange sequence writting CMOSIS registers - 2. Extra 8 byte padding in the end of frames - 3. Solve the conflict between DMA packet_length register and FPGA registers - 4. Some frame requests are lost - -Incomplete Frames ------------------ - If I'm trying to stream the data, the camera from time to time returns - incomplete frames. The provided part of the frame is coherent. But instead - of at least 3063824 bytes (just full frame without padding, normally I get - more due to the padding) I get only 3063808 bytes. This number 3063808 looks - like to be constant. - - If I send another frame request, however, it looks I got the missing data with - the next frame. - diff --git a/CMakeLists.txt b/CMakeLists.txt index a761acb..f8ccdc2 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -1,81 +1,40 @@ -project(pcitool) +project(ipecamera) -set(PCILIB_VERSION "0.1.0") -set(PCILIB_ABI_VERSION "1") +set(IPECAMERA_VERSION "0.0.1") +set(IPECAMERA_ABI_VERSION "0") cmake_minimum_required(VERSION 2.6) - -set(DISABLE_PCITOOL FALSE CACHE BOOL "Build only the library") - +list(APPEND CMAKE_MODULE_PATH "${CMAKE_SOURCE_DIR}/cmake") find_package(PkgConfig REQUIRED) find_package(Threads REQUIRED) +pkg_check_modules(UFODECODE ufodecode>=0.3 REQUIRED) -#Check in sibling directory -pkg_check_modules(UFODECODE ufodecode>=0.2 REQUIRED) - -if (NOT DISABLE_PCITOOL) - pkg_check_modules(FASTWRITER fastwriter REQUIRED) -endif (NOT DISABLE_PCITOOL) - -set(HEADERS pcilib.h pci.h register.h kmem.h irq.h dma.h event.h default.h tools.h error.h) -add_definitions("-fPIC --std=c99 -Wall -O2") -#add_definitions("-fPIC --std=c99 -Wall -O2 -pthread") - -add_subdirectory(dma) -add_subdirectory(ipecamera) -add_subdirectory(kapture) -add_subdirectory(pcitool) -add_subdirectory(apps) +pkg_check_modules(PCILIB pcitool>=0.2 REQUIRED) +exec_program("pkg-config --variable=plugindir pcitool" OUTPUT_VARIABLE PCILIB_PLUGIN_DIR) include_directories( - ${FASTWRITER_INCLUDE_DIRS} + ${CMAKE_SOURCE_DIR} + ${UFODECODE_INCLUDE_DIRS} + ${PCILIB_INCLUDE_DIRS} ) link_directories( - ${FASTWRITER_LIBRARY_DIRS} ${UFODECODE_LIBRARY_DIRS} + ${PCILIB_LIBRARY_DIRS} ) -add_library(pcilib SHARED pci.c register.c kmem.c irq.c dma.c event.c default.c tools.c error.c) -target_link_libraries(pcilib dma ipecamera kapture ${CMAKE_THREAD_LIBS_INIT} ${UFODECODE_LIBRARIES} ) -add_dependencies(pcilib dma ipecamera) - -set_target_properties(pcilib PROPERTIES - VERSION ${PCILIB_VERSION} - SOVERSION ${PCILIB_ABI_VERSION} -# LINK_FLAGS "-pthread" -# LINK_FLAGS "-pthread -Wl,--whole-archive,dma/libdma.a,ipecamera/libipecamera.a,--no-whole-archive" -) +set(HEADERS ${HEADERS} model.h cmosis.h base.h reader.h events.h data.h private.h ipecamera.h) -if (NOT DISABLE_PCITOOL) - add_executable(pci cli.c) - add_dependencies(pci pcitool) - target_link_libraries(pci pcilib pcitool ${FASTWRITER_LIBRARIES}) - set_target_properties(pci PROPERTIES - LINK_FLAGS ${CMAKE_THREAD_LIBS_INIT} - ) -endif (NOT DISABLE_PCITOOL) +add_library(ipecamera SHARED model.c cmosis.c base.c reader.c events.c data.c) -#set_target_properties(pci PROPERTIES -# LINK_FLAGS "-Wl,pcitool/libpcitool.a" -#) +target_link_libraries(ipecamera ${PCILIB_LIBRARIES} ${CMAKE_THREAD_LIBS_INIT}) -if(NOT DEFINED BIN_INSTALL_DIR) - set(BIN_INSTALL_DIR "${CMAKE_INSTALL_PREFIX}/bin") -endif(NOT DEFINED BIN_INSTALL_DIR) - - -install(TARGETS pcilib - LIBRARY DESTINATION lib${LIB_SUFFIX} +install(FILES ipecamera.h + DESTINATION include ) -if (NOT DISABLE_PCITOOL) - install(TARGETS pci - DESTINATION ${BIN_INSTALL_DIR} - ) -endif (NOT DISABLE_PCITOOL) - -install(FILES pcilib.h - DESTINATION include +install(TARGETS ipecamera + DESTINATION ${PCILIB_PLUGIN_DIR} ) + @@ -1,311 +0,0 @@ -Memory Addressing -================= - There is 3 types of addresses: virtual, physical, and bus. For DMA a bus - address is used. However, on x86 physical and bus addresses are the same (on - other architectures it is not guaranteed). Anyway, this assumption is still - used by xdma driver, it uses phiscal address for DMA access. I have ported - in the same way. Now, we need to provide additionaly bus-addresses in kmem - abstraction and use it in NWL DMA implementation. - -DMA Access Synchronization -========================== - - At driver level, few types of buffers are supported: - * SIMPLE - non-reusable buffers, the use infomation can be used for cleanup - after crashed applications. - * EXCLUSIVE - reusable buffers which can be mmaped by a single appliction - only. There is two modes of these buffers: - + Buffers in a STANDARD mode are created for a single DMA operation and - if such buffer is detected while trying to reuse, the last operation - has failed and reset is needed. - + Buffers in a PERSISTENT mode are preserved between invocations of - control application and cleaned up only after the PERSISTENT flag is - removed - * SHARED - reusable buffers shared by multiple processes. Not really - needed at the moment. - - KMEM_FLAG_HW - indicates that buffer can be used by hardware, acually this - means that DMA will be enabled afterwards. The driver is not able to check - if it really was enable and therefore will block any attempt to release - buffer until KMEM_HW_FLAG is passed to kmem_free routine as well. The later - should only called with KMEM_HW_FLAG after the DMA engine is stopped. Then, - the driver can be realesd by kmem_free if ref count reaches 0. - - KMEM_FLAG_EXCLUSIVE - prevents multiple processes mmaping the buffer - simultaneously. This is used to prevent multiple processes use the same - DMA engine at the same time. When passed to kmem_free, allows to clean - buffers with lost clients even for shared buffers. - - KMEM_FLAG_REUSE - requires reuse of existing buffer. If reusable buffer is - found (non-reusable buffers, i.e. allocated without KMEM_FLAG_REUSE are - ignored), it is returned instead of allocation. Three types of usage - counters are used. At moment of allocation, the HW reference is set if - neccessary. The usage counter is increased by kmem_alloc function and - decreased by kmem_free. Finally, the reference is obtained at returned - during mmap/munmap. So, on kmem_free, we do not clean - a) buffers with reference count above zero or hardware reference set. - REUSE flag should be supplied, overwise the error is returned - b) PERSISTENT buffer. REUSE flash should be supplied, overwise the - error is returned - c) non-exclusive buffers with usage counter above zero (For exclusive - buffer the value of usage counter above zero just means that application - have failed without cleaning buffers first. There is no easy way to - detect that for shared buffers, so it is left as manual operation in - this case) - d) any buffer if KMEM_FLAG_REUSE was provided to function - During module unload, only buffers with references can prevent cleanup. In - this case the only possiblity to free the driver is to call kmem_free - passing FORCE flags. - - KMEM_FLAG_PERSISTENT - if passed to allocation routine, changes mode of - buffer to PERSISTENT, if passed to free routine, vice-versa changes mode - of buffer to NORMAL. Basically, if we call 'pci --dma-start' this flag - should be passed to alloc and if we call 'pci --dma-stop' it should be - passed to free. In other case, the flag should not be present. - - If application crashed, the munmap while be still called cleaning software - references. However, the hardware reference will stay since it is not clear - if hardware channel was closed or not. To lift hardware reference, the - application can be re-executed (or dma_stop called, for instance). - * If there is no hardware reference, the buffers will be reused by next - call to application and for EXCLUSIVE buffer cleaned at the end. For SHARED - buffers they will be cleaned during module cleanup only (no active - references). - * The buffer will be reused by next call which can result in wrong behaviour - if buffer left in incoherent stage. This should be handled on upper level. - - - At pcilib/kmem level synchronization of multiple buffers is performed - * The HW reference and following modes should be consistent between member - parts: REUSABLE, PERSISTENT, EXCLUSIVE (only HW reference and PERSISTENT - mode should be checked, others are handled on dirver level) - * It is fine if only part of buffers are reused and others are newly - allocated. However, on higher level this can be checked and resulting - in failure. - - Treatment of inconsistencies: - * Buffers are in PRESISTENT mode, but newly allocated, OK - * Buffers are reused, but are not in PERSISTENT mode (for EXCLUSIVE buffers - this means that application has crashed during the last execution), OK - * Some of buffers are reused (not just REUSABLE, but actually reused), - others - not, OK until - a) either PERSISTENT flag is set or reused buffers are non-PERSISTENT - b) either HW flag is set or reused buffers does not hold HW reference - * PERSISTENT mode inconsistency, FAIL (even if we are going to set - PERSISTENT mode anyway) - * HW reference inconsistency, FAIL (even if we are going to set - HW flag anyway) - - On allocation error at some of the buffer, call clean routine and - * Preserve PERSISTENT mode and HW reference if buffers held them before - unsuccessful kmem initialization. Until the last failed block, the blocks - of kmem should be consistent. The HW/PERSISTENT flags should be removed - if all reused blocks were in HW/PERSISTENT mode. The last block needs - special treatment. The flags may be removed for the block if it was - HW/PERSISTENT state (and others not). - * Remove REUSE flag, we want to clean if allowed by current buffer status - * EXCLUSIVE flag is not important for kmem_free routine. - - - At DMA level - There is 4 components of DMA access: - * DMA engine enabled/disabled - * DMA engine IRQs enabled/disabled - always enabled at startup - * Memory buffers - * Ring start/stop pointers - - To prevent multiple processes accessing DMA engine in parallel, the first - action is buffer initialization which will fail if buffers already used - * Always with REUSE, EXCLUSIVE, and HW flags - * Optionally with PERSISTENT flag (if DMA_PERSISTENT flag is set) - If another DMA app is running, the buffer allocation will fail (no dma_stop - is executed in this case) - - Depending on PRESERVE flag, kmem_free will be called with REUSE flag - keeping buffer in memory (this is redundant since HW flag is enough) or HW - flag indicating that DMA engine is stopped and buffer could be cleaned. - PERSISTENT flag is defined by DMA_PERSISTENT flag passed to stop routine. - - PRESERVE flag is enforced if DMA_PERSISTENT is not passed to dma_stop - routine and either it: - a) Explicitely set by DMA_PERMANENT flag passed to dma_start - function - b) Implicitely set if DMA engine is already enabled during dma_start, - all buffers are reused, and are in persistent mode. - If PRESERVE flag is on, the engine will not be stopped at the end of - execution (and buffers will stay because of HW flag). - - If buffers are reused and are already in PERSISTENT mode, DMA engine was on - before dma_start (PRESERVE flag is ignored, because it can be enforced), - ring pointers are calculated from LAST_BD and states of ring elements. - If previous application crashed (i.e. buffers may be corrupted). Two - cases are possible: - * If during the call buffers were in non-PERSISTENT mode, it can be - easily detected - buffers are reused, but are not in PERSISTENT mode - (or at least was not before we set them to). In this case we just - reinitialize all buffers. - * If during the call buffers were in PERSISTENT mode, it is up to - user to check their consistency and restart DMA engine.] - - IRQs are enabled and disabled at each call - -DMA Reads -========= -standard: default reading mode, reads a single full packet -multipacket: reads all available packets -waiting multipacket: reads all available packets, after finishing the - last one waiting if new data arrives -exact read: read exactly specified number of bytes (should be - only supported if it is multiple of packets, otherwise - error should be returned) -ignore packets: autoterminate each buffer, depends on engine - configuration - - To handle differnt cases, the value returned by callback function instructs -the DMA library how long to wait for the next data to appear before timing -out. The following variants are possible: -terminate: just bail out -check: no timeout, just check if there is data, otherwise - terminate -timeout: standard DMA timeout, normaly used while receiving - fragments of packet: in this case it is expected - that device has already prepared data and only - the performance of DMA engine limits transfer speed -wait: wait until the data is prepared by the device, this - timeout is specified as argument to the dma_stream - function (standard DMA timeout is used by default) - - first | new_pkt | bufer - -------------------------- -standard wait | term | timeout -multiple packets wait | check | timeout - DMA_READ_FLAG_MULTIPACKET -waiting multipacket wait | wait | timeout - DMA_READ_FLAG_WAIT -exact wait | wait/term | timeout - limited by size parameter -ignore packets wait | wait/check| wait/check - just autoterminated - -Shall we do a special handling in case of overflow? - - -Buffering -========= - The DMA addresses are limited to 32 bits (~4GB for everything). This means we - can't really use DMA pages are sole buffers. Therefore, a second thread, with - a realtime scheduling policy if possible, will be spawned and will copy the - data from the DMA pages into the allocated buffers. On expiration of duration - or number of events set by autostop call, this thread will be stopped but - processing in streaming mode will continue until all copyied data is passed - to the callbacks. - - To avoid stalls, the IPECamera requires data to be read continuously read out. - For this reason, there is no locks in the readout thread. It will simplify - overwrite the old frames if data is not copied out timely. To handle this case - after getting the data and processing it, the calling application should use - return_data function and check return code. This function may return error - indicating that the data was overwritten meanwhile. Hence, the data is - corrupted and shoud be droped by the application. The copy_data function - performs this check and user application can be sure it get coherent data - in this case. - - There is a way to avoid this problem. For raw data, the rawdata callback - can be requested. This callback blocks execution of readout thread and - data may be treated safely by calling application. However, this may - cause problems to electronics. Therefore, only memcpy should be performed - on the data normally. - - The reconstructed data, however, may be safely accessed. As described above, - the raw data will be continuously overwritten by the reader thread. However, - reconstructed data, upon the get_data call, will be protected by the mutex. - - -Register Access Synchronization -=============================== - We need to serialize access to the registers by the different running - applications and handle case when registers are accessed indirectly by - writting PCI BARs (DMA implementations, for instance). - - - Module-assisted locking: - * During initialization the locking context is created (which is basicaly - a kmem_handle of type LOCK_PAGE. - * This locking context is passed to the kernel module along with lock type - (LOCK_BANK) and lock item (BANK ADDRESS). If lock context is already owns - lock on the specified bank, just reference number is increased, otherwise - we are trying to obtain new lock. - * Kernel module just iterates over all registered lock pages and checks if - any holds the specified lock. if not, the lock is obtained and registered - in the our lock page. - * This allows to share access between multiple threads of single application - (by using the same lock page) or protect (by using own lock pages by each of - the threads) - * Either on application cleanup or if application crashed, the memory mapping - of lock page is removed and, hence, locks are freed. - - - Multiple-ways of accessing registers - Because of reference counting, we can successfully obtain locks multiple - times if necessary. The following locks are protecting register access: - a) Global register_read/write lock bank before executing implementation - b) DMA bank is locked by global DMA functions. So we can access the - registers using plain PCI bar read/write. - c) Sequence of register operations can be protected with pcilib_lock_bank - function - Reading raw register space or PCI bank is not locked. - * Ok. We can detect banks which will be affected by PCI read/write and - lock them. But shall we do it? - -Register/DMA Configuration -========================== - - XML description of registers - - Formal XML-based (or non XML-based) language for DMA implementation. - a) Writting/Reading register values - b) Wait until <register1>=<value> on <register2>=<value> report error - c) ... ? - -IRQ Handling -============ - IRQ types: DMA IRQ, Event IRQ, other types - IRQ hardware source: To allow purely user-space implementation, as general - rule, only a single (standard) source should be used. - IRQ source: The dma/event engines, however, may detail this hardware source - and produce real IRQ source basing on the values of registers. For example, - for DMA IRQs the source may present engine number and for Event IRQs the - source may present event type. - - Only types can be enabled or disabled. The sources are enabled/disabled - by enabling/disabling correspondent DMA engines or Event types. The expected - workflow is following: - * We enabling IRQs in user-space (normally setting some registers). Normally, - just an Event IRQs, the DMA if necessary will be managed by DMA engine itself. - * We waiting for standard IRQ from hardware (driver) - * In the user space, we are checking registers to find out the real source - of IRQ (driver reports us just hardware source), generating appropriate - events, and acknowledge IRQ. This is dependent on implementation and should - be managed inside event API. - - I.e. the driver implements just two methods pcilib_wait_irq(hw_source), - pcilib_clear_irq(hw_source). Only a few hardware IRQ sources are defined. - In most cirstumances, the IRQ_SOURCE_DEFAULT is used. - - The DMA engine may provide 3 additional methods, to enable, disable, - and acknowledge IRQ. - - ... To be decided in details upon the need... - -Updating Firmware -================= - - JTag should be connected to USB connector on the board (next to Ethernet) - - The computer should be tourned off and on before programming - - The environment variable should be loaded - . /home/uros/.bashrc - - The application is called 'impact' - No project is needed, cancel initial proposals (No/Cancel) - Double-click on "Boundary Scan" - Right click in the right window and select "Init Chain" - We don't want to select bit file now (Yes and, then, click Cancel) - Right click on second (right) item and choose "Assign new CF file" - Select a bit file. Answer No, we don't want to attach SPI to SPI Prom - Select xv6vlx240t and program it - - Shutdown and start computer - - Firmware are in - v.2: /home/uros/Repo/UFO2_last_good_version_UFO2.bit - v.3: /home/uros/Repo/UFO3 - Step5 - best working revision - Step6 - last revision - -
\ No newline at end of file @@ -1,22 +0,0 @@ -High Priority (we would need it for IPE Camera) -============= - 1. Serialize access to the registers across applications - 2. Protect kmem_entries in the driver using spinlock - 3. Implement pcilib_configure_autotrigger - -Normal Priority (it would make just few things a bit easier) -=============== - 1. Implement software registers (stored in kernel-memory) - 2. Support FIFO reads/writes from/to registers - 3. Provide OR and AND operations on registers in cli - 4. Support writting a data from a binary file in cli - 5. Use bus-addresses instead of physcial addresses for DMA - -Low Priority (only as generalization for other projects) -============ - 1. XML configurations describing registers (and DMA engines?) - 2. Access register/bank lookups using hash tables - 3. Support for Network Registers and Network DMA - 4. Define a syntax for register dependencies / delays (?) - 5. Use pthread_condition_t instead of polling - diff --git a/apps/CMakeLists.txt b/apps/CMakeLists.txt deleted file mode 100644 index 24457e3..0000000 --- a/apps/CMakeLists.txt +++ /dev/null @@ -1,19 +0,0 @@ -include_directories( - ${CMAKE_SOURCE_DIR} -) - -link_directories(${UFODECODE_LIBRARY_DIRS}) - -add_executable(xilinx xilinx.c) -target_link_libraries(xilinx pcilib rt) - -add_executable(lorenzo_ipedma_test lorenzo_ipedma_test.c) -target_link_libraries(lorenzo_ipedma_test pcilib rt) - -add_executable(pio_test pio_test.c) -target_link_libraries(pio_test pcilib rt) - -add_executable(compare_to_value compare_to_value.c) - -add_executable(heb_strip_bad_values heb_strip_bad_values.c) -add_executable(check_counter check_counter.c) diff --git a/apps/check_counter.c b/apps/check_counter.c deleted file mode 100644 index b19b7d0..0000000 --- a/apps/check_counter.c +++ /dev/null @@ -1,45 +0,0 @@ -#include <stdio.h> -#include <stdlib.h> -#include <stdint.h> - -int main(int argc, char *argv[]) { - int block = 0; - uint32_t value = 0; - uint32_t buf[1024]; - - if (argc < 2) { - printf("Usage:\n\t\t%s <file-to-check>\n", argv[0]); - exit(0); - } - - FILE *f = fopen(argv[1], "r"); - if (!f) { - printf("Failed to open file %s\n", argv[1]); - exit(1); - } - - - while (!feof(f)) { - int i, n = fread(buf, 4, 1024, f); - - if (block) i = 0; - else { - i = 1; - value = (buf[0]); - } - - for (; i < n; i++) { - if ((buf[i]) != ++value) { - printf("Pos %lx (Block %i, dword %i) expected %x, but got %x\n", block * 4096 + i * 4, block, i, value, (buf[i])); - exit(1); - } - } - - if (n) block++; - } - - fclose(f); - - printf("Checked %i blocks. All is fine\n", block); - return 0; -} diff --git a/apps/compare_to_value.c b/apps/compare_to_value.c deleted file mode 100644 index 75ad353..0000000 --- a/apps/compare_to_value.c +++ /dev/null @@ -1,66 +0,0 @@ -#include <stdio.h> -#include <stdlib.h> -#include <stdint.h> - -int main(int argc, char *argv[]) { - long i, j, size, num; - size_t count = 0, total = 0; - int offset = 0, toread = 1, toskip = 0; - uint32_t value; - uint32_t *buf; - - if ((argc != 4)&&(argc != 7)) { - printf("Usage: %s <file> <dwords> <value> [offset_dwords read_dwords skip_dwords] \n", argv[0]); - exit(0); - } - - FILE *f = fopen(argv[1], "r"); - if (!f) { - printf("Can't open %s\n", argv[1]); - exit(1); - } - - size = atol(argv[2]); - if (size <= 0) { - printf("Can't parse size %s\n", argv[2]); - exit(1); - } - - if (sscanf(argv[3], "%x", &value) != 1) { - printf("Can't parse register %s\n", argv[3]); - exit(1); - } - - buf = malloc(size * sizeof(uint32_t)); - if (!buf) { - printf("Can't allocate %lu bytes of memory\n", size * sizeof(uint32_t)); - exit(1); - } - - if (argc == 7) { - offset = atoi(argv[4]); - toread = atoi(argv[5]); - toskip = atoi(argv[6]); - } - - - num = fread(buf, 4, size, f); - if (num != size) { - printf("Only %lu of %lu dwords in the file\n", num, size); - exit(1); - } - fclose(f); - - for (i = offset; i < size; i += toskip) { - for (j = 0; j < toread; j++, i++) { - total++; - if (buf[i] != value) { - count++; - } - } - } - free(buf); - - printf("%lu of %lu is wrong\n", count, total); - return 0; -} diff --git a/apps/heb_strip_bad_values.c b/apps/heb_strip_bad_values.c deleted file mode 100644 index e04a53c..0000000 --- a/apps/heb_strip_bad_values.c +++ /dev/null @@ -1,98 +0,0 @@ -#include <stdio.h> -#include <stdlib.h> -#include <stdint.h> -#include <unistd.h> -#include <sys/types.h> -#include <sys/stat.h> - -int main(int argc, char *argv[]) { - long i, num; - size_t count = 0, total = 0, size; - int offset = 3, toread = 1, toskip = 3; - uint32_t value; - uint32_t *buf; - uint32_t expected = 0; - uint32_t blocks = 0, status_good = 0; - - char fixed[4096]; - struct stat st_buf; - - if ((argc != 2)&&(argc != 5)) { - printf("Usage: %s <file> [offset_dwords read_dwords skip_dwords] \n", argv[0]); - exit(0); - } - - FILE *f = fopen(argv[1], "r"); - if (!f) { - printf("Can't open %s\n", argv[1]); - exit(1); - } - - stat(argv[1], &st_buf); - size = st_buf.st_size / sizeof(uint32_t); - - - buf = malloc(size * sizeof(uint32_t)); - if (!buf) { - printf("Can't allocate %lu bytes of memory\n", size * sizeof(uint32_t)); - exit(1); - } - - if (argc == 5) { - offset = atoi(argv[2]); - toread = atoi(argv[3]); - toskip = atoi(argv[4]); - } - - - num = fread(buf, 4, size, f); - if (num != size) { - printf("Failed to read %lu dwords, only %lu read\n", size, num); - exit(1); - } - fclose(f); - - sprintf(fixed, "%s.fixed", argv[1]); - f = fopen(fixed, "w"); - if (!f) { - printf("Failed to open %s for output\n", fixed); - exit(1); - } - - expected = (buf[offset]>>24) + 2; - for (i = 1; i < size; i += (toread + toskip)) { - total++; - - value = buf[i + offset] >> 24; -// printf("0x%lx: value (%lx) = expected (%lx)\n", i + offset, value, expected); - if (value == expected) { - if (!status_good) { - status_good = 1; - blocks++; - } - fwrite(&buf[i], 4, toread + toskip, f); - expected += 2; - if (expected == 0xb8) - expected = 0; - } else if ((!status_good)&&(value == 0)&&((i + toread + toskip)< size)) { - value = buf[i + offset + toread + toskip] >> 24; - if (value == 2) { - status_good = 1; - blocks++; - fwrite(&buf[i], 4, toread + toskip, f); - expected = 2; - } else { - count++; - } - } else { - printf("0x%lx: value (%x) = expected (%x)\n", (i + offset)*sizeof(uint32_t), value, expected); - status_good = 0; - count++; - } - } - fclose(f); - free(buf); - - printf("%lu of %lu is wrong\n", count, total); - return 0; -} diff --git a/apps/lorenzo_ipedma_test.c b/apps/lorenzo_ipedma_test.c deleted file mode 100644 index 3802e78..0000000 --- a/apps/lorenzo_ipedma_test.c +++ /dev/null @@ -1,749 +0,0 @@ -#define _POSIX_C_SOURCE 199309L -#include <stdio.h> -#include <stdlib.h> -#include <string.h> -#include <unistd.h> -#include <stdarg.h> -#include <time.h> -#include <sched.h> -#include <sys/time.h> -#include <sys/types.h> -#include <arpa/inet.h> -#include <sched.h> -#include <errno.h> - -#include "pcilib.h" -#include "irq.h" -#include "kmem.h" - -//#include <sys/ipc.h> -//#include <sys/shm.h> - - -#define DEVICE "/dev/fpga0" - -#define BAR PCILIB_BAR0 -#define USE_RING PCILIB_KMEM_USE(PCILIB_KMEM_USE_USER, 1) -#define USE PCILIB_KMEM_USE(PCILIB_KMEM_USE_USER, 2) -//#define STATIC_REGION 0x80000000 // to reserve 512 MB at the specified address, add "memmap=512M$2G" to kernel parameters - -#define BUFFERS 128 -#define ITERATIONS 1000 -#define DESC_THRESHOLD BUFFERS/8 // Lorenzo: after how many desc the FPGA must update the "written descriptor counter" in PC mem - // if set to 0, the update only happens when INT is received - -#define HUGE_PAGE 1 // number of pages per huge page -#define TLP_SIZE 32 // TLP SIZE = 64 for 256B payload, 32 for 128B payload -#define PAGE_SIZE 4096 // other values are not supported in the kernel - -//#define USE_64 // Lorenzo: use 64bit addressing - -//#define DUAL_CORE // Lorenzo: DUAL Core - -//#define SHARED_MEMORY // Lorenzo: Test for fast GUI - -#define CHECK_READY // Lorenzo: Check if PCI-Express is ready by reading 0x0 -#define CHECK_RESULTS // Lorenzo: Check if data received is ok (only for counter!) -//#define PRINT_RESULTS // Lorenzo: Save the received data in "data.out" -//#define EXIT_ON_EMPTY // Lorenzo: Exit if an "empty_detected" signal is received - -//#define HEB // Lorenzo: Testing HEB -//#define SWITCH_GENERATOR // Lorenzo: Testing HEB -> Turn data gen on/off - -//#define TEST_DDR // Lorenzo: Testing DDR - -#define TIMEOUT 1000000 - - - -/* IRQs are slow for some reason. REALTIME mode is slower. Adding delays does not really help, - otherall we have only 3 checks in average. Check ready seems to be not needed and adds quite - much extra time */ - -//#define USE_IRQ -//#define REALTIME -//#define ADD_DELAYS - - -#define FPGA_CLOCK 250 // Lorenzo: in MHz ! - - - -//#define WR(addr, value) { val = value; pcilib_write(pci, BAR, addr, sizeof(val), &val); } -//#define RD(addr, value) { pcilib_read(pci, BAR, addr, sizeof(val), &val); value = val; } -#define WR(addr, value) { *(uint32_t*)(bar + addr + offset) = value; } -#define RD(addr, value) { value = *(uint32_t*)(bar + addr + offset); } - -// ************************************************************************************** -// Progress BAR -// Process has done x out of n rounds, -// and we want a bar of width w and resolution r. - static inline void loadBar(int x, int n, int r, int w) - { - // Only update r times. - if ( x % (n/r +1) != 0 ) return; - - // Calculuate the ratio of complete-to-incomplete. - float ratio = x/(float)n; - int c = ratio * w; - - // Show the percentage complete. - printf("%3d%% [", (int)(ratio*100) ); - - // Show the load bar. - for (x=0; x<c; x++) - printf("="); - - for (x=c; x<w; x++) - printf(" "); - - // ANSI Control codes to go back to the - // previous line and clear it. - printf("]\n\033[F\033[J"); - } -// ************************************************************************************** - - - static void fail(const char *msg, ...) { - va_list va; - - va_start(va, msg); - vprintf(msg, va); - va_end(va); - printf("\n"); - - exit(-1); -} - -void hpsleep(size_t ns) { - struct timespec wait, tv; - - clock_gettime(CLOCK_REALTIME, &wait); - - wait.tv_nsec += ns; - if (wait.tv_nsec > 999999999) { - wait.tv_sec += 1; - wait.tv_nsec = 1000000000 - wait.tv_nsec; - } - - do { - clock_gettime(CLOCK_REALTIME, &tv); - } while ((wait.tv_sec > tv.tv_sec)||((wait.tv_sec == tv.tv_sec)&&(wait.tv_nsec > tv.tv_nsec))); -} - - -// ************************************************************************************** -int main() { - - - - int err; - long i, j, k; - int mem_diff; - pcilib_t *pci; - pcilib_kmem_handle_t *kdesc; - pcilib_kmem_handle_t *kbuf; - struct timeval start, end; - size_t run_time, size; - long long int size_mb; - void* volatile bar; - uintptr_t bus_addr[BUFFERS]; - uintptr_t kdesc_bus; - volatile uint32_t *desc; - typedef volatile uint32_t *Tbuf; - Tbuf ptr[BUFFERS]; - int switch_generator = 0; - - float performance, perf_counter; - pcilib_bar_t bar_tmp = BAR; - uintptr_t offset = 0; - - unsigned int temp; - int iterations_completed, buffers_filled; - - -// int shmid; - - - printf("\n\n**** **** **** KIT-DMA TEST **** **** ****\n\n"); - - size = ITERATIONS * BUFFERS * HUGE_PAGE * PAGE_SIZE; - size_mb = ITERATIONS * BUFFERS * HUGE_PAGE * 4 / 1024; - printf("Total size of memory buffer: \t %.3lf GBytes\n", (float)size_mb/1024 ); - printf("Using %d Buffers with %d iterations\n\n", BUFFERS, ITERATIONS ); - -#ifdef ADD_DELAYS - long rpt = 0, rpt2 = 0; - size_t best_time; - best_time = 1000000000L * HUGE_PAGE * PAGE_SIZE / (4L * 1024 * 1024 * 1024); -#endif /* ADD_DELAYS */ - - - pcilib_kmem_flags_t flags = PCILIB_KMEM_FLAG_HARDWARE|PCILIB_KMEM_FLAG_PERSISTENT|PCILIB_KMEM_FLAG_EXCLUSIVE/*|PCILIB_KMEM_FLAG_REUSE*/; // Lorenzo: if REUSE = 1, the re-allocation fails! - pcilib_kmem_flags_t free_flags = PCILIB_KMEM_FLAG_HARDWARE/*|PCILIB_KMEM_FLAG_EXCLUSIVE|PCILIB_KMEM_FLAG_REUSE*/; - pcilib_kmem_flags_t clean_flags = PCILIB_KMEM_FLAG_HARDWARE|PCILIB_KMEM_FLAG_PERSISTENT|PCILIB_KMEM_FLAG_EXCLUSIVE; - - pci = pcilib_open(DEVICE, PCILIB_MODEL_DETECT); - if (!pci) fail("pcilib_open"); - - bar = pcilib_map_bar(pci, BAR); - if (!bar) { - pcilib_close(pci); - fail("map bar"); - } - - pcilib_detect_address(pci, &bar_tmp, &offset, 1); - - pcilib_enable_irq(pci, PCILIB_IRQ_TYPE_ALL, 0); - pcilib_clear_irq(pci, PCILIB_IRQ_SOURCE_DEFAULT); - - pcilib_clean_kernel_memory(pci, USE, clean_flags); - pcilib_clean_kernel_memory(pci, USE_RING, clean_flags); - - kdesc = pcilib_alloc_kernel_memory(pci, PCILIB_KMEM_TYPE_CONSISTENT, 1, 128, 4096, USE_RING, flags); - kdesc_bus = pcilib_kmem_get_block_ba(pci, kdesc, 0); - desc = (uint32_t*)pcilib_kmem_get_block_ua(pci, kdesc, 0); - memset((void*)desc, 0, 5*sizeof(uint32_t)); - -#ifdef REALTIME - pid_t pid; - struct sched_param sched = {0}; - - pid = getpid(); - sched.sched_priority = sched_get_priority_min(SCHED_FIFO); - if (sched_setscheduler(pid, SCHED_FIFO, &sched)) - printf("Warning: not able to get real-time priority\n"); -#endif /* REALTIME */ - - // ****************************************************************** - // **** MEM: check 4k boundary ***** - // ****************************************************************** - - do { - printf("* Allocating KMem, "); -#ifdef STATIC_REGION - kbuf = pcilib_alloc_kernel_memory(pci, PCILIB_KMEM_TYPE_REGION_C2S, BUFFERS, HUGE_PAGE * PAGE_SIZE, STATIC_REGION, USE, flags); -#else - kbuf = pcilib_alloc_kernel_memory(pci, PCILIB_KMEM_TYPE_DMA_C2S_PAGE, BUFFERS, HUGE_PAGE * PAGE_SIZE, 4096, USE, flags); -#endif - - if (!kbuf) { - printf("KMem allocation failed\n"); - exit(0); - } - - // Pointers for Virtualized Mem - for (j = 0; j < BUFFERS; j++) { - ptr[j] = (volatile uint32_t*)pcilib_kmem_get_block_ua(pci, kbuf, j); - memset((ptr[j]), 0, HUGE_PAGE * PAGE_SIZE); - } - - err = 0; - - // Check if HW addresses satisfy 4k boundary condition, if not -> free (!!) and reallocate memory - printf("4k boundary test: "); - for (j = 0; j < BUFFERS; j++) { - temp = (((unsigned int)pcilib_kmem_get_block_ba(pci, kbuf, j)) % 4096); - //printf("%u", temp); - if (temp != 0) { - err = 1; - } - } - if (err == 1) { - pcilib_clean_kernel_memory(pci, USE, clean_flags); - pcilib_clean_kernel_memory(pci, USE_RING, clean_flags); - pcilib_free_kernel_memory(pci, kbuf, free_flags); - printf("failed \xE2\x9C\x98\n"); - } - else printf("passed \xE2\x9C\x93\n"); - - } while (err == 1); - - - // ****************************************************************** - // **** Allocate RAM buffer Memory ***** - // ****************************************************************** - - FILE * Output; - FILE * error_log; - -#ifdef CHECK_RESULTS - - uint32_t *temp_data[ITERATIONS][BUFFERS]; - - for (j=0; j < ITERATIONS; j++) { - for (i=0; i < BUFFERS; i++) { - temp_data[j][i] = (uint32_t *)malloc(HUGE_PAGE*PAGE_SIZE); - if (temp_data[j][i] == 0) { - printf("******* Error: could not allocate memory! ********\n"); - exit(0); - } - memset((void*)(temp_data[j][i]), 0, HUGE_PAGE * PAGE_SIZE); - } - } -#endif - -#ifdef SHARED_MEMORY - // give your shared memory an id, anything will do - key_t key = 123456; - char *shared_memory; - - // Setup shared memory, 11 is the size -/* if ((shmid = shmget(key, HUGE_PAGE*PAGE_SIZE, IPC_CREAT | 0666)) < 0) - { - printf("Error getting shared memory id"); - exit(1); - } - - // Attached shared memory - if ((shared_memory = shmat(shmid, NULL, 0)) == (char *) -1) - { - printf("Error attaching shared memory id"); - exit(1); - } - printf("* Shared memory created... Id:\t %d\n", key); - //////////////// SHARED MEMORY TEST */ -#endif - - Output = fopen ("data.out", "w"); - fclose(Output); - - error_log = fopen ("error_log.txt", "w"); - fclose(error_log); - - // ************************************* - Output = fopen("data.txt", "w"); - fclose(Output); - - // ****************************************************************** - // **** PCIe TEST ***** - // ****************************************************************** - - // Reset DMA - printf("* DMA: Reset...\n"); - WR(0x00, 0x1); - usleep(100000); - WR(0x00, 0x0); - usleep(100000); - -#ifdef CHECK_READY - printf("* PCIe: Testing..."); - RD(0x0, err); - if (err != 335746816) { - printf("\xE2\x9C\x98\n PCIe not ready!\n"); - exit(0); - } else { - printf("\xE2\x9C\x93 \n"); - } -#endif - - - // ****************************************************************** - // **** DMA CONFIGURATION ***** - // ****************************************************************** - - - printf("* DMA: Start Data Generator...\n"); - WR(0x04, 0x10) // Start data generator - - printf("* DMA: Send Data Fill Pattern 55aa55aa\n"); - WR(0x14, 0xbeef); - - printf("* DMA: Send Data Amount\n"); -#ifdef DUAL_CORE - WR(0x10, (HUGE_PAGE * (PAGE_SIZE / (4 * TLP_SIZE)))/2); -#else - WR(0x10, (HUGE_PAGE * (PAGE_SIZE / (4 * TLP_SIZE)))); -#endif - - printf("* DMA: Running mode: "); -#ifdef USE_64 - if (TLP_SIZE == 64) - { - WR(0x0C, 0x80040); - printf ("64bit - 256B Payload\n"); - } - else if (TLP_SIZE == 32) - { - WR(0x0C, 0x80020); - printf ("64bit - 128B Payload\n"); - } -#else - if (TLP_SIZE == 64) - { - WR(0x0C, 0x0040); - printf ("32bit - 256B Payload\n"); - } - else if (TLP_SIZE == 32) - { - WR(0x0C, 0x0020); - printf ("32bit - 128B Payload\n"); - } -#endif - - printf("* DMA: Reset Desc Memory...\n"); - WR(0x5C, 0x00); // RST Desc Memory - - //printf("Writing SW Read Descriptor\n"); - WR(0x58, BUFFERS-1); - //WR(0x58, 0x01); - - //printf("Writing the Descriptor Threshold\n"); - WR(0x60, DESC_THRESHOLD); - - //printf("Writing HW write Descriptor Address: %lx\n", kdesc_bus); - WR(0x54, kdesc_bus); - usleep(100000); - - printf("* DMA: Writing Descriptors\n"); - for (j = 0; j < BUFFERS; j++ ) { - bus_addr[j] = pcilib_kmem_get_block_ba(pci, kbuf, j); - // LEAVE THIS DELAY???!?!?!?! - usleep(1000); - printf("Writing descriptor num. %ld: \t %08lx \r", j, bus_addr[j]); - WR(0x50, bus_addr[j]); - } - - // ****************************************************************** - // **** HEB CONFIGURATION ***** - // ****************************************************************** -#ifdef HEB - - - printf("* DDR REGISTERS: AXI_BUF_SIZE \n"); - WR(0x9130, 0x1000); - - usleep(100000); - - printf("* HEB: Control \n"); - WR(0x9040, 0x00000001); - - usleep(100000); - - printf("* HEB: Control \n"); - WR(0x9040, 0x00000004); - - usleep(100000); - - printf("* HEB: Control \n"); - WR(0x9040, 0x00000000); - - usleep(100000); - - printf("* HEB: Writing Total Orbit Num\n"); - WR(0x9020, 0x2000); - - printf("* HEB: Orbit Skip Num h9028\n"); - WR(0x9028, 0x4); - - //printf("* HEB: LVDS_DELAY h9080\n"); - //WR(0x9080, 0x10101010); - - //printf("* HEB: Delay ADCs \n"); - //WR(0x9088, 0x001); - //WR(0x9090, 0x001); - //WR(0x9094, 0x001); - //WR(0x9098, 0x001); - - //printf("* HEB: Delay TH \n"); - //WR(0x90a0, 0x005); - - //printf("* HEB: Delay_FPGA_reg \n"); - //WR(0x90a8, 0x006); - - //printf("* HEB: Control \n"); - //WR(0x9040, 0x40000000); - - //usleep(1000000); - - printf("* HEB: Control \n"); - WR(0x9040, 0x40000bf0); - - usleep(100000); - - printf("* HEB: Control \n"); - WR(0x9040, 0x400003f0); - - usleep(100000); - - printf("* HEB: Control \n"); - WR(0x9040, 0x480007F0); - - usleep(100000); - - printf("* HEB: Control \n"); - WR(0x9040, 0x48000FF0); - - -#endif - - // ****************************************************************** - // **** TEST DDR conf ***** - // ****************************************************************** -#ifdef TEST_DDR - - - printf("* DDR: AXI_BUF_SIZE_ADDR: 4k\n"); - WR(0x9010, 0x04000); - - printf("* DDR: Control \n"); - WR(0x9000, 0x000000F); - - usleep(100000); - WR(0x9000, 0x00000008); - usleep(100000); - WR(0x9000, 0x08000008); - - usleep(50000); - - printf("* DDR: Control \n"); - WR(0x9000, 0x08000208); - - -#endif - - // ****************************************************************** - // **** START DMA ***** - // ****************************************************************** - - //printf ("\n ---- Press ENTER to start DMA ---- \n"); - //getchar(); - - printf("* DMA: Start \n"); - WR(0x04, 0x1f); - gettimeofday(&start, NULL); - - // ****************************************************************** - // **** Handshaking DMA ***** - // ****************************************************************** - - uint32_t curptr = 0, hwptr; - uint32_t curbuf = 0; - int empty = 0; - i = 0; - - - while (i < ITERATIONS) { - j = 0; - // printf("\ndesc0: %lx", htonl(desc[0])); - // printf("\ndesc1: %lx", htonl(desc[1])); - // printf("\ndesc2: %lx", htonl(desc[2])); - // printf("\ndesc3: %lx", htonl(desc[3])); - // printf("\ndesc4: %lx", htonl(desc[4])); - // printf("\ndesc5: %lx", htonl(desc[5])); - //printf("Iteration: %li of %li \r", i+1, ITERATIONS); - //loadBar(i+1, ITERATIONS, ITERATIONS, 30); - // printf("\nhwptr: %zu", hwptr); - // printf("\ncurptr: %zu", curptr); - - do { -#ifdef USE_64 - hwptr = htonl(desc[3]); -#else // 32-bit - hwptr = htonl(desc[4]); -#endif - j++; - //printf("\rcurptr: %lx \t \t hwptr: %lx", curptr, hwptr); - } while (hwptr == curptr); - - do { - pcilib_kmem_sync_block(pci, kbuf, PCILIB_KMEM_SYNC_FROMDEVICE, curbuf); -#ifdef CHECK_RESULTS - memcpy(temp_data[i][curbuf], ptr[curbuf], 4096); -#endif -#ifdef SHARED_MEMORY - memcpy(shared_memory, ptr[curbuf], 4096); -#endif - //printf("\ncurbuf: %08x", curbuf); - //printf("\nbus_addr[curbuf]\n: %08x",bus_addr[curbuf]); - // for (k = 0; k < 63; k++){ - // if (k%16 == 0) printf("\n# %d # :", k); - // printf(" %08x", ptr[curbuf][k]); - // } - //pcilib_kmem_sync_block(pci, kbuf, PCILIB_KMEM_SYNC_TODEVICE, curbuf); - curbuf++; - if (curbuf == BUFFERS) { - i++; - curbuf = 0; -#ifdef SWITCH_GENERATOR - if (switch_generator == 1) { - switch_generator = 0; - WR(0x9040, 0x100007F0); - } else { - WR(0x9040, 0x180007F0); - switch_generator = 1; - } -#endif - if (i >= ITERATIONS) break; - //if (i >= (ITERATIONS - 4) ) WR(0x04, 0x0f); - } - } while (bus_addr[curbuf] != hwptr); - -#ifdef EXIT_ON_EMPTY -#ifdef USE_64 - if (desc[1] != 0) -#else // 32bit - if (desc[2] != 0) -#endif - { - if (bus_addr[curbuf] == hwptr) { - empty = 1; - break; - } - } -#endif - - WR(0x58, curbuf + 1); - //printf("WR %d\n", curbuf + 1); - //printf("%u (%lu)\n", curbuf, j); - curptr = hwptr; - - } - - - - // ****************************************************************** - // **** Read performance and stop DMA ******* - // ****************************************************************** - - gettimeofday(&end, NULL); - WR(0x04, 0x00); - WR(0x01, 0x00); - RD(0x28, perf_counter); - - - - iterations_completed = i; - buffers_filled = curbuf; - if (empty) printf("* DMA: Empty FIFO! Last iteration: %li of %li\n", i+1, ITERATIONS); - printf ("* DMA: Stop\n\n"); - -#ifdef CHECK_RESULTS - printf ("First value:\t %08x\n", temp_data[0][0][0]); - printf ("Last value:\t %08x\n\n", temp_data[ITERATIONS-1][BUFFERS-1][(PAGE_SIZE/4)-4]); -#endif - - // ****************************************************************** - // **** Performance ******* - // ****************************************************************** - printf("Iterations done: %d\n", iterations_completed); - printf("Buffers filled on last iteration: %d\n", buffers_filled); - - - run_time = (end.tv_sec - start.tv_sec) * 1000000 + (end.tv_usec - start.tv_usec); - size = (long long int) (( BUFFERS * (iterations_completed) + buffers_filled) * HUGE_PAGE * PAGE_SIZE); - size_mb = (long long int) (( BUFFERS * (iterations_completed) + buffers_filled) * HUGE_PAGE * 4 / 1024); - printf("Performance: transfered %zu Mbytes in %zu us using %d buffers\n", (size_mb), run_time, BUFFERS); - //printf("Buffers: \t %d \n", BUFFERS); - //printf("Buf_Size: \t %d \n", PAGE_SIZE); - //printf("Perf_counter: \t %f \n", perf_counter); - performance = ((size_mb * FPGA_CLOCK * 1000000)/(perf_counter*256)); - printf("DMA perf counter:\t%d\n", (int)perf_counter); - printf("DMA side:\t\t%.3lf MB/s\n", performance); - printf("PC side:\t\t%.3lf MB/s\n\n", 1000000. * size_mb / run_time ); - - // ****************************************************************** - // **** Read Data ******* - // ****************************************************************** - - - #ifdef PRINT_RESULTS - printf("Writing Data to HDD... \n"); - for (i=0; i < iterations_completed; i++) { - for (j=0; j < BUFFERS; j++) - { - Output = fopen("data.out", "a"); - fwrite(temp_data[i][j], 4096, 1, Output); - fclose(Output); - } - loadBar(i+1, ITERATIONS, ITERATIONS, 30); - } - // Save last partially filled iteration - for (j=0; j < buffers_filled; j++) - { - Output = fopen("data.out", "a"); - fwrite(temp_data[iterations_completed][j], 4096, 1, Output); - fclose(Output); - } - printf("Data saved in data.out. \n"); - #endif - - #ifdef CHECK_RESULTS - err = 0; - error_log = fopen ("error_log.txt", "a"); - printf("\nChecking data ...\n"); - for (i=0; i < iterations_completed; i++) { - for (j = 0; j < BUFFERS; j++) { - for (k = 0; k < 1024 ; k++) - { - mem_diff = ((uint32_t)temp_data[i][j][k] - (uint32_t)temp_data[i][j][k+1]); - //if ((mem_diff == 1) || (mem_diff == (-7)) || (k == 1023) ) - if ((mem_diff == -1) || (k == 1023) ) - {;} - else { - fprintf(error_log, "Error in: \t IT %li \t BUF : %li \t OFFSET: %li \t | %08x --> %08x - DIFF: %d \n", i, j, k, temp_data[i][j][k], temp_data[i][j][k+1], mem_diff); - err++; - } - } - if (j != BUFFERS-1) { - // Check first and Last - mem_diff = (uint32_t)(temp_data[i][j+1][0] - temp_data[i][j][1023]); - if (mem_diff == (1)) - {;} - else { - fprintf(error_log, "Error_2 in: \t IT %li \t BUF : %li \t OFFSET: %li \t | %08x --> %08x - DIFF: %d \n", i, j, k, temp_data[i][j+1][0], temp_data[i][j][1023], mem_diff); - err++; - } - } - - } - loadBar(i+1, ITERATIONS, ITERATIONS, 30); - } - for (j = 0; j < buffers_filled; j++) { - for (k = 0; k < 1024 ; k++) - { - mem_diff = ((uint32_t)temp_data[iterations_completed][j][k] - (uint32_t)temp_data[iterations_completed][j][k+1]); - if ((mem_diff == -1) || (k == 1023) ) - {;} - else { - fprintf(error_log, "Error in: \t IT %li \t BUF : %li \t OFFSET: %li \t | %08x --> %08x - DIFF: %d \n", iterations_completed, j, k, temp_data[iterations_completed][j][k], temp_data[iterations_completed][j][k+1], mem_diff); - err++; - } - } - if (j != buffers_filled-1) { - // Check first and Last - mem_diff = (uint32_t)(temp_data[i][j+1][0] - temp_data[i][j][1023]); - if (mem_diff == (1)) - {;} - else { - fprintf(error_log, "Error_2 in: \t IT %li \t BUF : %li \t OFFSET: %li \t | %08x --> %08x - DIFF: %d \n", iterations_completed, j, k, temp_data[iterations_completed][j+1][0], temp_data[iterations_completed][j][1023], mem_diff); - err++; - } - } - } - if (err != 0) printf("\rChecking data: \xE2\x9C\x98 %d errors found \n See \"error_log.txt\" for details \n\n", err); - else printf("\rChecking data: \xE2\x9C\x93 no errors found \n\n"); - fclose(error_log); - #endif - - - // *********** Free Memory -#ifdef CHECK_RESULTS - for (i=0; i < ITERATIONS; i++) { - for (j=0; j < BUFFERS; j++) - { - free(temp_data[i][j]); - } - } -#endif CHECK_RESULTS - - pcilib_free_kernel_memory(pci, kbuf, free_flags); - pcilib_free_kernel_memory(pci, kdesc, free_flags); - pcilib_disable_irq(pci, 0); - pcilib_unmap_bar(pci, BAR, bar); - pcilib_close(pci); - -// shmdt(shmid); -// shmctl(shmid, IPC_RMID, NULL); - -} diff --git a/apps/pio_test.c b/apps/pio_test.c deleted file mode 100644 index 84439ee..0000000 --- a/apps/pio_test.c +++ /dev/null @@ -1,96 +0,0 @@ -#define _BSD_SOURCE -#define _POSIX_C_SOURCE 199309L -#include <stdio.h> -#include <stdlib.h> -#include <unistd.h> -#include <stdarg.h> -#include <time.h> -#include <sched.h> -#include <sys/time.h> - -#include "pcilib.h" -#include "irq.h" -#include "kmem.h" - -#define DEVICE "/dev/fpga0" -//#define REALTIME - -#define BAR PCILIB_BAR0 -#define BITS 32 -#define MASK ((1ll << BITS) - 1) - - -#define WR(addr, value) { *(uint32_t*)(bar + addr) = value; } -#define RD(addr, value) { value = *(uint32_t*)(bar + addr); } - -unsigned long long bits[BITS]; - -int main(int argc, char *argv[]) { - uint32_t i, j; - pcilib_t *pci; - uint32_t reg, value, diff, errors; - void* volatile bar; - - unsigned long long attempts = 0, failures = 0; - - if (argc < 2) { - printf("Usage: %s <register>\n", argv[0]); - exit(0); - } - - if (sscanf(argv[1], "%x", ®) != 1) { - printf("Can't parse register %s\n", argv[1]); - exit(1); - } - -#ifdef REALTIME - pid_t pid; - struct sched_param sched = {0}; - - pid = getpid(); - sched.sched_priority = sched_get_priority_min(SCHED_FIFO); - if (sched_setscheduler(pid, SCHED_FIFO, &sched)) - printf("Warning: not able to get real-time priority\n"); -#endif /* REALTIME */ - - pci = pcilib_open(DEVICE, PCILIB_MODEL_DETECT); - if (!pci) { - printf("pcilib_open\n"); - exit(1); - } - - bar = pcilib_map_bar(pci, BAR); - if (!bar) { - pcilib_close(pci); - printf("map bar\n"); - exit(1); - } - - for (i = 0; 1; i++) { - WR(reg, (i%MASK)); - RD(reg, value); - - attempts++; - if (value != (i%MASK)) { - failures++; - - diff = value ^ (i%MASK); - for (errors = 0, j = 0; j < BITS; j++) - if (diff&(1<<j)) errors++; - bits[errors]++; - - //printf("written: %x, read: %x\n", i, value); - } - - if ((i % 1048576 ) == 0) { - printf("Attempts %llu, failures %llu (", attempts, failures); - for (j = 1; j < BITS; j++) - printf("%llu ", bits[j]); - printf(")\n"); - } - - } - - pcilib_unmap_bar(pci, BAR, bar); - pcilib_close(pci); -} diff --git a/apps/xilinx.c b/apps/xilinx.c deleted file mode 100644 index 757c388..0000000 --- a/apps/xilinx.c +++ /dev/null @@ -1,225 +0,0 @@ -#define _BSD_SOURCE -#define _POSIX_C_SOURCE 199309L -#include <stdio.h> -#include <stdlib.h> -#include <string.h> -#include <unistd.h> -#include <stdarg.h> -#include <time.h> -#include <sched.h> -#include <sys/time.h> - -#include "pcilib.h" -#include "irq.h" -#include "kmem.h" - -#define DEVICE "/dev/fpga0" -#define BAR PCILIB_BAR0 -#define USE PCILIB_KMEM_USE(PCILIB_KMEM_USE_USER, 1) -#define STATIC_REGION 0x80000000 // to reserve 512 MB at the specified address, add "memmap=512M$2G" to kernel parameters -#define BUFFERS 1 -#define ITERATIONS 100 -#define TLP_SIZE 64 -#define HUGE_PAGE 4096 // number of pages per huge page -#define PAGE_SIZE 4096 // other values are not supported in the kernel -#define TIMEOUT 100000 - -/* IRQs are slow for some reason. REALTIME mode is slower. Adding delays does not really help, -otherall we have only 3 checks in average. Check ready seems to be not needed and adds quite -much extra time */ -#define USE_IRQ -//#define CHECK_READY -//#define REALTIME -//#define ADD_DELAYS -#define CHECK_RESULT - -//#define WR(addr, value) { val = value; pcilib_write(pci, BAR, addr, sizeof(val), &val); } -//#define RD(addr, value) { pcilib_read(pci, BAR, addr, sizeof(val), &val); value = val; } -#define WR(addr, value) { *(uint32_t*)(bar + addr + offset) = value; } -#define RD(addr, value) { value = *(uint32_t*)(bar + addr + offset); } - -static void fail(const char *msg, ...) { - va_list va; - - va_start(va, msg); - vprintf(msg, va); - va_end(va); - printf("\n"); - - exit(-1); -} - -void hpsleep(size_t ns) { - struct timespec wait, tv; - - clock_gettime(CLOCK_REALTIME, &wait); - - wait.tv_nsec += ns; - if (wait.tv_nsec > 999999999) { - wait.tv_sec += 1; - wait.tv_nsec = 1000000000 - wait.tv_nsec; - } - - do { - clock_gettime(CLOCK_REALTIME, &tv); - } while ((wait.tv_sec > tv.tv_sec)||((wait.tv_sec == tv.tv_sec)&&(wait.tv_nsec > tv.tv_nsec))); -} - - -int main() { - int err; - long i, j; - pcilib_t *pci; - pcilib_kmem_handle_t *kbuf; - uint32_t status; - struct timeval start, end; - size_t size, run_time; - void* volatile bar; - uintptr_t bus_addr[BUFFERS]; - - pcilib_bar_t bar_tmp = BAR; - uintptr_t offset = 0; - - pcilib_kmem_flags_t clean_flags = PCILIB_KMEM_FLAG_HARDWARE|PCILIB_KMEM_FLAG_PERSISTENT|PCILIB_KMEM_FLAG_EXCLUSIVE; - -#ifdef ADD_DELAYS - long rpt = 0, rpt2 = 0; - size_t best_time; - best_time = 1000000000L * HUGE_PAGE * PAGE_SIZE / (4L * 1024 * 1024 * 1024); -#endif /* ADD_DELAYS */ - -#ifdef REALTIME - pid_t pid; - struct sched_param sched = {0}; - - pid = getpid(); - sched.sched_priority = sched_get_priority_min(SCHED_FIFO); - if (sched_setscheduler(pid, SCHED_FIFO, &sched)) - printf("Warning: not able to get real-time priority\n"); -#endif /* REALTIME */ - - pci = pcilib_open(DEVICE, PCILIB_MODEL_DETECT); - if (!pci) fail("pcilib_open"); - - bar = pcilib_map_bar(pci, BAR); - if (!bar) { - pcilib_close(pci); - fail("map bar"); - } - - pcilib_detect_address(pci, &bar_tmp, &offset, 1); - - // Reset - WR(0x00, 1) - usleep(1000); - WR(0x00, 0) - - pcilib_enable_irq(pci, PCILIB_IRQ_TYPE_ALL, 0); - pcilib_clear_irq(pci, PCILIB_IRQ_SOURCE_DEFAULT); - - pcilib_clean_kernel_memory(pci, USE, clean_flags); - -#ifdef STATIC_REGION - kbuf = pcilib_alloc_kernel_memory(pci, PCILIB_KMEM_TYPE_REGION_C2S, BUFFERS, HUGE_PAGE * PAGE_SIZE, STATIC_REGION, USE, 0); -#else /* STATIC_REGION */ - kbuf = pcilib_alloc_kernel_memory(pci, PCILIB_KMEM_TYPE_DMA_C2S_PAGE, BUFFERS, HUGE_PAGE * PAGE_SIZE, 4096, USE, 0); -#endif /* STATIC_REGION */ - - if (!kbuf) { - printf("KMem allocation failed\n"); - exit(0); - } - - -#ifdef CHECK_RESULT - volatile uint32_t *ptr0 = pcilib_kmem_get_block_ua(pci, kbuf, 0); - - memset((void*)ptr0, 0, (HUGE_PAGE * PAGE_SIZE)); - - for (i = 0; i < (HUGE_PAGE * PAGE_SIZE / 4); i++) { - if (ptr0[i] != 0) break; - } - if (i < (HUGE_PAGE * PAGE_SIZE / 4)) { - printf("Initialization error in position %lu, value = %x\n", i * 4, ptr0[i]); - } -#endif /* CHECK_RESULT */ - - WR(0x04, 0) - WR(0x0C, TLP_SIZE) - WR(0x10, (HUGE_PAGE * (PAGE_SIZE / (4 * TLP_SIZE)))) - WR(0x14, 0x13131313) - - for (j = 0; j < BUFFERS; j++ ) { - bus_addr[j] = pcilib_kmem_get_block_ba(pci, kbuf, j); - } - - gettimeofday(&start, NULL); - - for (i = 0; i < ITERATIONS; i++) { - for (j = 0; j < BUFFERS; j++ ) { -// uintptr_t ba = pcilib_kmem_get_block_ba(pci, kbuf, j); -// WR(0x08, ba) - WR(0x08, bus_addr[j]); - WR(0x04, 0x01) - -#ifdef USE_IRQ - err = pcilib_wait_irq(pci, PCILIB_IRQ_SOURCE_DEFAULT, TIMEOUT, NULL); - if (err) printf("Timeout waiting for IRQ, err: %i\n", err); - - RD(0x04, status); - if ((status&0xFFFF) != 0x101) printf("Invalid status %x\n", status); -// WR(0x04, 0x00); -#else /* USE_IRQ */ -# ifdef ADD_DELAYS -// hpsleep(best_time); - do { - rpt++; - RD(0x04, status); - } while (status != 0x101); -# else /* ADD_DELAYS */ - do { - RD(0x04, status); - } while (status != 0x101); -# endif /* ADD_DELAYS */ -#endif /* USE_IRQ */ - - WR(0x00, 1) -#ifdef CHECK_READY - do { - rpt2++; - RD(0x04, status); - } while (status != 0); -#endif /* CHECK_READY */ - WR(0x00, 0) - } - } - gettimeofday(&end, NULL); - -#ifdef CHECK_RESULT - pcilib_kmem_sync_block(pci, kbuf, PCILIB_KMEM_SYNC_FROMDEVICE, 0); - - for (i = 0; i < (HUGE_PAGE * PAGE_SIZE / 4); i++) { -// printf("%lx ", ptr0[i]); - if (ptr0[i] != 0x13131313) break; - } - if (i < (HUGE_PAGE * PAGE_SIZE / 4)) { - printf("Error in position %lu, value = %x\n", i * 4, ptr0[i]); - } -#endif /* CHECK_RESULT */ - - pcilib_free_kernel_memory(pci, kbuf, 0); - pcilib_disable_irq(pci, 0); - pcilib_unmap_bar(pci, BAR, bar); - pcilib_close(pci); - - run_time = (end.tv_sec - start.tv_sec) * 1000000 + (end.tv_usec - start.tv_usec); - size = (long long int)ITERATIONS * BUFFERS * HUGE_PAGE * PAGE_SIZE; - - printf("%.3lf GB/s: transfered %zu bytes in %zu us using %u buffers\n", 1000000. * size / run_time / 1024 / 1024 / 1024, size, run_time, BUFFERS); - -# ifdef ADD_DELAYS - printf("Repeats: %lf, %lf\n",1. * rpt / (ITERATIONS * BUFFERS), 1. * rpt2 / (ITERATIONS * BUFFERS)); -#endif /* USE_IRQ */ - - -} diff --git a/ipecamera/ipecamera.c b/base.c index 892c59e..3d06bf3 100644 --- a/ipecamera/ipecamera.c +++ b/base.c @@ -12,11 +12,11 @@ #include <ufodecode.h> -#include "../tools.h" -#include "../error.h" -#include "../event.h" +#include <pcilib.h> +#include <pcilib/tools.h> +#include <pcilib/error.h> +#include <pcilib/event.h> -#include "pcilib.h" #include "private.h" #include "model.h" #include "reader.h" @@ -24,8 +24,6 @@ #include "data.h" -#include "dma/nwl.h" - #define FIND_REG(var, bank, name) \ ctx->var = pcilib_find_register(pcilib, bank, name); \ if (ctx->var == PCILIB_REGISTER_INVALID) { \ @@ -38,7 +36,7 @@ if (!err) { \ err = pcilib_read_register_by_id(pcilib, ctx->reg, &var); \ if (err) { \ - pcilib_error("Error reading %s register", ipecamera_registers[ctx->reg].name); \ + pcilib_error("Error reading %s register", model_info->registers[ctx->reg].name); \ } \ } @@ -46,7 +44,7 @@ if (!err) { \ err = pcilib_write_register_by_id(pcilib, ctx->reg, val); \ if (err) { \ - pcilib_error("Error writting %s register", ipecamera_registers[ctx->reg].name); \ + pcilib_error("Error writting %s register", model_info->registers[ctx->reg].name); \ } \ } @@ -54,16 +52,16 @@ if (!err) { \ err = pcilib_read_register_by_id(pcilib, ctx->reg, &value); \ if (err) { \ - pcilib_error("Error reading %s register", ipecamera_registers[ctx->reg].name); \ + pcilib_error("Error reading %s register", model_info->registers[ctx->reg].name); \ } \ if (value != check) { \ - pcilib_error("Unexpected value (0x%lx) of register %s", value, ipecamera_registers[ctx->reg].name); \ + pcilib_error("Unexpected value (0x%lx) of register %s", value, model_info->registers[ctx->reg].name); \ err = PCILIB_ERROR_INVALID_DATA; \ } \ } -#define IPECAMERA_GET_EXPECTED_STATUS(ctx) ((ctx->firmware == 4)?IPECAMERA_EXPECTED_STATUS_4:IPECAMERA_EXPECTED_STATUS) -#define CHECK_STATUS_REG() CHECK_REG(status_reg, IPECAMERA_GET_EXPECTED_STATUS(ctx)) +#define CHECK_STATUS() + //CHECK_REG(status_reg, IPECAMERA_GET_EXPECTED_STATUS(ctx)) #define CHECK_VALUE(value, val) \ if ((!err)&&(value != val)) { \ @@ -81,6 +79,8 @@ pcilib_context_t *ipecamera_init(pcilib_t *pcilib) { int err = 0; + const pcilib_model_description_t *model_info = pcilib_get_model_description(pcilib); + ipecamera_t *ctx = malloc(sizeof(ipecamera_t)); if (ctx) { @@ -115,13 +115,12 @@ pcilib_context_t *ipecamera_init(pcilib_t *pcilib) { GET_REG(firmware_version_reg, value); switch (value) { - case 4: case 5: ctx->firmware = value; break; default: -// pcilib_error("Unsupported version of firmware (%lu)", value); - ctx->firmware = 0; + ctx->firmware = 5; + pcilib_warning("Unsupported version of firmware (%lu)", value); } #ifdef IPECAMERA_BUG_POSTPONED_READ @@ -153,26 +152,19 @@ void ipecamera_free(pcilib_context_t *vctx) { } pcilib_dma_context_t *ipecamera_init_dma(pcilib_context_t *vctx) { -#ifdef IPECAMERA_DMA_R3 ipecamera_t *ctx = (ipecamera_t*)vctx; -#endif - pcilib_model_description_t *model_info = pcilib_get_model_description(vctx->pcilib); - if ((!model_info->dma_api)||(!model_info->dma_api->init)) { + const pcilib_model_description_t *model_info = pcilib_get_model_description(vctx->pcilib); + if ((!model_info->dma)||(!model_info->dma->api)||(!model_info->dma->api->init)) { pcilib_error("The DMA engine is not configured in model"); return NULL; } - -#ifdef IPECAMERA_DMA_R3 if (ctx->firmware) { - return model_info->dma_api->init(vctx->pcilib, PCILIB_NWL_MODIFICATION_IPECAMERA, NULL); + return model_info->dma->api->init(vctx->pcilib, NULL, NULL); } else { - return model_info->dma_api->init(vctx->pcilib, PCILIB_DMA_MODIFICATION_DEFAULT, NULL); + return model_info->dma->api->init(vctx->pcilib, "pci", NULL); } -#else - return model_info->dma_api->init(vctx->pcilib, PCILIB_DMA_MODIFICATION_DEFAULT, NULL); -#endif } @@ -258,17 +250,19 @@ int ipecamera_reset(pcilib_context_t *vctx) { usleep(10000); - err = pcilib_read_register_by_id(pcilib, status, &value); + + CHECK_STATUS(); if (err) { - pcilib_error("Error reading status register"); - return err; - } + err = pcilib_read_register_by_id(pcilib, status, &value); + + if (err) pcilib_error("Error reading status register"); + else pcilib_error("Camera returns unexpected status (status: %lx)", value); - if (value != IPECAMERA_GET_EXPECTED_STATUS(ctx)) { - pcilib_error("Unexpected value (%lx) of status register, expected %lx", value, IPECAMERA_GET_EXPECTED_STATUS(ctx)); return PCILIB_ERROR_VERIFY; } + // DS: Get rid of pending DMA data + return 0; } @@ -276,10 +270,13 @@ int ipecamera_reset(pcilib_context_t *vctx) { int ipecamera_start(pcilib_context_t *vctx, pcilib_event_t event_mask, pcilib_event_flags_t flags) { int i; int err = 0; + ipecamera_t *ctx = (ipecamera_t*)vctx; pcilib_t *pcilib = vctx->pcilib; pcilib_register_value_t value; + const pcilib_model_description_t *model_info = pcilib_get_model_description(pcilib); + pthread_attr_t attr; struct sched_param sched; @@ -298,16 +295,6 @@ int ipecamera_start(pcilib_context_t *vctx, pcilib_event_t event_mask, pcilib_ev return PCILIB_ERROR_INVALID_REQUEST; } - // Allow readout and clean the FRAME_REQUEST mode if set for some reason - usleep(IPECAMERA_SLEEP_TIME); - if (value&0x1000) ctx->fr_mode = 1; - else { - ctx->fr_mode = 0; - -// CHECK_STATUS_REG(); -// if (err) return err; - } - ctx->event_id = 0; ctx->preproc_id = 0; ctx->reported_id = 0; @@ -642,6 +629,8 @@ int ipecamera_trigger(pcilib_context_t *vctx, pcilib_event_t event, size_t trigg ipecamera_t *ctx = (ipecamera_t*)vctx; pcilib_t *pcilib = vctx->pcilib; + const pcilib_model_description_t *model_info = pcilib_get_model_description(pcilib); + if (!ctx) { pcilib_error("IPECamera imaging is not initialized"); return PCILIB_ERROR_NOTINITIALIZED; @@ -685,7 +674,7 @@ int ipecamera_trigger(pcilib_context_t *vctx, pcilib_event_t event, size_t trigg GET_REG(control_reg, value); SET_REG(control_reg, value|IPECAMERA_FRAME_REQUEST); usleep(IPECAMERA_WAIT_FRAME_RCVD_TIME); - //CHECK_REG(status_reg, IPECAMERA_EXPECTED_STATUS); + //DS: CHECK_REG(status_reg, IPECAMERA_EXPECTED_STATUS); SET_REG(control_reg, value); // We need to compute it differently, on top of that add exposure time and the time FPGA takes to read frame from CMOSIS diff --git a/ipecamera/public.h b/base.h index 5f494c2..beb3e1f 100644 --- a/ipecamera/public.h +++ b/base.h @@ -1,11 +1,10 @@ -#ifndef _IPECAMERA_PUBLIC_H -#define _IPECAMERA_PUBLIC_H +#ifndef _IPECAMERA_BASE_H +#define _IPECAMERA_BASE_H #include <stdio.h> +#include <pcilib.h> #include "ipecamera.h" -#include "../pcilib.h" - pcilib_context_t *ipecamera_init(pcilib_t *pcilib); void ipecamera_free(pcilib_context_t *ctx); @@ -22,4 +21,4 @@ int ipecamera_next_event(pcilib_context_t *vctx, pcilib_timeout_t timeout, pcili int ipecamera_get(pcilib_context_t *ctx, pcilib_event_id_t event_id, pcilib_event_data_type_t data_type, size_t arg_size, void *arg, size_t *size, void **buf); int ipecamera_return(pcilib_context_t *ctx, pcilib_event_id_t event_id, pcilib_event_data_type_t data_type, void *data); -#endif /* _IPECAMERA_PUBLIC_H */ +#endif /* _IPECAMERA_BASE_H */ @@ -1,3101 +0,0 @@ -#define _POSIX_C_SOURCE 200112L -#define _BSD_SOURCE - -#include <stdio.h> -#include <stdlib.h> -#include <string.h> -#include <strings.h> -#include <stdint.h> -#include <stdarg.h> -#include <fcntl.h> -#include <unistd.h> -#include <sys/time.h> -#include <sys/ioctl.h> -#include <sys/mman.h> -#include <errno.h> -#include <alloca.h> -#include <arpa/inet.h> -#include <sys/types.h> -#include <sys/stat.h> -#include <dirent.h> -#include <pthread.h> -#include <signal.h> - -#include <getopt.h> - -#include <fastwriter.h> - -#include "pcitool/sysinfo.h" -#include "pcitool/formaters.h" - -//#include "pci.h" -#include "tools.h" -#include "kernel.h" -#include "error.h" - -/* defines */ -#define MAX_KBUF 14 -//#define BIGBUFSIZE (512*1024*1024) -#define BIGBUFSIZE (1024*1024) - - -#define DEFAULT_FPGA_DEVICE "/dev/fpga0" - -#define LINE_WIDTH 80 -#define SEPARATOR_WIDTH 2 -#define BLOCK_SEPARATOR_WIDTH 2 -#define BLOCK_SIZE 8 -#define BENCHMARK_ITERATIONS 128 -#define STATUS_MESSAGE_INTERVAL 5 /* seconds */ - - -#define isnumber pcilib_isnumber -#define isxnumber pcilib_isxnumber -#define isnumber_n pcilib_isnumber_n -#define isxnumber_n pcilib_isxnumber_n - -typedef uint8_t access_t; - -typedef enum { - GRAB_MODE_GRAB = 1, - GRAB_MODE_TRIGGER = 2 -} GRAB_MODE; - -typedef enum { - MODE_INVALID, - MODE_INFO, - MODE_LIST, - MODE_BENCHMARK, - MODE_READ, - MODE_READ_REGISTER, - MODE_WRITE, - MODE_WRITE_REGISTER, - MODE_RESET, - MODE_GRAB, - MODE_START_DMA, - MODE_STOP_DMA, - MODE_LIST_DMA, - MODE_LIST_DMA_BUFFERS, - MODE_READ_DMA_BUFFER, - MODE_ENABLE_IRQ, - MODE_DISABLE_IRQ, - MODE_ACK_IRQ, - MODE_WAIT_IRQ, - MODE_ALLOC_KMEM, - MODE_LIST_KMEM, - MODE_READ_KMEM, - MODE_FREE_KMEM -} MODE; - -typedef enum { - ACCESS_BAR, - ACCESS_DMA, - ACCESS_FIFO, - ACCESS_CONFIG -} ACCESS_MODE; - -typedef enum { - FLAG_MULTIPACKET = 1, - FLAG_WAIT = 2 -} FLAGS; - - -typedef enum { - FORMAT_DEFAULT = 0, - FORMAT_RAW, - FORMAT_HEADER, - FORMAT_RINGFS -} FORMAT; - -typedef enum { - PARTITION_UNKNOWN, - PARTITION_RAW, - PARTITION_EXT4, - PARTITION_NULL -} PARTITION; - -typedef enum { - OPT_DEVICE = 'd', - OPT_MODEL = 'm', - OPT_BAR = 'b', - OPT_ACCESS = 'a', - OPT_ENDIANESS = 'e', - OPT_SIZE = 's', - OPT_OUTPUT = 'o', - OPT_TIMEOUT = 't', - OPT_INFO = 'i', - OPT_LIST = 'l', - OPT_READ = 'r', - OPT_WRITE = 'w', - OPT_GRAB = 'g', - OPT_QUIETE = 'q', - OPT_HELP = 'h', - OPT_RESET = 128, - OPT_BENCHMARK, - OPT_TRIGGER, - OPT_DATA_TYPE, - OPT_EVENT, - OPT_TRIGGER_RATE, - OPT_TRIGGER_TIME, - OPT_RUN_TIME, - OPT_FORMAT, - OPT_BUFFER, - OPT_THREADS, - OPT_LIST_DMA, - OPT_LIST_DMA_BUFFERS, - OPT_READ_DMA_BUFFER, - OPT_START_DMA, - OPT_STOP_DMA, - OPT_ENABLE_IRQ, - OPT_DISABLE_IRQ, - OPT_ACK_IRQ, - OPT_WAIT_IRQ, - OPT_ITERATIONS, - OPT_ALLOC_KMEM, - OPT_LIST_KMEM, - OPT_FREE_KMEM, - OPT_READ_KMEM, - OPT_BLOCK_SIZE, - OPT_ALIGNMENT, - OPT_TYPE, - OPT_FORCE, - OPT_VERIFY, - OPT_WAIT, - OPT_MULTIPACKET, - OPT_VERBOSE -} OPTIONS; - -static struct option long_options[] = { - {"device", required_argument, 0, OPT_DEVICE }, - {"model", required_argument, 0, OPT_MODEL }, - {"bar", required_argument, 0, OPT_BAR }, - {"access", required_argument, 0, OPT_ACCESS }, - {"endianess", required_argument, 0, OPT_ENDIANESS }, - {"size", required_argument, 0, OPT_SIZE }, - {"output", required_argument, 0, OPT_OUTPUT }, - {"timeout", required_argument, 0, OPT_TIMEOUT }, - {"iterations", required_argument, 0, OPT_ITERATIONS }, - {"info", no_argument, 0, OPT_INFO }, - {"list", no_argument, 0, OPT_LIST }, - {"reset", no_argument, 0, OPT_RESET }, - {"benchmark", optional_argument, 0, OPT_BENCHMARK }, - {"read", optional_argument, 0, OPT_READ }, - {"write", optional_argument, 0, OPT_WRITE }, - {"grab", optional_argument, 0, OPT_GRAB }, - {"trigger", optional_argument, 0, OPT_TRIGGER }, - {"data", required_argument, 0, OPT_DATA_TYPE }, - {"event", required_argument, 0, OPT_EVENT }, - {"run-time", required_argument, 0, OPT_RUN_TIME }, - {"trigger-rate", required_argument, 0, OPT_TRIGGER_RATE }, - {"trigger-time", required_argument, 0, OPT_TRIGGER_TIME }, - {"format", required_argument, 0, OPT_FORMAT }, - {"buffer", optional_argument, 0, OPT_BUFFER }, - {"threads", optional_argument, 0, OPT_THREADS }, - {"start-dma", required_argument, 0, OPT_START_DMA }, - {"stop-dma", optional_argument, 0, OPT_STOP_DMA }, - {"list-dma-engines", no_argument, 0, OPT_LIST_DMA }, - {"list-dma-buffers", required_argument, 0, OPT_LIST_DMA_BUFFERS }, - {"read-dma-buffer", required_argument, 0, OPT_READ_DMA_BUFFER }, - {"enable-irq", optional_argument, 0, OPT_ENABLE_IRQ }, - {"disable-irq", optional_argument, 0, OPT_DISABLE_IRQ }, - {"acknowledge-irq", optional_argument, 0, OPT_ACK_IRQ }, - {"wait-irq", optional_argument, 0, OPT_WAIT_IRQ }, - {"list-kernel-memory", optional_argument, 0, OPT_LIST_KMEM }, - {"read-kernel-memory", required_argument, 0, OPT_READ_KMEM }, - {"alloc-kernel-memory", required_argument, 0, OPT_ALLOC_KMEM }, - {"free-kernel-memory", required_argument, 0, OPT_FREE_KMEM }, - {"type", required_argument, 0, OPT_TYPE }, - {"block-size", required_argument, 0, OPT_BLOCK_SIZE }, - {"alignment", required_argument, 0, OPT_ALIGNMENT }, - {"quiete", no_argument, 0, OPT_QUIETE }, - {"verbose", optional_argument, 0, OPT_VERBOSE }, - {"force", no_argument, 0, OPT_FORCE }, - {"verify", no_argument, 0, OPT_VERIFY }, - {"multipacket", no_argument, 0, OPT_MULTIPACKET }, - {"wait", no_argument, 0, OPT_WAIT }, - {"help", no_argument, 0, OPT_HELP }, - { 0, 0, 0, 0 } -}; - - -void Usage(int argc, char *argv[], const char *format, ...) { - if (format) { - va_list ap; - - va_start(ap, format); - printf("Error %i: ", errno); - vprintf(format, ap); - printf("\n"); - va_end(ap); - - printf("\n"); - } - - - printf( -"Usage:\n" -" %s <mode> [options] [hex data]\n" -" Modes:\n" -" -i - Device Info\n" -" -l[l] - List (detailed) Data Banks & Registers\n" -" -r <addr|reg|dmaX> - Read Data/Register\n" -" -w <addr|reg|dmaX> - Write Data/Register\n" -" --benchmark <barX|dmaX> - Performance Evaluation\n" -" --reset - Reset board\n" -" --help - Help message\n" -"\n" -" Event Modes:\n" -" --trigger [event] - Trigger Events\n" -" -g [event] - Grab Events\n" -"\n" -" IRQ Modes:\n" -" --enable-irq [type] - Enable IRQs\n" -" --disable-irq [type] - Disable IRQs\n" -" --acknowledge-irq <source> - Clean IRQ queue\n" -" --wait-irq <source> - Wait for IRQ\n" - -" DMA Modes:\n" -" --start-dma <num>[r|w] - Start specified DMA engine\n" -" --stop-dma [num[r|w]] - Stop specified engine or DMA subsystem\n" -" --list-dma-engines - List active DMA engines\n" -" --list-dma-buffers <dma> - List buffers for specified DMA engine\n" -" --read-dma-buffer <dma:buf> - Read the specified buffer\n" -"\n" -" Kernel Modes:\n" -" --list-kernel-memory [use] - List kernel buffers\n" -" --read-kernel-memory <blk> - Read the specified block of the kernel memory\n" -" block is specified as: use:block_number\n" -" --alloc-kernel-memory <use> - Allocate kernel buffers (DANGEROUS)\n" -" --free-kernel-memory <use> - Cleans lost kernel space buffers (DANGEROUS)\n" -" dma - Remove all buffers allocated by DMA subsystem\n" -" #number - Remove all buffers with the specified use id\n" -"\n" -" Addressing:\n" -" -d <device> - FPGA device (/dev/fpga0)\n" -" -m <model> - Memory model (autodetected)\n" -" pci - Plain\n" -" ipecamera - IPE Camera\n" -" -b <bank> - PCI bar, Register bank, or DMA channel\n" -"\n" -" Options:\n" -" -s <size> - Number of words (default: 1)\n" -" -a [fifo|dma|config]<bits> - Access type and bits per word (default: 32)\n" -" -e <l|b> - Endianess Little/Big (default: host)\n" -" -o <file> - Append output to file (default: stdout)\n" -" -t <timeout|unlimited> - Timeout in microseconds\n" -" --check - Verify write operations\n" -"\n" -" Event Options:\n" -" --event <evt> - Specifies event for trigger and grab modes\n" -" --data <type> - Data type to request for the events\n" -" --run-time <us> - Limit time to grab/trigger events\n" -" -t <timeout|unlimited> - Timeout to stop if no events triggered\n" -" --trigger-rate <tps> - Generate tps triggers per second\n" -" --trigger-time <us> - Specifies delay between triggers (us)\n" -" -s <num|unlimited> - Number of events to grab and trigger\n" -" --format [type] - Specifies how event data should be stored\n" -" raw - Just write all events sequentially\n" -" add_header - Prefix events with 512 bit header:\n" -" event(64), data(64), nope(64), size(64)\n" -" seqnum(64), offset(64), timestamp(128)\n" -//" ringfs - Write to RingFS\n" -" --buffer [size] - Request data buffering, size in MB\n" -" --threads [num] - Allow multithreaded processing\n" -"\n" -" DMA Options:\n" -" --multipacket - Read multiple packets\n" -" --wait - Wait until data arrives\n" -"\n" -" Kernel Options:\n" -" --type <type> - Type of kernel memory to allocate\n" -" consistent - Consistent memory\n" -" s2c - DMA S2C (write) memory\n" -" c2s - DMA C2S (read) memory\n" -" --page-size <size> - Size of kernel buffer in bytes (default: page)\n" -" -s <size> - Number of buffers to allocate (default: 1)\n" -" --allignment <alignment> - Buffer alignment (default: page)\n" -"\n" -" Information:\n" -" --verbose [level] - Announce details of ongoing operations\n" -" -q - Quiete mode (suppress warnings)\n" -"\n" -" Data:\n" -" Data can be specified as sequence of hexdecimal number or\n" -" a single value prefixed with '*'. In this case it will be\n" -" replicated the specified amount of times\n" -"\n\n", -argv[0]); - - exit(0); -} - -static int StopFlag = 0; - -static void signal_exit_handler(int signo) { - if (++StopFlag > 2) - exit(-1); -} - - -void Error(const char *format, ...) { - va_list ap; - - va_start(ap, format); - printf("Error %i: ", errno); - vprintf(format, ap); - if (errno) printf("\n errno: %s", strerror(errno)); - printf("\n\n"); - va_end(ap); - - exit(-1); -} - -void Silence(const char *format, ...) { -} - -void List(pcilib_t *handle, pcilib_model_description_t *model_info, const char *bank, int details) { - int i,j; - pcilib_register_bank_description_t *banks; - pcilib_register_description_t *registers; - pcilib_event_description_t *events; - pcilib_event_data_type_description_t *types; - - const pcilib_board_info_t *board_info = pcilib_get_board_info(handle); - const pcilib_dma_info_t *dma_info = pcilib_get_dma_info(handle); - - for (i = 0; i < PCILIB_MAX_BANKS; i++) { - if (board_info->bar_length[i] > 0) { - printf(" BAR %d - ", i); - - switch ( board_info->bar_flags[i]&IORESOURCE_TYPE_BITS) { - case IORESOURCE_IO: printf(" IO"); break; - case IORESOURCE_MEM: printf("MEM"); break; - case IORESOURCE_IRQ: printf("IRQ"); break; - case IORESOURCE_DMA: printf("DMA"); break; - } - - if (board_info->bar_flags[i]&IORESOURCE_MEM_64) printf("64"); - else printf("32"); - - printf(", Start: 0x%08lx, Length: 0x%8lx, Flags: 0x%08lx\n", board_info->bar_start[i], board_info->bar_length[i], board_info->bar_flags[i] ); - } - } - printf("\n"); - - if ((dma_info)&&(dma_info->engines)) { - printf("DMA Engines: \n"); - for (i = 0; dma_info->engines[i]; i++) { - pcilib_dma_engine_description_t *engine = dma_info->engines[i]; - printf(" DMA %2d ", engine->addr); - switch (engine->direction) { - case PCILIB_DMA_FROM_DEVICE: - printf("C2S"); - break; - case PCILIB_DMA_TO_DEVICE: - printf("S2C"); - break; - case PCILIB_DMA_BIDIRECTIONAL: - printf("BI "); - break; - } - printf(" - Type: "); - switch (engine->type) { - case PCILIB_DMA_TYPE_BLOCK: - printf("Block"); - break; - case PCILIB_DMA_TYPE_PACKET: - printf("Packet"); - break; - default: - printf("Unknown"); - } - - printf(", Address Width: %02lu bits\n", engine->addr_bits); - } - printf("\n"); - } - - if ((bank)&&(bank != (char*)-1)) banks = NULL; - else banks = model_info->banks; - - if (banks) { - printf("Banks: \n"); - for (i = 0; banks[i].access; i++) { - printf(" 0x%02x %s", banks[i].addr, banks[i].name); - if ((banks[i].description)&&(banks[i].description[0])) { - printf(": %s", banks[i].description); - } - printf("\n"); - } - printf("\n"); - } - - if (bank == (char*)-1) registers = NULL; - else registers = model_info->registers; - - if (registers) { - pcilib_register_bank_addr_t bank_addr = 0; - if (bank) { - pcilib_register_bank_t bank_id = pcilib_find_bank(handle, bank); - pcilib_register_bank_description_t *b = model_info->banks + bank_id; - - bank_addr = b->addr; - if (b->description) printf("%s:\n", b->description); - else if (b->name) printf("Registers of bank %s:\n", b->name); - else printf("Registers of bank 0x%x:\n", b->addr); - } else { - printf("Registers: \n"); - } - for (i = 0; registers[i].bits; i++) { - const char *mode; - - if ((bank)&&(registers[i].bank != bank_addr)) continue; - if (registers[i].type == PCILIB_REGISTER_BITS) { - if (!details) continue; - - if (registers[i].bits > 1) { - printf(" [%2u:%2u] - %s\n", registers[i].offset, registers[i].offset + registers[i].bits, registers[i].name); - } else { - printf(" [ %2u] - %s\n", registers[i].offset, registers[i].name); - } - - continue; - } - - if (registers[i].mode == PCILIB_REGISTER_RW) mode = "RW"; - else if (registers[i].mode == PCILIB_REGISTER_R) mode = "R "; - else if (registers[i].mode == PCILIB_REGISTER_W) mode = " W"; - else mode = " "; - - printf(" 0x%02x (%2i %s) %s", registers[i].addr, registers[i].bits, mode, registers[i].name); - if ((details > 0)&&(registers[i].description)&&(registers[i].description[0])) { - printf(": %s", registers[i].description); - } - printf("\n"); - - } - printf("\n"); - } - - if (bank == (char*)-1) events = NULL; - else { - events = model_info->events; - types = model_info->data_types; - } - - if (events) { - printf("Events: \n"); - for (i = 0; events[i].name; i++) { - printf(" %s", events[i].name); - if ((events[i].description)&&(events[i].description[0])) { - printf(": %s", events[i].description); - } - - if (types) { - for (j = 0; types[j].name; j++) { - if (types[j].evid & events[i].evid) { - printf("\n %s", types[j].name); - if ((types[j].description)&&(types[j].description[0])) { - printf(": %s", types[j].description); - } - } - } - } - } - printf("\n"); - } -} - -void Info(pcilib_t *handle, pcilib_model_description_t *model_info) { - const pcilib_board_info_t *board_info = pcilib_get_board_info(handle); - - printf("Vendor: %x, Device: %x, Bus: %x, Slot: %x, Function: %x\n", board_info->vendor_id, board_info->device_id, board_info->bus, board_info->slot, board_info->func); - printf(" Interrupt - Pin: %i, Line: %i\n", board_info->interrupt_pin, board_info->interrupt_line); - List(handle, model_info, (char*)-1, 0); -} - - -#define BENCH_MAX_DMA_SIZE 4 * 1024 * 1024 -#define BENCH_MAX_FIFO_SIZE 1024 * 1024 - -int Benchmark(pcilib_t *handle, ACCESS_MODE mode, pcilib_dma_engine_addr_t dma, pcilib_bar_t bar, uintptr_t addr, size_t n, access_t access, size_t iterations) { - int err; - int i, j, errors; - void *data, *buf, *check; - void *fifo = NULL; - struct timeval start, end; - unsigned long time; - size_t size, min_size, max_size; - double mbs_in, mbs_out, mbs; - size_t irqs; - - const pcilib_board_info_t *board_info = pcilib_get_board_info(handle); - - if (mode == ACCESS_CONFIG) - Error("No benchmarking of configuration space acess is allowed"); - - if (mode == ACCESS_DMA) { - if (n) { - min_size = n * access; - max_size = n * access; - } else { - min_size = 1024; - max_size = BENCH_MAX_DMA_SIZE; - } - - for (size = min_size; size <= max_size; size *= 4) { - mbs_in = pcilib_benchmark_dma(handle, dma, addr, size, iterations, PCILIB_DMA_FROM_DEVICE); - mbs_out = pcilib_benchmark_dma(handle, dma, addr, size, iterations, PCILIB_DMA_TO_DEVICE); - mbs = pcilib_benchmark_dma(handle, dma, addr, size, iterations, PCILIB_DMA_BIDIRECTIONAL); - err = pcilib_wait_irq(handle, 0, 0, &irqs); - if (err) irqs = 0; - - printf("%8zu KB - ", size / 1024); - - printf("RW: "); - if (mbs < 0) printf("failed ... "); - else printf("%8.2lf MB/s", mbs); - - printf(", R: "); - if (mbs_in < 0) printf("failed ... "); - else printf("%8.2lf MB/s", mbs_in); - - printf(", W: "); - if (mbs_out < 0) printf("failed ... "); - else printf("%8.2lf MB/s", mbs_out); - - if (irqs) { - printf(", IRQs: %lu", irqs); - } - - printf("\n"); - } - - return 0; - } - - if (bar == PCILIB_BAR_INVALID) { - unsigned long maxlength = 0; - - - for (i = 0; i < PCILIB_MAX_BANKS; i++) { - if ((addr >= board_info->bar_start[i])&&((board_info->bar_start[i] + board_info->bar_length[i]) >= (addr + access))) { - bar = i; - break; - } - - if (board_info->bar_length[i] > maxlength) { - maxlength = board_info->bar_length[i]; - bar = i; - } - } - - if (bar < 0) Error("Data banks are not available"); - } - - if (n) { - if ((mode == ACCESS_BAR)&&(n * access > board_info->bar_length[bar])) Error("The specified size (%i) exceeds the size of bar (%i)", n * access, board_info->bar_length[bar]); - - min_size = n * access; - max_size = n * access; - } else { - min_size = access; - if (mode == ACCESS_BAR) max_size = board_info->bar_length[bar]; - else max_size = BENCH_MAX_FIFO_SIZE; - } - - err = posix_memalign( (void**)&buf, 256, max_size ); - if (!err) err = posix_memalign( (void**)&check, 256, max_size ); - if ((err)||(!buf)||(!check)) Error("Allocation of %i bytes of memory have failed", max_size); - - data = pcilib_map_bar(handle, bar); - if (!data) Error("Can't map bar %i", bar); - - if (mode == ACCESS_FIFO) { - fifo = data + (addr - board_info->bar_start[bar]) + (board_info->bar_start[bar] & pcilib_get_page_mask()); -// pcilib_resolve_register_address(handle, bar, addr); - if (!fifo) Error("Can't resolve address (%lx) in bar (%u)", addr, bar); - } - - if (mode == ACCESS_FIFO) - printf("Transfer time (Bank: %i, Fifo: %lx):\n", bar, addr); - else - printf("Transfer time (Bank: %i):\n", bar); - - for (size = min_size ; size < max_size; size *= 8) { - gettimeofday(&start,NULL); - if (mode == ACCESS_BAR) { - for (i = 0; i < BENCHMARK_ITERATIONS; i++) { - pcilib_memcpy(buf, data, size); - } - } else { - for (i = 0; i < BENCHMARK_ITERATIONS; i++) { - for (j = 0; j < (size/access); j++) { - pcilib_memcpy(buf + j * access, fifo, access); - } - } - } - gettimeofday(&end,NULL); - - time = (end.tv_sec - start.tv_sec)*1000000 + (end.tv_usec - start.tv_usec); - printf("%8zu bytes - read: %8.2lf MB/s", size, 1000000. * size * BENCHMARK_ITERATIONS / (time * 1024. * 1024.)); - - fflush(0); - - gettimeofday(&start,NULL); - if (mode == ACCESS_BAR) { - for (i = 0; i < BENCHMARK_ITERATIONS; i++) { - pcilib_memcpy(data, buf, size); - } - } else { - for (i = 0; i < BENCHMARK_ITERATIONS; i++) { - for (j = 0; j < (size/access); j++) { - pcilib_memcpy(fifo, buf + j * access, access); - } - } - } - gettimeofday(&end,NULL); - - time = (end.tv_sec - start.tv_sec)*1000000 + (end.tv_usec - start.tv_usec); - printf(", write: %8.2lf MB/s\n", 1000000. * size * BENCHMARK_ITERATIONS / (time * 1024. * 1024.)); - } - - pcilib_unmap_bar(handle, bar, data); - - printf("\n\nOpen-Transfer-Close time: \n"); - - for (size = 4 ; size < max_size; size *= 8) { - gettimeofday(&start,NULL); - if (mode == ACCESS_BAR) { - for (i = 0; i < BENCHMARK_ITERATIONS; i++) { - pcilib_read(handle, bar, 0, size, buf); - } - } else { - for (i = 0; i < BENCHMARK_ITERATIONS; i++) { - pcilib_read_fifo(handle, bar, addr, access, size / access, buf); - } - } - gettimeofday(&end,NULL); - - time = (end.tv_sec - start.tv_sec)*1000000 + (end.tv_usec - start.tv_usec); - printf("%8zu bytes - read: %8.2lf MB/s", size, 1000000. * size * BENCHMARK_ITERATIONS / (time * 1024. * 1024.)); - - fflush(0); - - gettimeofday(&start,NULL); - if (mode == ACCESS_BAR) { - for (i = 0; i < BENCHMARK_ITERATIONS; i++) { - pcilib_write(handle, bar, 0, size, buf); - } - } else { - for (i = 0; i < BENCHMARK_ITERATIONS; i++) { - pcilib_write_fifo(handle, bar, addr, access, size / access, buf); - } - } - - gettimeofday(&end,NULL); - - time = (end.tv_sec - start.tv_sec)*1000000 + (end.tv_usec - start.tv_usec); - printf(", write: %8.2lf MB/s", 1000000. * size * BENCHMARK_ITERATIONS / (time * 1024. * 1024.)); - - if (mode == ACCESS_BAR) { - gettimeofday(&start,NULL); - for (i = 0, errors = 0; i < BENCHMARK_ITERATIONS; i++) { - pcilib_write(handle, bar, 0, size, buf); - pcilib_read(handle, bar, 0, size, check); - if (memcmp(buf, check, size)) ++errors; - } - gettimeofday(&end,NULL); - - time = (end.tv_sec - start.tv_sec)*1000000 + (end.tv_usec - start.tv_usec); - printf(", write-verify: %8.2lf MB/s", 1000000. * size * BENCHMARK_ITERATIONS / (time * 1024. * 1024.)); - if (errors) printf(", errors: %u of %u", errors, BENCHMARK_ITERATIONS); - } - printf("\n"); - } - - printf("\n\n"); - - free(check); - free(buf); - - return 0; -} - -#define pci2host16(endianess, value) endianess? - -/* -typedef struct { - size_t size; - void *data; - size_t pos; - - int multi_mode; -} DMACallbackContext; - -static int DMACallback(void *arg, pcilib_dma_flags_t flags, size_t bufsize, void *buf) { - DMACallbackContext *ctx = (DMACallbackContext*)arg; - - if ((ctx->pos + bufsize > ctx->size)||(!ctx->data)) { - ctx->size *= 2; - ctx->data = realloc(ctx->data, ctx->size); - if (!ctx->data) { - Error("Allocation of %i bytes of memory have failed", ctx->size); - return 0; - } - } - - memcpy(ctx->data + ctx->pos, buf, bufsize); - ctx->pos += bufsize; - - if (flags & PCILIB_DMA_FLAG_EOP) return 0; - return 1; -} -*/ - - -int ReadData(pcilib_t *handle, ACCESS_MODE mode, FLAGS flags, pcilib_dma_engine_addr_t dma, pcilib_bar_t bar, uintptr_t addr, size_t n, access_t access, int endianess, size_t timeout, FILE *o) { - void *buf; - int i, err; - size_t ret, bytes; - size_t size = n * abs(access); - int block_width, blocks_per_line; - int numbers_per_block, numbers_per_line; - pcilib_dma_engine_t dmaid; - pcilib_dma_flags_t dma_flags = 0; - - int fd; - char stmp[256]; - struct stat st; - const pcilib_board_info_t *board_info; - - numbers_per_block = BLOCK_SIZE / access; - - block_width = numbers_per_block * ((access * 2) + SEPARATOR_WIDTH); - blocks_per_line = (LINE_WIDTH - 10) / (block_width + BLOCK_SEPARATOR_WIDTH); - if ((blocks_per_line > 1)&&(blocks_per_line % 2)) --blocks_per_line; - numbers_per_line = blocks_per_line * numbers_per_block; - - if (size) { - buf = malloc(size); - if (!buf) Error("Allocation of %zu bytes of memory has failed", size); - } else { - buf = NULL; - } - - switch (mode) { - case ACCESS_DMA: - if (timeout == (size_t)-1) timeout = PCILIB_DMA_TIMEOUT; - - dmaid = pcilib_find_dma_by_addr(handle, PCILIB_DMA_FROM_DEVICE, dma); - if (dmaid == PCILIB_DMA_ENGINE_INVALID) Error("Invalid DMA engine (%lu) is specified", dma); - - if (flags&FLAG_MULTIPACKET) dma_flags |= PCILIB_DMA_FLAG_MULTIPACKET; - if (flags&FLAG_WAIT) dma_flags |= PCILIB_DMA_FLAG_WAIT; - - if (size) { - err = pcilib_read_dma_custom(handle, dmaid, addr, size, dma_flags, timeout, buf, &bytes); - if (err) Error("Error (%i) is reported by DMA engine", err); - } else { - dma_flags |= PCILIB_DMA_FLAG_IGNORE_ERRORS; - - size = 2048; bytes = 0; - do { - size *= 2; - buf = realloc(buf, size); - if (!buf) Error("Allocation of %zu bytes of memory has failed", size); - err = pcilib_read_dma_custom(handle, dmaid, addr, size - bytes, dma_flags, timeout, buf + bytes, &ret); - bytes += ret; - - if ((!err)&&(flags&FLAG_MULTIPACKET)) { - err = PCILIB_ERROR_TOOBIG; - if ((flags&FLAG_WAIT)==0) timeout = 0; - } - } while (err == PCILIB_ERROR_TOOBIG); - } - - if ((err)&&(err != PCILIB_ERROR_TIMEOUT)) { - Error("Error (%i) during DMA read", err); - } - if (bytes <= 0) { - pcilib_warning("No data is returned by DMA engine"); - return 0; - } - size = bytes; - n = bytes / abs(access); - addr = 0; - break; - case ACCESS_FIFO: - pcilib_read_fifo(handle, bar, addr, access, n, buf); - addr = 0; - break; - case ACCESS_CONFIG: - board_info = pcilib_get_board_info(handle); - sprintf(stmp, "/sys/bus/pci/devices/0000:%02x:%02x.%1x/config", board_info->bus, board_info->slot, board_info->func); - fd = open(stmp, O_RDONLY); - - if ((!fd)||(fstat(fd, &st))) Error("Can't open %s", stmp); - - if (st.st_size < addr) - Error("Access beyond the end of PCI configuration space"); - - if (st.st_size < (addr + size)) { - n = (st.st_size - addr) / abs(access); - size = n * abs(access); - if (!n) Error("Access beyond the end of PCI configuration space"); - } - - lseek(fd, addr, SEEK_SET); - ret = read(fd, buf, size); - if (ret == (size_t)-1) Error("Error reading %s", stmp); - - if (ret < size) { - size = ret; - n = ret / abs(access); - } - - close(fd); - break; - default: - pcilib_read(handle, bar, addr, size, buf); - } - - if (endianess) pcilib_swap(buf, buf, abs(access), n); - - if (o) { - printf("Writting output (%zu bytes) to file (append to the end)...\n", n * abs(access)); - fwrite(buf, abs(access), n, o); - } else { - for (i = 0; i < n; i++) { - if (i) { - if (i%numbers_per_line == 0) printf("\n"); - else { - printf("%*s", SEPARATOR_WIDTH, ""); - if (i%numbers_per_block == 0) printf("%*s", BLOCK_SEPARATOR_WIDTH, ""); - } - } - - if (i%numbers_per_line == 0) printf("%8lx: ", addr + i * abs(access)); - - switch (access) { - case 1: printf("%0*hhx", access * 2, ((uint8_t*)buf)[i]); break; - case 2: printf("%0*hx", access * 2, ((uint16_t*)buf)[i]); break; - case 4: printf("%0*x", access * 2, ((uint32_t*)buf)[i]); break; - case 8: printf("%0*lx", access * 2, ((uint64_t*)buf)[i]); break; - } - } - printf("\n\n"); - } - - - free(buf); - return 0; -} - - - - -int ReadRegister(pcilib_t *handle, pcilib_model_description_t *model_info, const char *bank, const char *reg) { - int i; - int err; - const char *format; - - pcilib_register_bank_t bank_id; - pcilib_register_bank_addr_t bank_addr = 0; - - pcilib_register_value_t value; - - if (reg) { - pcilib_register_t regid = pcilib_find_register(handle, bank, reg); - bank_id = pcilib_find_bank_by_addr(handle, model_info->registers[regid].bank); - format = model_info->banks[bank_id].format; - if (!format) format = "%lu"; - - err = pcilib_read_register_by_id(handle, regid, &value); - // err = pcilib_read_register(handle, bank, reg, &value); - if (err) printf("Error reading register %s\n", reg); - else { - printf("%s = ", reg); - printf(format, value); - printf("\n"); - } - } else { - // Adding DMA registers - pcilib_get_dma_info(handle); - - if (model_info->registers) { - if (bank) { - bank_id = pcilib_find_bank(handle, bank); - bank_addr = model_info->banks[bank_id].addr; - } - - printf("Registers:\n"); - for (i = 0; model_info->registers[i].bits; i++) { - if ((model_info->registers[i].mode & PCILIB_REGISTER_R)&&((!bank)||(model_info->registers[i].bank == bank_addr))&&(model_info->registers[i].type != PCILIB_REGISTER_BITS)) { - bank_id = pcilib_find_bank_by_addr(handle, model_info->registers[i].bank); - format = model_info->banks[bank_id].format; - if (!format) format = "%lu"; - - err = pcilib_read_register_by_id(handle, i, &value); - if (err) printf(" %s = error reading value", model_info->registers[i].name); - else { - printf(" %s = ", model_info->registers[i].name); - printf(format, value); - } - - printf(" ["); - printf(format, model_info->registers[i].defvalue); - printf("]"); - printf("\n"); - } - } - } else { - printf("No registers"); - } - printf("\n"); - } - - return 0; -} - -#define WRITE_REGVAL(buf, n, access, o) {\ - uint##access##_t tbuf[n]; \ - for (i = 0; i < n; i++) { \ - tbuf[i] = (uint##access##_t)buf[i]; \ - } \ - fwrite(tbuf, access/8, n, o); \ -} - -int ReadRegisterRange(pcilib_t *handle, pcilib_model_description_t *model_info, const char *bank, uintptr_t addr, long addr_shift, size_t n, FILE *o) { - int err; - int i; - - pcilib_register_bank_description_t *banks = model_info->banks; - pcilib_register_bank_t bank_id = pcilib_find_bank(handle, bank); - - if (bank_id == PCILIB_REGISTER_BANK_INVALID) { - if (bank) Error("Invalid register bank is specified (%s)", bank); - else Error("Register bank should be specified"); - } - - int access = banks[bank_id].access / 8; -// int size = n * abs(access); - int block_width, blocks_per_line; - int numbers_per_block, numbers_per_line; - - numbers_per_block = BLOCK_SIZE / access; - - block_width = numbers_per_block * ((access * 2) + SEPARATOR_WIDTH); - blocks_per_line = (LINE_WIDTH - 6) / (block_width + BLOCK_SEPARATOR_WIDTH); - if ((blocks_per_line > 1)&&(blocks_per_line % 2)) --blocks_per_line; - numbers_per_line = blocks_per_line * numbers_per_block; - - - pcilib_register_value_t buf[n]; - err = pcilib_read_register_space(handle, bank, addr, n, buf); - if (err) Error("Error reading register space for bank \"%s\" at address %lx, size %lu", bank?bank:"default", addr, n); - - - if (o) { - printf("Writting output (%zu bytes) to file (append to the end)...\n", n * abs(access)); - switch (access) { - case 1: WRITE_REGVAL(buf, n, 8, o) break; - case 2: WRITE_REGVAL(buf, n, 16, o) break; - case 4: WRITE_REGVAL(buf, n, 32, o) break; - case 8: WRITE_REGVAL(buf, n, 64, o) break; - } - } else { - for (i = 0; i < n; i++) { - if (i) { - if (i%numbers_per_line == 0) printf("\n"); - else { - printf("%*s", SEPARATOR_WIDTH, ""); - if (i%numbers_per_block == 0) printf("%*s", BLOCK_SEPARATOR_WIDTH, ""); - } - } - - if (i%numbers_per_line == 0) printf("%4lx: ", addr + 4 * i - addr_shift); - printf("%0*lx", access * 2, (unsigned long)buf[i]); - } - printf("\n\n"); - } - - return 0; -} - -int WriteData(pcilib_t *handle, ACCESS_MODE mode, pcilib_dma_engine_addr_t dma, pcilib_bar_t bar, uintptr_t addr, size_t n, access_t access, int endianess, char ** data, int verify) { - int read_back = 0; - void *buf, *check; - int res = 0, i, err; - int size = n * abs(access); - size_t ret; - pcilib_dma_engine_t dmaid; - - if (mode == ACCESS_CONFIG) - Error("Writting to PCI configuration space is not supported"); - - err = posix_memalign( (void**)&buf, 256, size ); - if (!err) err = posix_memalign( (void**)&check, 256, size ); - if ((err)||(!buf)||(!check)) Error("Allocation of %i bytes of memory have failed", size); - - for (i = 0; i < n; i++) { - switch (access) { - case 1: res = sscanf(data[i], "%hhx", ((uint8_t*)buf)+i); break; - case 2: res = sscanf(data[i], "%hx", ((uint16_t*)buf)+i); break; - case 4: res = sscanf(data[i], "%x", ((uint32_t*)buf)+i); break; - case 8: res = sscanf(data[i], "%lx", ((uint64_t*)buf)+i); break; - default: Error("Unexpected data size (%lu)", access); - } - if ((res != 1)||(!isxnumber(data[i]))) Error("Can't parse data value at poition %i, (%s) is not valid hex number", i, data[i]); - } - - if (endianess) pcilib_swap(buf, buf, abs(access), n); - - switch (mode) { - case ACCESS_DMA: - dmaid = pcilib_find_dma_by_addr(handle, PCILIB_DMA_TO_DEVICE, dma); - if (dmaid == PCILIB_DMA_ENGINE_INVALID) Error("Invalid DMA engine (%lu) is specified", dma); - err = pcilib_write_dma(handle, dmaid, addr, size, buf, &ret); - if ((err)||(ret != size)) { - if (err == PCILIB_ERROR_TIMEOUT) Error("Timeout writting the data to DMA"); - else if (err) Error("DMA engine returned a error while writing the data"); - else if (!ret) Error("No data is written by DMA engine"); - else Error("Only %lu bytes of %lu is written by DMA engine", ret, size); - } - break; - case ACCESS_FIFO: - pcilib_write_fifo(handle, bar, addr, access, n, buf); - break; - default: - pcilib_write(handle, bar, addr, size, buf); - if (verify) { - pcilib_read(handle, bar, addr, size, check); - read_back = 1; - } - } - - if ((read_back)&&(memcmp(buf, check, size))) { - printf("Write failed: the data written and read differ, the foolowing is read back:\n"); - if (endianess) pcilib_swap(check, check, abs(access), n); - ReadData(handle, mode, 0, dma, bar, addr, n, access, endianess, (size_t)-1, NULL); - exit(-1); - } - - free(check); - free(buf); - - return 0; -} - -int WriteRegisterRange(pcilib_t *handle, pcilib_model_description_t *model_info, const char *bank, uintptr_t addr, long addr_shift, size_t n, char ** data) { - pcilib_register_value_t *buf, *check; - int res, i, err; - unsigned long value; - int size = n * sizeof(pcilib_register_value_t); - - err = posix_memalign( (void**)&buf, 256, size ); - if (!err) err = posix_memalign( (void**)&check, 256, size ); - if ((err)||(!buf)||(!check)) Error("Allocation of %i bytes of memory have failed", size); - - for (i = 0; i < n; i++) { - res = sscanf(data[i], "%lx", &value); - if ((res != 1)||(!isxnumber(data[i]))) Error("Can't parse data value at poition %i, (%s) is not valid hex number", i, data[i]); - buf[i] = value; - } - - err = pcilib_write_register_space(handle, bank, addr, n, buf); - if (err) Error("Error writting register space for bank \"%s\" at address %lx, size %lu", bank?bank:"default", addr, n); - - err = pcilib_read_register_space(handle, bank, addr, n, check); - if (err) Error("Error reading register space for bank \"%s\" at address %lx, size %lu", bank?bank:"default", addr, n); - - if (memcmp(buf, check, size)) { - printf("Write failed: the data written and read differ, the foolowing is read back:\n"); - ReadRegisterRange(handle, model_info, bank, addr, addr_shift, n, NULL); - exit(-1); - } - - free(check); - free(buf); - - return 0; - -} - -int WriteRegister(pcilib_t *handle, pcilib_model_description_t *model_info, const char *bank, const char *reg, char ** data) { - int err; - - unsigned long val; - pcilib_register_value_t value; - - const char *format = NULL; - - pcilib_register_t regid = pcilib_find_register(handle, bank, reg); - if (regid == PCILIB_REGISTER_INVALID) Error("Can't find register (%s) from bank (%s)", reg, bank?bank:"autodetected"); - -/* - pcilib_register_bank_t bank_id; - pcilib_register_bank_addr_t bank_addr; - - bank_id = pcilib_find_bank_by_addr(handle, model_info->registers[regid].bank); - if (bank_id == PCILIB_REGISTER_BANK_INVALID) Error("Can't find bank of the register (%s)", reg); - format = model_info->banks[bank_id].format; - if (!format) format = "%lu"; -*/ - - if (isnumber(*data)) { - if (sscanf(*data, "%li", &val) != 1) { - Error("Can't parse data value (%s) is not valid decimal number", *data); - } - - format = "%li"; - } else if (isxnumber(*data)) { - if (sscanf(*data, "%lx", &val) != 1) { - Error("Can't parse data value (%s) is not valid decimal number", *data); - } - - format = "0x%lx"; - } else { - Error("Can't parse data value (%s) is not valid decimal number", *data); - } - - value = val; - - err = pcilib_write_register(handle, bank, reg, value); - if (err) Error("Error writting register %s\n", reg); - - if ((model_info->registers[regid].mode&PCILIB_REGISTER_RW) == PCILIB_REGISTER_RW) { - err = pcilib_read_register(handle, bank, reg, &value); - if (err) Error("Error reading back register %s for verification\n", reg); - - if (val != value) { - Error("Failed to write register %s: %lu is written and %lu is read back", reg, val, value); - } else { - printf("%s = ", reg); - printf(format, value); - printf("\n"); - } - } else { - printf("%s is written\n ", reg); - } - - return 0; -} - -typedef struct { - pcilib_t *handle; - pcilib_event_t event; - pcilib_event_data_type_t data; - - fastwriter_t *writer; - - int verbose; - pcilib_timeout_t timeout; - size_t run_time; - size_t trigger_time; - size_t max_triggers; - pcilib_event_flags_t flags; - FORMAT format; - - volatile int event_pending; /**< Used to detect that we have read previously triggered event */ - volatile int trigger_thread_started; /**< Indicates that trigger thread is ready and we can't procced to start event recording */ - volatile int started; /**< Indicates that recording is started */ - - volatile int run_flag; - volatile int writing_flag; - - struct timeval first_frame; - struct timeval last_frame; - size_t last_num; - - size_t trigger_failed; - size_t trigger_count; - size_t event_count; - size_t incomplete_count; - size_t broken_count; - size_t missing_count; - size_t storage_count; - - struct timeval start_time; - struct timeval stop_time; -} GRABContext; - -int GrabCallback(pcilib_event_id_t event_id, pcilib_event_info_t *info, void *user) { - int err = 0; - void *data; - size_t size; - - GRABContext *ctx = (GRABContext*)user; - pcilib_t *handle = ctx->handle; - - gettimeofday(&ctx->last_frame, NULL); - - if (!ctx->event_count) { - memcpy(&ctx->first_frame, &ctx->last_frame, sizeof(struct timeval)); - } - - ctx->event_pending = 0; - ctx->event_count++; - - if (ctx->last_num) - ctx->missing_count += (info->seqnum - ctx->last_num) - 1; - ctx->last_num = info->seqnum; - - if (info->flags&PCILIB_EVENT_INFO_FLAG_BROKEN) { - ctx->incomplete_count++; - return PCILIB_STREAMING_CONTINUE; - } - - switch (ctx->format) { - case FORMAT_DEFAULT: - data = pcilib_get_data(handle, event_id, PCILIB_EVENT_DATA, &size); - break; - default: - data = pcilib_get_data(handle, event_id, PCILIB_EVENT_RAW_DATA, &size); - } - - if (!data) { - ctx->broken_count++; - return PCILIB_STREAMING_CONTINUE; - } - - if (ctx->format == FORMAT_HEADER) { - uint64_t header[8]; - header[0] = info->type; - header[1] = ctx->data; - header[2] = 0; - header[3] = size; - header[4] = info->seqnum; - header[5] = info->offset; - memcpy(header + 6, &info->timestamp, 16); - - err = fastwriter_push(ctx->writer, 64, header); - } - - if (!err) - err = fastwriter_push(ctx->writer, size, data); - - if (err) { - fastwriter_cancel(ctx->writer); - - if (err != EWOULDBLOCK) - Error("Storage error %i", err); - - ctx->storage_count++; - pcilib_return_data(handle, event_id, ctx->data, data); - return PCILIB_STREAMING_CONTINUE; - } - - err = pcilib_return_data(handle, event_id, ctx->data, data); - if (err) { - ctx->missing_count++; - fastwriter_cancel(ctx->writer); - return PCILIB_STREAMING_CONTINUE; - } - - err = fastwriter_commit(ctx->writer); - if (err) Error("Error commiting data to storage, Error: %i", err); - - return PCILIB_STREAMING_CONTINUE; -} - -int raw_data(pcilib_event_id_t event_id, pcilib_event_info_t *info, pcilib_event_flags_t flags, size_t size, void *data, void *user) { - int err; - - GRABContext *ctx = (GRABContext*)user; -// pcilib_t *handle = ctx->handle; - - - if ((info)&&(info->seqnum != ctx->last_num)) { - gettimeofday(&ctx->last_frame, NULL); - if (!ctx->event_count) { - memcpy(&ctx->first_frame, &ctx->last_frame, sizeof(struct timeval)); - } - - ctx->event_count++; - ctx->missing_count += (info->seqnum - ctx->last_num) - 1; - ctx->last_num = info->seqnum; - } - - err = fastwriter_push_data(ctx->writer, size, data); - if (err) { - if (err == EWOULDBLOCK) Error("Storage is not able to handle the data stream, buffer overrun"); - Error("Storage error %i", err); - } - - return PCILIB_STREAMING_CONTINUE; -} - - -void *Trigger(void *user) { - int err; - struct timeval start; - - GRABContext *ctx = (GRABContext*)user; - size_t trigger_time = ctx->trigger_time; - size_t max_triggers = ctx->max_triggers; - - ctx->trigger_thread_started = 1; - ctx->event_pending = 1; - - while (!ctx->started) ; - - gettimeofday(&start, NULL); - do { - err = pcilib_trigger(ctx->handle, ctx->event, 0, NULL); - if (err) ctx->trigger_failed++; - if ((++ctx->trigger_count == max_triggers)&&(max_triggers)) break; - - if (trigger_time) { - pcilib_add_timeout(&start, trigger_time); - if ((ctx->stop_time.tv_sec)&&(pcilib_timecmp(&start, &ctx->stop_time)>0)) break; - pcilib_sleep_until_deadline(&start); - } else { - while ((ctx->event_pending)&&(ctx->run_flag)) usleep(10); - ctx->event_pending = 1; - } - } while (ctx->run_flag); - - ctx->trigger_thread_started = 0; - - return NULL; -} - -void GrabStats(GRABContext *ctx, struct timeval *end_time) { - int verbose; - pcilib_timeout_t duration, fps_duration; - struct timeval cur; - double fps = 0, good_fps = 0; - size_t total, good, pending = 0; - - verbose = ctx->verbose; - - if (end_time) { - if (verbose++) { - printf("-------------------------------------------------------------------------------\n"); - } - } else { - gettimeofday(&cur, NULL); - end_time = &cur; - } - -// if ((ctx->event_count + ctx->missing_count) == 0) -// return; - - duration = pcilib_timediff(&ctx->start_time, end_time); - fps_duration = pcilib_timediff(&ctx->first_frame, &ctx->last_frame); - - if (ctx->trigger_count) { - total = ctx->trigger_count; - pending = ctx->trigger_count - ctx->event_count - ctx->missing_count - ctx->trigger_failed; - } else { - total = ctx->event_count + ctx->missing_count; - } - - good = ctx->event_count - ctx->broken_count - ctx->incomplete_count - ctx->storage_count; - - if (ctx->event_count > 1) { - fps = (ctx->event_count - 1) / (1.*fps_duration/1000000); - } - - if (good > 1) { - good_fps = (good - 1) / (1.*fps_duration/1000000); - } - - printf("Run: "); - PrintTime(duration); - - if (ctx->trigger_count) { - printf(", Triggers: "); - PrintNumber(ctx->trigger_count); - } - - printf(", Captured: "); - PrintNumber(ctx->event_count); - printf(" FPS %5.0lf", fps); - - if ((ctx->flags&PCILIB_EVENT_FLAG_RAW_DATA_ONLY) == 0) { - printf(", Stored: "); - PrintNumber(good); - printf(" FPS %5.0lf", good_fps); - } - - printf("\n"); - - if (verbose > 2) { - if (ctx->trigger_count) { - printf("Trig: "); - PrintNumber(ctx->trigger_count); - printf(" Issued: "); - PrintNumber(ctx->trigger_count - ctx->trigger_failed); - printf(" ("); - PrintPercent(ctx->trigger_count - ctx->trigger_failed, ctx->trigger_count); - printf("%%) Failed: "); - PrintNumber(ctx->trigger_failed); - printf( " ("); - PrintPercent(ctx->trigger_failed, ctx->trigger_count); - printf( "%%); Pending: "); - PrintNumber(pending); - printf( " ("); - PrintPercent(pending, ctx->trigger_count); - printf( "%%)\n"); - } - - if (ctx->flags&PCILIB_EVENT_FLAG_RAW_DATA_ONLY) { - printf("Captured: "); - PrintNumber(good); - } else { - printf("Good: "); - PrintNumber(good); - printf(", Dropped: "); - PrintNumber(ctx->storage_count); - printf(", Bad: "); - PrintNumber(ctx->incomplete_count); - printf(", Empty: "); - PrintNumber(ctx->broken_count); - } - printf(", Lost: "); - PrintNumber(ctx->missing_count); - printf("\n"); - } - - if (verbose > 1) { - if (ctx->flags&PCILIB_EVENT_FLAG_RAW_DATA_ONLY) { - printf("Captured: "); - PrintPercent(good, total); - } else { - printf("Good: "); - PrintPercent(good, total); - printf("%% Dropped: "); - PrintPercent(ctx->storage_count, total); - printf("%% Bad: "); - PrintPercent(ctx->incomplete_count, total); - printf("%% Empty: "); - PrintPercent(ctx->broken_count, total); - } - - printf("%% Lost: "); - PrintPercent(ctx->missing_count, total); - printf("%%"); - printf("\n"); - } -} - -void StorageStats(GRABContext *ctx) { - int err; - fastwriter_stats_t st; - - pcilib_timeout_t duration; - struct timeval cur; - - gettimeofday(&cur, NULL); - duration = pcilib_timediff(&ctx->start_time, &cur); - - - err = fastwriter_get_stats(ctx->writer, &st); - if (err) return; - - printf("Wrote "); - PrintSize(st.written); - printf(" of "); - PrintSize(st.commited); - printf(" at "); - PrintSize(1000000.*st.written / duration); - printf("/s, %6.2lf%% ", 100.*st.buffer_used / st.buffer_size); - printf(" of "); - PrintSize(st.buffer_size); - printf(" buffer (%6.2lf%% max)\n", 100.*st.buffer_max / st.buffer_size); -} - -void *Monitor(void *user) { - struct timeval deadline; - struct timeval nextinfo; - - GRABContext *ctx = (GRABContext*)user; - int verbose = ctx->verbose; - pcilib_timeout_t timeout = ctx->timeout; - - - if (timeout == PCILIB_TIMEOUT_INFINITE) timeout = 0; - -// while (!ctx->started); - - if (timeout) { - memcpy(&deadline, (struct timeval*)&ctx->last_frame, sizeof(struct timeval)); - pcilib_add_timeout(&deadline, timeout); - } - - if (verbose > 0) { - pcilib_calc_deadline(&nextinfo, STATUS_MESSAGE_INTERVAL*1000000); - } - - while (ctx->run_flag) { - if (StopFlag) { - pcilib_stop(ctx->handle, PCILIB_EVENT_FLAG_STOP_ONLY); - break; - } - - if (timeout) { - if (pcilib_calc_time_to_deadline(&deadline) == 0) { - memcpy(&deadline, (struct timeval*)&ctx->last_frame, sizeof(struct timeval)); - pcilib_add_timeout(&deadline, timeout); - - if (pcilib_calc_time_to_deadline(&deadline) == 0) { - pcilib_stop(ctx->handle, PCILIB_EVENT_FLAG_STOP_ONLY); - break; - } - } - } - - if (verbose > 0) { - if (pcilib_calc_time_to_deadline(&nextinfo) == 0) { - GrabStats(ctx, NULL); - StorageStats(ctx); - pcilib_calc_deadline(&nextinfo, STATUS_MESSAGE_INTERVAL*1000000); - } - } - - usleep(100000); - } - - pcilib_calc_deadline(&nextinfo, STATUS_MESSAGE_INTERVAL*1000000); - while (ctx->writing_flag) { - if (pcilib_calc_time_to_deadline(&nextinfo) == 0) { - if (verbose >= 0) StorageStats(ctx); - pcilib_calc_deadline(&nextinfo, STATUS_MESSAGE_INTERVAL*1000000); - } - - usleep(100000); - } - - return NULL; -} - -int TriggerAndGrab(pcilib_t *handle, GRAB_MODE grab_mode, const char *evname, const char *data_type, size_t num, size_t run_time, size_t trigger_time, pcilib_timeout_t timeout, PARTITION partition, FORMAT format, size_t buffer_size, size_t threads, int verbose, const char *output) { - int err; - GRABContext ctx; -// void *data = NULL; -// size_t size, written; - - pcilib_event_t event; - pcilib_event_t listen_events; - pcilib_event_data_type_t data; - - pthread_t monitor_thread; - pthread_t trigger_thread; - pthread_attr_t attr; - struct sched_param sched; - - struct timeval end_time; - pcilib_event_flags_t flags; - - if (evname) { - event = pcilib_find_event(handle, evname); - if (event == PCILIB_EVENT_INVALID) - Error("Can't find event (%s)", evname); - - listen_events = event; - } else { - listen_events = PCILIB_EVENTS_ALL; - event = PCILIB_EVENT0; - } - - if (data_type) { - data = pcilib_find_event_data_type(handle, event, data_type); - if (data == PCILIB_EVENT_DATA_TYPE_INVALID) - Error("Can't find data type (%s)", data_type); - } else { - data = PCILIB_EVENT_DATA; - } - - memset(&ctx, 0, sizeof(GRABContext)); - - ctx.handle = handle; - ctx.event = event; - ctx.data = data; - ctx.run_time = run_time; - ctx.timeout = timeout; - ctx.format = format; - - if (grab_mode&GRAB_MODE_GRAB) ctx.verbose = verbose; - else ctx.verbose = 0; - - if (grab_mode&GRAB_MODE_GRAB) { - ctx.writer = fastwriter_init(output, 0); - if (!ctx.writer) - Error("Can't initialize fastwritter library"); - - fastwriter_set_buffer_size(ctx.writer, buffer_size); - - err = fastwriter_open(ctx.writer, output, 0); - if (err) - Error("Error opening file (%s), Error: %i\n", output, err); - - ctx.writing_flag = 1; - } - - ctx.run_flag = 1; - - flags = PCILIB_EVENT_FLAGS_DEFAULT; - - if (data == PCILIB_EVENT_RAW_DATA) { - if (format == FORMAT_RAW) { - flags |= PCILIB_EVENT_FLAG_RAW_DATA_ONLY; - } - } else { - flags |= PCILIB_EVENT_FLAG_PREPROCESS; - } - - ctx.flags = flags; - -// printf("Limits: %lu %lu %lu\n", num, run_time, timeout); - pcilib_configure_autostop(handle, num, run_time); - - if (flags&PCILIB_EVENT_FLAG_RAW_DATA_ONLY) { - pcilib_configure_rawdata_callback(handle, &raw_data, &ctx); - } - - if (flags&PCILIB_EVENT_FLAG_PREPROCESS) { - pcilib_configure_preprocessing_threads(handle, threads); - } - - if (grab_mode&GRAB_MODE_TRIGGER) { - if (trigger_time) { - if ((timeout)&&(trigger_time * 2 > timeout)) { - timeout = 2 * trigger_time; - ctx.timeout = timeout; - } - } else { - // Otherwise, we will trigger next event after previous one is read - if (((grab_mode&GRAB_MODE_GRAB) == 0)||(flags&PCILIB_EVENT_FLAG_RAW_DATA_ONLY)) trigger_time = PCILIB_TRIGGER_TIMEOUT; - } - - ctx.max_triggers = num; - ctx.trigger_count = 0; - ctx.trigger_time = trigger_time; - - // We don't really care if RT priority is imposible - pthread_attr_init(&attr); - if (!pthread_attr_setschedpolicy(&attr, SCHED_FIFO)) { - sched.sched_priority = sched_get_priority_min(SCHED_FIFO); - pthread_attr_setschedparam(&attr, &sched); - } - - // Start triggering thread and wait until it is schedulled - if (pthread_create(&trigger_thread, &attr, Trigger, (void*)&ctx)) - Error("Error spawning trigger thread"); - - while (!ctx.trigger_thread_started) usleep(10); - } - - gettimeofday(&ctx.start_time, NULL); - - if (grab_mode&GRAB_MODE_GRAB) { - err = pcilib_start(handle, listen_events, flags); - if (err) Error("Failed to start event engine, error %i", err); - } - - ctx.started = 1; - - if (run_time) { - ctx.stop_time.tv_usec = ctx.start_time.tv_usec + run_time%1000000; - if (ctx.stop_time.tv_usec > 999999) { - ctx.stop_time.tv_usec -= 1000000; - __sync_synchronize(); - ctx.stop_time.tv_sec = ctx.start_time.tv_sec + 1 + run_time / 1000000; - } else { - __sync_synchronize(); - ctx.stop_time.tv_sec = ctx.start_time.tv_sec + run_time / 1000000; - } - } - - memcpy(&ctx.last_frame, &ctx.start_time, sizeof(struct timeval)); - if (pthread_create(&monitor_thread, NULL, Monitor, (void*)&ctx)) - Error("Error spawning monitoring thread"); - - if (grab_mode&GRAB_MODE_GRAB) { - err = pcilib_stream(handle, &GrabCallback, &ctx); - if (err) Error("Error streaming events, error %i", err); - } - - ctx.run_flag = 0; - - if (grab_mode&GRAB_MODE_TRIGGER) { - while (ctx.trigger_thread_started) usleep(10); - } - - if (grab_mode&GRAB_MODE_GRAB) { - pcilib_stop(handle, PCILIB_EVENT_FLAGS_DEFAULT); - } - - gettimeofday(&end_time, NULL); - - if (grab_mode&GRAB_MODE_TRIGGER) { - pthread_join(trigger_thread, NULL); - } - - - if (grab_mode&GRAB_MODE_GRAB) { - if (verbose >= 0) - printf("Grabbing is finished, flushing results....\n"); - - err = fastwriter_close(ctx.writer); - if (err) Error("Storage problems, error %i", err); - } - - ctx.writing_flag = 0; - - pthread_join(monitor_thread, NULL); - - if ((grab_mode&GRAB_MODE_GRAB)&&(verbose>=0)) { - GrabStats(&ctx, &end_time); - StorageStats(&ctx); - } - - fastwriter_destroy(ctx.writer); - - return 0; -} - -int StartStopDMA(pcilib_t *handle, pcilib_model_description_t *model_info, pcilib_dma_engine_addr_t dma, pcilib_dma_direction_t dma_direction, int start) { - int err; - pcilib_dma_engine_t dmaid; - - if (dma == PCILIB_DMA_ENGINE_ADDR_INVALID) { - const pcilib_dma_info_t *dma_info = pcilib_get_dma_info(handle); - - if (start) Error("DMA engine should be specified"); - - for (dmaid = 0; dma_info->engines[dmaid]; dmaid++) { - err = pcilib_start_dma(handle, dmaid, 0); - if (err) Error("Error starting DMA Engine (%s %i)", ((dma_info->engines[dmaid]->direction == PCILIB_DMA_FROM_DEVICE)?"C2S":"S2C"), dma_info->engines[dmaid]->addr); - err = pcilib_stop_dma(handle, dmaid, PCILIB_DMA_FLAG_PERSISTENT); - if (err) Error("Error stopping DMA Engine (%s %i)", ((dma_info->engines[dmaid]->direction == PCILIB_DMA_FROM_DEVICE)?"C2S":"S2C"), dma_info->engines[dmaid]->addr); - } - - return 0; - } - - if (dma_direction&PCILIB_DMA_FROM_DEVICE) { - dmaid = pcilib_find_dma_by_addr(handle, PCILIB_DMA_FROM_DEVICE, dma); - if (dmaid == PCILIB_DMA_ENGINE_INVALID) Error("Invalid DMA engine (C2S %lu) is specified", dma); - - if (start) { - err = pcilib_start_dma(handle, dmaid, PCILIB_DMA_FLAG_PERSISTENT); - if (err) Error("Error starting DMA engine (C2S %lu)", dma); - } else { - err = pcilib_start_dma(handle, dmaid, 0); - if (err) Error("Error starting DMA engine (C2S %lu)", dma); - err = pcilib_stop_dma(handle, dmaid, PCILIB_DMA_FLAG_PERSISTENT); - if (err) Error("Error stopping DMA engine (C2S %lu)", dma); - } - } - - if (dma_direction&PCILIB_DMA_TO_DEVICE) { - dmaid = pcilib_find_dma_by_addr(handle, PCILIB_DMA_TO_DEVICE, dma); - if (dmaid == PCILIB_DMA_ENGINE_INVALID) Error("Invalid DMA engine (S2C %lu) is specified", dma); - - if (start) { - err = pcilib_start_dma(handle, dmaid, PCILIB_DMA_FLAG_PERSISTENT); - if (err) Error("Error starting DMA engine (S2C %lu)", dma); - } else { - err = pcilib_start_dma(handle, dmaid, 0); - if (err) Error("Error starting DMA engine (S2C %lu)", dma); - err = pcilib_stop_dma(handle, dmaid, PCILIB_DMA_FLAG_PERSISTENT); - if (err) Error("Error stopping DMA engine (S2C %lu)", dma); - } - } - - return 0; -} - - -typedef struct { - pcilib_kmem_use_t use; - - int referenced; - int hw_lock; - int reusable; - int persistent; - int open; - - size_t count; - size_t size; -} kmem_use_info_t; - -#define MAX_USES 64 - -pcilib_kmem_use_t ParseUse(const char *use) { - unsigned long utmp; - - if (use) { - if ((!isxnumber(use))||(sscanf(use, "%lx", &utmp) != 1)) Error("Invalid use (%s) is specified", use); - - if (strlen(use) < 5) - return PCILIB_KMEM_USE(PCILIB_KMEM_USE_USER,utmp); - else - return utmp; - } - - Error("Kernel memory use is not specified"); - return 0; -} - -size_t FindUse(size_t *n_uses, kmem_use_info_t *uses, pcilib_kmem_use_t use) { - size_t i, n = *n_uses; - - if (uses[n - 1].use == use) return n - 1; - - for (i = 1; i < (n - 1); i++) { - if (uses[i].use == use) return i; - } - - if (n == MAX_USES) return 0; - - uses[n].use = use; - return (*n_uses)++; -} - - -kmem_use_info_t *GetUse(size_t n_uses, kmem_use_info_t *uses, pcilib_kmem_use_t use) { - size_t i; - for (i = 0; i < n_uses; i++) { - if (uses[i].use == use) { - if (uses[i].count) return uses + i; - else return NULL; - } - } - return NULL; -} - - -int ParseKMEM(pcilib_t *handle, const char *device, size_t *uses_number, kmem_use_info_t *uses) { - DIR *dir; - struct dirent *entry; - const char *pos; - char sysdir[256]; - char fname[256]; - char info[256]; - - size_t useid, n_uses = 1; // Use 0 is for others - - memset(uses, 0, sizeof(uses)); - - pos = strrchr(device, '/'); - if (pos) ++pos; - else pos = device; - - snprintf(sysdir, 255, "/sys/class/fpga/%s", pos); - - dir = opendir(sysdir); - if (!dir) Error("Can't open directory (%s)", sysdir); - - while ((entry = readdir(dir)) != NULL) { - FILE *f; - unsigned long use = 0; - unsigned long size = 0; - unsigned long refs = 0; - unsigned long mode = 0; - unsigned long hwref = 0; - - if (strncmp(entry->d_name, "kbuf", 4)) continue; - if (!isnumber(entry->d_name+4)) continue; - - snprintf(fname, 255, "%s/%s", sysdir, entry->d_name); - f = fopen(fname, "r"); - if (!f) Error("Can't access file (%s)", fname); - - while(!feof(f)) { - fgets(info, 256, f); - if (!strncmp(info, "use:", 4)) use = strtoul(info+4, NULL, 16); - if (!strncmp(info, "size:", 5)) size = strtoul(info+5, NULL, 10); - if (!strncmp(info, "refs:", 5)) refs = strtoul(info+5, NULL, 10); - if (!strncmp(info, "mode:", 5)) mode = strtoul(info+5, NULL, 16); - if (!strncmp(info, "hw ref:", 7)) hwref = strtoul(info+7, NULL, 10); - } - fclose(f); - - useid = FindUse(&n_uses, uses, use); - uses[useid].count++; - uses[useid].size += size; - if (refs) uses[useid].referenced = 1; - if (hwref) uses[useid].hw_lock = 1; - if (mode&KMEM_MODE_REUSABLE) uses[useid].reusable = 1; - if (mode&KMEM_MODE_PERSISTENT) uses[useid].persistent = 1; - if (mode&KMEM_MODE_COUNT) uses[useid].open = 1; - } - closedir(dir); - - *uses_number = n_uses; - - return 0; -} - -int ListKMEM(pcilib_t *handle, const char *device) { - int err; - char stmp[256]; - - size_t i, useid, n_uses; - kmem_use_info_t uses[MAX_USES]; - - err = ParseKMEM(handle, device, &n_uses, uses); - if (err) Error("Failed to parse kernel memory information provided through sysfs"); - - if ((n_uses == 1)&&(uses[0].count == 0)) { - printf("No kernel memory is allocated\n"); - return 0; - } - - printf("Use Type Count Total Size REF Mode \n"); - printf("--------------------------------------------------------------------------------\n"); - for (useid = 0; useid < n_uses; useid++) { - if (useid + 1 == n_uses) { - if (!uses[0].count) continue; - i = 0; - } else i = useid + 1; - - printf("%08x ", uses[i].use); - if (!i) printf("All Others "); - else if ((uses[i].use >> 16) == PCILIB_KMEM_USE_DMA_RING) printf("DMA%u %s Ring ", uses[i].use&0x7F, ((uses[i].use&0x80)?"S2C":"C2S")); - else if ((uses[i].use >> 16) == PCILIB_KMEM_USE_DMA_PAGES) printf("DMA%u %s Pages ", uses[i].use&0x7F, ((uses[i].use&0x80)?"S2C":"C2S")); - else if ((uses[i].use >> 16) == PCILIB_KMEM_USE_USER) printf("User %04x ", uses[i].use&0xFFFF); - else printf (" "); - printf(" "); - printf("% 6lu", uses[i].count); - printf(" "); - printf("% 10s", GetPrintSize(stmp, uses[i].size)); - printf(" "); - if (uses[i].referenced&&uses[i].hw_lock) printf("HW+SW"); - else if (uses[i].referenced) printf(" SW"); - else if (uses[i].hw_lock) printf("HW "); - else printf(" - "); - printf(" "); - if (uses[i].persistent) printf("Persistent"); - else if (uses[i].open) printf("Open "); - else if (uses[i].reusable) printf("Reusable "); - else printf("Closed "); - printf("\n"); - } - printf("--------------------------------------------------------------------------------\n"); - printf("REF - Software/Hardware Reference, MODE - Reusable/Persistent/Open\n"); - - - return 0; -} - -int DetailKMEM(pcilib_t *handle, const char *device, const char *use, size_t block) { - int err; - size_t i, n; - pcilib_kmem_handle_t *kbuf; - pcilib_kmem_use_t useid = ParseUse(use); - - size_t n_uses; - kmem_use_info_t uses[MAX_USES]; - kmem_use_info_t *use_info; - - if (block == (size_t)-1) { - err = ParseKMEM(handle, device, &n_uses, uses); - if (err) Error("Failed to parse kernel memory information provided through sysfs"); - use_info = GetUse(n_uses, uses, useid); - if (!use_info) Error("No kernel buffers is allocated for the specified use (%lx)", useid); - - i = 0; - n = use_info->count; - } else { - i = block; - n = block + 1; - } - - kbuf = pcilib_alloc_kernel_memory(handle, 0, n, 0, 0, useid, PCILIB_KMEM_FLAG_REUSE|PCILIB_KMEM_FLAG_TRY); - if (!kbuf) { - Error("Allocation of kernel buffer (use %lx, count %lu) is failed\n", useid, n); - return 0; - } - - printf("Buffer Address Hardware Address Bus Address\n"); - printf("--------------------------------------------------------------------------------\n"); - for (; i < n; i++) { - 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); - } - printf("\n"); - - pcilib_free_kernel_memory(handle, kbuf, KMEM_FLAG_REUSE); - - return 0; -} - - -int ReadKMEM(pcilib_t *handle, const char *device, pcilib_kmem_use_t useid, size_t block, size_t max_size, FILE *o) { - int err; - void *data; - size_t size; - pcilib_kmem_handle_t *kbuf; - - if (block == (size_t)-1) block = 0; - - kbuf = pcilib_alloc_kernel_memory(handle, 0, block + 1, 0, 0, useid, PCILIB_KMEM_FLAG_REUSE|PCILIB_KMEM_FLAG_TRY); - if (!kbuf) { - Error("The specified kernel buffer is not allocated\n"); - return 0; - } - - err = pcilib_kmem_sync_block(handle, kbuf, PCILIB_KMEM_SYNC_FROMDEVICE, block); - if (err) { - pcilib_free_kernel_memory(handle, kbuf, KMEM_FLAG_REUSE); - Error("The synchronization of kernel buffer has failed\n"); - return 0; - } - - data = 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; - - fwrite(data, 1, size, o?o:stdout); - } else { - pcilib_free_kernel_memory(handle, kbuf, KMEM_FLAG_REUSE); - Error("The specified block is not existing\n"); - return 0; - } - - pcilib_free_kernel_memory(handle, kbuf, KMEM_FLAG_REUSE); - - return 0; -} - -int AllocKMEM(pcilib_t *handle, const char *device, const char *use, const char *type, size_t size, size_t block_size, size_t alignment) { - pcilib_kmem_type_t ktype = PCILIB_KMEM_TYPE_PAGE; - pcilib_kmem_flags_t flags = KMEM_FLAG_REUSE; - pcilib_kmem_handle_t *kbuf; - pcilib_kmem_use_t useid = ParseUse(use); - - long page_size = sysconf(_SC_PAGESIZE); - - if (type) { - if (!strcmp(type, "consistent")) ktype = PCILIB_KMEM_TYPE_CONSISTENT; - else if (!strcmp(type, "c2s")) ktype = PCILIB_KMEM_TYPE_DMA_C2S_PAGE; - else if (!strcmp(type, "s2c")) ktype = PCILIB_KMEM_TYPE_DMA_S2C_PAGE; - else Error("Invalid memory type (%s) is specified", type); - } - - if ((block_size)&&(ktype != PCILIB_KMEM_TYPE_CONSISTENT)) - Error("Selected memory type does not allow custom size"); - - kbuf = pcilib_alloc_kernel_memory(handle, ktype, size, (block_size?block_size:page_size), (alignment?alignment:page_size), useid, flags|KMEM_FLAG_PERSISTENT); - if (!kbuf) Error("Allocation of kernel memory has failed"); - - pcilib_free_kernel_memory(handle, kbuf, flags); - - return 0; -} - -int FreeKMEM(pcilib_t *handle, const char *device, const char *use, int force) { - int err; - int i; - - pcilib_kmem_use_t useid; - - pcilib_kmem_flags_t flags = PCILIB_KMEM_FLAG_HARDWARE|PCILIB_KMEM_FLAG_PERSISTENT|PCILIB_KMEM_FLAG_EXCLUSIVE; - if (force) flags |= PCILIB_KMEM_FLAG_FORCE; // this will ignore mmap locks as well. - - if (!strcasecmp(use, "dma")) { - for (i = 0; i < PCILIB_MAX_DMA_ENGINES; i++) { - err = pcilib_clean_kernel_memory(handle, PCILIB_KMEM_USE(PCILIB_KMEM_USE_DMA_RING, i), flags); - if (err) Error("Error cleaning DMA%i C2S Ring buffer", i); - err = pcilib_clean_kernel_memory(handle, PCILIB_KMEM_USE(PCILIB_KMEM_USE_DMA_RING, 0x80|i), flags); - if (err) Error("Error cleaning DMA%i S2C Ring buffer", i); - err = pcilib_clean_kernel_memory(handle, PCILIB_KMEM_USE(PCILIB_KMEM_USE_DMA_PAGES, i), flags); - if (err) Error("Error cleaning DMA%i C2S Page buffers", i); - err = pcilib_clean_kernel_memory(handle, PCILIB_KMEM_USE(PCILIB_KMEM_USE_DMA_PAGES, 0x80|i), flags); - if (err) Error("Error cleaning DMA%i S2C Page buffers", i); - } - - return 0; - } - - useid = ParseUse(use); - err = pcilib_clean_kernel_memory(handle, useid, flags); - if (err) Error("Error cleaning kernel buffers for use (0x%lx)", useid); - - return 0; -} - -int ListDMA(pcilib_t *handle, const char *device, pcilib_model_description_t *model_info) { - int err; - - DIR *dir; - struct dirent *entry; - const char *pos; - char sysdir[256]; - char fname[256]; - char info[256]; - char stmp[256]; - - pcilib_dma_engine_t dmaid; - pcilib_dma_engine_status_t status; - - pos = strrchr(device, '/'); - if (pos) ++pos; - else pos = device; - - snprintf(sysdir, 255, "/sys/class/fpga/%s", pos); - - dir = opendir(sysdir); - if (!dir) Error("Can't open directory (%s)", sysdir); - - printf("DMA Engine Status Total Size Buffer Ring (1st used - 1st free)\n"); - printf("--------------------------------------------------------------------------------\n"); - while ((entry = readdir(dir)) != NULL) { - FILE *f; - unsigned long use = 0; -// unsigned long size = 0; -// unsigned long refs = 0; - unsigned long mode = 0; -// unsigned long hwref = 0; - - if (strncmp(entry->d_name, "kbuf", 4)) continue; - if (!isnumber(entry->d_name+4)) continue; - - snprintf(fname, 255, "%s/%s", sysdir, entry->d_name); - f = fopen(fname, "r"); - if (!f) Error("Can't access file (%s)", fname); - - while(!feof(f)) { - fgets(info, 256, f); - if (!strncmp(info, "use:", 4)) use = strtoul(info+4, NULL, 16); -// if (!strncmp(info, "size:", 5)) size = strtoul(info+5, NULL, 10); -// if (!strncmp(info, "refs:", 5)) refs = strtoul(info+5, NULL, 10); - if (!strncmp(info, "mode:", 5)) mode = strtoul(info+5, NULL, 16); -// if (!strncmp(info, "hw ref:", 7)) hwref = strtoul(info+7, NULL, 10); - } - fclose(f); - - if ((mode&(KMEM_MODE_REUSABLE|KMEM_MODE_PERSISTENT|KMEM_MODE_COUNT)) == 0) continue; // closed - if ((use >> 16) != PCILIB_KMEM_USE_DMA_RING) continue; - - if (use&0x80) { - dmaid = pcilib_find_dma_by_addr(handle, PCILIB_DMA_TO_DEVICE, use&0x7F); - } else { - dmaid = pcilib_find_dma_by_addr(handle, PCILIB_DMA_FROM_DEVICE, use&0x7F); - } - - if (dmaid == PCILIB_DMA_ENGINE_INVALID) continue; - - - printf("DMA%lu %s ", use&0x7F, (use&0x80)?"S2C":"C2S"); - err = pcilib_start_dma(handle, dmaid, 0); - if (err) { - printf("-- Wrong state, start is failed\n"); - continue; - } - - err = pcilib_get_dma_status(handle, dmaid, &status, 0, NULL); - if (err) { - printf("-- Wrong state, failed to obtain status\n"); - pcilib_stop_dma(handle, dmaid, 0); - continue; - } - - pcilib_stop_dma(handle, dmaid, 0); - - if (status.started) printf("S"); - else printf(" "); - - if (status.ring_head == status.ring_tail) printf(" "); - else printf("D"); - - printf(" "); - printf("% 10s", GetPrintSize(stmp, status.ring_size * status.buffer_size)); - - printf(" "); - printf("%zu - %zu (of %zu)", status.ring_tail, status.ring_head, status.ring_size); - - printf("\n"); - - } - closedir(dir); - - printf("--------------------------------------------------------------------------------\n"); - printf("S - Started, D - Data in buffers\n"); - - return 0; -} - -int ListBuffers(pcilib_t *handle, const char *device, pcilib_model_description_t *model_info, pcilib_dma_engine_addr_t dma, pcilib_dma_direction_t dma_direction) { - int err; - size_t i; - pcilib_dma_engine_t dmaid; - pcilib_dma_engine_status_t status; - pcilib_dma_buffer_status_t *buffer; - char stmp[256]; - - dmaid = pcilib_find_dma_by_addr(handle, dma_direction, dma); - if (dmaid == PCILIB_DMA_ENGINE_INVALID) Error("The specified DMA engine is not found"); - - err = pcilib_start_dma(handle, dmaid, 0); - if (err) Error("Error starting the specified DMA engine"); - - err = pcilib_get_dma_status(handle, dmaid, &status, 0, NULL); - if (err) Error("Failed to obtain status of the specified DMA engine"); - - buffer = (pcilib_dma_buffer_status_t*)malloc(status.ring_size*sizeof(pcilib_dma_buffer_status_t)); - if (!buffer) Error("Failed to allocate memory for status buffer"); - - err = pcilib_get_dma_status(handle, dmaid, &status, status.ring_size, buffer); - if (err) Error("Failed to obtain extended status of the specified DMA engine"); - - - printf("Buffer Status Total Size \n"); - printf("--------------------------------------------------------------------------------\n"); - - for (i = 0; i < status.ring_size; i++) { - printf("%8zu ", i); - printf("%c%c %c%c ", buffer[i].used?'U':' ', buffer[i].error?'E':' ', buffer[i].first?'F':' ', buffer[i].last?'L':' '); - printf("% 10s", GetPrintSize(stmp, buffer[i].size)); - printf("\n"); - } - - printf("--------------------------------------------------------------------------------\n"); - printf("U - Used, E - Error, F - First block, L - Last Block\n"); - - free(buffer); - - pcilib_stop_dma(handle, dmaid, 0); - - return 0; -} - -int ReadBuffer(pcilib_t *handle, const char *device, pcilib_model_description_t *model_info, pcilib_dma_engine_addr_t dma, pcilib_dma_direction_t dma_direction, size_t block, FILE *o) { - int err; - pcilib_dma_engine_t dmaid; - pcilib_dma_engine_status_t status; - pcilib_dma_buffer_status_t *buffer; - size_t size; - - dmaid = pcilib_find_dma_by_addr(handle, dma_direction, dma); - if (dmaid == PCILIB_DMA_ENGINE_INVALID) Error("The specified DMA engine is not found"); - - err = pcilib_start_dma(handle, dmaid, 0); - if (err) Error("Error starting the specified DMA engine"); - - err = pcilib_get_dma_status(handle, dmaid, &status, 0, NULL); - if (err) Error("Failed to obtain status of the specified DMA engine"); - - buffer = (pcilib_dma_buffer_status_t*)malloc(status.ring_size*sizeof(pcilib_dma_buffer_status_t)); - if (!buffer) Error("Failed to allocate memory for status buffer"); - - err = pcilib_get_dma_status(handle, dmaid, &status, status.ring_size, buffer); - if (err) Error("Failed to obtain extended status of the specified DMA engine"); - - if (block == (size_t)-1) { - // get current - } - - size = buffer[block].size; - - free(buffer); - - pcilib_stop_dma(handle, dmaid, 0); - - return ReadKMEM(handle, device, ((dma&0x7F)|((dma_direction == PCILIB_DMA_TO_DEVICE)?0x80:0x00))|(PCILIB_KMEM_USE_DMA_PAGES<<16), block, size, o); -} - - -int EnableIRQ(pcilib_t *handle, pcilib_model_description_t *model_info, pcilib_irq_type_t irq_type) { - int err; - - err = pcilib_enable_irq(handle, irq_type, 0); - if (err) { - if ((err != PCILIB_ERROR_NOTSUPPORTED)&&(err != PCILIB_ERROR_NOTAVAILABLE)) - Error("Error enabling IRQs"); - } - - return err; -} - -int DisableIRQ(pcilib_t *handle, pcilib_model_description_t *model_info, pcilib_irq_type_t irq_type) { - int err; - - err = pcilib_disable_irq(handle, 0); - if (err) { - if ((err != PCILIB_ERROR_NOTSUPPORTED)&&(err != PCILIB_ERROR_NOTAVAILABLE)) - Error("Error disabling IRQs"); - } - - return err; -} - -int AckIRQ(pcilib_t *handle, pcilib_model_description_t *model_info, pcilib_irq_hw_source_t irq_source) { - pcilib_clear_irq(handle, irq_source); - return 0; -} - -int WaitIRQ(pcilib_t *handle, pcilib_model_description_t *model_info, pcilib_irq_hw_source_t irq_source, pcilib_timeout_t timeout) { - int err; - size_t count; - - err = pcilib_wait_irq(handle, irq_source, timeout, &count); - if (err) { - if (err == PCILIB_ERROR_TIMEOUT) Error("Timeout waiting for IRQ"); - else Error("Error waiting for IRQ"); - } - - return 0; -} - - -int main(int argc, char **argv) { - int i; - long itmp; - size_t ztmp; - unsigned char c; - - const char *stmp; - const char *num_offset; - - int details = 0; - int verbose = 0; - int quiete = 0; - int force = 0; - int verify = 0; - - pcilib_model_t model = PCILIB_MODEL_DETECT; - pcilib_model_description_t *model_info; - MODE mode = MODE_INVALID; - GRAB_MODE grab_mode = 0; - size_t trigger_time = 0; - size_t run_time = 0; - size_t buffer = 0; - size_t threads = 1; - FORMAT format = FORMAT_DEFAULT; - PARTITION partition = PARTITION_UNKNOWN; - FLAGS flags = 0; - const char *atype = NULL; - const char *type = NULL; - ACCESS_MODE amode = ACCESS_BAR; - const char *fpga_device = DEFAULT_FPGA_DEVICE; - pcilib_bar_t bar = PCILIB_BAR_DETECT; - const char *addr = NULL; - const char *reg = NULL; - const char *bank = NULL; - char **data = NULL; - const char *event = NULL; - const char *data_type = NULL; - const char *dma_channel = NULL; - const char *use = NULL; - size_t block = (size_t)-1; - pcilib_irq_type_t irq_type = PCILIB_IRQ_TYPE_ALL; - pcilib_irq_hw_source_t irq_source = PCILIB_IRQ_SOURCE_DEFAULT; - pcilib_dma_direction_t dma_direction = PCILIB_DMA_BIDIRECTIONAL; - pcilib_kmem_use_t useid = 0; - - pcilib_dma_engine_addr_t dma = PCILIB_DMA_ENGINE_ADDR_INVALID; - long addr_shift = 0; - uintptr_t start = -1; - size_t block_size = 0; - size_t size = 1; - access_t access = 4; -// int skip = 0; - int endianess = 0; - size_t timeout = 0; - size_t alignment = 0; - const char *output = NULL; - FILE *ofile = NULL; - size_t iterations = BENCHMARK_ITERATIONS; - - pcilib_t *handle; - - int size_set = 0; - int timeout_set = 0; -// int run_time_set = 0; - - while ((c = getopt_long(argc, argv, "hqilr::w::g::d:m:t:b:a:s:e:o:", long_options, NULL)) != (unsigned char)-1) { - extern int optind; - switch (c) { - case OPT_HELP: - Usage(argc, argv, NULL); - break; - case OPT_INFO: - if (mode != MODE_INVALID) Usage(argc, argv, "Multiple operations are not supported"); - - mode = MODE_INFO; - break; - case OPT_LIST: - if (mode == MODE_LIST) details++; - else if (mode != MODE_INVALID) Usage(argc, argv, "Multiple operations are not supported"); - - mode = MODE_LIST; - break; - case OPT_RESET: - if (mode != MODE_INVALID) Usage(argc, argv, "Multiple operations are not supported"); - - mode = MODE_RESET; - break; - case OPT_BENCHMARK: - if (mode != MODE_INVALID) Usage(argc, argv, "Multiple operations are not supported"); - - mode = MODE_BENCHMARK; - - if (optarg) addr = optarg; - else if ((optind < argc)&&(argv[optind][0] != '-')) addr = argv[optind++]; - break; - case OPT_READ: - if (mode != MODE_INVALID) Usage(argc, argv, "Multiple operations are not supported"); - - mode = MODE_READ; - if (optarg) addr = optarg; - else if ((optind < argc)&&(argv[optind][0] != '-')) addr = argv[optind++]; - break; - case OPT_WRITE: - if (mode != MODE_INVALID) Usage(argc, argv, "Multiple operations are not supported"); - - mode = MODE_WRITE; - if (optarg) addr = optarg; - else if ((optind < argc)&&(argv[optind][0] != '-')) addr = argv[optind++]; - break; - case OPT_GRAB: - if ((mode != MODE_INVALID)&&((mode != MODE_GRAB)||(grab_mode&GRAB_MODE_GRAB))) Usage(argc, argv, "Multiple operations are not supported"); - - mode = MODE_GRAB; - grab_mode |= GRAB_MODE_GRAB; - - stmp = NULL; - if (optarg) stmp = optarg; - else if ((optind < argc)&&(argv[optind][0] != '-')) stmp = argv[optind++]; - - if (stmp) { - if ((event)&&(strcasecmp(stmp,event))) Usage(argc, argv, "Redefinition of considered event"); - event = stmp; - } - break; - case OPT_TRIGGER: - if ((mode != MODE_INVALID)&&((mode != MODE_GRAB)||(grab_mode&GRAB_MODE_TRIGGER))) Usage(argc, argv, "Multiple operations are not supported"); - - mode = MODE_GRAB; - grab_mode |= GRAB_MODE_TRIGGER; - - stmp = NULL; - if (optarg) stmp = optarg; - else if ((optind < argc)&&(argv[optind][0] != '-')) stmp = argv[optind++]; - - if (stmp) { - if ((event)&&(strcasecmp(stmp,event))) Usage(argc, argv, "Redefinition of considered event"); - event = stmp; - } - break; - case OPT_LIST_DMA: - if (mode != MODE_INVALID) Usage(argc, argv, "Multiple operations are not supported"); - - mode = MODE_LIST_DMA; - break; - case OPT_LIST_DMA_BUFFERS: - if (mode != MODE_INVALID) Usage(argc, argv, "Multiple operations are not supported"); - - mode = MODE_LIST_DMA_BUFFERS; - dma_channel = optarg; - break; - case OPT_READ_DMA_BUFFER: - if (mode != MODE_INVALID) Usage(argc, argv, "Multiple operations are not supported"); - - mode = MODE_READ_DMA_BUFFER; - - num_offset = strchr(optarg, ':'); - - if (num_offset) { - if (sscanf(num_offset + 1, "%zu", &block) != 1) - Usage(argc, argv, "Invalid buffer is specified (%s)", num_offset + 1); - - *(char*)num_offset = 0; - } else block = (size_t)-1; - - dma_channel = optarg; - break; - case OPT_START_DMA: - if (mode != MODE_INVALID) Usage(argc, argv, "Multiple operations are not supported"); - - mode = MODE_START_DMA; - if (optarg) dma_channel = optarg; - else if ((optind < argc)&&(argv[optind][0] != '-')) dma_channel = argv[optind++]; - break; - case OPT_STOP_DMA: - if (mode != MODE_INVALID) Usage(argc, argv, "Multiple operations are not supported"); - - mode = MODE_STOP_DMA; - if (optarg) dma_channel = optarg; - else if ((optind < argc)&&(argv[optind][0] != '-')) dma_channel = argv[optind++]; - break; - case OPT_ENABLE_IRQ: - if (mode != MODE_INVALID) Usage(argc, argv, "Multiple operations are not supported"); - - mode = MODE_ENABLE_IRQ; - if (optarg) num_offset = optarg; - else if ((optind < argc)&&(argv[optind][0] != '-')) num_offset = argv[optind++]; - else num_offset = NULL; - - if (num_offset) { - if ((!isnumber(num_offset))||(sscanf(num_offset, "%li", &itmp) != 1)) - Usage(argc, argv, "Invalid IRQ source is specified (%s)", num_offset); - - irq_type = itmp; - } - break; - case OPT_DISABLE_IRQ: - if (mode != MODE_INVALID) Usage(argc, argv, "Multiple operations are not supported"); - - mode = MODE_DISABLE_IRQ; - if (optarg) num_offset = optarg; - else if ((optind < argc)&&(argv[optind][0] != '-')) num_offset = argv[optind++]; - else num_offset = NULL; - - if (num_offset) { - if ((!isnumber(num_offset))||(sscanf(num_offset, "%li", &itmp) != 1)) - Usage(argc, argv, "Invalid IRQ source is specified (%s)", num_offset); - - irq_type = itmp; - } - break; - case OPT_ACK_IRQ: - if (mode != MODE_INVALID) Usage(argc, argv, "Multiple operations are not supported"); - - mode = MODE_ACK_IRQ; - if (optarg) num_offset = optarg; - else if ((optind < argc)&&(argv[optind][0] != '-')) num_offset = argv[optind++]; - else num_offset = NULL; - - if (num_offset) { - if ((!isnumber(num_offset))||(sscanf(num_offset, "%li", &itmp) != 1)) - Usage(argc, argv, "Invalid IRQ source is specified (%s)", num_offset); - - irq_source = itmp; - } - break; - case OPT_WAIT_IRQ: - if (mode != MODE_INVALID) Usage(argc, argv, "Multiple operations are not supported"); - - mode = MODE_WAIT_IRQ; - if (optarg) num_offset = optarg; - else if ((optind < argc)&&(argv[optind][0] != '-')) num_offset = argv[optind++]; - else num_offset = NULL; - - if (num_offset) { - if ((!isnumber(num_offset))||(sscanf(num_offset, "%li", &itmp) != 1)) - Usage(argc, argv, "Invalid IRQ source is specified (%s)", num_offset); - - irq_source = itmp; - } - break; - case OPT_LIST_KMEM: - if (mode != MODE_INVALID) Usage(argc, argv, "Multiple operations are not supported"); - mode = MODE_LIST_KMEM; - - if (optarg) use = optarg; - else if ((optind < argc)&&(argv[optind][0] != '-')) use = argv[optind++]; - else use = NULL; - - if (use) { - num_offset = strchr(use, ':'); - - if (num_offset) { - if (sscanf(num_offset + 1, "%zu", &block) != 1) - Usage(argc, argv, "Invalid block number is specified (%s)", num_offset + 1); - - *(char*)num_offset = 0; - } - } - break; - case OPT_READ_KMEM: - if (mode != MODE_INVALID) Usage(argc, argv, "Multiple operations are not supported"); - mode = MODE_READ_KMEM; - - num_offset = strchr(optarg, ':'); - - if (num_offset) { - if (sscanf(num_offset + 1, "%zu", &block) != 1) - Usage(argc, argv, "Invalid block number is specified (%s)", num_offset + 1); - - *(char*)num_offset = 0; - } - - use = optarg; - useid = ParseUse(use); - break; - case OPT_ALLOC_KMEM: - if (mode != MODE_INVALID) Usage(argc, argv, "Multiple operations are not supported"); - mode = MODE_ALLOC_KMEM; - - if (optarg) use = optarg; - else if ((optind < argc)&&(argv[optind][0] != '-')) use = argv[optind++]; - break; - case OPT_FREE_KMEM: - if (mode != MODE_INVALID) Usage(argc, argv, "Multiple operations are not supported"); - mode = MODE_FREE_KMEM; - - if (optarg) use = optarg; - else if ((optind < argc)&&(argv[optind][0] != '-')) use = argv[optind++]; - break; - case OPT_DEVICE: - fpga_device = optarg; - break; - case OPT_MODEL: - if (!strcasecmp(optarg, "pci")) model = PCILIB_MODEL_PCI; - else if (!strcasecmp(optarg, "ipecamera")) model = PCILIB_MODEL_IPECAMERA; - else if (!strcasecmp(optarg, "kapture")) model = PCILIB_MODEL_KAPTURE; - else Usage(argc, argv, "Invalid memory model (%s) is specified", optarg); - break; - case OPT_BAR: - bank = optarg; -// if ((sscanf(optarg,"%li", &itmp) != 1)||(itmp < 0)||(itmp >= PCILIB_MAX_BANKS)) Usage(argc, argv, "Invalid data bank (%s) is specified", optarg); -// else bar = itmp; - break; - case OPT_ALIGNMENT: - if ((!isnumber(optarg))||(sscanf(optarg, "%zu", &alignment) != 1)) { - Usage(argc, argv, "Invalid alignment is specified (%s)", optarg); - } - break; - case OPT_ACCESS: - if (!strncasecmp(optarg, "fifo", 4)) { - atype = "fifo"; - num_offset = optarg + 4; - amode = ACCESS_FIFO; - } else if (!strncasecmp(optarg, "dma", 3)) { - atype = "dma"; - num_offset = optarg + 3; - amode = ACCESS_DMA; - } else if (!strncasecmp(optarg, "bar", 3)) { - atype = "plain"; - num_offset = optarg + 3; - amode = ACCESS_BAR; - } else if (!strncasecmp(optarg, "config", 6)) { - atype = "config"; - num_offset = optarg + 6; - amode = ACCESS_CONFIG; - } else if (!strncasecmp(optarg, "plain", 5)) { - atype = "plain"; - num_offset = optarg + 5; - amode = ACCESS_BAR; - } else { - num_offset = optarg; - } - - if (*num_offset) { - if ((!isnumber(num_offset))||(sscanf(num_offset, "%li", &itmp) != 1)) - Usage(argc, argv, "Invalid access type (%s) is specified", optarg); - - switch (itmp) { - case 8: access = 1; break; - case 16: access = 2; break; - case 32: access = 4; break; - case 64: access = 8; break; - default: Usage(argc, argv, "Invalid data width (%s) is specified", num_offset); - } - } - break; - case OPT_SIZE: - if ((!isnumber(optarg))||(sscanf(optarg, "%zu", &size) != 1)) { - if (strcasecmp(optarg, "unlimited")) - Usage(argc, argv, "Invalid size is specified (%s)", optarg); - else - size = 0;//(size_t)-1; - } - - size_set = 1; - break; - case OPT_BLOCK_SIZE: - if ((!isnumber(optarg))||(sscanf(optarg, "%zu", &block_size) != 1)) { - Usage(argc, argv, "Invalid size is specified (%s)", optarg); - } - break; - case OPT_ENDIANESS: - if ((*optarg == 'b')||(*optarg == 'B')) { - if (ntohs(1) == 1) endianess = 0; - else endianess = 1; - } else if ((*optarg == 'l')||(*optarg == 'L')) { - if (ntohs(1) == 1) endianess = 1; - else endianess = 0; - } else Usage(argc, argv, "Invalid endianess is specified (%s)", optarg); - - break; - case OPT_TIMEOUT: - if ((!isnumber(optarg))||(sscanf(optarg, "%zu", &timeout) != 1)) { - if (strcasecmp(optarg, "unlimited")) - Usage(argc, argv, "Invalid timeout is specified (%s)", optarg); - else - timeout = PCILIB_TIMEOUT_INFINITE; - } - timeout_set = 1; - break; - case OPT_OUTPUT: - output = optarg; - break; - case OPT_ITERATIONS: - if ((!isnumber(optarg))||(sscanf(optarg, "%zu", &iterations) != 1)) - Usage(argc, argv, "Invalid number of iterations is specified (%s)", optarg); - break; - case OPT_EVENT: - event = optarg; - break; - case OPT_TYPE: - type = optarg; - break; - case OPT_DATA_TYPE: - data_type = optarg; - break; - case OPT_RUN_TIME: - if ((!isnumber(optarg))||(sscanf(optarg, "%zu", &run_time) != 1)) { - if (strcasecmp(optarg, "unlimited")) - Usage(argc, argv, "Invalid run-time is specified (%s)", optarg); - else - run_time = 0; - } -// run_time_set = 1; - break; - case OPT_TRIGGER_TIME: - if ((!isnumber(optarg))||(sscanf(optarg, "%zu", &trigger_time) != 1)) - Usage(argc, argv, "Invalid trigger-time is specified (%s)", optarg); - break; - case OPT_TRIGGER_RATE: - if ((!isnumber(optarg))||(sscanf(optarg, "%zu", &ztmp) != 1)) - Usage(argc, argv, "Invalid trigger-rate is specified (%s)", optarg); - - trigger_time = (1000000 / ztmp) + ((1000000 % ztmp)?1:0); - break; - case OPT_BUFFER: - if (optarg) num_offset = optarg; - else if ((optind < argc)&&(argv[optind][0] != '-')) num_offset = argv[optind++]; - else num_offset = NULL; - - if (num_offset) { - if ((!isnumber(num_offset))||(sscanf(num_offset, "%zu", &buffer) != 1)) - Usage(argc, argv, "Invalid buffer size is specified (%s)", num_offset); - buffer *= 1024 * 1024; - } else { - buffer = get_free_memory(); - if (buffer < 256) Error("Not enough free memory (%lz MB) for buffering", buffer / 1024 / 1024); - - buffer -= 128 + buffer/16; - } - break; - case OPT_THREADS: - if (optarg) num_offset = optarg; - else if ((optind < argc)&&(argv[optind][0] != '-')) num_offset = argv[optind++]; - else num_offset = NULL; - - if (num_offset) { - if ((!isnumber(num_offset))||(sscanf(num_offset, "%zu", &threads) != 1)) - Usage(argc, argv, "Invalid threads number is specified (%s)", num_offset); - } else { - threads = 0; - } - break; - case OPT_FORMAT: - if (!strcasecmp(optarg, "raw")) format = FORMAT_RAW; - else if (!strcasecmp(optarg, "add_header")) format = FORMAT_HEADER; -// else if (!strcasecmp(optarg, "ringfs")) format = FORMAT_RINGFS; - else if (strcasecmp(optarg, "default")) Error("Invalid format (%s) is specified", optarg); - break; - case OPT_QUIETE: - quiete = 1; - verbose = -1; - break; - case OPT_VERBOSE: - if (optarg) num_offset = optarg; - else if ((optind < argc)&&(argv[optind][0] != '-')) num_offset = argv[optind++]; - else num_offset = NULL; - - if (num_offset) { - if ((!isnumber(num_offset))||(sscanf(num_offset, "%i", &verbose) != 1)) - Usage(argc, argv, "Invalid verbosity level is specified (%s)", num_offset); - } else { - verbose = 1; - } - break; - case OPT_FORCE: - force = 1; - break; - case OPT_VERIFY: - verify = 1; - break; - case OPT_MULTIPACKET: - flags |= FLAG_MULTIPACKET; - break; - case OPT_WAIT: - flags |= FLAG_WAIT; - break; - default: - Usage(argc, argv, "Unknown option (%s) with argument (%s)", optarg?argv[optind-2]:argv[optind-1], optarg?optarg:"(null)"); - } - } - - if (mode == MODE_INVALID) { - if (argc > 1) Usage(argc, argv, "Operation is not specified"); - else Usage(argc, argv, NULL); - } - - pcilib_set_error_handler(&Error, quiete?Silence:NULL); - - handle = pcilib_open(fpga_device, model); - if (handle < 0) Error("Failed to open FPGA device: %s", fpga_device); - - model = pcilib_get_model(handle); - model_info = pcilib_get_model_description(handle); - - switch (mode) { - case MODE_WRITE: - if (((argc - optind) == 1)&&(*argv[optind] == '*')) { - int vallen = strlen(argv[optind]); - if (vallen > 1) { - data = (char**)malloc(size * (vallen + sizeof(char*))); - if (!data) Error("Error allocating memory for data array"); - - for (i = 0; i < size; i++) { - data[i] = ((char*)data) + size * sizeof(char*) + i * vallen; - strcpy(data[i], argv[optind] + 1); - } - } else { - data = (char**)malloc(size * (9 + sizeof(char*))); - if (!data) Error("Error allocating memory for data array"); - - for (i = 0; i < size; i++) { - data[i] = ((char*)data) + size * sizeof(char*) + i * 9; - sprintf(data[i], "%x", i); - } - } - } else if ((argc - optind) == size) data = argv + optind; - else Usage(argc, argv, "The %i data values is specified, but %i required", argc - optind, size); - case MODE_READ: - if (!addr) { - if (model == PCILIB_MODEL_PCI) { - if ((amode != ACCESS_DMA)&&(amode != ACCESS_CONFIG)) - Usage(argc, argv, "The address is not specified"); - } else ++mode; - } - break; - case MODE_START_DMA: - case MODE_STOP_DMA: - case MODE_LIST_DMA_BUFFERS: - case MODE_READ_DMA_BUFFER: - if ((dma_channel)&&(*dma_channel)) { - itmp = strlen(dma_channel) - 1; - if (dma_channel[itmp] == 'r') dma_direction = PCILIB_DMA_FROM_DEVICE; - else if (dma_channel[itmp] == 'w') dma_direction = PCILIB_DMA_TO_DEVICE; - - if (dma_direction != PCILIB_DMA_BIDIRECTIONAL) itmp--; - - if (strncmp(dma_channel, "dma", 3)) num_offset = dma_channel; - else { - num_offset = dma_channel + 3; - itmp -= 3; - } - - if (bank) { - if (strncmp(num_offset, bank, itmp)) Usage(argc, argv, "Conflicting DMA channels are specified in mode parameter (%s) and bank parameter (%s)", dma_channel, bank); - } - - if (!isnumber_n(num_offset, itmp)) - Usage(argc, argv, "Invalid DMA channel (%s) is specified", dma_channel); - - dma = atoi(num_offset); - } - break; - default: - if (argc > optind) Usage(argc, argv, "Invalid non-option parameters are supplied"); - } - - - if (addr) { - if ((!strncmp(addr, "dma", 3))&&((addr[3]==0)||isnumber(addr+3))) { - if ((atype)&&(amode != ACCESS_DMA)) Usage(argc, argv, "Conflicting access modes, the DMA read is requested, but access type is (%s)", type); - if (bank) { - if ((addr[3] != 0)&&(strcmp(addr + 3, bank))) Usage(argc, argv, "Conflicting DMA channels are specified in read parameter (%s) and bank parameter (%s)", addr + 3, bank); - } else { - if (addr[3] == 0) Usage(argc, argv, "The DMA channel is not specified"); - } - dma = atoi(addr + 3); - amode = ACCESS_DMA; - addr = NULL; - } else if ((!strncmp(addr, "bar", 3))&&((addr[3]==0)||isnumber(addr+3))) { - if ((atype)&&(amode != ACCESS_BAR)) Usage(argc, argv, "Conflicting access modes, the plain PCI read is requested, but access type is (%s)", type); - if ((addr[3] != 0)&&(strcmp(addr + 3, bank))) Usage(argc, argv, "Conflicting PCI bars are specified in read parameter (%s) and bank parameter (%s)", addr + 3, bank); - bar = atoi(addr + 3); - amode = ACCESS_BAR; - addr = NULL; - } else if (!strcmp(addr, "config")) { - if ((atype)&&(amode != ACCESS_CONFIG)) Usage(argc, argv, "Conflicting access modes, the read of PCI configurataion space is requested, but access type is (%s)", type); - amode = ACCESS_CONFIG; - addr = NULL; - } else if ((isxnumber(addr))&&(sscanf(addr, "%lx", &start) == 1)) { - // check if the address in the register range - pcilib_register_range_t *ranges = model_info->ranges; - - if (ranges) { - for (i = 0; ranges[i].start != ranges[i].end; i++) - if ((start >= ranges[i].start)&&(start <= ranges[i].end)) break; - - // register access in plain mode - if (ranges[i].start != ranges[i].end) { - pcilib_register_bank_t regbank = pcilib_find_bank_by_addr(handle, ranges[i].bank); - if (regbank == PCILIB_REGISTER_BANK_INVALID) Error("Configuration error: register bank specified in the address range is not found"); - - bank = model_info->banks[regbank].name; - start += ranges[i].addr_shift; - addr_shift = ranges[i].addr_shift; - ++mode; - } - } - } else { - if (pcilib_find_register(handle, bank, addr) == PCILIB_REGISTER_INVALID) { - Usage(argc, argv, "Invalid address (%s) is specified", addr); - } else { - reg = addr; - ++mode; - } - } - } - - if (mode == MODE_GRAB) { - if (output) { - char fsname[128]; - if (!get_file_fs(output, 127, fsname)) { - if (!strcmp(fsname, "ext4")) partition = PARTITION_EXT4; - else if (!strcmp(fsname, "raw")) partition = PARTITION_RAW; - } - } else { - output = "/dev/null"; - partition = PARTITION_NULL; - } - - if (!timeout_set) { - if (run_time) timeout = PCILIB_TIMEOUT_INFINITE; - else timeout = PCILIB_EVENT_TIMEOUT; - } - - if (!size_set) { - if (run_time) size = 0; - } - } - - if (mode != MODE_GRAB) { - if (size == (size_t)-1) - Usage(argc, argv, "Unlimited size is not supported in selected operation mode"); - } - - - if ((bank)&&(amode == ACCESS_DMA)) { - if ((!isnumber(bank))||(sscanf(bank,"%li", &itmp) != 1)||(itmp < 0)) - Usage(argc, argv, "Invalid DMA channel (%s) is specified", bank); - else dma = itmp; - } else if (bank) { - switch (mode) { - case MODE_BENCHMARK: - case MODE_READ: - case MODE_WRITE: - if ((!isnumber(bank))||(sscanf(bank,"%li", &itmp) != 1)||(itmp < 0)||(itmp >= PCILIB_MAX_BANKS)) - Usage(argc, argv, "Invalid data bank (%s) is specified", bank); - else bar = itmp; - break; - default: - if (pcilib_find_bank(handle, bank) == PCILIB_REGISTER_BANK_INVALID) - Usage(argc, argv, "Invalid data bank (%s) is specified", bank); - } - } - - signal(SIGINT, signal_exit_handler); - - if ((mode != MODE_GRAB)&&(output)) { - ofile = fopen(output, "a+"); - if (!ofile) { - Error("Failed to open file \"%s\"", output); - } - } - - switch (mode) { - case MODE_INFO: - Info(handle, model_info); - break; - case MODE_LIST: - List(handle, model_info, bank, details); - break; - case MODE_BENCHMARK: - Benchmark(handle, amode, dma, bar, start, size_set?size:0, access, iterations); - break; - case MODE_READ: - if (amode == ACCESS_DMA) { - ReadData(handle, amode, flags, dma, bar, start, size_set?size:0, access, endianess, timeout_set?timeout:(size_t)-1, ofile); - } else if (amode == ACCESS_CONFIG) { - ReadData(handle, amode, flags, dma, bar, addr?start:0, (addr||size_set)?size:(256/abs(access)), access, endianess, (size_t)-1, ofile); - } else if (addr) { - ReadData(handle, amode, flags, dma, bar, start, size, access, endianess, (size_t)-1, ofile); - } else { - Error("Address to read is not specified"); - } - break; - case MODE_READ_REGISTER: - if ((reg)||(!addr)) ReadRegister(handle, model_info, bank, reg); - else ReadRegisterRange(handle, model_info, bank, start, addr_shift, size, ofile); - break; - case MODE_WRITE: - WriteData(handle, amode, dma, bar, start, size, access, endianess, data, verify); - break; - case MODE_WRITE_REGISTER: - if (reg) WriteRegister(handle, model_info, bank, reg, data); - else WriteRegisterRange(handle, model_info, bank, start, addr_shift, size, data); - break; - case MODE_RESET: - pcilib_reset(handle); - break; - case MODE_GRAB: - TriggerAndGrab(handle, grab_mode, event, data_type, size, run_time, trigger_time, timeout, partition, format, buffer, threads, verbose, output); - break; - case MODE_LIST_DMA: - ListDMA(handle, fpga_device, model_info); - break; - case MODE_LIST_DMA_BUFFERS: - ListBuffers(handle, fpga_device, model_info, dma, dma_direction); - break; - case MODE_READ_DMA_BUFFER: - ReadBuffer(handle, fpga_device, model_info, dma, dma_direction, block, ofile); - break; - case MODE_START_DMA: - StartStopDMA(handle, model_info, dma, dma_direction, 1); - break; - case MODE_STOP_DMA: - StartStopDMA(handle, model_info, dma, dma_direction, 0); - break; - case MODE_ENABLE_IRQ: - EnableIRQ(handle, model_info, irq_type); - break; - case MODE_DISABLE_IRQ: - DisableIRQ(handle, model_info, irq_type); - break; - case MODE_ACK_IRQ: - AckIRQ(handle, model_info, irq_source); - break; - case MODE_WAIT_IRQ: - WaitIRQ(handle, model_info, irq_source, timeout); - break; - case MODE_LIST_KMEM: - if (use) DetailKMEM(handle, fpga_device, use, block); - else ListKMEM(handle, fpga_device); - break; - case MODE_READ_KMEM: - ReadKMEM(handle, fpga_device, useid, block, 0, ofile); - break; - case MODE_ALLOC_KMEM: - AllocKMEM(handle, fpga_device, use, type, size, block_size, alignment); - break; - case MODE_FREE_KMEM: - FreeKMEM(handle, fpga_device, use, force); - break; - case MODE_INVALID: - break; - } - - if (ofile) fclose(ofile); - - pcilib_close(handle); - - if (data != argv + optind) free(data); -} diff --git a/ipecamera/model.c b/cmosis.c index e60561b..a8a2251 100644 --- a/ipecamera/model.c +++ b/cmosis.c @@ -4,9 +4,12 @@ #include <unistd.h> #include <assert.h> -#include "../tools.h" -#include "../error.h" -#include "model.h" +#include <pcilib.h> +#include <pcilib/tools.h> +#include <pcilib/error.h> + +#include "cmosis.h" +#include "private.h" #define ADDR_MASK 0x7F00 #define WRITE_BIT 0x8000 @@ -23,11 +26,12 @@ //static pcilib_register_value_t ipecamera_bit_mask[9] = { 0, 1, 3, 7, 15, 31, 63, 127, 255 }; -int ipecamera_read(pcilib_t *ctx, pcilib_register_bank_description_t *bank, pcilib_register_addr_t addr, pcilib_register_value_t *value) { +int ipecamera_cmosis_read(pcilib_t *ctx, pcilib_register_bank_context_t *bank_ctx, pcilib_register_addr_t addr, pcilib_register_value_t *value) { uint32_t val, tmp[4]; char *wr, *rd; struct timeval start;//, cur; int retries = RETRIES; + const pcilib_register_bank_description_t *bank = bank_ctx->bank; assert(addr < 128); @@ -52,21 +56,21 @@ retry: ipecamera_datacpy(wr, &val, bank); #ifdef IPECAMERA_SIMPLIFIED_READOUT - usleep(PCILIB_REGISTER_TIMEOUT); + usleep(IPECAMERA_REGISTER_TIMEOUT); // ipecamera_datacpy(tmp, rd, bank); -// usleep(PCILIB_REGISTER_TIMEOUT); +// usleep(IPECAMERA_REGISTER_TIMEOUT); ipecamera_datacpy(wr, &val, bank); - usleep(PCILIB_REGISTER_TIMEOUT); + usleep(IPECAMERA_REGISTER_TIMEOUT); // ipecamera_datacpy(tmp, rd, bank); -// usleep(PCILIB_REGISTER_TIMEOUT); +// usleep(IPECAMERA_REGISTER_TIMEOUT); ipecamera_datacpy(wr, &val, bank); - usleep(PCILIB_REGISTER_TIMEOUT); + usleep(IPECAMERA_REGISTER_TIMEOUT); #endif /* IPECAMERA_SIMPLIFIED_READOUT */ gettimeofday(&start, NULL); #ifdef IPECAMERA_MULTIREAD - usleep(PCILIB_REGISTER_TIMEOUT); + usleep(IPECAMERA_REGISTER_TIMEOUT); pcilib_datacpy(tmp, rd, 4, 4, bank->raw_endianess); val = tmp[0]; #else /* IPECAMERA_MULTIREAD */ @@ -74,7 +78,7 @@ retry: while ((val & READ_READY_BIT) == 0) { gettimeofday(&cur, NULL); - if (((cur.tv_sec - start.tv_sec)*1000000 + (cur.tv_usec - start.tv_usec)) > PCILIB_REGISTER_TIMEOUT) break; + if (((cur.tv_sec - start.tv_sec)*1000000 + (cur.tv_usec - start.tv_usec)) > IPECAMERA_REGISTER_TIMEOUT) break; ipecamera_datacpy(&val, rd, bank); } @@ -113,11 +117,12 @@ retry: return 0; } -int ipecamera_write(pcilib_t *ctx, pcilib_register_bank_description_t *bank, pcilib_register_addr_t addr, pcilib_register_value_t value) { +int ipecamera_cmosis_write(pcilib_t *ctx, pcilib_register_bank_context_t *bank_ctx, pcilib_register_addr_t addr, pcilib_register_value_t value) { uint32_t val, tmp[4]; char *wr, *rd; struct timeval start;//, cur; int retries = RETRIES; + const pcilib_register_bank_description_t *bank = bank_ctx->bank; assert(addr < 128); assert(value < 256); @@ -142,28 +147,28 @@ retry: ipecamera_datacpy(wr, &val, bank); #ifdef IPECAMERA_SIMPLIFIED_READOUT - usleep(PCILIB_REGISTER_TIMEOUT); + usleep(IPECAMERA_REGISTER_TIMEOUT); // ipecamera_datacpy(tmp, rd, bank); -// usleep(PCILIB_REGISTER_TIMEOUT); +// usleep(IPECAMERA_REGISTER_TIMEOUT); ipecamera_datacpy(wr, &val, bank); - usleep(PCILIB_REGISTER_TIMEOUT); + usleep(IPECAMERA_REGISTER_TIMEOUT); // ipecamera_datacpy(tmp, rd, bank); -// usleep(PCILIB_REGISTER_TIMEOUT); +// usleep(IPECAMERA_REGISTER_TIMEOUT); ipecamera_datacpy(wr, &val, bank); - usleep(PCILIB_REGISTER_TIMEOUT); + usleep(IPECAMERA_REGISTER_TIMEOUT); #endif /* IPECAMERA_SIMPLIFIED_READOUT */ gettimeofday(&start, NULL); #ifdef IPECAMERA_MULTIREAD - usleep(PCILIB_REGISTER_TIMEOUT); + usleep(IPECAMERA_REGISTER_TIMEOUT); pcilib_datacpy(tmp, rd, 4, 4, bank->raw_endianess); val = tmp[0]; #else /* IPECAMERA_MULTIREAD */ ipecamera_datacpy(&val, rd, bank); while ((val & READ_READY_BIT) == 0) { gettimeofday(&cur, NULL); - if (((cur.tv_sec - start.tv_sec)*1000000 + (cur.tv_usec - start.tv_usec)) > PCILIB_REGISTER_TIMEOUT) break; + if (((cur.tv_sec - start.tv_sec)*1000000 + (cur.tv_usec - start.tv_usec)) > IPECAMERA_REGISTER_TIMEOUT) break; ipecamera_datacpy(&val, rd, bank); } diff --git a/cmosis.h b/cmosis.h new file mode 100644 index 0000000..0d9c7a1 --- /dev/null +++ b/cmosis.h @@ -0,0 +1,9 @@ +#ifndef _IPECAMERA_CMOSIS_H +#define _IPECAMERA_CMOSIS_H + +#include <pcilib/bank.h> + +int ipecamera_cmosis_read(pcilib_t *ctx, pcilib_register_bank_context_t *bank, pcilib_register_addr_t addr, pcilib_register_value_t *value); +int ipecamera_cmosis_write(pcilib_t *ctx, pcilib_register_bank_context_t *bank, pcilib_register_addr_t addr, pcilib_register_value_t value); + +#endif /* _IPECAMERA_CMOSIS_H */ diff --git a/common.mk b/common.mk deleted file mode 100644 index c8d7387..0000000 --- a/common.mk +++ /dev/null @@ -1,61 +0,0 @@ -# Compiler and default flags -CC ?= gcc -CFLAGS ?= -O0 - - -# Defaults for directories -ROOTDIR ?= $(shell pwd) - -INCDIR ?= $(ROOTDIR) -BINDIR ?= $(ROOTDIR) -LIBDIR ?= $(ROOTDIR) -OBJDIR ?= $(ROOTDIR) -DEPENDDIR ?= $(ROOTDIR) - -CXXFLAGS += $(addprefix -I ,$(INCDIR)) -fPIC -CFLAGS += $(addprefix -I ,$(INCDIR)) -fPIC -std=c99 - -# Source files in this directory -SRC = $(wildcard *.cpp) -SRCC = $(wildcard *.c) - -SRC += $(wildcard ipecamera/*.cpp) -SRCC += $(wildcard ipecamera/*.c) - -SRC += $(wildcard dma/*.cpp) -SRCC += $(wildcard dma/*.c) - -# Corresponding object files -OBJ = $(addprefix $(OBJDIR)/,$(SRC:.cpp=.o)) -OBJ += $(addprefix $(OBJDIR)/,$(SRCC:.c=.o)) - -# Corresponding dependency files -DEPEND = $(addprefix $(DEPENDDIR)/,$(SRC:.cpp=.d)) -DEPEND += $(addprefix $(DEPENDDIR)/,$(SRCC:.c=.d)) - -# This makes Verbose easier. Just prefix $(Q) to any command -ifdef VERBOSE - Q ?= -else - Q ?= @ -endif - -############################################################### -# Target definitions - -# Target for automatic dependency generation -depend: $(DEPEND) $(DEPENDC); - -# This rule generates a dependency makefile for each source -$(DEPENDDIR)/%.d: %.c - @echo -e "DEPEND \t$<" - $(Q)$(CC) $(addprefix -I ,$(INCDIR)) -MM -MF $@ \ - -MT $(OBJDIR)/$(<:.c=.o) -MT $@ $< - -# This includes the automatically -# generated dependency files --include $(DEPEND) - -$(OBJDIR)/%.o: %.c - @echo -e "CC \t$<" - $(Q)@$(CC) $(CFLAGS) -c -o $@ $< diff --git a/ipecamera/data.c b/data.c index 2bcccd5..adb9c82 100644 --- a/ipecamera/data.c +++ b/data.c @@ -11,10 +11,10 @@ #include <ufodecode.h> -#include "../tools.h" -#include "../error.h" +#include <pcilib.h> +#include <pcilib/tools.h> +#include <pcilib/error.h> -#include "pcilib.h" #include "private.h" #include "data.h" diff --git a/ipecamera/data.h b/data.h index 846cb78..846cb78 100644 --- a/ipecamera/data.h +++ b/data.h diff --git a/default.c b/default.c deleted file mode 100644 index 0ea4d61..0000000 --- a/default.c +++ /dev/null @@ -1,34 +0,0 @@ -#include <sys/time.h> -#include <arpa/inet.h> -#include <assert.h> - -#include "tools.h" -#include "default.h" -#include "error.h" - -#define default_datacpy(dst, src, access, bank) pcilib_datacpy(dst, src, access, 1, bank->raw_endianess) - -int pcilib_default_read(pcilib_t *ctx, pcilib_register_bank_description_t *bank, pcilib_register_addr_t addr, pcilib_register_value_t *value) { - char *ptr; - pcilib_register_value_t val = 0; - int access = bank->access / 8; - - ptr = pcilib_resolve_register_address(ctx, bank->bar, bank->read_addr + addr); - default_datacpy(&val, ptr, access, bank); - -// *value = val&BIT_MASK(bits); - *value = val; - - return 0; -} - - -int pcilib_default_write(pcilib_t *ctx, pcilib_register_bank_description_t *bank, pcilib_register_addr_t addr, pcilib_register_value_t value) { - char *ptr; - int access = bank->access / 8; - - ptr = pcilib_resolve_register_address(ctx, bank->bar, bank->write_addr + addr); - default_datacpy(ptr, &value, access, bank); - - return 0; -} diff --git a/default.h b/default.h deleted file mode 100644 index 6b2cf93..0000000 --- a/default.h +++ /dev/null @@ -1,9 +0,0 @@ -#ifndef _PCILIB_DEFAULT_H -#define _PCILIB_DEFAULT_H - -#include "pcilib.h" - -int pcilib_default_read(pcilib_t *ctx, pcilib_register_bank_description_t *bank, pcilib_register_addr_t addr, pcilib_register_value_t *value); -int pcilib_default_write(pcilib_t *ctx, pcilib_register_bank_description_t *bank, pcilib_register_addr_t addr, pcilib_register_value_t value); - -#endif /* _PCILIB_DEFAULT_H */ @@ -1,327 +0,0 @@ -#include <stdio.h> -#include <string.h> -#include <strings.h> -#include <stdlib.h> -#include <stdint.h> -#include <stdarg.h> -#include <fcntl.h> -#include <unistd.h> -#include <sys/ioctl.h> -#include <sys/mman.h> -#include <arpa/inet.h> -#include <sys/time.h> -#include <errno.h> -#include <assert.h> - -#include "error.h" -#include "pcilib.h" -#include "pci.h" -#include "dma.h" - -const pcilib_dma_info_t *pcilib_get_dma_info(pcilib_t *ctx) { - if (!ctx->dma_ctx) { - pcilib_model_description_t *model_info = pcilib_get_model_description(ctx); - - if ((ctx->event_ctx)&&(model_info->event_api->init_dma)) { - pcilib_map_register_space(ctx); - ctx->dma_ctx = model_info->event_api->init_dma(ctx->event_ctx); - } else if ((model_info->dma_api)&&(model_info->dma_api->init)) { - pcilib_map_register_space(ctx); - ctx->dma_ctx = model_info->dma_api->init(ctx, PCILIB_DMA_MODIFICATION_DEFAULT, NULL); - } - - if (!ctx->dma_ctx) return NULL; - } - - return &ctx->dma_info; -} - -pcilib_dma_engine_t pcilib_find_dma_by_addr(pcilib_t *ctx, pcilib_dma_direction_t direction, pcilib_dma_engine_addr_t dma) { - pcilib_dma_engine_t i; - - const pcilib_dma_info_t *info = pcilib_get_dma_info(ctx); - if (!info) { - pcilib_error("DMA Engine is not configured in the current model"); - return PCILIB_ERROR_NOTSUPPORTED; - } - - for (i = 0; info->engines[i]; i++) { - if ((info->engines[i]->addr == dma)&&((info->engines[i]->direction&direction)==direction)) break; - } - - if (info->engines[i]) return i; - return PCILIB_DMA_ENGINE_INVALID; -} - -int pcilib_set_dma_engine_description(pcilib_t *ctx, pcilib_dma_engine_t engine, pcilib_dma_engine_description_t *desc) { - ctx->dma_info.engines[engine] = desc; - - return 0; -} - -int pcilib_start_dma(pcilib_t *ctx, pcilib_dma_engine_t dma, pcilib_dma_flags_t flags) { - const pcilib_dma_info_t *info = pcilib_get_dma_info(ctx); - if (!info) { - pcilib_error("DMA is not supported by the device"); - return PCILIB_ERROR_NOTSUPPORTED; - } - - if (!ctx->model_info.dma_api) { - pcilib_error("DMA Engine is not configured in the current model"); - return PCILIB_ERROR_NOTAVAILABLE; - } - - if (!ctx->model_info.dma_api->start_dma) { - return 0; - } - - return ctx->model_info.dma_api->start_dma(ctx->dma_ctx, dma, flags); -} - -int pcilib_stop_dma(pcilib_t *ctx, pcilib_dma_engine_t dma, pcilib_dma_flags_t flags) { - const pcilib_dma_info_t *info = pcilib_get_dma_info(ctx); - - if (!info) { - pcilib_error("DMA is not supported by the device"); - return PCILIB_ERROR_NOTSUPPORTED; - } - - if (!ctx->model_info.dma_api) { - pcilib_error("DMA Engine is not configured in the current model"); - return PCILIB_ERROR_NOTAVAILABLE; - } - - if (!ctx->model_info.dma_api->stop_dma) { - return 0; - } - - return ctx->model_info.dma_api->stop_dma(ctx->dma_ctx, dma, flags); -} - -int pcilib_enable_irq(pcilib_t *ctx, pcilib_irq_type_t irq_type, pcilib_dma_flags_t flags) { - const pcilib_dma_info_t *info = pcilib_get_dma_info(ctx); - - if ((!info)||(!ctx->model_info.dma_api)||(!ctx->model_info.dma_api->enable_irq)) return 0; - - return ctx->model_info.dma_api->enable_irq(ctx->dma_ctx, irq_type, flags); -} - -int pcilib_disable_irq(pcilib_t *ctx, pcilib_dma_flags_t flags) { - const pcilib_dma_info_t *info = pcilib_get_dma_info(ctx); - - if ((!info)||(!ctx->model_info.dma_api)||(!ctx->model_info.dma_api->disable_irq)) return 0; - - return ctx->model_info.dma_api->disable_irq(ctx->dma_ctx, flags); -} - -int pcilib_acknowledge_irq(pcilib_t *ctx, pcilib_irq_type_t irq_type, pcilib_irq_source_t irq_source) { - const pcilib_dma_info_t *info = pcilib_get_dma_info(ctx); - - if ((!info)||(!ctx->model_info.dma_api)||(!ctx->model_info.dma_api->acknowledge_irq)) return 0; - - return ctx->model_info.dma_api->acknowledge_irq(ctx->dma_ctx, irq_type, irq_source); -} - -typedef struct { - size_t size; - void *data; - size_t pos; - - pcilib_dma_flags_t flags; -} pcilib_dma_read_callback_context_t; - -static int pcilib_dma_read_callback(void *arg, pcilib_dma_flags_t flags, size_t bufsize, void *buf) { - pcilib_dma_read_callback_context_t *ctx = (pcilib_dma_read_callback_context_t*)arg; - - if (ctx->pos + bufsize > ctx->size) { - if ((ctx->flags&PCILIB_DMA_FLAG_IGNORE_ERRORS) == 0) - pcilib_error("Buffer size (%li) is not large enough for DMA packet, at least %li bytes is required", ctx->size, ctx->pos + bufsize); - return -PCILIB_ERROR_TOOBIG; - } - - memcpy(ctx->data + ctx->pos, buf, bufsize); - ctx->pos += bufsize; - - if (flags & PCILIB_DMA_FLAG_EOP) { - if ((ctx->pos < ctx->size)&&(ctx->flags&PCILIB_DMA_FLAG_MULTIPACKET)) { - if (ctx->flags&PCILIB_DMA_FLAG_WAIT) return PCILIB_STREAMING_WAIT; - else return PCILIB_STREAMING_CONTINUE; - } - return PCILIB_STREAMING_STOP; - } - - return PCILIB_STREAMING_REQ_FRAGMENT; -} - -static int pcilib_dma_skip_callback(void *arg, pcilib_dma_flags_t flags, size_t bufsize, void *buf) { - struct timeval *tv = (struct timeval*)arg; - struct timeval cur; - - if (tv) { - gettimeofday(&cur, NULL); - if ((cur.tv_sec > tv->tv_sec)||((cur.tv_sec == tv->tv_sec)&&(cur.tv_usec > tv->tv_usec))) return PCILIB_STREAMING_STOP; - } - - return PCILIB_STREAMING_REQ_PACKET; -} - -int pcilib_stream_dma(pcilib_t *ctx, pcilib_dma_engine_t dma, uintptr_t addr, size_t size, pcilib_dma_flags_t flags, pcilib_timeout_t timeout, pcilib_dma_callback_t cb, void *cbattr) { - const pcilib_dma_info_t *info = pcilib_get_dma_info(ctx); - if (!info) { - pcilib_error("DMA is not supported by the device"); - return PCILIB_ERROR_NOTSUPPORTED; - } - - if (!ctx->model_info.dma_api) { - pcilib_error("DMA Engine is not configured in the current model"); - return PCILIB_ERROR_NOTAVAILABLE; - } - - if (!ctx->model_info.dma_api->stream) { - pcilib_error("The DMA read is not supported by configured DMA engine"); - return PCILIB_ERROR_NOTSUPPORTED; - } - - if (!info->engines[dma]) { - pcilib_error("The DMA engine (%i) is not supported by device", dma); - return PCILIB_ERROR_NOTAVAILABLE; - } - - if ((info->engines[dma]->direction&PCILIB_DMA_FROM_DEVICE) == 0) { - pcilib_error("The selected engine (%i) is S2C-only and does not support reading", dma); - return PCILIB_ERROR_NOTSUPPORTED; - } - - return ctx->model_info.dma_api->stream(ctx->dma_ctx, dma, addr, size, flags, timeout, cb, cbattr); -} - -int pcilib_read_dma_custom(pcilib_t *ctx, pcilib_dma_engine_t dma, uintptr_t addr, size_t size, pcilib_dma_flags_t flags, pcilib_timeout_t timeout, void *buf, size_t *read_bytes) { - int err; - - pcilib_dma_read_callback_context_t opts = { - size, buf, 0, flags - }; - - err = pcilib_stream_dma(ctx, dma, addr, size, flags, timeout, pcilib_dma_read_callback, &opts); - if (read_bytes) *read_bytes = opts.pos; - return err; -} - -int pcilib_read_dma(pcilib_t *ctx, pcilib_dma_engine_t dma, uintptr_t addr, size_t size, void *buf, size_t *read_bytes) { - int err; - - pcilib_dma_read_callback_context_t opts = { - size, buf, 0, 0 - }; - - err = pcilib_stream_dma(ctx, dma, addr, size, PCILIB_DMA_FLAGS_DEFAULT, PCILIB_DMA_TIMEOUT, pcilib_dma_read_callback, &opts); - if (read_bytes) *read_bytes = opts.pos; - return err; -} - - -int pcilib_skip_dma(pcilib_t *ctx, pcilib_dma_engine_t dma) { - int err; - struct timeval tv, cur; - - gettimeofday(&tv, NULL); - tv.tv_usec += PCILIB_DMA_SKIP_TIMEOUT; - tv.tv_sec += tv.tv_usec / 1000000; - tv.tv_usec += tv.tv_usec % 1000000; - - do { - // IMMEDIATE timeout is not working properly, so default is set - err = pcilib_stream_dma(ctx, dma, 0, 0, PCILIB_DMA_FLAGS_DEFAULT, PCILIB_DMA_TIMEOUT, pcilib_dma_skip_callback, &tv); - gettimeofday(&cur, NULL); - } while ((!err)&&((cur.tv_sec < tv.tv_sec)||((cur.tv_sec == tv.tv_sec)&&(cur.tv_usec < tv.tv_usec)))); - - if ((cur.tv_sec > tv.tv_sec)||((cur.tv_sec == tv.tv_sec)&&(cur.tv_usec > tv.tv_usec))) return PCILIB_ERROR_TIMEOUT; - - return 0; -} - - -int pcilib_push_dma(pcilib_t *ctx, pcilib_dma_engine_t dma, uintptr_t addr, size_t size, pcilib_dma_flags_t flags, pcilib_timeout_t timeout, void *buf, size_t *written) { - const pcilib_dma_info_t *info = pcilib_get_dma_info(ctx); - if (!info) { - pcilib_error("DMA is not supported by the device"); - return PCILIB_ERROR_NOTSUPPORTED; - } - - if (!ctx->model_info.dma_api) { - pcilib_error("DMA Engine is not configured in the current model"); - return PCILIB_ERROR_NOTAVAILABLE; - } - - if (!ctx->model_info.dma_api->push) { - pcilib_error("The DMA write is not supported by configured DMA engine"); - return PCILIB_ERROR_NOTSUPPORTED; - } - - if (!info->engines[dma]) { - pcilib_error("The DMA engine (%i) is not supported by device", dma); - return PCILIB_ERROR_NOTAVAILABLE; - } - - if ((info->engines[dma]->direction&PCILIB_DMA_TO_DEVICE) == 0) { - pcilib_error("The selected engine (%i) is C2S-only and does not support writes", dma); - return PCILIB_ERROR_NOTSUPPORTED; - } - - return ctx->model_info.dma_api->push(ctx->dma_ctx, dma, addr, size, flags, timeout, buf, written); -} - - -int pcilib_write_dma(pcilib_t *ctx, pcilib_dma_engine_t dma, uintptr_t addr, size_t size, void *buf, size_t *written_bytes) { - return pcilib_push_dma(ctx, dma, addr, size, PCILIB_DMA_FLAG_EOP|PCILIB_DMA_FLAG_WAIT, PCILIB_DMA_TIMEOUT, buf, written_bytes); -} - -double pcilib_benchmark_dma(pcilib_t *ctx, pcilib_dma_engine_addr_t dma, uintptr_t addr, size_t size, size_t iterations, pcilib_dma_direction_t direction) { - const pcilib_dma_info_t *info = pcilib_get_dma_info(ctx); - if (!info) { - pcilib_error("DMA is not supported by the device"); - return 0; - } - - if (!ctx->model_info.dma_api) { - pcilib_error("DMA Engine is not configured in the current model"); - return -1; - } - - if (!ctx->model_info.dma_api->benchmark) { - pcilib_error("The DMA benchmark is not supported by configured DMA engine"); - return -1; - } - - if (!info->engines[dma]) { - pcilib_error("The DMA engine (%i) is not supported by device", dma); - return -1; - } - - return ctx->model_info.dma_api->benchmark(ctx->dma_ctx, dma, addr, size, iterations, direction); -} - -int pcilib_get_dma_status(pcilib_t *ctx, pcilib_dma_engine_t dma, pcilib_dma_engine_status_t *status, size_t n_buffers, pcilib_dma_buffer_status_t *buffers) { - const pcilib_dma_info_t *info = pcilib_get_dma_info(ctx); - if (!info) { - pcilib_error("DMA is not supported by the device"); - return 0; - } - - if (!ctx->model_info.dma_api) { - pcilib_error("DMA Engine is not configured in the current model"); - return -1; - } - - if (!ctx->model_info.dma_api->status) { - memset(status, 0, sizeof(pcilib_dma_engine_status_t)); - return -1; - } - - if (!info->engines[dma]) { - pcilib_error("The DMA engine (%i) is not supported by device", dma); - return -1; - } - - return ctx->model_info.dma_api->status(ctx->dma_ctx, dma, status, n_buffers, buffers); -} @@ -1,52 +0,0 @@ -#ifndef _PCILIB_DMA_H -#define _PCILIB_DMA_H - -#define PCILIB_DMA_BUFFER_INVALID ((size_t)-1) -#define PCILIB_DMA_MODIFICATION_DEFAULT 0 /**< first 0x100 are reserved */ - -typedef uint32_t pcilib_dma_modification_t; - -typedef struct { - int started; - size_t ring_size, buffer_size; - size_t ring_head, ring_tail; -} pcilib_dma_engine_status_t; - -typedef struct { - int used; - int error; - int first; - int last; - size_t size; -} pcilib_dma_buffer_status_t; - -struct pcilib_dma_api_description_s { - const char *title; - - pcilib_dma_context_t *(*init)(pcilib_t *ctx, pcilib_dma_modification_t type, void *arg); - void (*free)(pcilib_dma_context_t *ctx); - - int (*status)(pcilib_dma_context_t *ctx, pcilib_dma_engine_t dma, pcilib_dma_engine_status_t *status, size_t n_buffers, pcilib_dma_buffer_status_t *buffers); - - int (*enable_irq)(pcilib_dma_context_t *ctx, pcilib_irq_type_t irq_type, pcilib_dma_flags_t flags); - int (*disable_irq)(pcilib_dma_context_t *ctx, pcilib_dma_flags_t flags); - int (*acknowledge_irq)(pcilib_dma_context_t *ctx, pcilib_irq_type_t irq_type, pcilib_irq_source_t irq_source); - - int (*start_dma)(pcilib_dma_context_t *ctx, pcilib_dma_engine_t dma, pcilib_dma_flags_t flags); - int (*stop_dma)(pcilib_dma_context_t *ctx, pcilib_dma_engine_t dma, pcilib_dma_flags_t flags); - - int (*push)(pcilib_dma_context_t *ctx, pcilib_dma_engine_t dma, uintptr_t addr, size_t size, pcilib_dma_flags_t flags, pcilib_timeout_t timeout, void *buf, size_t *written); - int (*stream)(pcilib_dma_context_t *ctx, pcilib_dma_engine_t dma, uintptr_t addr, size_t size, pcilib_dma_flags_t flags, pcilib_timeout_t timeout, pcilib_dma_callback_t cb, void *cbattr); - - double (*benchmark)(pcilib_dma_context_t *ctx, pcilib_dma_engine_addr_t dma, uintptr_t addr, size_t size, size_t iterations, pcilib_dma_direction_t direction); -}; - -struct pcilib_dma_context_s { - int ignore_eop; -}; - - -int pcilib_set_dma_engine_description(pcilib_t *ctx, pcilib_dma_engine_t engine, pcilib_dma_engine_description_t *desc); -int pcilib_get_dma_status(pcilib_t *ctx, pcilib_dma_engine_t dma, pcilib_dma_engine_status_t *status, size_t n_buffers, pcilib_dma_buffer_status_t *buffers); - -#endif /* _PCILIB_DMA_H */ diff --git a/dma/CMakeLists.txt b/dma/CMakeLists.txt deleted file mode 100644 index 44bf18c..0000000 --- a/dma/CMakeLists.txt +++ /dev/null @@ -1,9 +0,0 @@ -include_directories( - ${CMAKE_SOURCE_DIR} -) - - -set(HEADERS ${HEADERS} nwl.h nwl_private.h nwl_engine.h nwl_irq.h nwl_loopback.h nwl_register.h ipe.h ipe_private.h ipe_registers.h) - -add_library(dma STATIC nwl.c nwl_engine.c nwl_irq.c nwl_loopback.c nwl_register.c ipe.c) - diff --git a/dma/ipe.c b/dma/ipe.c deleted file mode 100644 index 61480d4..0000000 --- a/dma/ipe.c +++ /dev/null @@ -1,541 +0,0 @@ -#define _PCILIB_DMA_IPE_C -#define _BSD_SOURCE - -#include <stdio.h> -#include <stdlib.h> -#include <string.h> -#include <unistd.h> -#include <sys/time.h> -#include <arpa/inet.h> - -#include "pci.h" -#include "pcilib.h" -#include "error.h" -#include "tools.h" - -#include "ipe.h" -#include "ipe_private.h" -#include "ipe_registers.h" - - -#define WR(addr, value) { *(uint32_t*)(ctx->base_addr + addr) = value; } -#define RD(addr, value) { value = *(uint32_t*)(ctx->base_addr + addr); } - - -pcilib_dma_context_t *dma_ipe_init(pcilib_t *pcilib, pcilib_dma_modification_t type, void *arg) { - int err = 0; - - pcilib_model_description_t *model_info = pcilib_get_model_description(pcilib); - - ipe_dma_t *ctx = malloc(sizeof(ipe_dma_t)); - - if (ctx) { - memset(ctx, 0, sizeof(ipe_dma_t)); - ctx->pcilib = pcilib; -// ctx->mode64 = 1; - - memset(ctx->engine, 0, 2 * sizeof(pcilib_dma_engine_description_t)); - ctx->engine[0].addr = 0; - ctx->engine[0].type = PCILIB_DMA_TYPE_PACKET; - ctx->engine[0].direction = PCILIB_DMA_FROM_DEVICE; - ctx->engine[0].addr_bits = 32; - pcilib_set_dma_engine_description(pcilib, 0, &ctx->engine[0]); - pcilib_set_dma_engine_description(pcilib, 1, NULL); - - pcilib_register_bank_t dma_bank = pcilib_find_bank_by_addr(pcilib, PCILIB_REGISTER_BANK_DMA); - if (dma_bank == PCILIB_REGISTER_BANK_INVALID) { - free(ctx); - pcilib_error("DMA Register Bank could not be found"); - return NULL; - } - - ctx->dma_bank = model_info->banks + dma_bank; - ctx->base_addr = pcilib_resolve_register_address(pcilib, ctx->dma_bank->bar, ctx->dma_bank->read_addr); - - err = pcilib_add_registers(ctx->pcilib, 0, ipe_dma_registers); - if (err) { - free(ctx); - pcilib_error("Error adding DMA registers"); - return NULL; - } - } - - return (pcilib_dma_context_t*)ctx; -} - -void dma_ipe_free(pcilib_dma_context_t *vctx) { - ipe_dma_t *ctx = (ipe_dma_t*)vctx; - - if (ctx) { - dma_ipe_stop(vctx, PCILIB_DMA_ENGINE_ALL, PCILIB_DMA_FLAGS_DEFAULT); - free(ctx); - } -} - - -int dma_ipe_start(pcilib_dma_context_t *vctx, pcilib_dma_engine_t dma, pcilib_dma_flags_t flags) { - size_t i; - - ipe_dma_t *ctx = (ipe_dma_t*)vctx; - - int preserve = 0; - pcilib_kmem_flags_t kflags; - pcilib_kmem_reuse_state_t reuse_desc, reuse_pages; - - volatile void *desc_va; - volatile uint32_t *last_written_addr_ptr; - - pcilib_register_value_t value; - - uint32_t address64; - - - if (dma == PCILIB_DMA_ENGINE_INVALID) return 0; - else if (dma > 1) return PCILIB_ERROR_INVALID_BANK; - - if (!ctx->started) ctx->started = 1; - - if (flags&PCILIB_DMA_FLAG_PERSISTENT) ctx->preserve = 1; - - if (ctx->pages) return 0; - - kflags = PCILIB_KMEM_FLAG_REUSE|PCILIB_KMEM_FLAG_EXCLUSIVE|PCILIB_KMEM_FLAG_HARDWARE|(ctx->preserve?PCILIB_KMEM_FLAG_PERSISTENT:0); - pcilib_kmem_handle_t *desc = pcilib_alloc_kernel_memory(ctx->pcilib, PCILIB_KMEM_TYPE_CONSISTENT, 1, IPEDMA_DESCRIPTOR_SIZE, IPEDMA_DESCRIPTOR_ALIGNMENT, PCILIB_KMEM_USE(PCILIB_KMEM_USE_DMA_RING, 0x00), kflags); - pcilib_kmem_handle_t *pages = pcilib_alloc_kernel_memory(ctx->pcilib, PCILIB_KMEM_TYPE_DMA_C2S_PAGE, IPEDMA_DMA_PAGES, 0, 0, PCILIB_KMEM_USE(PCILIB_KMEM_USE_DMA_PAGES, 0x00), kflags); - - if (!desc||!pages) { - if (pages) pcilib_free_kernel_memory(ctx->pcilib, pages, 0); - if (desc) pcilib_free_kernel_memory(ctx->pcilib, desc, 0); - return PCILIB_ERROR_MEMORY; - } - reuse_desc = pcilib_kmem_is_reused(ctx->pcilib, desc); - reuse_pages = pcilib_kmem_is_reused(ctx->pcilib, pages); - - if (reuse_desc == reuse_pages) { - if (reuse_desc & PCILIB_KMEM_REUSE_PARTIAL) pcilib_warning("Inconsistent DMA buffers are found (only part of required buffers is available), reinitializing..."); - else if (reuse_desc & PCILIB_KMEM_REUSE_REUSED) { - if ((reuse_desc & PCILIB_KMEM_REUSE_PERSISTENT) == 0) pcilib_warning("Lost DMA buffers are found (non-persistent mode), reinitializing..."); - else if ((reuse_desc & PCILIB_KMEM_REUSE_HARDWARE) == 0) pcilib_warning("Lost DMA buffers are found (missing HW reference), reinitializing..."); - else { -#ifndef IPEDMA_BUG_DMARD - RD(IPEDMA_REG_PAGE_COUNT, value); - - if (value != IPEDMA_DMA_PAGES) pcilib_warning("Inconsistent DMA buffers are found (Number of allocated buffers (%lu) does not match current request (%lu)), reinitializing...", value + 1, IPEDMA_DMA_PAGES); - else -#endif /* IPEDMA_BUG_DMARD */ - preserve = 1; - } - } - } else pcilib_warning("Inconsistent DMA buffers (modes of ring and page buffers does not match), reinitializing...."); - - desc_va = pcilib_kmem_get_ua(ctx->pcilib, desc); - if (ctx->mode64) last_written_addr_ptr = desc_va + 3 * sizeof(uint32_t); - else last_written_addr_ptr = desc_va + 4 * sizeof(uint32_t); - - if (preserve) { - ctx->reused = 1; - ctx->preserve = 1; - - -// usleep(100000); - - // Detect the current state of DMA engine -#ifdef IPEDMA_BUG_DMARD - FILE *f = fopen("/tmp/pcitool_lastread", "r"); - if (!f) pcilib_error("Can't read current status"); - fread(&value, 1, sizeof(pcilib_register_value_t), f); - fclose(f); -#else /* IPEDMA_BUG_DMARD */ - RD(IPEDMA_REG_LAST_READ, value); - // Numbered from 1 in FPGA - value--; -#endif /* IPEDMA_BUG_DMARD */ - - ctx->last_read = value; - } else { - ctx->reused = 0; - - // Disable DMA - WR(IPEDMA_REG_CONTROL, 0x0); - usleep(100000); - - // Reset DMA engine - WR(IPEDMA_REG_RESET, 0x1); - usleep(100000); - WR(IPEDMA_REG_RESET, 0x0); - usleep(100000); - -#ifndef IPEDMA_BUG_DMARD - // Verify PCIe link status - RD(IPEDMA_REG_RESET, value); - if (value != 0x14031700) pcilib_warning("PCIe is not ready, code is %lx", value); -#endif /* IPEDMA_BUG_DMARD */ - - // Enable 64 bit addressing and configure TLP and PACKET sizes (40 bit mode can be used with big pre-allocated buffers later) - if (ctx->mode64) address64 = 0x8000 | (0<<24); - else address64 = 0; - - WR(IPEDMA_REG_TLP_SIZE, address64 | IPEDMA_TLP_SIZE); - WR(IPEDMA_REG_TLP_COUNT, IPEDMA_PAGE_SIZE / (4 * IPEDMA_TLP_SIZE * IPEDMA_CORES)); - - // Setting progress register threshold - WR(IPEDMA_REG_UPDATE_THRESHOLD, IPEDMA_DMA_PROGRESS_THRESHOLD); - - // Reseting configured DMA pages - WR(IPEDMA_REG_PAGE_COUNT, 0); - - // Setting current read position and configuring progress register - WR(IPEDMA_REG_LAST_READ, IPEDMA_DMA_PAGES); - WR(IPEDMA_REG_UPDATE_ADDR, pcilib_kmem_get_block_ba(ctx->pcilib, desc, 0)); - - // Instructing DMA engine that writting should start from the first DMA page - *last_written_addr_ptr = 0;//htonl(pcilib_kmem_get_block_ba(ctx->pcilib, pages, IPEDMA_DMA_PAGES - 1)); - - - for (i = 0; i < IPEDMA_DMA_PAGES; i++) { - uintptr_t bus_addr_check, bus_addr = pcilib_kmem_get_block_ba(ctx->pcilib, pages, i); - WR(IPEDMA_REG_PAGE_ADDR, bus_addr); - if (bus_addr%4096) printf("Bad address %lu: %lx\n", i, bus_addr); - - RD(IPEDMA_REG_PAGE_ADDR, bus_addr_check); - if (bus_addr_check != bus_addr) { - pcilib_error("Written (%x) and read (%x) bus addresses does not match\n", bus_addr, bus_addr_check); - } - - usleep(1000); - } - - // Enable DMA - WR(IPEDMA_REG_CONTROL, 0x1); - - ctx->last_read = IPEDMA_DMA_PAGES - 1; - -#ifdef IPEDMA_BUG_DMARD - FILE *f = fopen("/tmp/pcitool_lastread", "w"); - if (!f) pcilib_error("Can't write current status"); - value = ctx->last_read; - fwrite(&value, 1, sizeof(pcilib_register_value_t), f); - fclose(f); -#endif /* IPEDMA_BUG_DMARD */ - } - -// ctx->last_read_addr = htonl(pcilib_kmem_get_block_ba(ctx->pcilib, pages, ctx->last_read)); - ctx->last_read_addr = pcilib_kmem_get_block_ba(ctx->pcilib, pages, ctx->last_read); - - - ctx->desc = desc; - ctx->pages = pages; - ctx->page_size = pcilib_kmem_get_block_size(ctx->pcilib, pages, 0);; - ctx->ring_size = IPEDMA_DMA_PAGES; - - return 0; -} - -int dma_ipe_stop(pcilib_dma_context_t *vctx, pcilib_dma_engine_t dma, pcilib_dma_flags_t flags) { - pcilib_kmem_flags_t kflags; - - ipe_dma_t *ctx = (ipe_dma_t*)vctx; - - if (!ctx->started) return 0; - - if ((dma != PCILIB_DMA_ENGINE_INVALID)&&(dma > 1)) return PCILIB_ERROR_INVALID_BANK; - - // ignoring previous setting if flag specified - if (flags&PCILIB_DMA_FLAG_PERSISTENT) { - ctx->preserve = 0; - } - - if (ctx->preserve) { - kflags = PCILIB_KMEM_FLAG_REUSE; - } else { - kflags = PCILIB_KMEM_FLAG_HARDWARE|PCILIB_KMEM_FLAG_PERSISTENT; - - ctx->started = 0; - - // Disable DMA - WR(IPEDMA_REG_CONTROL, 0); - usleep(100000); - - // Reset DMA engine - WR(IPEDMA_REG_RESET, 0x1); - usleep(100000); - WR(IPEDMA_REG_RESET, 0x0); - usleep(100000); - - // Reseting configured DMA pages - WR(IPEDMA_REG_PAGE_COUNT, 0); - usleep(100000); - } - - // Clean buffers - if (ctx->desc) { - pcilib_free_kernel_memory(ctx->pcilib, ctx->desc, kflags); - ctx->desc = NULL; - } - - if (ctx->pages) { - pcilib_free_kernel_memory(ctx->pcilib, ctx->pages, kflags); - ctx->pages = NULL; - } - - return 0; -} - - -int dma_ipe_get_status(pcilib_dma_context_t *vctx, pcilib_dma_engine_t dma, pcilib_dma_engine_status_t *status, size_t n_buffers, pcilib_dma_buffer_status_t *buffers) { - size_t i; - ipe_dma_t *ctx = (ipe_dma_t*)vctx; - - void *desc_va = (void*)pcilib_kmem_get_ua(ctx->pcilib, ctx->desc); - uint32_t *last_written_addr_ptr; - uint32_t last_written_addr; - - if (!status) return -1; - - if (ctx->mode64) last_written_addr_ptr = desc_va + 3 * sizeof(uint32_t); - else last_written_addr_ptr = desc_va + 4 * sizeof(uint32_t); - - last_written_addr = *last_written_addr_ptr; - - status->started = ctx->started; - status->ring_size = ctx->ring_size; - status->buffer_size = ctx->page_size; - - // For simplicity, we keep last_read here, and fix in the end - status->ring_tail = ctx->last_read; - - // Find where the ring head is actually are - for (i = 0; i < ctx->ring_size; i++) { - uintptr_t bus_addr = pcilib_kmem_get_block_ba(ctx->pcilib, ctx->pages, i); - - if (bus_addr == last_written_addr) { - status->ring_head = i; - break; - } - } - - if (i == ctx->ring_size) { - if (last_written_addr) { - pcilib_warning("DMA is in unknown state, last_written_addr does not correspond any of available buffers"); - return -1; - } - status->ring_head = 0; - status->ring_tail = 0; - } - - if (n_buffers > ctx->ring_size) n_buffers = ctx->ring_size; - - if (buffers) { - memset(buffers, 0, n_buffers * sizeof(pcilib_dma_buffer_status_t)); - if (status->ring_head >= status->ring_tail) { - for (i = status->ring_tail + 1; (i <= status->ring_head)&&(i < n_buffers); i++) { - buffers[i].used = 1; - buffers[i].size = ctx->page_size; - buffers[i].first = 1; - buffers[i].last = 1; - } - } else { - for (i = 0; (i <= status->ring_head)&&(i < n_buffers); i++) { - buffers[i].used = 1; - buffers[i].size = ctx->page_size; - buffers[i].first = 1; - buffers[i].last = 1; - } - - for (i = status->ring_tail + 1; (i < status->ring_size)&&(i < n_buffers); i++) { - buffers[i].used = 1; - buffers[i].size = ctx->page_size; - buffers[i].first = 1; - buffers[i].last = 1; - } - } - } - - // We actually keep last_read in the ring_tail, so need to increase - if (status->ring_tail != status->ring_head) { - status->ring_tail++; - if (status->ring_tail == status->ring_size) status->ring_tail = 0; - } - - return 0; -} - -int dma_ipe_stream_read(pcilib_dma_context_t *vctx, pcilib_dma_engine_t dma, uintptr_t addr, size_t size, pcilib_dma_flags_t flags, pcilib_timeout_t timeout, pcilib_dma_callback_t cb, void *cbattr) { - int err, ret = PCILIB_STREAMING_REQ_PACKET; - - - pcilib_timeout_t wait = 0; - struct timeval start, cur; - - volatile void *desc_va; - volatile uint32_t *last_written_addr_ptr; - volatile uint32_t *empty_detected_ptr; - - pcilib_dma_flags_t packet_flags = PCILIB_DMA_FLAG_EOP; - -#ifdef IPEDMA_BUG_DMARD - pcilib_register_value_t value; -#endif /* IPEDMA_BUG_DMARD */ - - size_t cur_read; - - ipe_dma_t *ctx = (ipe_dma_t*)vctx; - - err = dma_ipe_start(vctx, dma, PCILIB_DMA_FLAGS_DEFAULT); - if (err) return err; - - desc_va = (void*)pcilib_kmem_get_ua(ctx->pcilib, ctx->desc); - - if (ctx->mode64) last_written_addr_ptr = desc_va + 3 * sizeof(uint32_t); - else last_written_addr_ptr = desc_va + 4 * sizeof(uint32_t); - - empty_detected_ptr = last_written_addr_ptr - 2; - - do { - switch (ret&PCILIB_STREAMING_TIMEOUT_MASK) { - case PCILIB_STREAMING_CONTINUE: - // Hardware indicates that there is no more data pending and we can safely stop if there is no data in the kernel buffers already -#ifdef IPEDMA_SUPPORT_EMPTY_DETECTED - if (*empty_detected_ptr) - wait = 0; - else -#endif /* IPEDMA_SUPPORT_EMPTY_DETECTED */ - wait = IPEDMA_DMA_TIMEOUT; - break; - case PCILIB_STREAMING_WAIT: - wait = (timeout > IPEDMA_DMA_TIMEOUT)?timeout:IPEDMA_DMA_TIMEOUT; - break; -// case PCILIB_STREAMING_CHECK: wait = 0; break; - } - -#ifdef IPEDMA_DEBUG - printf("Waiting for data: %u (last read) 0x%x (last read addr) 0x%x (last_written)\n", ctx->last_read, ctx->last_read_addr, *last_written_addr_ptr); -#endif /* IPEDMA_DEBUG */ - - gettimeofday(&start, NULL); - memcpy(&cur, &start, sizeof(struct timeval)); - while (((*last_written_addr_ptr == 0)||(ctx->last_read_addr == (*last_written_addr_ptr)))&&((wait == PCILIB_TIMEOUT_INFINITE)||(((cur.tv_sec - start.tv_sec)*1000000 + (cur.tv_usec - start.tv_usec)) < wait))) { - usleep(10); -#ifdef IPEDMA_SUPPORT_EMPTY_DETECTED - if ((ret != PCILIB_STREAMING_REQ_PACKET)&&(*empty_detected_ptr)) break; -#endif /* IPEDMA_SUPPORT_EMPTY_DETECTED */ - gettimeofday(&cur, NULL); - } - - // Failing out if we exited on timeout - if ((ctx->last_read_addr == (*last_written_addr_ptr))||(*last_written_addr_ptr == 0)) { -#ifdef IPEDMA_SUPPORT_EMPTY_DETECTED -# ifdef IPEDMA_DEBUG - if ((wait)&&(*last_written_addr_ptr)&&(!*empty_detected_ptr)) - pcilib_warning("The empty_detected flag is not set, but no data arrived within %lu us\n", wait); -# endif /* IPEDMA_DEBUG */ -#endif /* IPEDMA_SUPPORT_EMPTY_DETECTED */ - return (ret&PCILIB_STREAMING_FAIL)?PCILIB_ERROR_TIMEOUT:0; - } - - // Getting next page to read - cur_read = ctx->last_read + 1; - if (cur_read == ctx->ring_size) cur_read = 0; - -#ifdef IPEDMA_DEBUG - printf("Reading: %u (last read) 0x%x (last read addr) 0x%x (last_written)\n", cur_read, ctx->last_read_addr, *last_written_addr_ptr); -#endif /* IPEDMA_DEBUG */ - -#ifdef IPEDMA_DETECT_PACKETS - if ((*empty_detected_ptr)&&(pcilib_kmem_get_block_ba(ctx->pcilib, ctx->pages, cur_read) == (*last_written_addr_ptr))) packet_flags = PCILIB_DMA_FLAG_EOP; - else packet_flags = 0; -#endif /* IPEDMA_DETECT_PACKETS */ - - pcilib_kmem_sync_block(ctx->pcilib, ctx->pages, PCILIB_KMEM_SYNC_FROMDEVICE, cur_read); - void *buf = pcilib_kmem_get_block_ua(ctx->pcilib, ctx->pages, cur_read); - ret = cb(cbattr, packet_flags, ctx->page_size, buf); - if (ret < 0) return -ret; - -// DS: Fixme, it looks like we can avoid calling this for the sake of performance -// pcilib_kmem_sync_block(ctx->pcilib, ctx->pages, PCILIB_KMEM_SYNC_TODEVICE, cur_read); - - // Numbered from 1 - WR(IPEDMA_REG_LAST_READ, cur_read + 1); - - ctx->last_read = cur_read; -// ctx->last_read_addr = htonl(pcilib_kmem_get_block_ba(ctx->pcilib, ctx->pages, cur_read)); - ctx->last_read_addr = pcilib_kmem_get_block_ba(ctx->pcilib, ctx->pages, cur_read); - -#ifdef IPEDMA_BUG_DMARD - FILE *f = fopen("/tmp/pcitool_lastread", "w"); - if (!f) pcilib_error("Can't write current status"); - value = cur_read; - fwrite(&value, 1, sizeof(pcilib_register_value_t), f); - fclose(f); -#endif /* IPEDMA_BUG_DMARD */ - - } while (ret); - - return 0; -} - -double dma_ipe_benchmark(pcilib_dma_context_t *vctx, pcilib_dma_engine_addr_t dma, uintptr_t addr, size_t size, size_t iterations, pcilib_dma_direction_t direction) { - int err = 0; - - ipe_dma_t *ctx = (ipe_dma_t*)vctx; - - int iter; - size_t us = 0; - struct timeval start, cur; - - void *buf; - size_t bytes, rbytes; - - if ((direction == PCILIB_DMA_TO_DEVICE)||(direction == PCILIB_DMA_BIDIRECTIONAL)) return -1.; - - if ((dma != PCILIB_DMA_ENGINE_INVALID)&&(dma > 1)) return -1.; - - err = dma_ipe_start(vctx, 0, PCILIB_DMA_FLAGS_DEFAULT); - if (err) return err; - - WR(IPEDMA_REG_CONTROL, 0x0); - - err = pcilib_skip_dma(ctx->pcilib, 0); - if (err) { - pcilib_error("Can't start benchmark, devices continuously writes unexpected data using DMA engine"); - return -1; - } - - if (size%IPEDMA_PAGE_SIZE) size = (1 + size / IPEDMA_PAGE_SIZE) * IPEDMA_PAGE_SIZE; - - // Allocate memory and prepare data - buf = malloc(size); - if (!buf) return -1; - - for (iter = 0; iter < iterations; iter++) { - gettimeofday(&start, NULL); - - // Starting DMA - WR(IPEDMA_REG_CONTROL, 0x1); - - for (bytes = 0; bytes < size; bytes += rbytes) { - err = pcilib_read_dma(ctx->pcilib, 0, addr, size - bytes, buf + bytes, &rbytes); - if (err) { - pcilib_error("Can't read data from DMA, error %i", err); - return -1; - } - } - - // Stopping DMA - WR(IPEDMA_REG_CONTROL, 0x0); - if (err) break; - - gettimeofday(&cur, NULL); - us += ((cur.tv_sec - start.tv_sec)*1000000 + (cur.tv_usec - start.tv_usec)); - - err = pcilib_skip_dma(ctx->pcilib, 0); - if (err) { - pcilib_error("Can't start iteration, devices continuously writes unexpected data using DMA engine"); - break; - } - } - - free(buf); - - return err?-1:((1. * size * iterations * 1000000) / (1024. * 1024. * us)); -} diff --git a/dma/ipe.h b/dma/ipe.h deleted file mode 100644 index 2c34ff1..0000000 --- a/dma/ipe.h +++ /dev/null @@ -1,42 +0,0 @@ -#ifndef _PCILIB_DMA_IPE_H -#define _PCILIB_DMA_IPE_H - -#include <stdio.h> -#include "../pcilib.h" - -//#define PCILIB_NWL_MODIFICATION_IPECAMERA 0x100 - -pcilib_dma_context_t *dma_ipe_init(pcilib_t *ctx, pcilib_dma_modification_t type, void *arg); -void dma_ipe_free(pcilib_dma_context_t *vctx); - -int dma_ipe_get_status(pcilib_dma_context_t *vctx, pcilib_dma_engine_t dma, pcilib_dma_engine_status_t *status, size_t n_buffers, pcilib_dma_buffer_status_t *buffers); - - -int dma_ipe_start(pcilib_dma_context_t *ctx, pcilib_dma_engine_t dma, pcilib_dma_flags_t flags); -int dma_ipe_stop(pcilib_dma_context_t *ctx, pcilib_dma_engine_t dma, pcilib_dma_flags_t flags); - -int dma_ipe_stream_read(pcilib_dma_context_t *vctx, pcilib_dma_engine_t dma, uintptr_t addr, size_t size, pcilib_dma_flags_t flags, pcilib_timeout_t timeout, pcilib_dma_callback_t cb, void *cbattr); -double dma_ipe_benchmark(pcilib_dma_context_t *vctx, pcilib_dma_engine_addr_t dma, uintptr_t addr, size_t size, size_t iterations, pcilib_dma_direction_t direction); - - -#ifdef _PCILIB_DMA_IPE_C -pcilib_dma_api_description_t ipe_dma_api = { - "ipe_dma", - dma_ipe_init, - dma_ipe_free, - dma_ipe_get_status, - NULL, - NULL, - NULL, - dma_ipe_start, - dma_ipe_stop, - NULL, - dma_ipe_stream_read, - dma_ipe_benchmark -}; -#else -extern pcilib_dma_api_description_t ipe_dma_api; -#endif - - -#endif /* _PCILIB_DMA_IPE_H */ diff --git a/dma/ipe_private.h b/dma/ipe_private.h deleted file mode 100644 index fd44011..0000000 --- a/dma/ipe_private.h +++ /dev/null @@ -1,59 +0,0 @@ -#ifndef _PCILIB_DMA_IPE_PRIVATE_H -#define _PCILIB_DMA_IPE_PRIVATE_H - -#define IPEDMA_CORES 1 -#define IPEDMA_TLP_SIZE 32 -#define IPEDMA_PAGE_SIZE 4096 -#define IPEDMA_DMA_PAGES 16 /**< number of DMA pages in the ring buffer to allocate */ -#define IPEDMA_DMA_PROGRESS_THRESHOLD 1 /**< how many pages the DMA engine should fill before reporting progress */ -#define IPEDMA_DESCRIPTOR_SIZE 128 -#define IPEDMA_DESCRIPTOR_ALIGNMENT 64 - -//#define IPEDMA_DEBUG -//#define IPEDMA_BUG_DMARD /**< No register read during DMA transfer */ -//#define IPEDMA_DETECT_PACKETS /**< Using empty_deceted flag */ -#define IPEDMA_SUPPORT_EMPTY_DETECTED /**< Avoid waiting for data when empty_detected flag is set in hardware */ -#define IPEDMA_DMA_TIMEOUT 100000 /**< us, overrides PCILIB_DMA_TIMEOUT (actual hardware timeout is 50ms according to Lorenzo) */ - -#define IPEDMA_REG_RESET 0x00 -#define IPEDMA_REG_CONTROL 0x04 -#define IPEDMA_REG_TLP_SIZE 0x0C -#define IPEDMA_REG_TLP_COUNT 0x10 -#define IPEDMA_REG_PAGE_ADDR 0x50 -#define IPEDMA_REG_UPDATE_ADDR 0x54 -#define IPEDMA_REG_LAST_READ 0x58 -#define IPEDMA_REG_PAGE_COUNT 0x5C -#define IPEDMA_REG_UPDATE_THRESHOLD 0x60 - - - -typedef struct ipe_dma_s ipe_dma_t; - -struct ipe_dma_s { - struct pcilib_dma_context_s dmactx; - pcilib_dma_engine_description_t engine[2]; - - pcilib_t *pcilib; - - pcilib_register_bank_description_t *dma_bank; - char *base_addr; - - pcilib_irq_type_t irq_enabled; /**< indicates that IRQs are enabled */ - pcilib_irq_type_t irq_preserve; /**< indicates that IRQs should not be disabled during clean-up */ - int irq_started; /**< indicates that IRQ subsystem is initialized (detecting which types should be preserverd) */ - - int started; /**< indicates that DMA buffers are initialized and reading is allowed */ - int writting; /**< indicates that we are in middle of writting packet */ - int reused; /**< indicates that DMA was found intialized, buffers were reused, and no additional initialization is needed */ - int preserve; /**< indicates that DMA should not be stopped during clean-up */ - int mode64; /**< indicates 64-bit operation mode */ - - pcilib_kmem_handle_t *desc; /**< in-memory status descriptor written by DMA engine upon operation progess */ - pcilib_kmem_handle_t *pages; /**< collection of memory-locked pages for DMA operation */ - - size_t ring_size, page_size; - size_t last_read, last_read_addr, last_written; - -}; - -#endif /* _PCILIB_DMA_IPE_PRIVATE_H */ diff --git a/dma/ipe_registers.h b/dma/ipe_registers.h deleted file mode 100644 index 17fc41a..0000000 --- a/dma/ipe_registers.h +++ /dev/null @@ -1,44 +0,0 @@ -#ifndef _PCILIB_DMA_IPE_REGISTERS_H -#define _PCILIB_DMA_IPE_REGISTERS_H - -#ifdef _PCILIB_DMA_IPE_C -static pcilib_register_description_t ipe_dma_registers[] = { - {0x0000, 0, 32, 0, 0x00000000, PCILIB_REGISTER_RW , PCILIB_REGISTER_STANDARD, PCILIB_REGISTER_BANK_DMA, "dcr", "Device Control Status Register"}, - {0x0000, 0, 1, 0, 0x00000000, PCILIB_REGISTER_RW , PCILIB_REGISTER_BITS, PCILIB_REGISTER_BANK_DMA, "reset_dma", ""}, - {0x0000, 16, 4, 0, 0x00000000, PCILIB_REGISTER_R , PCILIB_REGISTER_BITS, PCILIB_REGISTER_BANK_DMA, "datapath_width", ""}, - {0x0000, 24, 8, 0, 0x00000000, PCILIB_REGISTER_R , PCILIB_REGISTER_BITS, PCILIB_REGISTER_BANK_DMA, "fpga_family", ""}, - {0x0004, 0, 32, 0, 0x00000000, PCILIB_REGISTER_RW , PCILIB_REGISTER_STANDARD, PCILIB_REGISTER_BANK_DMA, "ddmacr", "Device DMA Control Status Register"}, - {0x0004, 0, 1, 0, 0xFFFFFFFF, PCILIB_REGISTER_RW , PCILIB_REGISTER_BITS, PCILIB_REGISTER_BANK_DMA, "mwr_start", "Start writting memory"}, - {0x0004, 5, 1, 0, 0x00000000, PCILIB_REGISTER_R , PCILIB_REGISTER_BITS, PCILIB_REGISTER_BANK_DMA, "mwr_relxed_order", ""}, - {0x0004, 6, 1, 0, 0x00000000, PCILIB_REGISTER_R , PCILIB_REGISTER_BITS, PCILIB_REGISTER_BANK_DMA, "mwr_nosnoop", ""}, - {0x0004, 7, 1, 0, 0x00000000, PCILIB_REGISTER_R , PCILIB_REGISTER_BITS, PCILIB_REGISTER_BANK_DMA, "mwr_int_dis", ""}, - {0x0004, 16, 1, 0, 0x00000000, PCILIB_REGISTER_R , PCILIB_REGISTER_BITS, PCILIB_REGISTER_BANK_DMA, "mrd_start", ""}, - {0x0004, 21, 1, 0, 0x00000000, PCILIB_REGISTER_R , PCILIB_REGISTER_BITS, PCILIB_REGISTER_BANK_DMA, "mrd_relaxed_order", ""}, - {0x0004, 22, 1, 0, 0x00000000, PCILIB_REGISTER_R , PCILIB_REGISTER_BITS, PCILIB_REGISTER_BANK_DMA, "mrd_nosnoop", ""}, - {0x0004, 23, 1, 0, 0x00000000, PCILIB_REGISTER_R , PCILIB_REGISTER_BITS, PCILIB_REGISTER_BANK_DMA, "mrd_int_dis", ""}, - {0x000C, 0, 32, 0, 0x00000000, PCILIB_REGISTER_RW , PCILIB_REGISTER_STANDARD, PCILIB_REGISTER_BANK_DMA, "mwr_size", "DMA TLP size"}, - {0x000C, 0, 16, 0x20, 0xFFFFFFFF, PCILIB_REGISTER_RW , PCILIB_REGISTER_BITS, PCILIB_REGISTER_BANK_DMA, "mwr_len", "Max TLP size"}, - {0x000C, 16, 3, 0, 0x00000000, PCILIB_REGISTER_R , PCILIB_REGISTER_BITS, PCILIB_REGISTER_BANK_DMA, "mwr_tlp_tc", "TC for TLP packets"}, - {0x000C, 19, 1, 0, 0xFFFFFFFF, PCILIB_REGISTER_RW , PCILIB_REGISTER_BITS, PCILIB_REGISTER_BANK_DMA, "mwr_64b_en", "Enable 64 bit memory addressing"}, - {0x000C, 20, 1, 0, 0x00000000, PCILIB_REGISTER_R , PCILIB_REGISTER_BITS, PCILIB_REGISTER_BANK_DMA, "mwr_phant_func_dis", "Disable MWR phantom function"}, - {0x000C, 24, 8, 0, 0xFFFFFFFF, PCILIB_REGISTER_RW , PCILIB_REGISTER_BITS, PCILIB_REGISTER_BANK_DMA, "mwr_up_addr", "Upper address for 64 bit memory addressing"}, - {0x0010, 0, 32, 0, 0x00000000, PCILIB_REGISTER_RW , PCILIB_REGISTER_STANDARD, PCILIB_REGISTER_BANK_DMA, "mwr_count", "Write DMA TLP Count"}, - {0x0014, 0, 32, 0, 0x00000000, PCILIB_REGISTER_RW , PCILIB_REGISTER_STANDARD, PCILIB_REGISTER_BANK_DMA, "mwr_pattern", "DMA generator data pattern"}, - {0x0028, 0, 32, 0, 0x00000000, PCILIB_REGISTER_R , PCILIB_REGISTER_STANDARD, PCILIB_REGISTER_BANK_DMA, "mwr_perf", "MWR Performance"}, - {0x003C, 0, 32, 0, 0x00000000, PCILIB_REGISTER_R , PCILIB_REGISTER_STANDARD, PCILIB_REGISTER_BANK_DMA, "cfg_lnk_width", "Negotiated and max width of PCIe Link"}, - {0x003C, 0, 6, 0, 0x00000000, PCILIB_REGISTER_R , PCILIB_REGISTER_BITS, PCILIB_REGISTER_BANK_DMA, "cfg_cap_max_lnk_width", "Max link width"}, - {0x003C, 8, 6, 0, 0x00000000, PCILIB_REGISTER_R , PCILIB_REGISTER_BITS, PCILIB_REGISTER_BANK_DMA, "cfg_prg_max_lnk_width", "Negotiated link width"}, - {0x0040, 0, 32, 0, 0x00000000, PCILIB_REGISTER_R , PCILIB_REGISTER_STANDARD, PCILIB_REGISTER_BANK_DMA, "cfg_payload_size", ""}, - {0x0040, 0, 4, 0, 0x00000000, PCILIB_REGISTER_R , PCILIB_REGISTER_BITS, PCILIB_REGISTER_BANK_DMA, "cfg_cap_max_payload_size", "Max payload size"}, - {0x0040, 8, 3, 0, 0x00000000, PCILIB_REGISTER_R , PCILIB_REGISTER_BITS, PCILIB_REGISTER_BANK_DMA, "cfg_prg_max_payload_size", "Prog max payload size"}, - {0x0040, 16, 3, 0, 0x00000000, PCILIB_REGISTER_R , PCILIB_REGISTER_BITS, PCILIB_REGISTER_BANK_DMA, "cfg_max_rd_req_size", "Max read request size"}, - {0x0050, 0, 32, 0, 0x00000000, PCILIB_REGISTER_RW , PCILIB_REGISTER_STANDARD, PCILIB_REGISTER_BANK_DMA, "desc_mem_din", "Descriptor memory"}, - {0x0054, 0, 32, 0, 0x00000000, PCILIB_REGISTER_RW , PCILIB_REGISTER_STANDARD, PCILIB_REGISTER_BANK_DMA, "update_addr", "Address of progress register"}, - {0x0058, 0, 32, 0, 0x00000000, PCILIB_REGISTER_RW , PCILIB_REGISTER_STANDARD, PCILIB_REGISTER_BANK_DMA, "last_descriptor_read", "Last descriptor read by the host"}, - {0x005C, 0, 32, 0, 0x00000000, PCILIB_REGISTER_RW , PCILIB_REGISTER_STANDARD, PCILIB_REGISTER_BANK_DMA, "desc_mem_addr", "Number of descriptors configured"}, - {0x0060, 0, 32, 0, 0x00000000, PCILIB_REGISTER_RW , PCILIB_REGISTER_STANDARD, PCILIB_REGISTER_BANK_DMA, "update_thresh", "Update threshold of progress register"}, - {0, 0, 0, 0, 0x00000000, 0, 0, 0, NULL, NULL} -}; -#endif /* _PCILIB_DMA_IPE_C */ - -#endif /* _PCILIB_DMA_IPE_REGISTERS_H */ diff --git a/dma/nwl.c b/dma/nwl.c deleted file mode 100644 index 52b46ef..0000000 --- a/dma/nwl.c +++ /dev/null @@ -1,139 +0,0 @@ -#define _PCILIB_DMA_NWL_C -#define _BSD_SOURCE - -#include <stdio.h> -#include <stdlib.h> -#include <string.h> -#include <unistd.h> -#include <sys/time.h> - -#include "pci.h" -#include "pcilib.h" -#include "error.h" -#include "tools.h" -#include "nwl_private.h" - -#include "nwl_defines.h" - -int dma_nwl_start(pcilib_dma_context_t *vctx, pcilib_dma_engine_t dma, pcilib_dma_flags_t flags) { - int err; - nwl_dma_t *ctx = (nwl_dma_t*)vctx; - - if (!ctx->started) { - // global initialization, should we do anything? - ctx->started = 1; - } - - if (dma == PCILIB_DMA_ENGINE_INVALID) return 0; - else if (dma > ctx->n_engines) return PCILIB_ERROR_INVALID_BANK; - - if (flags&PCILIB_DMA_FLAG_PERSISTENT) ctx->engines[dma].preserve = 1; - - err = dma_nwl_start_engine(ctx, dma); - - return err; -} - -int dma_nwl_stop(pcilib_dma_context_t *vctx, pcilib_dma_engine_t dma, pcilib_dma_flags_t flags) { - int err; - int preserving = 0; - - nwl_dma_t *ctx = (nwl_dma_t*)vctx; - - if (!ctx->started) return 0; - - // stop everything - if (dma == PCILIB_DMA_ENGINE_INVALID) { - for (dma = 0; dma < ctx->n_engines; dma++) { - if (flags&PCILIB_DMA_FLAG_PERSISTENT) { - ctx->engines[dma].preserve = 0; - } - - if (ctx->engines[dma].preserve) preserving = 1; - - err = dma_nwl_stop_engine(ctx, dma); - if (err) return err; - } - - // global cleanup, should we do anything? - if (!preserving) { - ctx->started = 0; - } - - return 0; - } - - if (dma > ctx->n_engines) return PCILIB_ERROR_INVALID_BANK; - - // ignorign previous setting if flag specified - if (flags&PCILIB_DMA_FLAG_PERSISTENT) { - ctx->engines[dma].preserve = 0; - } - - return dma_nwl_stop_engine(ctx, dma); -} - - -pcilib_dma_context_t *dma_nwl_init(pcilib_t *pcilib, pcilib_dma_modification_t type, void *arg) { - int i; - int err; - pcilib_dma_engine_t n_engines; - - pcilib_model_description_t *model_info = pcilib_get_model_description(pcilib); - - nwl_dma_t *ctx = malloc(sizeof(nwl_dma_t)); - if (ctx) { - memset(ctx, 0, sizeof(nwl_dma_t)); - ctx->pcilib = pcilib; - ctx->type = type; - - if (type == PCILIB_NWL_MODIFICATION_IPECAMERA) { - ctx->dmactx.ignore_eop = 1; - } - - pcilib_register_bank_t dma_bank = pcilib_find_bank_by_addr(pcilib, PCILIB_REGISTER_BANK_DMA); - if (dma_bank == PCILIB_REGISTER_BANK_INVALID) { - free(ctx); - pcilib_error("DMA Register Bank could not be found"); - return NULL; - } - - ctx->dma_bank = model_info->banks + dma_bank; - ctx->base_addr = pcilib_resolve_register_address(pcilib, ctx->dma_bank->bar, ctx->dma_bank->read_addr); - - for (i = 0, n_engines = 0; i < 2 * PCILIB_MAX_DMA_ENGINES; i++) { - char *addr = ctx->base_addr + DMA_OFFSET + i * DMA_ENGINE_PER_SIZE; - - memset(ctx->engines + n_engines, 0, sizeof(pcilib_nwl_engine_description_t)); - - err = dma_nwl_read_engine_config(ctx, ctx->engines + n_engines, addr); - if (err) continue; - - pcilib_set_dma_engine_description(pcilib, n_engines, (pcilib_dma_engine_description_t*)(ctx->engines + n_engines)); - ++n_engines; - } - pcilib_set_dma_engine_description(pcilib, n_engines, NULL); - - ctx->n_engines = n_engines; - - err = nwl_add_registers(ctx); - if (err) { - free(ctx); - pcilib_error("Failed to add DMA registers"); - return NULL; - } - } - return (pcilib_dma_context_t*)ctx; -} - -void dma_nwl_free(pcilib_dma_context_t *vctx) { - nwl_dma_t *ctx = (nwl_dma_t*)vctx; - - if (ctx) { - if (ctx->type == PCILIB_DMA_MODIFICATION_DEFAULT) dma_nwl_stop_loopback(ctx); - dma_nwl_free_irq(ctx); - dma_nwl_stop(vctx, PCILIB_DMA_ENGINE_ALL, PCILIB_DMA_FLAGS_DEFAULT); - - free(ctx); - } -} diff --git a/dma/nwl.h b/dma/nwl.h deleted file mode 100644 index 21df94c..0000000 --- a/dma/nwl.h +++ /dev/null @@ -1,46 +0,0 @@ -#ifndef _PCILIB_DMA_NWL_H -#define _PCILIB_DMA_NWL_H - -#include <stdio.h> -#include "../pcilib.h" - -#define PCILIB_NWL_MODIFICATION_IPECAMERA 0x100 - -pcilib_dma_context_t *dma_nwl_init(pcilib_t *ctx, pcilib_dma_modification_t type, void *arg); -void dma_nwl_free(pcilib_dma_context_t *vctx); - -int dma_nwl_get_status(pcilib_dma_context_t *vctx, pcilib_dma_engine_t dma, pcilib_dma_engine_status_t *status, size_t n_buffers, pcilib_dma_buffer_status_t *buffers); - -int dma_nwl_enable_irq(pcilib_dma_context_t *vctx, pcilib_irq_type_t type, pcilib_dma_flags_t flags); -int dma_nwl_disable_irq(pcilib_dma_context_t *vctx, pcilib_dma_flags_t flags); -int dma_nwl_acknowledge_irq(pcilib_dma_context_t *ctx, pcilib_irq_type_t irq_type, pcilib_irq_source_t irq_source); - -int dma_nwl_start(pcilib_dma_context_t *ctx, pcilib_dma_engine_t dma, pcilib_dma_flags_t flags); -int dma_nwl_stop(pcilib_dma_context_t *ctx, pcilib_dma_engine_t dma, pcilib_dma_flags_t flags); - -int dma_nwl_write_fragment(pcilib_dma_context_t *vctx, pcilib_dma_engine_t dma, uintptr_t addr, size_t size, pcilib_dma_flags_t flags, pcilib_timeout_t timeout, void *data, size_t *written); -int dma_nwl_stream_read(pcilib_dma_context_t *vctx, pcilib_dma_engine_t dma, uintptr_t addr, size_t size, pcilib_dma_flags_t flags, pcilib_timeout_t timeout, pcilib_dma_callback_t cb, void *cbattr); -double dma_nwl_benchmark(pcilib_dma_context_t *vctx, pcilib_dma_engine_addr_t dma, uintptr_t addr, size_t size, size_t iterations, pcilib_dma_direction_t direction); - - -#ifdef _PCILIB_DMA_NWL_C -pcilib_dma_api_description_t nwl_dma_api = { - "nwl_dma", - dma_nwl_init, - dma_nwl_free, - dma_nwl_get_status, - dma_nwl_enable_irq, - dma_nwl_disable_irq, - dma_nwl_acknowledge_irq, - dma_nwl_start, - dma_nwl_stop, - dma_nwl_write_fragment, - dma_nwl_stream_read, - dma_nwl_benchmark -}; -#else -extern pcilib_dma_api_description_t nwl_dma_api; -#endif - - -#endif /* _PCILIB_DMA_NWL_H */ diff --git a/dma/nwl_defines.h b/dma/nwl_defines.h deleted file mode 100644 index ce3b686..0000000 --- a/dma/nwl_defines.h +++ /dev/null @@ -1,145 +0,0 @@ -/** @name Buffer Descriptor offsets - * USR fields are defined by higher level IP. For example, checksum offload - * setup for EMAC type devices. The 1st 8 words are utilized by hardware. Any - * words after the 8th are for software use only. - * @{ - */ -#define DMA_BD_BUFL_STATUS_OFFSET 0x00 /**< Buffer length + status */ -#define DMA_BD_USRL_OFFSET 0x04 /**< User logic specific - LSBytes */ -#define DMA_BD_USRH_OFFSET 0x08 /**< User logic specific - MSBytes */ -#define DMA_BD_CARDA_OFFSET 0x0C /**< Card address */ -#define DMA_BD_BUFL_CTRL_OFFSET 0x10 /**< Buffer length + control */ -#define DMA_BD_BUFAL_OFFSET 0x14 /**< Buffer address LSBytes */ -#define DMA_BD_BUFAH_OFFSET 0x18 /**< Buffer address MSBytes */ -#define DMA_BD_NDESC_OFFSET 0x1C /**< Next descriptor pointer */ - -/* Bit masks for some BD fields */ -#define DMA_BD_BUFL_MASK 0x000FFFFF /**< Byte count */ -#define DMA_BD_STATUS_MASK 0xFF000000 /**< Status Flags */ -#define DMA_BD_CTRL_MASK 0xFF000000 /**< Control Flags */ - -/* Bit masks for BD control field */ -#define DMA_BD_INT_ERROR_MASK 0x02000000 /**< Intr on error */ -#define DMA_BD_INT_COMP_MASK 0x01000000 /**< Intr on BD completion */ - -/* Bit masks for BD status field */ -#define DMA_BD_SOP_MASK 0x80000000 /**< Start of packet */ -#define DMA_BD_EOP_MASK 0x40000000 /**< End of packet */ -#define DMA_BD_ERROR_MASK 0x10000000 /**< BD had error */ -#define DMA_BD_USER_HIGH_ZERO_MASK 0x08000000 /**< User High Status zero */ -#define DMA_BD_USER_LOW_ZERO_MASK 0x04000000 /**< User Low Status zero */ -#define DMA_BD_SHORT_MASK 0x02000000 /**< BD not fully used */ -#define DMA_BD_COMP_MASK 0x01000000 /**< BD completed */ - - - -#define DMA_BD_MINIMUM_ALIGNMENT 0x40 /**< Minimum byte alignment */ - -/* Common DMA registers */ -#define REG_DMA_CTRL_STATUS 0x4000 /**< DMA Common Ctrl & Status */ - -/* These engine registers are applicable to both S2C and C2S channels. - * Register field mask and shift definitions are later in this file. - */ - -#define REG_DMA_ENG_CAP 0x00000000 /**< DMA Engine Capabilities */ -#define REG_DMA_ENG_CTRL_STATUS 0x00000004 /**< DMA Engine Control */ -#define REG_DMA_ENG_NEXT_BD 0x00000008 /**< HW Next desc pointer */ -#define REG_SW_NEXT_BD 0x0000000C /**< SW Next desc pointer */ -#define REG_DMA_ENG_LAST_BD 0x00000010 /**< HW Last completed pointer */ -#define REG_DMA_ENG_ACTIVE_TIME 0x00000014 /**< DMA Engine Active Time */ -#define REG_DMA_ENG_WAIT_TIME 0x00000018 /**< DMA Engine Wait Time */ -#define REG_DMA_ENG_COMP_BYTES 0x0000001C /**< DMA Engine Completed Bytes */ - -/* Register masks. The following constants define bit locations of various - * control bits in the registers. For further information on the meaning of - * the various bit masks, refer to the hardware spec. - * - * Masks have been written assuming HW bits 0-31 correspond to SW bits 0-31 - */ - -/** @name Bitmasks of REG_DMA_CTRL_STATUS register. - * @{ - */ -#define DMA_INT_ENABLE 0x00000001 /**< Enable global interrupts */ -#define DMA_INT_DISABLE 0x00000000 /**< Disable interrupts */ -#define DMA_INT_ACTIVE_MASK 0x00000002 /**< Interrupt active? */ -#define DMA_INT_PENDING_MASK 0x00000004 /**< Engine interrupt pending */ -#define DMA_INT_MSI_MODE 0x00000008 /**< MSI or Legacy mode? */ -#define DMA_USER_INT_ENABLE 0x00000010 /**< Enable user interrupts */ -#define DMA_USER_INT_ACTIVE_MASK 0x00000020 /**< Int - user interrupt */ -#define DMA_USER_INT_ACK 0x00000020 /**< Acknowledge */ -#define DMA_MPS_USED 0x00000700 /**< MPS Used */ -#define DMA_MRRS_USED 0x00007000 /**< MRRS Used */ -#define DMA_S2C_ENG_INT_VAL 0x00FF0000 /**< IRQ value of 1st 8 S2Cs */ -#define DMA_C2S_ENG_INT_VAL 0xFF000000 /**< IRQ value of 1st 8 C2Ss */ - -/** @name Bitmasks of REG_DMA_ENG_CAP register. - * @{ - */ -/* DMA engine characteristics */ -#define DMA_ENG_PRESENT_MASK 0x00000001 /**< DMA engine present? */ -#define DMA_ENG_DIRECTION_MASK 0x00000002 /**< DMA engine direction */ -#define DMA_ENG_C2S 0x00000002 /**< DMA engine - C2S */ -#define DMA_ENG_S2C 0x00000000 /**< DMA engine - S2C */ -#define DMA_ENG_TYPE_MASK 0x00000030 /**< DMA engine type */ -#define DMA_ENG_BLOCK 0x00000000 /**< DMA engine - Block type */ -#define DMA_ENG_PACKET 0x00000010 /**< DMA engine - Packet type */ -#define DMA_ENG_NUMBER 0x0000FF00 /**< DMA engine number */ -#define DMA_ENG_BD_MAX_BC 0x3F000000 /**< DMA engine max buffer size */ - - -/* Shift constants for selected masks */ -#define DMA_ENG_NUMBER_SHIFT 8 -#define DMA_ENG_BD_MAX_BC_SHIFT 24 - -/** @name Bitmasks of REG_DMA_ENG_CTRL_STATUS register. - * @{ - */ -/* Interrupt activity and acknowledgement bits */ -#define DMA_ENG_INT_ENABLE 0x00000001 /**< Enable interrupts */ -#define DMA_ENG_INT_DISABLE 0x00000000 /**< Disable interrupts */ -#define DMA_ENG_INT_ACTIVE_MASK 0x00000002 /**< Interrupt active? */ -#define DMA_ENG_INT_ACK 0x00000002 /**< Interrupt ack */ -#define DMA_ENG_INT_BDCOMP 0x00000004 /**< Int - BD completion */ -#define DMA_ENG_INT_BDCOMP_ACK 0x00000004 /**< Acknowledge */ -#define DMA_ENG_INT_ALERR 0x00000008 /**< Int - BD align error */ -#define DMA_ENG_INT_ALERR_ACK 0x00000008 /**< Acknowledge */ -#define DMA_ENG_INT_FETERR 0x00000010 /**< Int - BD fetch error */ -#define DMA_ENG_INT_FETERR_ACK 0x00000010 /**< Acknowledge */ -#define DMA_ENG_INT_ABORTERR 0x00000020 /**< Int - DMA abort error */ -#define DMA_ENG_INT_ABORTERR_ACK 0x00000020 /**< Acknowledge */ -#define DMA_ENG_INT_CHAINEND 0x00000080 /**< Int - BD chain ended */ -#define DMA_ENG_INT_CHAINEND_ACK 0x00000080 /**< Acknowledge */ - -/* DMA engine control */ -#define DMA_ENG_ENABLE_MASK 0x00000100 /**< DMA enabled? */ -#define DMA_ENG_ENABLE 0x00000100 /**< Enable DMA */ -#define DMA_ENG_DISABLE 0x00000000 /**< Disable DMA */ -#define DMA_ENG_STATE_MASK 0x00000C00 /**< Current DMA state? */ -#define DMA_ENG_RUNNING 0x00000400 /**< DMA running */ -#define DMA_ENG_IDLE 0x00000000 /**< DMA idle */ -#define DMA_ENG_WAITING 0x00000800 /**< DMA waiting */ -#define DMA_ENG_STATE_WAITED 0x00001000 /**< DMA waited earlier */ -#define DMA_ENG_WAITED_ACK 0x00001000 /**< Acknowledge */ -#define DMA_ENG_USER_RESET 0x00004000 /**< Reset only user logic */ -#define DMA_ENG_RESET 0x00008000 /**< Reset DMA engine + user */ - -#define DMA_ENG_ALLINT_MASK 0x000000BE /**< To get only int events */ - -#define DMA_ENGINE_PER_SIZE 0x100 /**< Separation between engine regs */ -#define DMA_OFFSET 0 /**< Starting register offset */ - /**< Size of DMA engine reg space */ -#define DMA_SIZE (MAX_DMA_ENGINES * DMA_ENGINE_PER_SIZE) - - -#define TX_CONFIG_ADDRESS 0x9108 /* Reg for controlling TX data */ -#define RX_CONFIG_ADDRESS 0x9100 /* Reg for controlling RX pkt generator */ -#define PKT_SIZE_ADDRESS 0x9104 /* Reg for programming packet size */ -#define STATUS_ADDRESS 0x910C /* Reg for checking TX pkt checker status */ - -/* Test start / stop conditions */ -#define PKTCHKR 0x00000001 /* Enable TX packet checker */ -#define PKTGENR 0x00000001 /* Enable RX packet generator */ -#define CHKR_MISMATCH 0x00000001 /* TX checker reported data mismatch */ -#define LOOPBACK 0x00000002 /* Enable TX data loopback onto RX */ diff --git a/dma/nwl_engine.c b/dma/nwl_engine.c deleted file mode 100644 index f541d0b..0000000 --- a/dma/nwl_engine.c +++ /dev/null @@ -1,318 +0,0 @@ -#define _BSD_SOURCE - -#include <stdio.h> -#include <stdlib.h> -#include <string.h> -#include <unistd.h> -#include <sys/time.h> - -#include "pci.h" -#include "pcilib.h" -#include "error.h" -#include "tools.h" -#include "nwl_private.h" - -#include "nwl_defines.h" - -#include "nwl_engine_buffers.h" - -int dma_nwl_read_engine_config(nwl_dma_t *ctx, pcilib_nwl_engine_description_t *info, char *base) { - uint32_t val; - - info->base_addr = base; - - nwl_read_register(val, ctx, base, REG_DMA_ENG_CAP); - - if ((val & DMA_ENG_PRESENT_MASK) == 0) return PCILIB_ERROR_NOTAVAILABLE; - - info->desc.addr = (val & DMA_ENG_NUMBER) >> DMA_ENG_NUMBER_SHIFT; - if ((info->desc.addr > PCILIB_MAX_DMA_ENGINES)||(info->desc.addr < 0)) return PCILIB_ERROR_INVALID_DATA; - - switch (val & DMA_ENG_DIRECTION_MASK) { - case DMA_ENG_C2S: - info->desc.direction = PCILIB_DMA_FROM_DEVICE; - break; - default: - info->desc.direction = PCILIB_DMA_TO_DEVICE; - } - - switch (val & DMA_ENG_TYPE_MASK) { - case DMA_ENG_BLOCK: - info->desc.type = PCILIB_DMA_TYPE_BLOCK; - break; - case DMA_ENG_PACKET: - info->desc.type = PCILIB_DMA_TYPE_PACKET; - break; - default: - info->desc.type = PCILIB_DMA_TYPE_UNKNOWN; - } - - info->desc.addr_bits = (val & DMA_ENG_BD_MAX_BC) >> DMA_ENG_BD_MAX_BC_SHIFT; - - info->base_addr = base; - - return 0; -} - -int dma_nwl_start_engine(nwl_dma_t *ctx, pcilib_dma_engine_t dma) { - int err; - uint32_t val; - uint32_t ring_pa; - struct timeval start, cur; - - pcilib_nwl_engine_description_t *info = ctx->engines + dma; - char *base = ctx->engines[dma].base_addr; - - if (info->started) return 0; - - - // This will only successed if there are no parallel access to DMA engine - err = dma_nwl_allocate_engine_buffers(ctx, info); - if (err) { - info->started = 1; - dma_nwl_stop_engine(ctx, dma); - return err; - } - - if (info->reused) { - info->preserve = 1; - - dma_nwl_acknowledge_irq((pcilib_dma_context_t*)ctx, PCILIB_DMA_IRQ, dma); - -#ifdef NWL_GENERATE_DMA_IRQ - dma_nwl_enable_engine_irq(ctx, dma); -#endif /* NWL_GENERATE_DMA_IRQ */ - } else { - // Disable IRQs - err = dma_nwl_disable_engine_irq(ctx, dma); - if (err) { - info->started = 1; - dma_nwl_stop_engine(ctx, dma); - return err; - } - - // Disable Engine & Reseting - val = DMA_ENG_DISABLE|DMA_ENG_USER_RESET; - nwl_write_register(val, ctx, base, REG_DMA_ENG_CTRL_STATUS); - - gettimeofday(&start, NULL); - do { - nwl_read_register(val, ctx, base, REG_DMA_ENG_CTRL_STATUS); - gettimeofday(&cur, NULL); - } while ((val & (DMA_ENG_STATE_MASK|DMA_ENG_USER_RESET))&&(((cur.tv_sec - start.tv_sec)*1000000 + (cur.tv_usec - start.tv_usec)) < PCILIB_REGISTER_TIMEOUT)); - - if (val & (DMA_ENG_STATE_MASK|DMA_ENG_USER_RESET)) { - pcilib_error("Timeout during reset of DMA engine %i", info->desc.addr); - - info->started = 1; - dma_nwl_stop_engine(ctx, dma); - return PCILIB_ERROR_TIMEOUT; - } - - val = DMA_ENG_RESET; - nwl_write_register(val, ctx, base, REG_DMA_ENG_CTRL_STATUS); - - gettimeofday(&start, NULL); - do { - nwl_read_register(val, ctx, base, REG_DMA_ENG_CTRL_STATUS); - gettimeofday(&cur, NULL); - } while ((val & DMA_ENG_RESET)&&(((cur.tv_sec - start.tv_sec)*1000000 + (cur.tv_usec - start.tv_usec)) < PCILIB_REGISTER_TIMEOUT)); - - if (val & DMA_ENG_RESET) { - pcilib_error("Timeout during reset of DMA engine %i", info->desc.addr); - - info->started = 1; - dma_nwl_stop_engine(ctx, dma); - return PCILIB_ERROR_TIMEOUT; - } - - dma_nwl_acknowledge_irq((pcilib_dma_context_t*)ctx, PCILIB_DMA_IRQ, dma); - - ring_pa = pcilib_kmem_get_pa(ctx->pcilib, info->ring); - nwl_write_register(ring_pa, ctx, info->base_addr, REG_DMA_ENG_NEXT_BD); - nwl_write_register(ring_pa, ctx, info->base_addr, REG_SW_NEXT_BD); - - __sync_synchronize(); - - nwl_read_register(val, ctx, info->base_addr, REG_DMA_ENG_CTRL_STATUS); - val |= (DMA_ENG_ENABLE); - nwl_write_register(val, ctx, info->base_addr, REG_DMA_ENG_CTRL_STATUS); - - __sync_synchronize(); - -#ifdef NWL_GENERATE_DMA_IRQ - dma_nwl_enable_engine_irq(ctx, dma); -#endif /* NWL_GENERATE_DMA_IRQ */ - - if (info->desc.direction == PCILIB_DMA_FROM_DEVICE) { - ring_pa += (info->ring_size - 1) * PCILIB_NWL_DMA_DESCRIPTOR_SIZE; - nwl_write_register(ring_pa, ctx, info->base_addr, REG_SW_NEXT_BD); - - info->tail = 0; - info->head = (info->ring_size - 1); - } else { - info->tail = 0; - info->head = 0; - } - } - - info->started = 1; - - return 0; -} - - -int dma_nwl_stop_engine(nwl_dma_t *ctx, pcilib_dma_engine_t dma) { - int err; - uint32_t val; - uint32_t ring_pa; - struct timeval start, cur; - pcilib_kmem_flags_t flags; - - - pcilib_nwl_engine_description_t *info = ctx->engines + dma; - char *base = ctx->engines[dma].base_addr; - - if (!info->started) return 0; - - info->started = 0; - - err = dma_nwl_disable_engine_irq(ctx, dma); - if (err) return err; - - if (!info->preserve) { - // Stopping DMA is not enough reset is required - val = DMA_ENG_DISABLE|DMA_ENG_USER_RESET|DMA_ENG_RESET; - nwl_write_register(val, ctx, base, REG_DMA_ENG_CTRL_STATUS); - - gettimeofday(&start, NULL); - do { - nwl_read_register(val, ctx, base, REG_DMA_ENG_CTRL_STATUS); - gettimeofday(&cur, NULL); - } while ((val & (DMA_ENG_RUNNING))&&(((cur.tv_sec - start.tv_sec)*1000000 + (cur.tv_usec - start.tv_usec)) < PCILIB_REGISTER_TIMEOUT)); - - if (info->ring) { - ring_pa = pcilib_kmem_get_pa(ctx->pcilib, info->ring); - nwl_write_register(ring_pa, ctx, info->base_addr, REG_DMA_ENG_NEXT_BD); - nwl_write_register(ring_pa, ctx, info->base_addr, REG_SW_NEXT_BD); - } - } - - dma_nwl_acknowledge_irq((pcilib_dma_context_t*)ctx, PCILIB_DMA_IRQ, dma); - - if (info->preserve) { - flags = PCILIB_KMEM_FLAG_REUSE; - } else { - flags = PCILIB_KMEM_FLAG_HARDWARE|PCILIB_KMEM_FLAG_PERSISTENT; - } - - // Clean buffers - if (info->ring) { - pcilib_free_kernel_memory(ctx->pcilib, info->ring, flags); - info->ring = NULL; - } - - if (info->pages) { - pcilib_free_kernel_memory(ctx->pcilib, info->pages, flags); - info->pages = NULL; - } - - return 0; -} - -int dma_nwl_write_fragment(pcilib_dma_context_t *vctx, pcilib_dma_engine_t dma, uintptr_t addr, size_t size, pcilib_dma_flags_t flags, pcilib_timeout_t timeout, void *data, size_t *written) { - int err; - size_t pos; - size_t bufnum; - nwl_dma_t *ctx = (nwl_dma_t*)vctx; - - pcilib_nwl_engine_description_t *info = ctx->engines + dma; - - err = dma_nwl_start(vctx, dma, PCILIB_DMA_FLAGS_DEFAULT); - if (err) return err; - - if (data) { - for (pos = 0; pos < size; pos += info->page_size) { - int block_size = min2(size - pos, info->page_size); - - bufnum = dma_nwl_get_next_buffer(ctx, info, 1, timeout); - if (bufnum == PCILIB_DMA_BUFFER_INVALID) { - if (written) *written = pos; - return PCILIB_ERROR_TIMEOUT; - } - - void *buf = pcilib_kmem_get_block_ua(ctx->pcilib, info->pages, bufnum); - - pcilib_kmem_sync_block(ctx->pcilib, info->pages, PCILIB_KMEM_SYNC_FROMDEVICE, bufnum); - memcpy(buf, data, block_size); - pcilib_kmem_sync_block(ctx->pcilib, info->pages, PCILIB_KMEM_SYNC_TODEVICE, bufnum); - - err = dma_nwl_push_buffer(ctx, info, block_size, (flags&PCILIB_DMA_FLAG_EOP)&&((pos + block_size) == size), timeout); - if (err) { - if (written) *written = pos; - return err; - } - } - } - - if (written) *written = size; - - if (flags&PCILIB_DMA_FLAG_WAIT) { - bufnum = dma_nwl_get_next_buffer(ctx, info, PCILIB_NWL_DMA_PAGES - 1, timeout); - if (bufnum == PCILIB_DMA_BUFFER_INVALID) return PCILIB_ERROR_TIMEOUT; - } - - return 0; -} - -int dma_nwl_stream_read(pcilib_dma_context_t *vctx, pcilib_dma_engine_t dma, uintptr_t addr, size_t size, pcilib_dma_flags_t flags, pcilib_timeout_t timeout, pcilib_dma_callback_t cb, void *cbattr) { - int err, ret = PCILIB_STREAMING_REQ_PACKET; - pcilib_timeout_t wait = 0; - size_t res = 0; - size_t bufnum; - size_t bufsize; - - nwl_dma_t *ctx = (nwl_dma_t*)vctx; - - int eop; - - pcilib_nwl_engine_description_t *info = ctx->engines + dma; - - err = dma_nwl_start(vctx, dma, PCILIB_DMA_FLAGS_DEFAULT); - if (err) return err; - - do { - switch (ret&PCILIB_STREAMING_TIMEOUT_MASK) { - case PCILIB_STREAMING_CONTINUE: wait = PCILIB_DMA_TIMEOUT; break; - case PCILIB_STREAMING_WAIT: wait = timeout; break; -// case PCILIB_STREAMING_CHECK: wait = 0; break; - } - - bufnum = dma_nwl_wait_buffer(ctx, info, &bufsize, &eop, wait); - if (bufnum == PCILIB_DMA_BUFFER_INVALID) { - return (ret&PCILIB_STREAMING_FAIL)?PCILIB_ERROR_TIMEOUT:0; - } - - // EOP is not respected in IPE Camera - if (ctx->dmactx.ignore_eop) eop = 1; - - pcilib_kmem_sync_block(ctx->pcilib, info->pages, PCILIB_KMEM_SYNC_FROMDEVICE, bufnum); - void *buf = pcilib_kmem_get_block_ua(ctx->pcilib, info->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 -// pcilib_kmem_sync_block(ctx->pcilib, info->pages, PCILIB_KMEM_SYNC_TODEVICE, bufnum); - dma_nwl_return_buffer(ctx, info); - - res += bufsize; - - } while (ret); - - return 0; -} - -int dma_nwl_wait_completion(nwl_dma_t * ctx, pcilib_dma_engine_t dma, pcilib_timeout_t timeout) { - if (dma_nwl_get_next_buffer(ctx, ctx->engines + dma, PCILIB_NWL_DMA_PAGES - 1, PCILIB_DMA_TIMEOUT) == (PCILIB_NWL_DMA_PAGES - 1)) return 0; - else return PCILIB_ERROR_TIMEOUT; -} - diff --git a/dma/nwl_engine.h b/dma/nwl_engine.h deleted file mode 100644 index f9f3f60..0000000 --- a/dma/nwl_engine.h +++ /dev/null @@ -1,12 +0,0 @@ -#ifndef _PCILIB_DMA_NWL_ENGINE_H -#define _PCILIB_DMA_NWL_ENGINE_H - -int dma_nwl_read_engine_config(nwl_dma_t *ctx, pcilib_nwl_engine_description_t *info, char *base); -int dma_nwl_start_engine(nwl_dma_t *ctx, pcilib_dma_engine_t dma); -int dma_nwl_stop_engine(nwl_dma_t *ctx, pcilib_dma_engine_t dma); - -int dma_nwl_wait_completion(nwl_dma_t * ctx, pcilib_dma_engine_t dma, pcilib_timeout_t timeout); - - -#endif /* _PCILIB_DMA_NWL_ENGINE_H */ - diff --git a/dma/nwl_engine_buffers.h b/dma/nwl_engine_buffers.h deleted file mode 100644 index c45c3ca..0000000 --- a/dma/nwl_engine_buffers.h +++ /dev/null @@ -1,412 +0,0 @@ -#define NWL_RING_GET(data, offset) *(uint32_t*)(((char*)(data)) + (offset)) -#define NWL_RING_SET(data, offset, val) *(uint32_t*)(((char*)(data)) + (offset)) = (val) -#define NWL_RING_UPDATE(data, offset, mask, val) *(uint32_t*)(((char*)(data)) + (offset)) = ((*(uint32_t*)(((char*)(data)) + (offset)))&(mask))|(val) - -static int dma_nwl_compute_read_s2c_pointers(nwl_dma_t *ctx, pcilib_nwl_engine_description_t *info, unsigned char *ring, uint32_t ring_pa) { - uint32_t val; - - char *base = info->base_addr; - - nwl_read_register(val, ctx, base, REG_SW_NEXT_BD); - if ((val < ring_pa)||((val - ring_pa) % PCILIB_NWL_DMA_DESCRIPTOR_SIZE)) { - if (val < ring_pa) pcilib_warning("Inconsistent S2C DMA Ring buffer is found (REG_SW_NEXT_BD register value (%lx) is below start of ring [%lx,%lx])", val, ring_pa, PCILIB_NWL_DMA_DESCRIPTOR_SIZE); - else pcilib_warning("Inconsistent S2C DMA Ring buffer is found (REG_SW_NEXT_BD register value (%zu / %u) is fractal)", val - ring_pa, PCILIB_NWL_DMA_DESCRIPTOR_SIZE); - return PCILIB_ERROR_INVALID_STATE; - } - - info->head = (val - ring_pa) / PCILIB_NWL_DMA_DESCRIPTOR_SIZE; - if (info->head >= PCILIB_NWL_DMA_PAGES) { - pcilib_warning("Inconsistent S2C DMA Ring buffer is found (REG_SW_NEXT_BD register value (%zu) out of range)", info->head); - return PCILIB_ERROR_INVALID_STATE; - } - - nwl_read_register(val, ctx, base, REG_DMA_ENG_NEXT_BD); - if ((val < ring_pa)||((val - ring_pa) % PCILIB_NWL_DMA_DESCRIPTOR_SIZE)) { - if (val < ring_pa) pcilib_warning("Inconsistent S2C DMA Ring buffer is found (REG_DMA_ENG_NEXT_BD register value (%lx) is below start of ring [%lx,%lx])", val, ring_pa, PCILIB_NWL_DMA_DESCRIPTOR_SIZE); - else pcilib_warning("Inconsistent S2C DMA Ring buffer is found (REG_DMA_ENG_NEXT_BD register value (%zu / %u) is fractal)", val - ring_pa, PCILIB_NWL_DMA_DESCRIPTOR_SIZE); - return PCILIB_ERROR_INVALID_STATE; - } - - info->tail = (val - ring_pa) / PCILIB_NWL_DMA_DESCRIPTOR_SIZE; - if (info->tail >= PCILIB_NWL_DMA_PAGES) { - pcilib_warning("Inconsistent S2C DMA Ring buffer is found (REG_DMA_ENG_NEXT_BD register value (%zu) out of range)", info->tail); - return PCILIB_ERROR_INVALID_STATE; - } - -#ifdef DEBUG_NWL - printf("S2C: %lu %lu\n", info->tail, info->head); -#endif /* DEBUG_NWL */ - - return 0; -} - -static int dma_nwl_compute_read_c2s_pointers(nwl_dma_t *ctx, pcilib_nwl_engine_description_t *info, unsigned char *ring, uint32_t ring_pa) { - uint32_t val; - - char *base = info->base_addr; - - nwl_read_register(val, ctx, base, REG_SW_NEXT_BD); - if ((val < ring_pa)||((val - ring_pa) % PCILIB_NWL_DMA_DESCRIPTOR_SIZE)) { - if (val < ring_pa) pcilib_warning("Inconsistent C2S DMA Ring buffer is found (REG_SW_NEXT_BD register value (%lx) is below start of the ring [%lx,%lx])", val, ring_pa, PCILIB_NWL_DMA_DESCRIPTOR_SIZE); - else pcilib_warning("Inconsistent C2S DMA Ring buffer is found (REG_SW_NEXT_BD register value (%zu / %u) is fractal)", val - ring_pa, PCILIB_NWL_DMA_DESCRIPTOR_SIZE); - return PCILIB_ERROR_INVALID_STATE; - } - - info->head = (val - ring_pa) / PCILIB_NWL_DMA_DESCRIPTOR_SIZE; - if (info->head >= PCILIB_NWL_DMA_PAGES) { - pcilib_warning("Inconsistent C2S DMA Ring buffer is found (REG_SW_NEXT_BD register value (%zu) out of range)", info->head); - return PCILIB_ERROR_INVALID_STATE; - } - - info->tail = info->head + 1; - if (info->tail == PCILIB_NWL_DMA_PAGES) info->tail = 0; - -#ifdef DEBUG_NWL - printf("C2S: %lu %lu\n", info->tail, info->head); -#endif /* DEBUG_NWL */ - - return 0; -} - - -static int dma_nwl_allocate_engine_buffers(nwl_dma_t *ctx, pcilib_nwl_engine_description_t *info) { - int err = 0; - - int i; - int preserve = 0; - uint16_t sub_use; - uint32_t val; - uint32_t buf_sz; - uint64_t buf_pa; - pcilib_kmem_reuse_state_t reuse_ring, reuse_pages; - pcilib_kmem_flags_t flags; - pcilib_kmem_type_t type; - - char *base = info->base_addr; - - if (info->pages) return 0; - - // Or bidirectional specified by 0x0|addr, or read 0x0|addr and write 0x80|addr - type = (info->desc.direction == PCILIB_DMA_TO_DEVICE)?PCILIB_KMEM_TYPE_DMA_S2C_PAGE:PCILIB_KMEM_TYPE_DMA_C2S_PAGE; - sub_use = info->desc.addr|((info->desc.direction == PCILIB_DMA_TO_DEVICE)?0x80:0x00); - flags = PCILIB_KMEM_FLAG_REUSE|PCILIB_KMEM_FLAG_EXCLUSIVE|PCILIB_KMEM_FLAG_HARDWARE|(info->preserve?PCILIB_KMEM_FLAG_PERSISTENT:0); - - pcilib_kmem_handle_t *ring = pcilib_alloc_kernel_memory(ctx->pcilib, PCILIB_KMEM_TYPE_CONSISTENT, 1, PCILIB_NWL_DMA_PAGES * PCILIB_NWL_DMA_DESCRIPTOR_SIZE, PCILIB_NWL_ALIGNMENT, PCILIB_KMEM_USE(PCILIB_KMEM_USE_DMA_RING, sub_use), flags); - pcilib_kmem_handle_t *pages = pcilib_alloc_kernel_memory(ctx->pcilib, type, PCILIB_NWL_DMA_PAGES, 0, 0, PCILIB_KMEM_USE(PCILIB_KMEM_USE_DMA_PAGES, sub_use), flags); - - if (!ring||!pages) { - if (pages) pcilib_free_kernel_memory(ctx->pcilib, pages, 0); - if (ring) pcilib_free_kernel_memory(ctx->pcilib, ring, 0); - return PCILIB_ERROR_MEMORY; - } - - reuse_ring = pcilib_kmem_is_reused(ctx->pcilib, ring); - reuse_pages = pcilib_kmem_is_reused(ctx->pcilib, pages); - -// I guess idea here was that we not need to check all that stuff during the second iteration -// which is basicaly true (shall we expect any driver-triggered changes or parallel accesses?) -// but still we need to set preserve flag (and that if we enforcing preservation --start-dma). -// Probably having checks anyway is not harming... -// if (!info->preserve) { - if (reuse_ring == reuse_pages) { - if (reuse_ring & PCILIB_KMEM_REUSE_PARTIAL) pcilib_warning("Inconsistent DMA buffers are found (only part of required buffers is available), reinitializing..."); - else if (reuse_ring & PCILIB_KMEM_REUSE_REUSED) { - if ((reuse_ring & PCILIB_KMEM_REUSE_PERSISTENT) == 0) pcilib_warning("Lost DMA buffers are found (non-persistent mode), reinitializing..."); - else if ((reuse_ring & PCILIB_KMEM_REUSE_HARDWARE) == 0) pcilib_warning("Lost DMA buffers are found (missing HW reference), reinitializing..."); - else { - nwl_read_register(val, ctx, info->base_addr, REG_DMA_ENG_CTRL_STATUS); - - if ((val&DMA_ENG_RUNNING) == 0) pcilib_warning("Lost DMA buffers are found (DMA engine is stopped), reinitializing..."); - else preserve = 1; - } - } - } else pcilib_warning("Inconsistent DMA buffers (modes of ring and page buffers does not match), reinitializing...."); -// } - - - unsigned char *data = (unsigned char*)pcilib_kmem_get_ua(ctx->pcilib, ring); - uint32_t ring_pa = pcilib_kmem_get_pa(ctx->pcilib, ring); - - if (preserve) { - if (info->desc.direction == PCILIB_DMA_FROM_DEVICE) err = dma_nwl_compute_read_c2s_pointers(ctx, info, data, ring_pa); - else err = dma_nwl_compute_read_s2c_pointers(ctx, info, data, ring_pa); - - if (err) preserve = 0; - } - - if (preserve) { - info->reused = 1; - buf_sz = pcilib_kmem_get_block_size(ctx->pcilib, pages, 0); - } else { - info->reused = 0; - - memset(data, 0, PCILIB_NWL_DMA_PAGES * PCILIB_NWL_DMA_DESCRIPTOR_SIZE); - - for (i = 0; i < PCILIB_NWL_DMA_PAGES; i++, data += PCILIB_NWL_DMA_DESCRIPTOR_SIZE) { - buf_pa = pcilib_kmem_get_block_pa(ctx->pcilib, pages, i); - buf_sz = pcilib_kmem_get_block_size(ctx->pcilib, pages, i); - - NWL_RING_SET(data, DMA_BD_NDESC_OFFSET, ring_pa + ((i + 1) % PCILIB_NWL_DMA_PAGES) * PCILIB_NWL_DMA_DESCRIPTOR_SIZE); - NWL_RING_SET(data, DMA_BD_BUFAL_OFFSET, buf_pa&0xFFFFFFFF); - NWL_RING_SET(data, DMA_BD_BUFAH_OFFSET, buf_pa>>32); -#ifdef NWL_GENERATE_DMA_IRQ - NWL_RING_SET(data, DMA_BD_BUFL_CTRL_OFFSET, buf_sz | DMA_BD_INT_ERROR_MASK | DMA_BD_INT_COMP_MASK); -#else /* NWL_GENERATE_DMA_IRQ */ - NWL_RING_SET(data, DMA_BD_BUFL_CTRL_OFFSET, buf_sz); -#endif /* NWL_GENERATE_DMA_IRQ */ - } - - val = ring_pa; - nwl_write_register(val, ctx, base, REG_DMA_ENG_NEXT_BD); - nwl_write_register(val, ctx, base, REG_SW_NEXT_BD); - - info->head = 0; - info->tail = 0; - } - - info->ring = ring; - info->pages = pages; - info->page_size = buf_sz; - info->ring_size = PCILIB_NWL_DMA_PAGES; - - return 0; -} - - -static size_t dma_nwl_clean_buffers(nwl_dma_t * ctx, pcilib_nwl_engine_description_t *info) { - size_t res = 0; - uint32_t status; - - unsigned char *ring = pcilib_kmem_get_ua(ctx->pcilib, info->ring); - ring += info->tail * PCILIB_NWL_DMA_DESCRIPTOR_SIZE; - -next_buffer: - status = NWL_RING_GET(ring, DMA_BD_BUFL_STATUS_OFFSET)&DMA_BD_STATUS_MASK; -// control = NWL_RING_GET(ring, DMA_BD_BUFL_CTRL_OFFSET)&DMA_BD_CTRL_MASK; - - if (status & DMA_BD_ERROR_MASK) { - pcilib_error("NWL DMA Engine reported error in ring descriptor"); - return (size_t)-1; - } - - if (status & DMA_BD_SHORT_MASK) { - pcilib_error("NWL DMA Engine reported short error"); - return (size_t)-1; - } - - if (status & DMA_BD_COMP_MASK) { - info->tail++; - if (info->tail == info->ring_size) { - ring -= (info->tail - 1) * PCILIB_NWL_DMA_DESCRIPTOR_SIZE; - info->tail = 0; - } else { - ring += PCILIB_NWL_DMA_DESCRIPTOR_SIZE; - } - - res++; - - if (info->tail != info->head) goto next_buffer; - } - -// printf("====> Cleaned: %i\n", res); - return res; -} - - -static size_t dma_nwl_get_next_buffer(nwl_dma_t * ctx, pcilib_nwl_engine_description_t *info, size_t n_buffers, pcilib_timeout_t timeout) { - struct timeval start, cur; - - size_t res, n = 0; - size_t head; - - for (head = info->head; (((head + 1)%info->ring_size) != info->tail)&&(n < n_buffers); head++, n++); - if (n == n_buffers) return info->head; - - gettimeofday(&start, NULL); - - res = dma_nwl_clean_buffers(ctx, info); - if (res == (size_t)-1) return PCILIB_DMA_BUFFER_INVALID; - else n += res; - - - while (n < n_buffers) { - if (timeout != PCILIB_TIMEOUT_INFINITE) { - gettimeofday(&cur, NULL); - if (((cur.tv_sec - start.tv_sec)*1000000 + (cur.tv_usec - start.tv_usec)) > timeout) break; - } - - usleep (10); - - res = dma_nwl_clean_buffers(ctx, info); - if (res == (size_t)-1) return PCILIB_DMA_BUFFER_INVALID; - else if (res > 0) { - gettimeofday(&start, NULL); - n += res; - } - } - - if (n < n_buffers) return PCILIB_DMA_BUFFER_INVALID; - - return info->head; -} - -static int dma_nwl_push_buffer(nwl_dma_t *ctx, pcilib_nwl_engine_description_t *info, size_t size, int eop, pcilib_timeout_t timeout) { - int flags = 0; - - uint32_t val; - unsigned char *ring = pcilib_kmem_get_ua(ctx->pcilib, info->ring); - uint32_t ring_pa = pcilib_kmem_get_pa(ctx->pcilib, info->ring); - - ring += info->head * PCILIB_NWL_DMA_DESCRIPTOR_SIZE; - - - if (!info->writting) { - flags |= DMA_BD_SOP_MASK; - info->writting = 1; - } - if (eop) { - flags |= DMA_BD_EOP_MASK; - info->writting = 0; - } - - NWL_RING_SET(ring, DMA_BD_BUFL_CTRL_OFFSET, size|flags); - NWL_RING_SET(ring, DMA_BD_BUFL_STATUS_OFFSET, size); - - info->head++; - if (info->head == info->ring_size) info->head = 0; - - val = ring_pa + info->head * PCILIB_NWL_DMA_DESCRIPTOR_SIZE; - nwl_write_register(val, ctx, info->base_addr, REG_SW_NEXT_BD); - - return 0; -} - - -static size_t dma_nwl_wait_buffer(nwl_dma_t *ctx, pcilib_nwl_engine_description_t *info, size_t *size, int *eop, pcilib_timeout_t timeout) { - struct timeval start, cur; - uint32_t status_size, status; - - unsigned char *ring = pcilib_kmem_get_ua(ctx->pcilib, info->ring); - - ring += info->tail * PCILIB_NWL_DMA_DESCRIPTOR_SIZE; - - gettimeofday(&start, NULL); - - do { - status_size = NWL_RING_GET(ring, DMA_BD_BUFL_STATUS_OFFSET); - status = status_size & DMA_BD_STATUS_MASK; - - if (status & DMA_BD_ERROR_MASK) { - pcilib_error("NWL DMA Engine reported error in ring descriptor"); - return (size_t)-1; - } - - if (status & DMA_BD_COMP_MASK) { - if (status & DMA_BD_EOP_MASK) *eop = 1; - else *eop = 0; - - *size = status_size & DMA_BD_BUFL_MASK; - -/* - if (mrd) { - if ((info->tail + 1) == info->ring_size) ring -= info->tail * PCILIB_NWL_DMA_DESCRIPTOR_SIZE; - else ring += PCILIB_NWL_DMA_DESCRIPTOR_SIZE; - *mrd = NWL_RING_GET(ring, DMA_BD_BUFL_STATUS_OFFSET)&DMA_BD_COMP_MASK; - } -*/ - - return info->tail; - } - - usleep(10); - gettimeofday(&cur, NULL); - } while ((timeout == PCILIB_TIMEOUT_INFINITE)||(((cur.tv_sec - start.tv_sec)*1000000 + (cur.tv_usec - start.tv_usec)) < timeout)); - - return (size_t)-1; -} - -/* - // This function is not used now, but we may need it in the future -static int dma_nwl_is_overflown(nwl_dma_t *ctx, pcilib_nwl_engine_description_t *info) { - uint32_t status; - unsigned char *ring = pcilib_kmem_get_ua(ctx->pcilib, info->ring); - if (info->tail > 0) ring += (info->tail - 1) * PCILIB_NWL_DMA_DESCRIPTOR_SIZE; - else ring += (info->ring_size - 1) * PCILIB_NWL_DMA_DESCRIPTOR_SIZE; - - status = NWL_RING_GET(ring, DMA_BD_BUFL_STATUS_OFFSET); - return status&DMA_BD_COMP_MASK?1:0; -} -*/ - -static int dma_nwl_return_buffer(nwl_dma_t *ctx, pcilib_nwl_engine_description_t *info) { - uint32_t val; - - unsigned char *ring = pcilib_kmem_get_ua(ctx->pcilib, info->ring); - uint32_t ring_pa = pcilib_kmem_get_pa(ctx->pcilib, info->ring); - size_t bufsz = pcilib_kmem_get_block_size(ctx->pcilib, info->pages, info->tail); - - ring += info->tail * PCILIB_NWL_DMA_DESCRIPTOR_SIZE; - -#ifdef NWL_GENERATE_DMA_IRQ - NWL_RING_SET(ring, DMA_BD_BUFL_CTRL_OFFSET, bufsz | DMA_BD_INT_ERROR_MASK | DMA_BD_INT_COMP_MASK); -#else /* NWL_GENERATE_DMA_IRQ */ - NWL_RING_SET(ring, DMA_BD_BUFL_CTRL_OFFSET, bufsz); -#endif /* NWL_GENERATE_DMA_IRQ */ - - NWL_RING_SET(ring, DMA_BD_BUFL_STATUS_OFFSET, 0); - - val = ring_pa + info->tail * PCILIB_NWL_DMA_DESCRIPTOR_SIZE; - nwl_write_register(val, ctx, info->base_addr, REG_SW_NEXT_BD); - - info->tail++; - if (info->tail == info->ring_size) info->tail = 0; - - return 0; -} - -int dma_nwl_get_status(pcilib_dma_context_t *vctx, pcilib_dma_engine_t dma, pcilib_dma_engine_status_t *status, size_t n_buffers, pcilib_dma_buffer_status_t *buffers) { - size_t i; - uint32_t bstatus; - nwl_dma_t *ctx = (nwl_dma_t*)vctx; - pcilib_nwl_engine_description_t *info = ctx->engines + dma; - unsigned char *ring = (unsigned char*)pcilib_kmem_get_ua(ctx->pcilib, info->ring); - - - if (!status) return -1; - - status->started = info->started; - status->ring_size = info->ring_size; - status->buffer_size = info->page_size; - status->ring_tail = info->tail; - - if (info->desc.direction == PCILIB_DMA_FROM_DEVICE) { - size_t pos = 0; - for (i = 0; i < info->ring_size; i++) { - pos = status->ring_tail + i; - if (pos >= info->ring_size) pos -= info->ring_size; - - bstatus = NWL_RING_GET(ring + pos * PCILIB_NWL_DMA_DESCRIPTOR_SIZE, DMA_BD_BUFL_STATUS_OFFSET); - if ((bstatus&(DMA_BD_ERROR_MASK|DMA_BD_COMP_MASK)) == 0) break; - } - status->ring_head = pos; - } else { - status->ring_head = info->head; - } - - - if (buffers) { - for (i = 0; (i < info->ring_size)&&(i < n_buffers); i++) { - bstatus = NWL_RING_GET(ring, DMA_BD_BUFL_STATUS_OFFSET); - - buffers[i].error = bstatus & (DMA_BD_ERROR_MASK/*|DMA_BD_SHORT_MASK*/); - buffers[i].used = bstatus & DMA_BD_COMP_MASK; - buffers[i].size = bstatus & DMA_BD_BUFL_MASK; - buffers[i].first = bstatus & DMA_BD_SOP_MASK; - buffers[i].last = bstatus & DMA_BD_EOP_MASK; - - ring += PCILIB_NWL_DMA_DESCRIPTOR_SIZE; - } - } - - return 0; -} diff --git a/dma/nwl_irq.c b/dma/nwl_irq.c deleted file mode 100644 index e71c76a..0000000 --- a/dma/nwl_irq.c +++ /dev/null @@ -1,119 +0,0 @@ -#include <stdio.h> -#include <stdlib.h> -#include <string.h> -#include <unistd.h> -#include <sys/time.h> - -#include "pcilib.h" - -#include "pci.h" -#include "error.h" -#include "tools.h" - -#include "nwl_private.h" -#include "nwl_defines.h" - -int dma_nwl_init_irq(nwl_dma_t *ctx, uint32_t val) { - if (val&(DMA_INT_ENABLE|DMA_USER_INT_ENABLE)) { - if (val&DMA_INT_ENABLE) ctx->irq_preserve |= PCILIB_DMA_IRQ; - if (val&DMA_USER_INT_ENABLE) ctx->irq_preserve |= PCILIB_EVENT_IRQ; - } - - ctx->irq_started = 1; - return 0; -} - -int dma_nwl_free_irq(nwl_dma_t *ctx) { - if (ctx->irq_started) { - dma_nwl_disable_irq((pcilib_dma_context_t*)ctx, 0); - if (ctx->irq_preserve) dma_nwl_enable_irq((pcilib_dma_context_t*)ctx, ctx->irq_preserve, 0); - ctx->irq_enabled = 0; - ctx->irq_started = 0; - } - return 0; -} - -int dma_nwl_enable_irq(pcilib_dma_context_t *vctx, pcilib_irq_type_t type, pcilib_dma_flags_t flags) { - uint32_t val; - nwl_dma_t *ctx = (nwl_dma_t*)vctx; - - if (flags&PCILIB_DMA_FLAG_PERSISTENT) ctx->irq_preserve |= type; - - if ((ctx->irq_enabled&type) == type) return 0; - - type |= ctx->irq_enabled; - - nwl_read_register(val, ctx, ctx->base_addr, REG_DMA_CTRL_STATUS); - if (!ctx->irq_started) dma_nwl_init_irq(ctx, val); - - val &= ~(DMA_INT_ENABLE|DMA_USER_INT_ENABLE); - nwl_write_register(val, ctx, ctx->base_addr, REG_DMA_CTRL_STATUS); - - pcilib_clear_irq(ctx->pcilib, NWL_DMA_IRQ_SOURCE); - - if (type & PCILIB_DMA_IRQ) val |= DMA_INT_ENABLE; - if (type & PCILIB_EVENT_IRQ) val |= DMA_USER_INT_ENABLE; - nwl_write_register(val, ctx, ctx->base_addr, REG_DMA_CTRL_STATUS); - - ctx->irq_enabled = type; - - return 0; -} - - -int dma_nwl_disable_irq(pcilib_dma_context_t *vctx, pcilib_dma_flags_t flags) { - uint32_t val; - nwl_dma_t *ctx = (nwl_dma_t*)vctx; - - ctx->irq_enabled = 0; - - nwl_read_register(val, ctx, ctx->base_addr, REG_DMA_CTRL_STATUS); - if (!ctx->irq_started) dma_nwl_init_irq(ctx, val); - val &= ~(DMA_INT_ENABLE|DMA_USER_INT_ENABLE); - nwl_write_register(val, ctx, ctx->base_addr, REG_DMA_CTRL_STATUS); - - if (flags&PCILIB_DMA_FLAG_PERSISTENT) ctx->irq_preserve = 0; - - return 0; -} - - -int dma_nwl_enable_engine_irq(nwl_dma_t *ctx, pcilib_dma_engine_t dma) { - uint32_t val; - - dma_nwl_enable_irq((pcilib_dma_context_t*)ctx, PCILIB_DMA_IRQ, 0); - - nwl_read_register(val, ctx, ctx->engines[dma].base_addr, REG_DMA_ENG_CTRL_STATUS); - val |= (DMA_ENG_INT_ENABLE); - nwl_write_register(val, ctx, ctx->engines[dma].base_addr, REG_DMA_ENG_CTRL_STATUS); - - return 0; -} - -int dma_nwl_disable_engine_irq(nwl_dma_t *ctx, pcilib_dma_engine_t dma) { - uint32_t val; - - nwl_read_register(val, ctx, ctx->engines[dma].base_addr, REG_DMA_ENG_CTRL_STATUS); - val &= ~(DMA_ENG_INT_ENABLE); - nwl_write_register(val, ctx, ctx->engines[dma].base_addr, REG_DMA_ENG_CTRL_STATUS); - - return 0; -} - -int dma_nwl_acknowledge_irq(pcilib_dma_context_t *vctx, pcilib_irq_type_t irq_type, pcilib_irq_source_t irq_source) { - uint32_t val; - - nwl_dma_t *ctx = (nwl_dma_t*)vctx; - pcilib_nwl_engine_description_t *info = ctx->engines + irq_source; - - if (irq_type != PCILIB_DMA_IRQ) return PCILIB_ERROR_NOTSUPPORTED; - if (irq_source >= ctx->n_engines) return PCILIB_ERROR_NOTAVAILABLE; - - nwl_read_register(val, ctx, info->base_addr, REG_DMA_ENG_CTRL_STATUS); - if (val & DMA_ENG_INT_ACTIVE_MASK) { - val |= DMA_ENG_ALLINT_MASK; - nwl_write_register(val, ctx, info->base_addr, REG_DMA_ENG_CTRL_STATUS); - } - - return 0; -} diff --git a/dma/nwl_irq.h b/dma/nwl_irq.h deleted file mode 100644 index 811b632..0000000 --- a/dma/nwl_irq.h +++ /dev/null @@ -1,10 +0,0 @@ -#ifndef _PCILIB_NWL_IRQ_H -#define _PCILIB_NWL_IRQ_H - -int dma_nwl_init_irq(nwl_dma_t *ctx, uint32_t val); -int dma_nwl_free_irq(nwl_dma_t *ctx); - -int dma_nwl_enable_engine_irq(nwl_dma_t *ctx, pcilib_dma_engine_t dma); -int dma_nwl_disable_engine_irq(nwl_dma_t *ctx, pcilib_dma_engine_t dma); - -#endif /* _PCILIB_NWL_IRQ_H */ diff --git a/dma/nwl_loopback.c b/dma/nwl_loopback.c deleted file mode 100644 index 381a462..0000000 --- a/dma/nwl_loopback.c +++ /dev/null @@ -1,255 +0,0 @@ -#define _BSD_SOURCE -#include <stdio.h> -#include <stdlib.h> -#include <string.h> -#include <unistd.h> -#include <sys/time.h> - -#include "pci.h" -#include "pcilib.h" -#include "error.h" -#include "tools.h" -#include "nwl_private.h" - -#include "nwl_defines.h" - -#define NWL_BUG_EXTRA_DATA - - -int dma_nwl_start_loopback(nwl_dma_t *ctx, pcilib_dma_direction_t direction, size_t packet_size) { - uint32_t val; - - ctx->loopback_started = 1; - dma_nwl_stop_loopback(ctx); - - val = packet_size; - nwl_write_register(val, ctx, ctx->base_addr, PKT_SIZE_ADDRESS); - - if (ctx->type == PCILIB_DMA_MODIFICATION_DEFAULT) { - switch (direction) { - case PCILIB_DMA_BIDIRECTIONAL: - val = LOOPBACK; - nwl_write_register(val, ctx, ctx->base_addr, TX_CONFIG_ADDRESS); - break; - case PCILIB_DMA_TO_DEVICE: - return -1; - case PCILIB_DMA_FROM_DEVICE: - val = PKTGENR; - nwl_write_register(val, ctx, ctx->base_addr, RX_CONFIG_ADDRESS); - break; - } - } - - ctx->loopback_started = 1; - - return 0; -} - -int dma_nwl_stop_loopback(nwl_dma_t *ctx) { - uint32_t val = 0; - - if (!ctx->loopback_started) return 0; - - /* Stop in any case, otherwise we can have problems in benchmark due to - engine initialized in previous run, and benchmark is only actual usage. - Otherwise, we should detect current loopback status during initialization */ - - if (ctx->type == PCILIB_DMA_MODIFICATION_DEFAULT) { - nwl_write_register(val, ctx, ctx->base_addr, TX_CONFIG_ADDRESS); - nwl_write_register(val, ctx, ctx->base_addr, RX_CONFIG_ADDRESS); - } - - ctx->loopback_started = 0; - - return 0; -} - -double dma_nwl_benchmark(pcilib_dma_context_t *vctx, pcilib_dma_engine_addr_t dma, uintptr_t addr, size_t size, size_t iterations, pcilib_dma_direction_t direction) { - int iter, i; - int err; - size_t bytes, rbytes; - uint32_t *buf, *cmp; - const char *error = NULL; - size_t packet_size, blocks; - - size_t us = 0; - struct timeval start, cur; - - nwl_dma_t *ctx = (nwl_dma_t*)vctx; - - pcilib_dma_engine_t readid = pcilib_find_dma_by_addr(ctx->pcilib, PCILIB_DMA_FROM_DEVICE, dma); - pcilib_dma_engine_t writeid = pcilib_find_dma_by_addr(ctx->pcilib, PCILIB_DMA_TO_DEVICE, dma); - - if (size%sizeof(uint32_t)) size = 1 + size / sizeof(uint32_t); - else size /= sizeof(uint32_t); - - // Not supported - if (ctx->type == PCILIB_DMA_MODIFICATION_DEFAULT) { - if (direction == PCILIB_DMA_TO_DEVICE) return -1.; - } -// else if ((direction == PCILIB_DMA_FROM_DEVICE)&&(ctx->type != PCILIB_DMA_MODIFICATION_DEFAULT)) return -1.; - - // Stop Generators and drain old data - if (ctx->type == PCILIB_DMA_MODIFICATION_DEFAULT) dma_nwl_stop_loopback(ctx); -// dma_nwl_stop_engine(ctx, readid); // DS: replace with something better - - __sync_synchronize(); - - err = pcilib_skip_dma(ctx->pcilib, readid); - if (err) { - pcilib_error("Can't start benchmark, devices continuously writes unexpected data using DMA engine"); - return -1; - } - -#ifdef NWL_GENERATE_DMA_IRQ - dma_nwl_enable_engine_irq(ctx, readid); - dma_nwl_enable_engine_irq(ctx, writeid); -#endif /* NWL_GENERATE_DMA_IRQ */ - - if (size * sizeof(uint32_t) > NWL_MAX_PACKET_SIZE) { - packet_size = NWL_MAX_PACKET_SIZE; - blocks = (size * sizeof(uint32_t)) / packet_size + (((size*sizeof(uint32_t))%packet_size)?1:0); - } else { - packet_size = size * sizeof(uint32_t); - blocks = 1; - } - - dma_nwl_start_loopback(ctx, direction, packet_size); - - // Allocate memory and prepare data - buf = malloc(blocks * packet_size * sizeof(uint32_t)); - cmp = malloc(blocks * packet_size * sizeof(uint32_t)); - if ((!buf)||(!cmp)) { - if (buf) free(buf); - if (cmp) free(cmp); - return -1; - } - - if (ctx->type == PCILIB_NWL_MODIFICATION_IPECAMERA) { - pcilib_write_register(ctx->pcilib, NULL, "control", 0x1e5); - usleep(100000); - pcilib_write_register(ctx->pcilib, NULL, "control", 0x1e1); - - // This way causes more problems with garbage - //pcilib_write_register(ctx->pcilib, NULL, "control", 0x3e1); - } - - // Benchmark - for (iter = 0; iter < iterations; iter++) { - memset(cmp, 0x13 + iter, size * sizeof(uint32_t)); - - if (ctx->type == PCILIB_NWL_MODIFICATION_IPECAMERA) { - pcilib_write_register(ctx->pcilib, NULL, "control", 0x1e1); - } - - if ((direction&PCILIB_DMA_TO_DEVICE)||(ctx->type != PCILIB_DMA_MODIFICATION_DEFAULT)) { - memcpy(buf, cmp, size * sizeof(uint32_t)); - - if (direction&PCILIB_DMA_TO_DEVICE) { - gettimeofday(&start, NULL); - } - - err = pcilib_write_dma(ctx->pcilib, writeid, addr, size * sizeof(uint32_t), buf, &bytes); - if ((err)||(bytes != size * sizeof(uint32_t))) { - error = "Write failed"; - break; - } - - if (direction&PCILIB_DMA_TO_DEVICE) { - // wait written - if (direction == PCILIB_DMA_TO_DEVICE) { - dma_nwl_wait_completion(ctx, writeid, PCILIB_DMA_TIMEOUT); - } - gettimeofday(&cur, NULL); - us += ((cur.tv_sec - start.tv_sec)*1000000 + (cur.tv_usec - start.tv_usec)); - } - } - - if (ctx->type == PCILIB_NWL_MODIFICATION_IPECAMERA) { - pcilib_write_register(ctx->pcilib, NULL, "control", 0x3e1); - } - - memset(buf, 0, size * sizeof(uint32_t)); - - if (direction&PCILIB_DMA_FROM_DEVICE) { - gettimeofday(&start, NULL); - } - - for (i = 0, bytes = 0; i < blocks; i++) { -#ifdef NWL_BUG_EXTRA_DATA - retry: -#endif - - err = pcilib_read_dma(ctx->pcilib, readid, addr, packet_size * sizeof(uint32_t), buf + (bytes>>2), &rbytes); - if ((err)||(rbytes%sizeof(uint32_t))) { - break; - } -#ifdef NWL_BUG_EXTRA_DATA - else if (rbytes == 8) { - goto retry; - } -#endif - bytes += rbytes; - } - - if (direction&PCILIB_DMA_FROM_DEVICE) { - gettimeofday(&cur, NULL); - us += ((cur.tv_sec - start.tv_sec)*1000000 + (cur.tv_usec - start.tv_usec)); - } -#ifdef NWL_BUG_EXTRA_DATA - if ((err)||((bytes != size * sizeof(uint32_t))&&((bytes - 8) != size * sizeof(uint32_t)))) { -#else - if ((err)||(bytes != size * sizeof(uint32_t))) { -#endif - printf("Expected: %zu bytes, but %zu read, error: %i\n", size * sizeof(uint32_t), bytes, err); - error = "Read failed"; - break; - } - -#ifndef NWL_BUG_EXTRA_DATA - if (direction == PCILIB_DMA_BIDIRECTIONAL) { - if (memcmp(buf, cmp, size * sizeof(uint32_t))) { - for (i = 0; i < size; i++) - if (buf[i] != cmp[i]) break; - - bytes = i; - printf("Expected: *0x%lx, Written at dword %lu:", 0x13 + iter, bytes); - for (; (i < size)&&(i < (bytes + 16)); i++) { - if (((i - bytes)%8)==0) printf("\n"); - printf("% 10lx", buf[i]); - } - printf("\n"); - - error = "Written and read values does not match"; - break; - } - } -#endif - } - - if (ctx->type == PCILIB_NWL_MODIFICATION_IPECAMERA) { - pcilib_write_register(ctx->pcilib, NULL, "control", 0x1e1); - } - - if (error) { - pcilib_warning("%s at iteration %i, error: %i, bytes: %zu", error, iter, err, bytes); - } - -#ifdef NWL_GENERATE_DMA_IRQ - dma_nwl_disable_engine_irq(ctx, writeid); - dma_nwl_disable_engine_irq(ctx, readid); -#endif /* NWL_GENERATE_DMA_IRQ */ - - dma_nwl_stop_loopback(ctx); - - __sync_synchronize(); - - if (direction == PCILIB_DMA_FROM_DEVICE) { - pcilib_skip_dma(ctx->pcilib, readid); - } - - free(cmp); - free(buf); - - return /*error?-1:*/(1. * size * sizeof(uint32_t) * iterations * 1000000) / (1024. * 1024. * us); -} diff --git a/dma/nwl_loopback.h b/dma/nwl_loopback.h deleted file mode 100644 index 63c8446..0000000 --- a/dma/nwl_loopback.h +++ /dev/null @@ -1,7 +0,0 @@ -#ifndef _PCILIB_NWL_LOOPBACK_H -#define _PCILIB_NWL_LOOPBACK_H - -int dma_nwl_start_loopback(nwl_dma_t *ctx, pcilib_dma_direction_t direction, size_t packet_size); -int dma_nwl_stop_loopback(nwl_dma_t *ctx); - -#endif /* _PCILIB_NWL_LOOPBACK_H */ diff --git a/dma/nwl_private.h b/dma/nwl_private.h deleted file mode 100644 index 756e6ca..0000000 --- a/dma/nwl_private.h +++ /dev/null @@ -1,67 +0,0 @@ -#ifndef _PCILIB_DMA_NWL_PRIVATE_H -#define _PCILIB_DMA_NWL_PRIVATE_H - -typedef struct nwl_dma_s nwl_dma_t; -typedef struct pcilib_nwl_engine_description_s pcilib_nwl_engine_description_t; - -#define NWL_DMA_IRQ_SOURCE 0 - -#define NWL_XAUI_ENGINE 0 -#define NWL_XRAWDATA_ENGINE 1 -#define NWL_MAX_PACKET_SIZE 4096 //16384 -//#define NWL_GENERATE_DMA_IRQ - -#define PCILIB_NWL_ALIGNMENT 64 // in bytes -#define PCILIB_NWL_DMA_DESCRIPTOR_SIZE 64 // in bytes -#define PCILIB_NWL_DMA_PAGES 256 // 1024 - -//#define DEBUG_HARDWARE -//#define DEBUG_NWL - -#include "nwl.h" -#include "nwl_irq.h" -#include "nwl_register.h" -#include "nwl_engine.h" -#include "nwl_loopback.h" - -#define nwl_read_register(var, ctx, base, reg) pcilib_datacpy(&var, base + reg, 4, 1, ctx->dma_bank->raw_endianess) -#define nwl_write_register(var, ctx, base, reg) pcilib_datacpy(base + reg, &var, 4, 1, ctx->dma_bank->raw_endianess) - -struct pcilib_nwl_engine_description_s { - pcilib_dma_engine_description_t desc; - char *base_addr; - - size_t ring_size, page_size; - size_t head, tail; - pcilib_kmem_handle_t *ring; - pcilib_kmem_handle_t *pages; - - int started; /**< indicates that DMA buffers are initialized and reading is allowed */ - int writting; /**< indicates that we are in middle of writting packet */ - int reused; /**< indicates that DMA was found intialized, buffers were reused, and no additional initialization is needed */ - int preserve; /**< indicates that DMA should not be stopped during clean-up */ -}; - - -struct nwl_dma_s { - struct pcilib_dma_context_s dmactx; - - pcilib_t *pcilib; - - pcilib_dma_modification_t type; - - pcilib_register_bank_description_t *dma_bank; - char *base_addr; - - pcilib_irq_type_t irq_enabled; /**< indicates that IRQs are enabled */ - pcilib_irq_type_t irq_preserve; /**< indicates that IRQs should not be disabled during clean-up */ - int started; /**< indicates that DMA subsystem is initialized and DMA engine can start */ - int irq_started; /**< indicates that IRQ subsystem is initialized (detecting which types should be preserverd) */ - int loopback_started; /**< indicates that benchmarking subsystem is initialized */ - - pcilib_dma_engine_t n_engines; - pcilib_nwl_engine_description_t engines[PCILIB_MAX_DMA_ENGINES + 1]; -}; - - -#endif /* _PCILIB_DMA_NWL_PRIVATE_H */ diff --git a/dma/nwl_register.c b/dma/nwl_register.c deleted file mode 100644 index 6a3771a..0000000 --- a/dma/nwl_register.c +++ /dev/null @@ -1,77 +0,0 @@ -#define _PCILIB_NWL_REGISTER_C - -#include <stdio.h> -#include <stdlib.h> -#include <string.h> -#include <unistd.h> -#include <sys/time.h> - -#include "pcilib.h" - -#include "pci.h" -#include "error.h" -#include "tools.h" - -#include "nwl_private.h" -#include "nwl_register.h" - -int nwl_add_registers(nwl_dma_t *ctx) { - int err; - size_t n, i, j; - int length; - const char *names[NWL_MAX_DMA_ENGINE_REGISTERS]; - uintptr_t addr[NWL_MAX_DMA_ENGINE_REGISTERS]; - - // We don't want DMA registers - if (pcilib_find_bank_by_addr(ctx->pcilib, PCILIB_REGISTER_BANK_DMA) == PCILIB_REGISTER_BANK_INVALID) return 0; - - err = pcilib_add_registers(ctx->pcilib, 0, nwl_dma_registers); - if (err) return err; - - if (ctx->type == PCILIB_DMA_MODIFICATION_DEFAULT) { - err = pcilib_add_registers(ctx->pcilib, 0, nwl_xrawdata_registers); - if (err) return err; - } - - - for (n = 0; nwl_dma_engine_registers[n].bits; n++) { - names[n] = nwl_dma_engine_registers[n].name; - addr[n] = nwl_dma_engine_registers[n].addr; - } - - if (ctx->n_engines > 9) length = 2; - else length = 1; - - - for (i = 0; i < ctx->n_engines; i++) { - for (j = 0; nwl_dma_engine_registers[j].bits; j++) { - const char *direction; - nwl_dma_engine_registers[j].name = nwl_dma_engine_register_names[i * NWL_MAX_DMA_ENGINE_REGISTERS + j]; - nwl_dma_engine_registers[j].addr = addr[j] + (ctx->engines[i].base_addr - ctx->base_addr); -// printf("%lx %lx\n", (ctx->engines[i].base_addr - ctx->base_addr), nwl_dma_engine_registers[j].addr); - - switch (ctx->engines[i].desc.direction) { - case PCILIB_DMA_FROM_DEVICE: - direction = "r"; - break; - case PCILIB_DMA_TO_DEVICE: - direction = "w"; - break; - default: - direction = ""; - } - - sprintf((char*)nwl_dma_engine_registers[j].name, names[j], length, ctx->engines[i].desc.addr, direction); - } - - err = pcilib_add_registers(ctx->pcilib, n, nwl_dma_engine_registers); - if (err) return err; - } - - for (n = 0; nwl_dma_engine_registers[n].bits; n++) { - nwl_dma_engine_registers[n].name = names[n]; - nwl_dma_engine_registers[n].addr = addr[n]; - } - - return 0; -} diff --git a/dma/nwl_register.h b/dma/nwl_register.h deleted file mode 100644 index a71942b..0000000 --- a/dma/nwl_register.h +++ /dev/null @@ -1,97 +0,0 @@ -#ifndef _PCILIB_NWL_REGISTERS_H -#define _PCILIB_NWL_REGISTERS_H - -#ifdef _PCILIB_NWL_REGISTER_C - // DMA -static pcilib_register_description_t nwl_dma_registers[] = { - {0x4000, 0, 32, 0, 0x00000011, PCILIB_REGISTER_RW , PCILIB_REGISTER_STANDARD, PCILIB_REGISTER_BANK_DMA, "dma_control_and_status", ""}, - {0x4000, 0, 1, 0, 0x00000011, PCILIB_REGISTER_RW , PCILIB_REGISTER_BITS, PCILIB_REGISTER_BANK_DMA, "dma_interrupt_enable", ""}, - {0x4000, 1, 1, 0, 0x00000011, PCILIB_REGISTER_R , PCILIB_REGISTER_BITS, PCILIB_REGISTER_BANK_DMA, "dma_interrupt_active", ""}, - {0x4000, 2, 1, 0, 0x00000011, PCILIB_REGISTER_R , PCILIB_REGISTER_BITS, PCILIB_REGISTER_BANK_DMA, "dma_interrupt_pending", ""}, - {0x4000, 3, 1, 0, 0x00000011, PCILIB_REGISTER_R , PCILIB_REGISTER_BITS, PCILIB_REGISTER_BANK_DMA, "dma_interrupt_mode", ""}, - {0x4000, 4, 1, 0, 0x00000011, PCILIB_REGISTER_RW , PCILIB_REGISTER_BITS, PCILIB_REGISTER_BANK_DMA, "dma_user_interrupt_enable", ""}, - {0x4000, 5, 1, 0, 0x00000011, PCILIB_REGISTER_RW1C, PCILIB_REGISTER_BITS, PCILIB_REGISTER_BANK_DMA, "dma_user_interrupt_active", ""}, - {0x4000, 16, 8, 0, 0x00000000, PCILIB_REGISTER_R , PCILIB_REGISTER_BITS, PCILIB_REGISTER_BANK_DMA, "dma_s2c_interrupt_status", ""}, - {0x4000, 24, 8, 0, 0x00000000, PCILIB_REGISTER_R , PCILIB_REGISTER_BITS, PCILIB_REGISTER_BANK_DMA, "dma_c2s_interrupt_status", ""}, - {0x8000, 0, 32, 0, 0x00000000, PCILIB_REGISTER_R , PCILIB_REGISTER_STANDARD, PCILIB_REGISTER_BANK_DMA, "dma_design_version", ""}, - {0x8000, 0, 4, 0, 0x00000000, PCILIB_REGISTER_R , PCILIB_REGISTER_BITS, PCILIB_REGISTER_BANK_DMA, "dma_subversion_number", ""}, - {0x8000, 4, 8, 0, 0x00000000, PCILIB_REGISTER_R , PCILIB_REGISTER_BITS, PCILIB_REGISTER_BANK_DMA, "dma_version_number", ""}, - {0x8000, 28, 4, 0, 0x00000000, PCILIB_REGISTER_R , PCILIB_REGISTER_BITS, PCILIB_REGISTER_BANK_DMA, "dma_targeted_device", ""}, - {0x8200, 0, 32, 0, 0x00000000, PCILIB_REGISTER_R , PCILIB_REGISTER_STANDARD, PCILIB_REGISTER_BANK_DMA, "dma_transmit_utilization", ""}, - {0x8200, 0, 2, 0, 0x00000000, PCILIB_REGISTER_R , PCILIB_REGISTER_BITS, PCILIB_REGISTER_BANK_DMA, "dma_transmit_sample_count", ""}, - {0x8200, 2, 30, 0, 0x00000000, PCILIB_REGISTER_R , PCILIB_REGISTER_BITS, PCILIB_REGISTER_BANK_DMA, "dma_transmit_dword_count", ""}, - {0x8204, 0, 32, 0, 0x00000000, PCILIB_REGISTER_R , PCILIB_REGISTER_STANDARD, PCILIB_REGISTER_BANK_DMA, "dma_receive_utilization", ""}, - {0x8004, 0, 2, 0, 0x00000000, PCILIB_REGISTER_R , PCILIB_REGISTER_BITS, PCILIB_REGISTER_BANK_DMA, "dma_receive_sample_count", ""}, - {0x8004, 2, 30, 0, 0x00000000, PCILIB_REGISTER_R , PCILIB_REGISTER_BITS, PCILIB_REGISTER_BANK_DMA, "dma_receive_dword_count", ""}, - {0x8208, 0, 32, 0, 0x00000000, PCILIB_REGISTER_R , PCILIB_REGISTER_STANDARD, PCILIB_REGISTER_BANK_DMA, "dma_mwr", ""}, - {0x8008, 0, 2, 0, 0x00000000, PCILIB_REGISTER_R , PCILIB_REGISTER_BITS, PCILIB_REGISTER_BANK_DMA, "dma_mwr_sample_count", ""}, - {0x8008, 2, 30, 0, 0x00000000, PCILIB_REGISTER_R , PCILIB_REGISTER_BITS, PCILIB_REGISTER_BANK_DMA, "dma_mwr_dword_count", ""}, - {0x820C, 0, 32, 0, 0x00000000, PCILIB_REGISTER_R , PCILIB_REGISTER_STANDARD, PCILIB_REGISTER_BANK_DMA, "dma_cpld", ""}, - {0x820C, 0, 2, 0, 0x00000000, PCILIB_REGISTER_R , PCILIB_REGISTER_BITS, PCILIB_REGISTER_BANK_DMA, "dma_cpld_sample_count", ""}, - {0x820C, 2, 30, 0, 0x00000000, PCILIB_REGISTER_R , PCILIB_REGISTER_BITS, PCILIB_REGISTER_BANK_DMA, "dma_cpld_dword_count", ""}, - {0x8210, 0, 12, 0, 0x00000000, PCILIB_REGISTER_R , PCILIB_REGISTER_STANDARD, PCILIB_REGISTER_BANK_DMA, "dma_init_fc_cpld", ""}, - {0x8214, 0, 8, 0, 0x00000000, PCILIB_REGISTER_R , PCILIB_REGISTER_STANDARD, PCILIB_REGISTER_BANK_DMA, "dma_init_fc_cplh", ""}, - {0x8218, 0, 12, 0, 0x00000000, PCILIB_REGISTER_R , PCILIB_REGISTER_STANDARD, PCILIB_REGISTER_BANK_DMA, "dma_init_fc_npd", ""}, - {0x821C, 0, 8, 0, 0x00000000, PCILIB_REGISTER_R , PCILIB_REGISTER_STANDARD, PCILIB_REGISTER_BANK_DMA, "dma_init_fc_nph", ""}, - {0x8220, 0, 12, 0, 0x00000000, PCILIB_REGISTER_R , PCILIB_REGISTER_STANDARD, PCILIB_REGISTER_BANK_DMA, "dma_init_fc_pd", ""}, - {0x8224, 0, 8, 0, 0x00000000, PCILIB_REGISTER_R , PCILIB_REGISTER_STANDARD, PCILIB_REGISTER_BANK_DMA, "dma_init_fc_ph", ""}, - {0, 0, 0, 0, 0x00000000, 0, 0, 0, NULL, NULL} -}; - - // DMA Engine Registers -#define NWL_MAX_DMA_ENGINE_REGISTERS 64 -#define NWL_MAX_REGISTER_NAME 128 -static char nwl_dma_engine_register_names[PCILIB_MAX_DMA_ENGINES * NWL_MAX_DMA_ENGINE_REGISTERS][NWL_MAX_REGISTER_NAME]; -static pcilib_register_description_t nwl_dma_engine_registers[] = { - {0x0000, 0, 32, 0, 0x00000000, PCILIB_REGISTER_R , PCILIB_REGISTER_STANDARD, PCILIB_REGISTER_BANK_DMA, "dma%0*u%s_engine_capabilities", ""}, - {0x0000, 0, 1, 0, 0x00000000, PCILIB_REGISTER_R , PCILIB_REGISTER_BITS, PCILIB_REGISTER_BANK_DMA, "dma%0*u%s_present", ""}, - {0x0000, 1, 1, 0, 0x00000000, PCILIB_REGISTER_R , PCILIB_REGISTER_BITS, PCILIB_REGISTER_BANK_DMA, "dma%0*u%s_direction", ""}, - {0x0000, 4, 2, 0, 0x00000000, PCILIB_REGISTER_R , PCILIB_REGISTER_BITS, PCILIB_REGISTER_BANK_DMA, "dma%0*u%s_type", ""}, - {0x0000, 8, 8, 0, 0x00000000, PCILIB_REGISTER_R , PCILIB_REGISTER_BITS, PCILIB_REGISTER_BANK_DMA, "dma%0*u%s_number", ""}, - {0x0000, 24, 6, 0, 0x00000000, PCILIB_REGISTER_R , PCILIB_REGISTER_BITS, PCILIB_REGISTER_BANK_DMA, "dma%0*u%s_max_buffer_size", ""}, - {0x0004, 0, 32, 0, 0x0000C100, PCILIB_REGISTER_RW , PCILIB_REGISTER_STANDARD, PCILIB_REGISTER_BANK_DMA, "dma%0*u%s_engine_control", ""}, - {0x0004, 0, 1, 0, 0x0000C100, PCILIB_REGISTER_R , PCILIB_REGISTER_BITS, PCILIB_REGISTER_BANK_DMA, "dma%0*u%s_interrupt_enable", ""}, - {0x0004, 1, 1, 0, 0x0000C100, PCILIB_REGISTER_RW1C, PCILIB_REGISTER_BITS, PCILIB_REGISTER_BANK_DMA, "dma%0*u%s_interrupt_active", ""}, - {0x0004, 2, 1, 0, 0x0000C100, PCILIB_REGISTER_RW1C, PCILIB_REGISTER_BITS, PCILIB_REGISTER_BANK_DMA, "dma%0*u%s_descriptor_complete", ""}, - {0x0004, 3, 1, 0, 0x0000C100, PCILIB_REGISTER_RW1C, PCILIB_REGISTER_BITS, PCILIB_REGISTER_BANK_DMA, "dma%0*u%s_descriptor_alignment_error", ""}, - {0x0004, 4, 1, 0, 0x0000C100, PCILIB_REGISTER_RW1C, PCILIB_REGISTER_BITS, PCILIB_REGISTER_BANK_DMA, "dma%0*u%s_descriptor_fetch_error", ""}, - {0x0004, 5, 1, 0, 0x0000C100, PCILIB_REGISTER_RW1C, PCILIB_REGISTER_BITS, PCILIB_REGISTER_BANK_DMA, "dma%0*u%s_sw_abort_error", ""}, - {0x0004, 8, 1, 0, 0x0000C100, PCILIB_REGISTER_RW , PCILIB_REGISTER_BITS, PCILIB_REGISTER_BANK_DMA, "dma%0*u%s_enable", ""}, - {0x0004, 10, 1, 0, 0x0000C100, PCILIB_REGISTER_R , PCILIB_REGISTER_BITS, PCILIB_REGISTER_BANK_DMA, "dma%0*u%s_running", ""}, - {0x0004, 11, 1, 0, 0x0000C100, PCILIB_REGISTER_R , PCILIB_REGISTER_BITS, PCILIB_REGISTER_BANK_DMA, "dma%0*u%s_waiting", ""}, - {0x0004, 14, 1, 0, 0x0000C100, PCILIB_REGISTER_RW , PCILIB_REGISTER_BITS, PCILIB_REGISTER_BANK_DMA, "dma%0*u%s_reset_request", ""}, - {0x0004, 15, 1, 0, 0x0000C100, PCILIB_REGISTER_W , PCILIB_REGISTER_BITS, PCILIB_REGISTER_BANK_DMA, "dma%0*u%s_reset", ""}, - {0x0008, 0, 32, 0, 0x00000000, PCILIB_REGISTER_RW , PCILIB_REGISTER_STANDARD, PCILIB_REGISTER_BANK_DMA, "dma%0*u%s_next_descriptor", ""}, - {0x000C, 0, 32, 0, 0x00000000, PCILIB_REGISTER_RW , PCILIB_REGISTER_STANDARD, PCILIB_REGISTER_BANK_DMA, "dma%0*u%s_sw_descriptor", ""}, - {0x0010, 0, 32, 0, 0x00000000, PCILIB_REGISTER_R , PCILIB_REGISTER_STANDARD, PCILIB_REGISTER_BANK_DMA, "dma%0*u%s_last_descriptor", ""}, - {0x0014, 0, 32, 0, 0x00000000, PCILIB_REGISTER_R , PCILIB_REGISTER_STANDARD, PCILIB_REGISTER_BANK_DMA, "dma%0*u%s_active_time", ""}, - {0x0018, 0, 32, 0, 0x00000000, PCILIB_REGISTER_R , PCILIB_REGISTER_STANDARD, PCILIB_REGISTER_BANK_DMA, "dma%0*u%s_wait_time", ""}, - {0x001C, 0, 32, 0, 0x00000000, PCILIB_REGISTER_R , PCILIB_REGISTER_STANDARD, PCILIB_REGISTER_BANK_DMA, "dma%0*u%s_counter", ""}, - {0x001C, 0, 2, 0, 0x00000000, PCILIB_REGISTER_R , PCILIB_REGISTER_BITS, PCILIB_REGISTER_BANK_DMA, "dma%0*u%s_sample_count", ""}, - {0x001C, 2, 30, 0, 0x00000000, PCILIB_REGISTER_R , PCILIB_REGISTER_BITS, PCILIB_REGISTER_BANK_DMA, "dma%0*u%s_dword_count", ""}, - {0, 0, 0, 0, 0x00000000, 0, 0, 0, NULL, NULL} -}; - -/* - // XAUI registers -static pcilib_register_description_t nwl_xaui_registers[] = { - {0, 0, 0, 0, 0, 0, 0, NULL, NULL} -}; -*/ - - // XRAWDATA registers -static pcilib_register_description_t nwl_xrawdata_registers[] = { - {0x9100, 0, 1, 0, 0x00000000, PCILIB_REGISTER_RW, PCILIB_REGISTER_STANDARD, PCILIB_REGISTER_BANK_DMA, "xrawdata_enable_generator", ""}, - {0x9104, 0, 16, 0, 0x00000000, PCILIB_REGISTER_RW, PCILIB_REGISTER_STANDARD, PCILIB_REGISTER_BANK_DMA, "xrawdata_packet_length", ""}, - {0x9108, 0, 2, 0, 0x00000003, PCILIB_REGISTER_RW, PCILIB_REGISTER_STANDARD, PCILIB_REGISTER_BANK_DMA, "xrawdata_control", ""}, - {0x9108, 0, 1, 0, 0x00000003, PCILIB_REGISTER_RW, PCILIB_REGISTER_BITS, PCILIB_REGISTER_BANK_DMA, "xrawdata_enable_checker", ""}, - {0x9108, 1, 1, 0, 0x00000003, PCILIB_REGISTER_RW, PCILIB_REGISTER_BITS, PCILIB_REGISTER_BANK_DMA, "xrawdata_enable_loopback", ""}, - {0x910C, 0, 1, 0, 0x00000000, PCILIB_REGISTER_R , PCILIB_REGISTER_STANDARD, PCILIB_REGISTER_BANK_DMA, "xrawdata_data_mistmatch", ""}, - {0, 0, 0, 0, 0x00000000, 0, 0, 0, NULL, NULL} -}; - -#endif /* _PCILIB_NWL_REGISTERS_C */ - -int nwl_add_registers(nwl_dma_t *ctx); - -#endif /* _PCILIB_NWL_REGISTERS_H */ diff --git a/driver/Makefile b/driver/Makefile deleted file mode 100644 index e353228..0000000 --- a/driver/Makefile +++ /dev/null @@ -1,49 +0,0 @@ - -obj-m := pciDriver.o -pciDriver-objs := base.o int.o umem.o kmem.o sysfs.o ioctl.o - -KERNELDIR ?= /lib/modules/$(shell uname -r)/build -INSTALLDIR ?= /lib/modules/$(shell uname -r)/extra -PWD := $(shell pwd) - -EXTRA_CFLAGS += -I$(M)/.. - -default: - @KERNEL_GCC_VERSION=`cat /proc/version | head -n1 | cut -d " " -f 7` ;\ - GCC_VERSION=`$(CC) --version | head -n 1 | tr ' ' '\n' | grep -e "[0-9]\+\.[0-9]" | tail -n 1` ;\ - if [ $$KERNEL_GCC_VERSION != $$GCC_VERSION ]; then \ - echo "Kernel is compiled with gcc $$KERNEL_GCC_VERSION, but you are now using $$GCC_VERSION" ;\ - GCC_MAJOR=`echo $$KERNEL_GCC_VERSION | cut -d "." -f 1-2` ;\ - newCC=gcc-$$GCC_MAJOR ;\ - CC=`which $$newCC 2>/dev/null` ;\ - if [ $$? -ne 0 ]; then \ - echo "No compiler of $$GCC_MAJOR series is installed" ;\ - exit 1 ;\ - fi ;\ - GCC_VERSION=`$$CC --version | head -n 1 | tr ' ' '\n' | grep -e "[0-9]\+\.[0-9]" | head -n 1` ;\ - if [ $$KERNEL_GCC_VERSION != $$GCC_VERSION ]; then \ - echo "The $$GCC_VERSION of $$GCC_MAJOR series is installed" ;\ - exit 1 ;\ - fi ;\ - echo "Setting CC to $$newCC" ;\ - else \ - CC=$(CC) ;\ - fi ;\ - $(MAKE) $(CFLAGS) -C $(KERNELDIR) M=$(PWD) CC=$$CC modules - -install: - @mkdir -p $(INSTALLDIR) - @echo "INSTALL $(INSTALLDIR)/pciDriver.ko" - @install -m 755 pciDriver.ko $(INSTALLDIR) - @echo "INSTALL /usr/include/pciDriver/driver/pciDriver.h" - @mkdir -p /usr/include/pciDriver/driver - @install -m 644 pciDriver.h /usr/include/pciDriver/driver - -uninstall: - @echo "UNINSTALL $(INSTALLDIR)/pciDriver.ko" - @rm -f $(INSTALLDIR)/pciDriver.ko - @echo "UNINSTALL /usr/include/pciDriver/driver/pciDriver.h" - @rm -rf /usr/include/pciDriver/driver - -clean: - rm -rf *.o *.ko *.mod.c .*.o.cmd .*.o.tmp .*.ko.cmd .*.o *.symvers modules.order .tmp_versions diff --git a/driver/base.c b/driver/base.c deleted file mode 100644 index 974224d..0000000 --- a/driver/base.c +++ /dev/null @@ -1,676 +0,0 @@ -/** - * - * @file base.c - * @author Guillermo Marcus - * @date 2009-04-05 - * @brief Contains the main code which connects all the different parts and does - * basic driver tasks like initialization. - * - * This is a full rewrite of the pciDriver. - * New default is to support kernel 2.6, using kernel 2.6 APIs. - * - */ - -/* - * Change History: - * - * $Log: not supported by cvs2svn $ - * Revision 1.13 2008-05-30 11:38:15 marcus - * Added patches for kernel 2.6.24 - * - * Revision 1.12 2008-01-24 14:21:36 marcus - * Added a CLEAR_INTERRUPT_QUEUE ioctl. - * Added a sysfs attribute to show the outstanding IRQ queues. - * - * Revision 1.11 2008-01-24 12:53:11 marcus - * Corrected wait_event condition in waiti_ioctl. Improved the loop too. - * - * Revision 1.10 2008-01-14 10:39:39 marcus - * Set some messages as debug instead of normal. - * - * Revision 1.9 2008-01-11 10:18:28 marcus - * Modified interrupt mechanism. Added atomic functions and queues, to address race conditions. Removed unused interrupt code. - * - * Revision 1.8 2007-07-17 13:15:55 marcus - * Removed Tasklets. - * Using newest map for the ABB interrupts. - * - * Revision 1.7 2007-07-06 15:56:04 marcus - * Change default status for OLD_REGISTERS to not defined. - * - * Revision 1.6 2007-07-05 15:29:59 marcus - * Corrected issue with the bar mapping for interrupt handling. - * Added support up to kernel 2.6.20 - * - * Revision 1.5 2007-05-29 07:50:18 marcus - * Split code into 2 files. May get merged in the future again.... - * - * Revision 1.4 2007/03/01 17:47:34 marcus - * Fixed bug when the kernel memory was less than one page, it was not locked properly, recalling an old mapping issue in this case. - * - * Revision 1.3 2007/03/01 17:01:22 marcus - * comment fix (again). - * - * Revision 1.2 2007/03/01 17:00:25 marcus - * Changed some comment in the log. - * - * Revision 1.1 2007/03/01 16:57:43 marcus - * Divided driver file to ease the interrupt hooks for the user of the driver. - * Modified Makefile accordingly. - * - * From pciDriver.c: - * Revision 1.11 2006/12/11 16:15:43 marcus - * Fixed kernel buffer mmapping, and driver crash when application crashes. - * Buffer memory is now marked reserved during allocation, and mmaped with - * remap_xx_range. - * - * Revision 1.10 2006/11/21 09:50:49 marcus - * Added PROGRAPE4 vendor/device IDs. - * - * Revision 1.9 2006/11/17 18:47:36 marcus - * Removed MERGE_SGENTRIES flag, now it is selected at runtime with 'type'. - * Removed noncached in non-prefetchable areas, to allow the use of MTRRs. - * - * Revision 1.8 2006/11/17 16:41:21 marcus - * Added slot number to the PCI info IOctl. - * - * Revision 1.7 2006/11/13 12:30:34 marcus - * Added a IOctl call, to confiure the interrupt response. (testing pending). - * Basic interrupts are now supported, using a Tasklet and Completions. - * - * Revision 1.6 2006/11/08 21:30:02 marcus - * Added changes after compile tests in kernel 2.6.16 - * - * Revision 1.5 2006/10/31 07:57:38 marcus - * Improved the pfn calculation in nopage(), to deal with some possible border - * conditions. It was really no issue, because they are normally page-aligned - * anyway, but to be on the safe side. - * - * Revision 1.4 2006/10/30 19:37:40 marcus - * Solved bug on kernel memory not mapping properly. - * - * Revision 1.3 2006/10/18 11:19:20 marcus - * Added kernel 2.6.8 support based on comments from Joern Adamczewski (GSI). - * - * Revision 1.2 2006/10/18 11:04:15 marcus - * Bus Master is only activated when we detect a specific board. - * - * Revision 1.1 2006/10/10 14:46:51 marcus - * Initial commit of the new pciDriver for kernel 2.6 - * - * Revision 1.9 2006/10/05 11:30:46 marcus - * Prerelease. Added bus and devfn to pciInfo for compatibility. - * - * Revision 1.8 2006/09/25 16:51:07 marcus - * Added PCI config IOctls, and implemented basic mmap functions. - * - * Revision 1.7 2006/09/20 11:12:41 marcus - * Added Merge SG entries - * - * Revision 1.6 2006/09/19 17:22:18 marcus - * backup commit. - * - * Revision 1.5 2006/09/18 17:13:11 marcus - * backup commit. - * - * Revision 1.4 2006/09/15 15:44:41 marcus - * backup commit. - * - * Revision 1.3 2006/08/15 11:40:02 marcus - * backup commit. - * - * Revision 1.2 2006/08/12 18:28:42 marcus - * Sync with the laptop - * - * Revision 1.1 2006/08/11 15:30:46 marcus - * Sync with the laptop - * - */ - -#include <linux/version.h> - -/* Check macros and kernel version first */ -#ifndef KERNEL_VERSION -#error "No KERNEL_VERSION macro! Stopping." -#endif - -#ifndef LINUX_VERSION_CODE -#error "No LINUX_VERSION_CODE macro! Stopping." -#endif - -#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,8) -#error "This driver has been tested only for Kernel 2.6.8 or above." -#endif - -/* Required includes */ -#include <linux/string.h> -#include <linux/slab.h> -#include <linux/types.h> -#include <linux/init.h> -#include <linux/module.h> -#include <linux/pci.h> -#include <linux/kernel.h> -#include <linux/errno.h> -#include <linux/fs.h> -#include <linux/cdev.h> -#include <linux/sysfs.h> -#include <asm/atomic.h> -#include <linux/pagemap.h> -#include <linux/spinlock.h> -#include <linux/list.h> -#include <asm/scatterlist.h> -#include <linux/vmalloc.h> -#include <linux/stat.h> -#include <linux/interrupt.h> -#include <linux/wait.h> - -/* Configuration for the driver (what should be compiled in, module name, etc...) */ -#include "config.h" - -/* Compatibility functions/definitions (provides functions which are not available on older kernels) */ -#include "compat.h" - -/* External interface for the driver */ -#include "pciDriver.h" - -/* Internal definitions for all parts (prototypes, data, macros) */ -#include "common.h" - -/* Internal definitions for the base part */ -#include "base.h" - -/* Internal definitions of the IRQ handling part */ -#include "int.h" - -/* Internal definitions for kernel memory */ -#include "kmem.h" - -/* Internal definitions for user space memory */ -#include "umem.h" - -#include "ioctl.h" - -/*************************************************************************/ -/* Module device table associated with this driver */ -MODULE_DEVICE_TABLE(pci, pcidriver_ids); - -/* Module init and exit points */ -module_init(pcidriver_init); -module_exit(pcidriver_exit); - -/* Module info */ -MODULE_AUTHOR("Guillermo Marcus"); -MODULE_DESCRIPTION("Simple PCI Driver"); -MODULE_LICENSE("GPL v2"); - -/* Module class */ -static struct class_compat *pcidriver_class; - -/** - * - * Called when loading the driver - * - */ -static int __init pcidriver_init(void) -{ - int err; - - /* Initialize the device count */ - atomic_set(&pcidriver_deviceCount, 0); - - /* Allocate character device region dynamically */ - if ((err = alloc_chrdev_region(&pcidriver_devt, MINORNR, MAXDEVICES, NODENAME)) != 0) { - mod_info("Couldn't allocate chrdev region. Module not loaded.\n"); - goto init_alloc_fail; - } - mod_info("Major %d allocated to nodename '%s'\n", MAJOR(pcidriver_devt), NODENAME); - - /* Register driver class */ - pcidriver_class = class_create(THIS_MODULE, NODENAME); - - if (IS_ERR(pcidriver_class)) { - mod_info("No sysfs support. Module not loaded.\n"); - goto init_class_fail; - } - - /* Register PCI driver. This function returns the number of devices on some - * systems, therefore check for errors as < 0. */ - if ((err = pci_register_driver(&pcidriver_driver)) < 0) { - mod_info("Couldn't register PCI driver. Module not loaded.\n"); - goto init_pcireg_fail; - } - - mod_info("Module loaded\n"); - - return 0; - -init_pcireg_fail: - class_destroy(pcidriver_class); -init_class_fail: - unregister_chrdev_region(pcidriver_devt, MAXDEVICES); -init_alloc_fail: - return err; -} - -/** - * - * Called when unloading the driver - * - */ -static void pcidriver_exit(void) -{ - pci_unregister_driver(&pcidriver_driver); - unregister_chrdev_region(pcidriver_devt, MAXDEVICES); - - if (pcidriver_class != NULL) - class_destroy(pcidriver_class); - - mod_info("Module unloaded\n"); -} - -/*************************************************************************/ -/* Driver functions */ - -/** - * - * This struct defines the PCI entry points. - * Will be registered at module init. - * - */ -static struct pci_driver pcidriver_driver = { - .name = MODNAME, - .id_table = pcidriver_ids, - .probe = pcidriver_probe, - .remove = pcidriver_remove, -}; - -/** - * - * This function is called when installing the driver for a device - * @param pdev Pointer to the PCI device - * - */ -static int __devinit pcidriver_probe(struct pci_dev *pdev, const struct pci_device_id *id) -{ - int err; - int devno; - pcidriver_privdata_t *privdata; - int devid; - - /* At the moment there is no difference between these boards here, other than - * printing a different message in the log. - * - * However, there is some difference in the interrupt handling functions. - */ - if (id->vendor == PCIE_XILINX_VENDOR_ID) { - if (id->device == PCIE_ML605_DEVICE_ID) { - mod_info("Found ML605 board at %s\n", dev_name(&pdev->dev)); - } else if (id->device == PCIE_IPECAMERA_DEVICE_ID) { - mod_info("Found IPE Camera at %s\n", dev_name(&pdev->dev)); - } else if (id->device == PCIE_KAPTURE_DEVICE_ID) { - mod_info("Found KAPTURE board at %s\n", dev_name(&pdev->dev)); - } else { - mod_info("Found unknown Xilinx device (%x) at %s\n", id->device, dev_name(&pdev->dev)); - } - } else { - /* It is something else */ - mod_info( "Found unknown board (%x:%x) at %s\n", id->vendor, id->device, dev_name(&pdev->dev)); - } - - /* Enable the device */ - if ((err = pci_enable_device(pdev)) != 0) { - mod_info("Couldn't enable device\n"); - goto probe_pcien_fail; - } - - /* Bus master & dma */ - if ((id->vendor == PCIE_XILINX_VENDOR_ID)&&(id->device == PCIE_IPECAMERA_DEVICE_ID)) { - pci_set_master(pdev); - - err = pci_set_dma_mask(pdev, DMA_BIT_MASK(32)); - if (err < 0) { - printk(KERN_ERR "pci_set_dma_mask failed\n"); - goto probe_dma_fail; - } - } - - /* Set Memory-Write-Invalidate support */ - if ((err = pci_set_mwi(pdev)) != 0) - mod_info("MWI not supported. Continue without enabling MWI.\n"); - - /* Get / Increment the device id */ - devid = atomic_inc_return(&pcidriver_deviceCount) - 1; - if (devid >= MAXDEVICES) { - mod_info("Maximum number of devices reached! Increase MAXDEVICES.\n"); - err = -ENOMSG; - goto probe_maxdevices_fail; - } - - /* Allocate and initialize the private data for this device */ - if ((privdata = kcalloc(1, sizeof(*privdata), GFP_KERNEL)) == NULL) { - err = -ENOMEM; - goto probe_nomem; - } - - INIT_LIST_HEAD(&(privdata->kmem_list)); - spin_lock_init(&(privdata->kmemlist_lock)); - atomic_set(&privdata->kmem_count, 0); - - INIT_LIST_HEAD(&(privdata->umem_list)); - spin_lock_init(&(privdata->umemlist_lock)); - atomic_set(&privdata->umem_count, 0); - - pci_set_drvdata( pdev, privdata ); - privdata->pdev = pdev; - - /* Device add to sysfs */ - devno = MKDEV(MAJOR(pcidriver_devt), MINOR(pcidriver_devt) + devid); - privdata->devno = devno; - if (pcidriver_class != NULL) { - /* FIXME: some error checking missing here */ - privdata->class_dev = class_device_create(pcidriver_class, NULL, devno, &(pdev->dev), NODENAMEFMT, MINOR(pcidriver_devt) + devid, privdata); - class_set_devdata( privdata->class_dev, privdata ); - mod_info("Device /dev/%s%d added\n",NODENAME,MINOR(pcidriver_devt) + devid); - } - - /* Setup mmaped BARs into kernel space */ - if ((err = pcidriver_probe_irq(privdata)) != 0) - goto probe_irq_probe_fail; - - /* Populate sysfs attributes for the class device */ - /* TODO: correct errorhandling. ewww. must remove the files in reversed order :-( */ - #define sysfs_attr(name) do { \ - if (class_device_create_file(sysfs_attr_def_pointer, &sysfs_attr_def_name(name)) != 0) \ - goto probe_device_create_fail; \ - } while (0) - #ifdef ENABLE_IRQ - sysfs_attr(irq_count); - sysfs_attr(irq_queues); - #endif - - sysfs_attr(mmap_mode); - sysfs_attr(mmap_area); - sysfs_attr(kmem_count); - sysfs_attr(kmem_alloc); - sysfs_attr(kmem_free); - sysfs_attr(kbuffers); - sysfs_attr(umappings); - sysfs_attr(umem_unmap); - #undef sysfs_attr - - /* Register character device */ - cdev_init( &(privdata->cdev), &pcidriver_fops ); - privdata->cdev.owner = THIS_MODULE; - privdata->cdev.ops = &pcidriver_fops; - err = cdev_add( &privdata->cdev, devno, 1 ); - if (err) { - mod_info( "Couldn't add character device.\n" ); - goto probe_cdevadd_fail; - } - - return 0; - -probe_device_create_fail: -probe_cdevadd_fail: -probe_irq_probe_fail: - pcidriver_irq_unmap_bars(privdata); - kfree(privdata); -probe_nomem: - atomic_dec(&pcidriver_deviceCount); -probe_maxdevices_fail: -probe_dma_fail: - pci_disable_device(pdev); -probe_pcien_fail: - return err; -} - -/** - * - * This function is called when disconnecting a device - * - */ -static void __devexit pcidriver_remove(struct pci_dev *pdev) -{ - pcidriver_privdata_t *privdata; - - /* Get private data from the device */ - privdata = pci_get_drvdata(pdev); - - /* Removing sysfs attributes from class device */ - #define sysfs_attr(name) do { \ - class_device_remove_file(sysfs_attr_def_pointer, &sysfs_attr_def_name(name)); \ - } while (0) - #ifdef ENABLE_IRQ - sysfs_attr(irq_count); - sysfs_attr(irq_queues); - #endif - - sysfs_attr(mmap_mode); - sysfs_attr(mmap_area); - sysfs_attr(kmem_count); - sysfs_attr(kmem_alloc); - sysfs_attr(kmem_free); - sysfs_attr(kbuffers); - sysfs_attr(umappings); - sysfs_attr(umem_unmap); - #undef sysfs_attr - - /* Free all allocated kmem buffers before leaving */ - pcidriver_kmem_free_all( privdata ); - -#ifdef ENABLE_IRQ - pcidriver_remove_irq(privdata); -#endif - - /* Removing Character device */ - cdev_del(&(privdata->cdev)); - - /* Removing the device from sysfs */ - class_device_destroy(pcidriver_class, privdata->devno); - - /* Releasing privdata */ - kfree(privdata); - - /* Disabling PCI device */ - pci_disable_device(pdev); - - mod_info("Device at %s removed\n", dev_name(&pdev->dev)); -} - -/*************************************************************************/ -/* File operations */ -/*************************************************************************/ - -/** - * This struct defines the file operation entry points. - * - * @see pcidriver_ioctl - * @see pcidriver_mmap - * @see pcidriver_open - * @see pcidriver_release - * - */ -static struct file_operations pcidriver_fops = { - .owner = THIS_MODULE, -#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,11) - .ioctl = pcidriver_ioctl, -#else - .unlocked_ioctl = pcidriver_ioctl, -#endif - .mmap = pcidriver_mmap, - .open = pcidriver_open, - .release = pcidriver_release, -}; - -void pcidriver_module_get(pcidriver_privdata_t *privdata) { - atomic_inc(&(privdata->refs)); -// mod_info("Ref: %i\n", atomic_read(&(privdata->refs))); -} - -void pcidriver_module_put(pcidriver_privdata_t *privdata) { - if (atomic_add_negative(-1, &(privdata->refs))) { - atomic_inc(&(privdata->refs)); - mod_info("Reference counting error..."); - } else { -// mod_info("Unref: %i\n", atomic_read(&(privdata->refs))); - } -} - -/** - * - * Called when an application open()s a /dev/fpga*, attaches the private data - * with the file pointer. - * - */ -int pcidriver_open(struct inode *inode, struct file *filp) -{ - pcidriver_privdata_t *privdata; - - /* Set the private data area for the file */ - privdata = container_of( inode->i_cdev, pcidriver_privdata_t, cdev); - filp->private_data = privdata; - - pcidriver_module_get(privdata); - - return 0; -} - -/** - * - * Called when the application close()s the file descriptor. Does nothing at - * the moment. - * - */ -int pcidriver_release(struct inode *inode, struct file *filp) -{ - pcidriver_privdata_t *privdata; - - /* Get the private data area */ - privdata = filp->private_data; - - pcidriver_module_put(privdata); - - return 0; -} - -/** - * - * This function is the entry point for mmap() and calls either pcidriver_mmap_pci - * or pcidriver_mmap_kmem - * - * @see pcidriver_mmap_pci - * @see pcidriver_mmap_kmem - * - */ -int pcidriver_mmap(struct file *filp, struct vm_area_struct *vma) -{ - pcidriver_privdata_t *privdata; - int ret = 0, bar; - - mod_info_dbg("Entering mmap\n"); - - /* Get the private data area */ - privdata = filp->private_data; - - /* Check the current mmap mode */ - switch (privdata->mmap_mode) { - case PCIDRIVER_MMAP_PCI: - /* Mmap a PCI region */ - switch (privdata->mmap_area) { - case PCIDRIVER_BAR0: bar = 0; break; - case PCIDRIVER_BAR1: bar = 1; break; - case PCIDRIVER_BAR2: bar = 2; break; - case PCIDRIVER_BAR3: bar = 3; break; - case PCIDRIVER_BAR4: bar = 4; break; - case PCIDRIVER_BAR5: bar = 5; break; - default: - mod_info("Attempted to mmap a PCI area with the wrong mmap_area value: %d\n",privdata->mmap_area); - return -EINVAL; /* invalid parameter */ - break; - } - ret = pcidriver_mmap_pci(privdata, vma, bar); - break; - case PCIDRIVER_MMAP_KMEM: - /* mmap a Kernel buffer */ - ret = pcidriver_mmap_kmem(privdata, vma); - break; - default: - mod_info( "Invalid mmap_mode value (%d)\n",privdata->mmap_mode ); - return -EINVAL; /* Invalid parameter (mode) */ - } - - return ret; -} - -/*************************************************************************/ -/* Internal driver functions */ -int pcidriver_mmap_pci(pcidriver_privdata_t *privdata, struct vm_area_struct *vmap, int bar) -{ - int ret = 0; - unsigned long bar_addr; - unsigned long bar_length, vma_size; - unsigned long bar_flags; - - mod_info_dbg("Entering mmap_pci\n"); - - /* Get info of the BAR to be mapped */ - bar_addr = pci_resource_start(privdata->pdev, bar); - bar_length = pci_resource_len(privdata->pdev, bar); - bar_flags = pci_resource_flags(privdata->pdev, bar); - - /* Check sizes */ - vma_size = (vmap->vm_end - vmap->vm_start); - - if ((vma_size != bar_length) && - ((bar_length < PAGE_SIZE) && (vma_size != PAGE_SIZE))) { - mod_info( "mmap size is not correct! bar: %lu - vma: %lu\n", bar_length, vma_size ); - return -EINVAL; - } - - if (bar_flags & IORESOURCE_IO) { - /* Unlikely case, we will mmap a IO region */ - - /* IO regions are never cacheable */ -#ifdef pgprot_noncached - vmap->vm_page_prot = pgprot_noncached(vmap->vm_page_prot); -#endif - - /* Map the BAR */ - ret = io_remap_pfn_range_compat( - vmap, - vmap->vm_start, - bar_addr, - bar_length, - vmap->vm_page_prot); - } else { - /* Normal case, mmap a memory region */ - - /* Ensure this VMA is non-cached, if it is not flaged as prefetchable. - * If it is prefetchable, caching is allowed and will give better performance. - * This should be set properly by the BIOS, but we want to be sure. */ - /* adapted from drivers/char/mem.c, mmap function. */ -#ifdef pgprot_noncached -/* Setting noncached disables MTRR registers, and we want to use them. - * So we take this code out. This can lead to caching problems if and only if - * the System BIOS set something wrong. Check LDDv3, page 425. - */ -// if (!(bar_flags & IORESOURCE_PREFETCH)) -// vmap->vm_page_prot = pgprot_noncached(vmap->vm_page_prot); -#endif - - /* Map the BAR */ - ret = remap_pfn_range_compat( - vmap, - vmap->vm_start, - bar_addr, - bar_length, - vmap->vm_page_prot); - } - - if (ret) { - mod_info("remap_pfn_range failed\n"); - return -EAGAIN; - } - - return 0; /* success */ -} diff --git a/driver/base.h b/driver/base.h deleted file mode 100644 index 9384e2d..0000000 --- a/driver/base.h +++ /dev/null @@ -1,85 +0,0 @@ -#ifndef _PCIDRIVER_BASE_H -#define _PCIDRIVER_BASE_H - -#include "sysfs.h" - -/** - * - * This file contains prototypes and data structures for internal use of the pciDriver. - * - * - */ - -/* prototypes for file_operations */ -static struct file_operations pcidriver_fops; -int pcidriver_mmap( struct file *filp, struct vm_area_struct *vmap ); -int pcidriver_open(struct inode *inode, struct file *filp ); -int pcidriver_release(struct inode *inode, struct file *filp); - -/* prototypes for device operations */ -static struct pci_driver pcidriver_driver; -static int __devinit pcidriver_probe(struct pci_dev *pdev, const struct pci_device_id *id); -static void __devexit pcidriver_remove(struct pci_dev *pdev); - - - -/* prototypes for module operations */ -static int __init pcidriver_init(void); -static void pcidriver_exit(void); - -/* - * This is the table of PCI devices handled by this driver by default - * If you want to add devices dynamically to this list, do: - * - * echo "vendor device" > /sys/bus/pci/drivers/pciDriver/new_id - * where vendor and device are in hex, without leading '0x'. - * - * The IDs themselves can be found in common.h - * - * For more info, see <kernel-source>/Documentation/pci.txt - * - * __devinitdata is applied because the kernel does not need those - * tables any more after boot is finished on systems which don't - * support hotplug. - * - */ - -static const __devinitdata struct pci_device_id pcidriver_ids[] = { - { PCI_DEVICE( PCIE_XILINX_VENDOR_ID, PCIE_ML605_DEVICE_ID ) }, // PCI-E Xilinx ML605 - { PCI_DEVICE( PCIE_XILINX_VENDOR_ID, PCIE_IPECAMERA_DEVICE_ID ) }, // PCI-E IPE Camera - { PCI_DEVICE( PCIE_XILINX_VENDOR_ID, PCIE_KAPTURE_DEVICE_ID ) }, // PCI-E KAPTURE board for HEB - {0,0,0,0}, -}; - -/* prototypes for internal driver functions */ -int pcidriver_pci_read( pcidriver_privdata_t *privdata, pci_cfg_cmd *pci_cmd ); -int pcidriver_pci_write( pcidriver_privdata_t *privdata, pci_cfg_cmd *pci_cmd ); -int pcidriver_pci_info( pcidriver_privdata_t *privdata, pcilib_board_info_t *pci_info ); - -int pcidriver_mmap_pci( pcidriver_privdata_t *privdata, struct vm_area_struct *vmap , int bar ); -int pcidriver_mmap_kmem( pcidriver_privdata_t *privdata, struct vm_area_struct *vmap ); - -/*************************************************************************/ -/* Static data */ -/* Hold the allocated major & minor numbers */ -static dev_t pcidriver_devt; - -/* Number of devices allocated */ -static atomic_t pcidriver_deviceCount; - -/* Sysfs attributes */ -static DEVICE_ATTR(mmap_mode, (S_IRUGO | S_IWUGO), pcidriver_show_mmap_mode, pcidriver_store_mmap_mode); -static DEVICE_ATTR(mmap_area, (S_IRUGO | S_IWUGO), pcidriver_show_mmap_area, pcidriver_store_mmap_area); -static DEVICE_ATTR(kmem_count, S_IRUGO, pcidriver_show_kmem_count, NULL); -static DEVICE_ATTR(kbuffers, S_IRUGO, pcidriver_show_kbuffers, NULL); -static DEVICE_ATTR(kmem_alloc, S_IWUGO, NULL, pcidriver_store_kmem_alloc); -static DEVICE_ATTR(kmem_free, S_IWUGO, NULL, pcidriver_store_kmem_free); -static DEVICE_ATTR(umappings, S_IRUGO, pcidriver_show_umappings, NULL); -static DEVICE_ATTR(umem_unmap, S_IWUGO, NULL, pcidriver_store_umem_unmap); - -#ifdef ENABLE_IRQ -static DEVICE_ATTR(irq_count, S_IRUGO, pcidriver_show_irq_count, NULL); -static DEVICE_ATTR(irq_queues, S_IRUGO, pcidriver_show_irq_queues, NULL); -#endif - -#endif diff --git a/driver/common.h b/driver/common.h deleted file mode 100644 index eba56d7..0000000 --- a/driver/common.h +++ /dev/null @@ -1,108 +0,0 @@ -#ifndef _PCIDRIVER_COMMON_H -#define _PCIDRIVER_COMMON_H - -#include "pcilib_types.h" - -/*************************************************************************/ -/* Private data types and structures */ - - -/* Define an entry in the kmem list (this list is per device) */ -/* This list keeps references to the allocated kernel buffers */ -typedef struct { - int id; - enum dma_data_direction direction; - - struct list_head list; - dma_addr_t dma_handle; - unsigned long cpua; - unsigned long size; - unsigned long type; - unsigned long align; - - unsigned long use; - unsigned long item; - - spinlock_t lock; - unsigned long mode; - unsigned long refs; - - struct class_device_attribute sysfs_attr; /* initialized when adding the entry */ -} pcidriver_kmem_entry_t; - -/* Define an entry in the umem list (this list is per device) */ -/* This list keeps references to the SG lists for each mapped userspace region */ -typedef struct { - int id; - struct list_head list; - unsigned int nr_pages; /* number of pages for this user memeory area */ - struct page **pages; /* list of pointers to the pages */ - unsigned int nents; /* actual entries in the scatter/gatter list (NOT nents for the map function, but the result) */ - struct scatterlist *sg; /* list of sg entries */ - struct class_device_attribute sysfs_attr; /* initialized when adding the entry */ -} pcidriver_umem_entry_t; - -/* Hold the driver private data */ -typedef struct { - dev_t devno; /* device number (major and minor) */ - struct pci_dev *pdev; /* PCI device */ - struct class_device *class_dev; /* Class device */ - struct cdev cdev; /* char device struct */ - int mmap_mode; /* current mmap mode */ - int mmap_area; /* current PCI mmap area */ - -#ifdef ENABLE_IRQ - int irq_enabled; /* Non-zero if IRQ is enabled */ - int irq_count; /* Just an IRQ counter */ - - wait_queue_head_t irq_queues[ PCIDRIVER_INT_MAXSOURCES ]; - /* One queue per interrupt source */ - atomic_t irq_outstanding[ PCIDRIVER_INT_MAXSOURCES ]; - /* Outstanding interrupts per queue */ - volatile unsigned int *bars_kmapped[6]; /* PCI BARs mmapped in kernel space */ - -#endif - - spinlock_t kmemlist_lock; /* Spinlock to lock kmem list operations */ - struct list_head kmem_list; /* List of 'kmem_list_entry's associated with this device */ - atomic_t kmem_count; /* id for next kmem entry */ - - int kmem_cur_id; /* Currently selected kmem buffer, for mmap */ - - spinlock_t umemlist_lock; /* Spinlock to lock umem list operations */ - struct list_head umem_list; /* List of 'umem_list_entry's associated with this device */ - atomic_t umem_count; /* id for next umem entry */ - - int msi_mode; /* Flag specifying if interrupt have been initialized in MSI mode */ - atomic_t refs; /* Reference counter */ -} pcidriver_privdata_t; - - -void pcidriver_module_get(pcidriver_privdata_t *privdata); -void pcidriver_module_put(pcidriver_privdata_t *privdata); - -/*************************************************************************/ -/* Some nice defines that make code more readable */ -/* This is to print nice info in the log */ - -#ifdef DEBUG - #define mod_info( args... ) \ - do { printk( KERN_INFO "%s - %s : ", MODNAME , __FUNCTION__ );\ - printk( args ); } while(0) - #define mod_info_dbg( args... ) \ - do { printk( KERN_INFO "%s - %s : ", MODNAME , __FUNCTION__ );\ - printk( args ); } while(0) -#else - #define mod_info( args... ) \ - do { printk( KERN_INFO "%s: ", MODNAME );\ - printk( args ); } while(0) - #define mod_info_dbg( args... ) -#endif - -#define mod_crit( args... ) \ - do { printk( KERN_CRIT "%s: ", MODNAME );\ - printk( args ); } while(0) - -#define MIN(a, b) ((a) < (b) ? (a) : (b)) - -#endif diff --git a/driver/compat.h b/driver/compat.h deleted file mode 100644 index 25e402a..0000000 --- a/driver/compat.h +++ /dev/null @@ -1,198 +0,0 @@ -/** - * - * @file compat.h - * @author Michael Stapelberg - * @date 2009-04-05 - * @brief Contains compatibility definitions for the different linux kernel versions to avoid - * putting ifdefs all over the driver code. - * - */ -#ifndef _COMPAT_H -#define _COMPAT_H - -#if LINUX_VERSION_CODE >= KERNEL_VERSION(3,8,0) -# define __devinit -# define __devexit -# define __devinitdata -#endif - -/* dev_name is the wrapper one needs to use to access what was formerly called - * bus_id in struct device. However, before 2.6.27, direct access was necessary, - * so we provide our own version. */ -#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,27) -static inline const char *dev_name(struct device *dev) { - return dev->bus_id; -} -#endif - -/* SetPageLocked disappeared in v2.6.27 */ -#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,27) - #define compat_lock_page SetPageLocked - #define compat_unlock_page ClearPageLocked -#else - /* in v2.6.28, __set_page_locked and __clear_page_locked was introduced */ - #if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,28) - #define compat_lock_page __set_page_locked - #define compat_unlock_page __clear_page_locked - #else - /* However, in v2.6.27 itself, neither of them is there, so - * we need to use our own function fiddling with bits inside - * the page struct :-\ */ - static inline void compat_lock_page(struct page *page) { - __set_bit(PG_locked, &page->flags); - } - - static inline void compat_unlock_page(struct page *page) { - __clear_bit(PG_locked, &page->flags); - } - #endif -#endif - -/* Before 2.6.13, simple_class was the standard interface. Nowadays, it's just called class */ -#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,13) - - #define class_compat class_simple - - /* These functions are redirected to their old corresponding functions */ - #define class_create(module, name) class_simple_create(module, name) - #define class_destroy(type) class_simple_destroy(type) - #define class_device_destroy(unused, devno) class_simple_device_remove(devno) - #define class_device_create(type, unused, devno, devpointer, nameformat, minor, unused) \ - class_simple_device_add(type, devno, devpointer, nameformat, minor) - #define class_set_devdata(classdev, privdata) classdev->class_data = privdata - #define DEVICE_ATTR_COMPAT - #define sysfs_attr_def_name(name) class_device_attr_##name - #define sysfs_attr_def_pointer privdata->class_dev - #define SYSFS_GET_FUNCTION(name) ssize_t name(struct class_device *cls, char *buf) - #define SYSFS_SET_FUNCTION(name) ssize_t name(struct class_device *cls, const char *buf, size_t count) - #define SYSFS_GET_PRIVDATA (pcidriver_privdata_t*)cls->class_data - -#else - -/* In 2.6.26, device.h was changed quite significantly. Luckily, it only affected - type/function names, for the most part. */ -//#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,26) - #define class_device_attribute device_attribute - #define CLASS_DEVICE_ATTR DEVICE_ATTR - #define class_device device - #define class_data dev -#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,27) - #define class_device_create(type, parent, devno, devpointer, nameformat, minor, privdata) \ - device_create(type, parent, devno, privdata, nameformat, minor) -#else - #define class_device_create(type, parent, devno, devpointer, nameformat, minor, unused) \ - device_create(type, parent, devno, nameformat, minor) -#endif - #define class_device_create_file device_create_file - #define class_device_remove_file device_remove_file - #define class_device_destroy device_destroy - #define DEVICE_ATTR_COMPAT struct device_attribute *attr, - #define class_set_devdata dev_set_drvdata - - #define sysfs_attr_def_name(name) dev_attr_##name - #define sysfs_attr_def_pointer privdata->class_dev - #define SYSFS_GET_FUNCTION(name) ssize_t name(struct device *dev, struct device_attribute *attr, char *buf) - #define SYSFS_SET_FUNCTION(name) ssize_t name(struct device *dev, struct device_attribute *attr, const char *buf, size_t count) - #define SYSFS_GET_PRIVDATA dev_get_drvdata(dev) - -//#endif - -#define class_compat class - -#endif - -/* The arguments of IRQ handlers have been changed in 2.6.19. It's very likely that - int irq will disappear somewhen in the future (current is 2.6.29), too. */ -#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,19) - #define IRQ_HANDLER_FUNC(name) irqreturn_t name(int irq, void *dev_id) -#else - #define IRQ_HANDLER_FUNC(name) irqreturn_t name(int irq, void *dev_id, struct pt_regs *regs) -#endif - -/* atomic_inc_return appeared in 2.6.9, at least in CERN scientific linux, provide - compatibility wrapper for older kernels */ -#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,9) -static int atomic_inc_return(atomic_t *variable) { - atomic_inc(variable); - return atomic_read(variable); -} -#endif - -/* sg_set_page is available starting at 2.6.24 */ -#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,24) - -#define sg_set_page(sg, set_page, set_length, set_offset) do { \ - (sg)->page = set_page; \ - (sg)->length = set_length; \ - (sg)->offset = set_offset; \ -} while (0) - -#endif - -/* Before 2.6.20, disable was not an atomic counter, so this check was needed */ -#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,20) -#define pci_disable_device(pdev) do { \ - if (pdev->is_enabled) \ - pci_disable_device(pdev); \ -} while (0) -#endif - -/* Before 2.6.24, scatter/gather lists did not need to be initialized */ -#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,24) - #define sg_init_table(sg, nr_pages) -#endif - -/* SA_SHIRQ was renamed to IRQF_SHARED in 2.6.24 */ -#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,24) - #define request_irq(irq, irq_handler, modname, privdata) request_irq(irq, irq_handler, IRQF_SHARED, modname, privdata) -#else - #define request_irq(irq, irq_handler, modname, privdata) request_irq(irq, irq_handler, SA_SHIRQ, modname, privdata) -#endif - -/* In 2.6.13, io_remap_page_range was removed in favor for io_remap_pfn_range which works on - more platforms and allows more memory space */ -#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,13) -#define io_remap_pfn_range_compat(vmap, vm_start, bar_addr, bar_length, vm_page_prot) \ - io_remap_pfn_range(vmap, vm_start, (bar_addr >> PAGE_SHIFT), bar_length, vm_page_prot) -#else -#define io_remap_pfn_range_compat(vmap, vm_start, bar_addr, bar_length, vm_page_prot) \ - io_remap_page_range(vmap, vm_start, bar_addr, bar_length, vm_page_prot) -#endif - -/* In 2.6.10, remap_pfn_range was introduced, see io_remap_pfn_range_compat */ -#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,10) -#define remap_pfn_range_compat(vmap, vm_start, bar_addr, bar_length, vm_page_prot) \ - remap_pfn_range(vmap, vm_start, (bar_addr >> PAGE_SHIFT), bar_length, vm_page_prot) - -#define remap_pfn_range_cpua_compat(vmap, vm_start, cpua, size, vm_page_prot) \ - remap_pfn_range(vmap, vm_start, page_to_pfn(virt_to_page((void*)cpua)), size, vm_page_prot) - -#else -#define remap_pfn_range_compat(vmap, vm_start, bar_addr, bar_length, vm_page_prot) \ - remap_page_range(vmap, vm_start, bar_addr, bar_length, vm_page_prot) - -#define remap_pfn_range_cpua_compat(vmap, vm_start, cpua, size, vm_page_prot) \ - remap_page_range(vmap, vm_start, virt_to_phys((void*)cpua), size, vm_page_prot) -#endif - -/** - * Go over the pages of the kmem buffer, and mark them as reserved. - * This is needed, otherwise mmaping the kernel memory to user space - * will fail silently (mmaping /dev/null) when using remap_xx_range. - */ -static inline void set_pages_reserved_compat(unsigned long cpua, unsigned long size) -{ - /* Starting in 2.6.15, the PG_RESERVED bit was removed. - See also http://lwn.net/Articles/161204/ */ -#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,15) - struct page *page, *last_page; - - page = virt_to_page(cpua); - last_page = virt_to_page(cpua + size - 1); - - for (; page <= last_page; page++) - SetPageReserved(page); -#endif -} - -#endif diff --git a/driver/config.h b/driver/config.h deleted file mode 100644 index c217afd..0000000 --- a/driver/config.h +++ /dev/null @@ -1,23 +0,0 @@ -/*******************************/ -/* Configuration of the driver */ -/*******************************/ - -/* Debug messages */ -//#define DEBUG - -/* Enable/disable IRQ handling */ -#define ENABLE_IRQ - -/* The name of the module */ -#define MODNAME "pciDriver" - -/* Major number is allocated dynamically */ -/* Minor number */ -#define MINORNR 0 - -/* Node name of the char device */ -#define NODENAME "fpga" -#define NODENAMEFMT "fpga%d" - -/* Maximum number of devices*/ -#define MAXDEVICES 4 diff --git a/driver/int.c b/driver/int.c deleted file mode 100644 index 5dbcb7f..0000000 --- a/driver/int.c +++ /dev/null @@ -1,258 +0,0 @@ -/** - * - * @file int.c - * @author Guillermo Marcus - * @date 2009-04-05 - * @brief Contains the interrupt handler. - * - */ - -/* - * Change History: - * - * $Log: not supported by cvs2svn $ - * Revision 1.7 2008-01-11 10:18:28 marcus - * Modified interrupt mechanism. Added atomic functions and queues, to address race conditions. Removed unused interrupt code. - * - * Revision 1.6 2007-11-04 20:58:22 marcus - * Added interrupt generator acknowledge. - * Fixed wrong operator. - * - * Revision 1.5 2007-10-31 15:42:21 marcus - * Added IG ack for testing, may be removed later. - * - * Revision 1.4 2007-07-17 13:15:56 marcus - * Removed Tasklets. - * Using newest map for the ABB interrupts. - * - * Revision 1.3 2007-07-05 15:30:30 marcus - * Added support for both register maps of the ABB. - * - * Revision 1.2 2007-05-29 07:50:18 marcus - * Split code into 2 files. May get merged in the future again.... - * - * Revision 1.1 2007/03/01 16:57:43 marcus - * Divided driver file to ease the interrupt hooks for the user of the driver. - * Modified Makefile accordingly. - * - */ - -#include <linux/version.h> -#include <linux/string.h> -#include <linux/types.h> -#include <linux/list.h> -#include <linux/interrupt.h> -#include <linux/pci.h> -#include <linux/cdev.h> -#include <linux/wait.h> -#include <linux/sched.h> -#include <stdbool.h> - -#include "config.h" - -#include "compat.h" - -#include "pciDriver.h" - -#include "common.h" - -#include "int.h" - -/* - * The ID between IRQ_SOURCE in irq_outstanding and the actual source is arbitrary. - * Therefore, be careful when communicating with multiple implementations. - */ - -/* IRQ_SOURCES */ -#define ABB_IRQ_CH0 0 -#define ABB_IRQ_CH1 1 -#define ABB_IRQ_IG 2 - -/* See ABB user’s guide, register definitions (3.1) */ -#define ABB_INT_ENABLE (0x0010 >> 2) -#define ABB_INT_STAT (0x0008 >> 2) - -#define ABB_INT_CH1_TIMEOUT (1 << 4) -#define ABB_INT_CH0_TIMEOUT (1 << 5) -#define ABB_INT_IG (1 << 2) -#define ABB_INT_CH0 (1 << 1) /* downstream */ -#define ABB_INT_CH1 (1) /* upstream */ - -#define ABB_CH0_CTRL (108 >> 2) -#define ABB_CH1_CTRL (72 >> 2) -#define ABB_CH_RESET (0x0201000A) -#define ABB_IG_CTRL (0x0080 >> 2) -#define ABB_IG_ACK (0x00F0) - -/** - * - * If IRQ-handling is enabled, this function will be called from pcidriver_probe - * to initialize the IRQ handling (maps the BARs) - * - */ -int pcidriver_probe_irq(pcidriver_privdata_t *privdata) -{ - unsigned char int_pin, int_line; - unsigned long bar_addr, bar_len, bar_flags; - int i; - int err; - - for (i = 0; i < 6; i++) - privdata->bars_kmapped[i] = NULL; - - for (i = 0; i < 6; i++) { - bar_addr = pci_resource_start(privdata->pdev, i); - bar_len = pci_resource_len(privdata->pdev, i); - bar_flags = pci_resource_flags(privdata->pdev, i); - - /* check if it is a valid BAR, skip if not */ - if ((bar_addr == 0) || (bar_len == 0)) - continue; - - /* Skip IO regions (map only mem regions) */ - if (bar_flags & IORESOURCE_IO) - continue; - - /* Check if the region is available */ - if ((err = pci_request_region(privdata->pdev, i, NULL)) != 0) { - mod_info( "Failed to request BAR memory region.\n" ); - return err; - } - - /* Map it into kernel space. */ - /* For x86 this is just a dereference of the pointer, but that is - * not portable. So we need to do the portable way. Thanks Joern! - */ - - /* respect the cacheable-bility of the region */ - if (bar_flags & IORESOURCE_PREFETCH) - privdata->bars_kmapped[i] = ioremap(bar_addr, bar_len); - else - privdata->bars_kmapped[i] = ioremap_nocache(bar_addr, bar_len); - - /* check for error */ - if (privdata->bars_kmapped[i] == NULL) { - mod_info( "Failed to remap BAR%d into kernel space.\n", i ); - return -EIO; - } - } - - /* Initialize the interrupt handler for this device */ - /* Initialize the wait queues */ - for (i = 0; i < PCIDRIVER_INT_MAXSOURCES; i++) { - init_waitqueue_head(&(privdata->irq_queues[i])); - atomic_set(&(privdata->irq_outstanding[i]), 0); - } - - /* Initialize the irq config */ - if ((err = pci_read_config_byte(privdata->pdev, PCI_INTERRUPT_PIN, &int_pin)) != 0) { - /* continue without interrupts */ - int_pin = 0; - mod_info("Error getting the interrupt pin. Disabling interrupts for this device\n"); - } - - /* Disable interrupts and activate them if everything can be set up properly */ - privdata->irq_enabled = 0; - - if (int_pin == 0) - return 0; - - if ((err = pci_read_config_byte(privdata->pdev, PCI_INTERRUPT_LINE, &int_line)) != 0) { - mod_info("Error getting the interrupt line. Disabling interrupts for this device\n"); - return 0; - } - - /* Enable interrupts using MSI mode */ - if (!pci_enable_msi(privdata->pdev)) - privdata->msi_mode = 1; - - /* register interrupt handler */ - if ((err = request_irq(privdata->pdev->irq, pcidriver_irq_handler, MODNAME, privdata)) != 0) { - mod_info("Error registering the interrupt handler. Disabling interrupts for this device\n"); - return 0; - } - - privdata->irq_enabled = 1; - mod_info("Registered Interrupt Handler at pin %i, line %i, IRQ %i\n", int_pin, int_line, privdata->pdev->irq ); - - return 0; -} - -/** - * - * Frees/cleans up the data structures, called from pcidriver_remove() - * - */ -void pcidriver_remove_irq(pcidriver_privdata_t *privdata) -{ - /* Release the IRQ handler */ - if (privdata->irq_enabled != 0) - free_irq(privdata->pdev->irq, privdata); - - if (privdata->msi_mode) { - pci_disable_msi(privdata->pdev); - privdata->msi_mode = 0; - } - - pcidriver_irq_unmap_bars(privdata); -} - -/** - * - * Unmaps the BARs and releases them - * - */ -void pcidriver_irq_unmap_bars(pcidriver_privdata_t *privdata) -{ - int i; - - for (i = 0; i < 6; i++) { - if (privdata->bars_kmapped[i] == NULL) - continue; - - iounmap((void*)privdata->bars_kmapped[i]); - pci_release_region(privdata->pdev, i); - } -} - -/** - * - * Acknowledges the receival of an interrupt to the card. - * - * @returns true if the card was acknowledget - * @returns false if the interrupt was not for one of our cards - * - * @see check_acknowlegde_channel - * - */ -static bool pcidriver_irq_acknowledge(pcidriver_privdata_t *privdata) -{ - int channel = 0; -// volatile unsigned int *bar; -// bar = privdata->bars_kmapped[0]; -// mod_info_dbg("interrupt registers. ISR: %x, IER: %x\n", bar[ABB_INT_STAT], bar[ABB_INT_ENABLE]); - - atomic_inc(&(privdata->irq_outstanding[channel])); - wake_up_interruptible(&(privdata->irq_queues[channel])); - - return true; -} - -/** - * - * Handles IRQs. At the moment, this acknowledges the card that this IRQ - * was received and then increases the driver's IRQ counter. - * - * @see pcidriver_irq_acknowledge - * - */ -IRQ_HANDLER_FUNC(pcidriver_irq_handler) -{ - pcidriver_privdata_t *privdata = (pcidriver_privdata_t *)dev_id; - - if (!pcidriver_irq_acknowledge(privdata)) - return IRQ_NONE; - - privdata->irq_count++; - return IRQ_HANDLED; -} diff --git a/driver/int.h b/driver/int.h deleted file mode 100644 index 4a834c7..0000000 --- a/driver/int.h +++ /dev/null @@ -1,9 +0,0 @@ -#if !defined(_PCIDRIVER_INT_H) && defined(ENABLE_IRQ) -#define _PCIDRIVER_INT_H - -int pcidriver_probe_irq(pcidriver_privdata_t *privdata); -void pcidriver_remove_irq(pcidriver_privdata_t *privdata); -void pcidriver_irq_unmap_bars(pcidriver_privdata_t *privdata); -IRQ_HANDLER_FUNC(pcidriver_irq_handler); - -#endif diff --git a/driver/ioctl.c b/driver/ioctl.c deleted file mode 100644 index 2d4af73..0000000 --- a/driver/ioctl.c +++ /dev/null @@ -1,471 +0,0 @@ -/** - * - * @file ioctl.c - * @author Guillermo Marcus - * @date 2009-04-05 - * @brief Contains the functions handling the different ioctl calls. - * - */ -#include <linux/version.h> -#include <linux/string.h> -#include <linux/slab.h> -#include <linux/types.h> -#include <linux/init.h> -#include <linux/module.h> -#include <linux/pci.h> -#include <linux/kernel.h> -#include <linux/errno.h> -#include <linux/fs.h> -#include <linux/cdev.h> -#include <linux/sysfs.h> -#include <asm/atomic.h> -#include <linux/pagemap.h> -#include <linux/spinlock.h> -#include <linux/list.h> -#include <asm/scatterlist.h> -#include <linux/vmalloc.h> -#include <linux/stat.h> -#include <linux/interrupt.h> -#include <linux/wait.h> -#include <linux/sched.h> - -#include "config.h" /* Configuration for the driver */ -#include "compat.h" /* Compatibility functions/definitions */ -#include "pciDriver.h" /* External interface for the driver */ -#include "common.h" /* Internal definitions for all parts */ -#include "kmem.h" /* Internal definitions for kernel memory */ -#include "umem.h" /* Internal definitions for user space memory */ -#include "ioctl.h" /* Internal definitions for the ioctl part */ - -/** Declares a variable of the given type with the given name and copies it from userspace */ -#define READ_FROM_USER(type, name) \ - type name; \ - if ((ret = copy_from_user(&name, (type*)arg, sizeof(name))) != 0) \ - return -EFAULT; - -/** Writes back the given variable with the given type to userspace */ -#define WRITE_TO_USER(type, name) \ - if ((ret = copy_to_user((type*)arg, &name, sizeof(name))) != 0) \ - return -EFAULT; - -/** - * - * Sets the mmap mode for following mmap() calls. - * - * @param arg Not a pointer, but either PCIDRIVER_MMAP_PCI or PCIDRIVER_MMAP_KMEM - * - */ -static int ioctl_mmap_mode(pcidriver_privdata_t *privdata, unsigned long arg) -{ - if ((arg != PCIDRIVER_MMAP_PCI) && (arg != PCIDRIVER_MMAP_KMEM)) - return -EINVAL; - - /* change the mode */ - privdata->mmap_mode = arg; - - return 0; -} - -/** - * - * Sets the mmap area (BAR) for following mmap() calls. - * - */ -static int ioctl_mmap_area(pcidriver_privdata_t *privdata, unsigned long arg) -{ - /* validate input */ - if ((arg < PCIDRIVER_BAR0) || (arg > PCIDRIVER_BAR5)) - return -EINVAL; - - /* change the PCI area to mmap */ - privdata->mmap_area = arg; - - return 0; -} - -/** - * - * Reads/writes a byte/word/dword of the device's PCI config. - * - * @see pcidriver_pci_read - * @see pcidriver_pci_write - * - */ -static int ioctl_pci_config_read_write(pcidriver_privdata_t *privdata, unsigned int cmd, unsigned long arg) -{ - int ret; - READ_FROM_USER(pci_cfg_cmd, pci_cmd); - - if (cmd == PCIDRIVER_IOC_PCI_CFG_RD) { - switch (pci_cmd.size) { - case PCIDRIVER_PCI_CFG_SZ_BYTE: - ret = pci_read_config_byte( privdata->pdev, pci_cmd.addr, &(pci_cmd.val.byte) ); - break; - case PCIDRIVER_PCI_CFG_SZ_WORD: - ret = pci_read_config_word( privdata->pdev, pci_cmd.addr, &(pci_cmd.val.word) ); - break; - case PCIDRIVER_PCI_CFG_SZ_DWORD: - ret = pci_read_config_dword( privdata->pdev, pci_cmd.addr, &(pci_cmd.val.dword) ); - break; - default: - return -EINVAL; /* Wrong size setting */ - } - } else { - switch (pci_cmd.size) { - case PCIDRIVER_PCI_CFG_SZ_BYTE: - ret = pci_write_config_byte( privdata->pdev, pci_cmd.addr, pci_cmd.val.byte ); - break; - case PCIDRIVER_PCI_CFG_SZ_WORD: - ret = pci_write_config_word( privdata->pdev, pci_cmd.addr, pci_cmd.val.word ); - break; - case PCIDRIVER_PCI_CFG_SZ_DWORD: - ret = pci_write_config_dword( privdata->pdev, pci_cmd.addr, pci_cmd.val.dword ); - break; - default: - return -EINVAL; /* Wrong size setting */ - break; - } - } - - WRITE_TO_USER(pci_cfg_cmd, pci_cmd); - - return 0; -} - -/** - * - * Gets the PCI information for the device. - * - * @see pcidriver_pci_info - * - */ -static int ioctl_pci_info(pcidriver_privdata_t *privdata, unsigned long arg) -{ - int ret; - int bar; - READ_FROM_USER(pcilib_board_info_t, pci_info); - - pci_info.vendor_id = privdata->pdev->vendor; - pci_info.device_id = privdata->pdev->device; - pci_info.bus = privdata->pdev->bus->number; - pci_info.slot = PCI_SLOT(privdata->pdev->devfn); - pci_info.devfn = privdata->pdev->devfn; - pci_info.func = PCI_FUNC(privdata->pdev->devfn); - - if ((ret = pci_read_config_byte(privdata->pdev, PCI_INTERRUPT_PIN, &(pci_info.interrupt_pin))) != 0) - return ret; - - if ((ret = pci_read_config_byte(privdata->pdev, PCI_INTERRUPT_LINE, &(pci_info.interrupt_line))) != 0) - return ret; - - for (bar = 0; bar < 6; bar++) { - pci_info.bar_start[bar] = pci_resource_start(privdata->pdev, bar); - pci_info.bar_length[bar] = pci_resource_len(privdata->pdev, bar); - pci_info.bar_flags[bar] = pci_resource_flags(privdata->pdev, bar); - } - - WRITE_TO_USER(pcilib_board_info_t, pci_info); - - return 0; -} - -/** - * - * Allocates kernel memory. - * - * @see pcidriver_kmem_alloc - * - */ -static int ioctl_kmem_alloc(pcidriver_privdata_t *privdata, unsigned long arg) -{ - int ret; - READ_FROM_USER(kmem_handle_t, khandle); - - if ((ret = pcidriver_kmem_alloc(privdata, &khandle)) != 0) - return ret; - - WRITE_TO_USER(kmem_handle_t, khandle); - - return 0; -} - -/** - * - * Frees kernel memory. - * - * @see pcidriver_kmem_free - * - */ -static int ioctl_kmem_free(pcidriver_privdata_t *privdata, unsigned long arg) -{ - int ret; - READ_FROM_USER(kmem_handle_t, khandle); - - if ((ret = pcidriver_kmem_free(privdata, &khandle)) != 0) - return ret; - - return 0; -} - -/** - * - * Syncs kernel memory. - * - * @see pcidriver_kmem_sync - * - */ -static int ioctl_kmem_sync(pcidriver_privdata_t *privdata, unsigned long arg) -{ - int ret; - READ_FROM_USER(kmem_sync_t, ksync); - - if ((ret = pcidriver_kmem_sync(privdata, &ksync)) != 0) - return ret; - - WRITE_TO_USER(kmem_sync_t, ksync); - - return 0; -} - -/* - * - * Maps the given scatter/gather list from memory to PCI bus addresses. - * - * @see pcidriver_umem_sgmap - * - */ -static int ioctl_umem_sgmap(pcidriver_privdata_t *privdata, unsigned long arg) -{ - int ret; - READ_FROM_USER(umem_handle_t, uhandle); - - if ((ret = pcidriver_umem_sgmap(privdata, &uhandle)) != 0) - return ret; - - WRITE_TO_USER(umem_handle_t, uhandle); - - return 0; -} - -/** - * - * Unmaps the given scatter/gather list. - * - * @see pcidriver_umem_sgunmap - * - */ -static int ioctl_umem_sgunmap(pcidriver_privdata_t *privdata, unsigned long arg) -{ - int ret; - pcidriver_umem_entry_t *umem_entry; - READ_FROM_USER(umem_handle_t, uhandle); - - /* Find the associated umem_entry for this buffer, - * return -EINVAL if the specified handle id is invalid */ - if ((umem_entry = pcidriver_umem_find_entry_id(privdata, uhandle.handle_id)) == NULL) - return -EINVAL; - - if ((ret = pcidriver_umem_sgunmap(privdata, umem_entry)) != 0) - return ret; - - return 0; -} - -/** - * - * Copies the scatter/gather list from kernelspace to userspace. - * - * @see pcidriver_umem_sgget - * - */ -static int ioctl_umem_sgget(pcidriver_privdata_t *privdata, unsigned long arg) -{ - int ret; - READ_FROM_USER(umem_sglist_t, usglist); - - /* The umem_sglist_t has a pointer to the scatter/gather list itself which - * needs to be copied separately. The number of elements is stored in ->nents. - * As the list can get very big, we need to use vmalloc. */ - if ((usglist.sg = vmalloc(usglist.nents * sizeof(umem_sgentry_t))) == NULL) - return -ENOMEM; - - /* copy array to kernel structure */ - ret = copy_from_user(usglist.sg, ((umem_sglist_t *)arg)->sg, (usglist.nents)*sizeof(umem_sgentry_t)); - if (ret) return -EFAULT; - - if ((ret = pcidriver_umem_sgget(privdata, &usglist)) != 0) - return ret; - - /* write data to user space */ - ret = copy_to_user(((umem_sglist_t *)arg)->sg, usglist.sg, (usglist.nents)*sizeof(umem_sgentry_t)); - if (ret) return -EFAULT; - - /* free array memory */ - vfree(usglist.sg); - - /* restore sg pointer to vma address in user space before copying */ - usglist.sg = ((umem_sglist_t *)arg)->sg; - - WRITE_TO_USER(umem_sglist_t, usglist); - - return 0; -} - -/** - * - * Syncs user memory. - * - * @see pcidriver_umem_sync - * - */ -static int ioctl_umem_sync(pcidriver_privdata_t *privdata, unsigned long arg) -{ - int ret; - READ_FROM_USER(umem_handle_t, uhandle); - - return pcidriver_umem_sync( privdata, &uhandle ); -} - -/** - * - * Waits for an interrupt - * - * @param arg Not a pointer, but the irq source to wait for (unsigned int) - * - */ -static int ioctl_wait_interrupt(pcidriver_privdata_t *privdata, unsigned long arg) -{ -#ifdef ENABLE_IRQ - int ret; - unsigned long timeout; - unsigned int irq_source; - unsigned long temp = 0; - - READ_FROM_USER(interrupt_wait_t, irq_handle); - - irq_source = irq_handle.source; - - if (irq_source >= PCIDRIVER_INT_MAXSOURCES) - return -EFAULT; /* User tried to overrun the IRQ_SOURCES array */ - - timeout = jiffies + (irq_handle.timeout * HZ / 1000000); - - /* Thanks to Joern for the correction and tips! */ - /* done this way to avoid wrong behaviour (endless loop) of the compiler in AMD platforms */ - do { - /* We wait here with an interruptible timeout. This will be interrupted - * by int.c:check_acknowledge_channel() as soon as in interrupt for - * the specified source arrives. */ - wait_event_interruptible_timeout( (privdata->irq_queues[irq_source]), (atomic_read(&(privdata->irq_outstanding[irq_source])) > 0), (10*HZ/1000) ); - - if (atomic_add_negative( -1, &(privdata->irq_outstanding[irq_source])) ) - atomic_inc( &(privdata->irq_outstanding[irq_source]) ); - else - temp = 1; - } while ((!temp)&&(jiffies < timeout)); - - if ((temp)&&(irq_handle.count)) { - while (!atomic_add_negative( -1, &(privdata->irq_outstanding[irq_source]))) temp++; - atomic_inc( &(privdata->irq_outstanding[irq_source]) ); - } - - irq_handle.count = temp; - - WRITE_TO_USER(interrupt_wait_t, irq_handle); - - return 0; -#else - mod_info("Asked to wait for interrupt but interrupts are not enabled in the driver\n"); - return -EFAULT; -#endif -} - -/** - * - * Clears the interrupt wait queue. - * - * @param arg Not a pointer, but the irq source (unsigned int) - * @returns -EFAULT if the user specified an irq source out of range - * - */ -static int ioctl_clear_ioq(pcidriver_privdata_t *privdata, unsigned long arg) -{ -#ifdef ENABLE_IRQ - unsigned int irq_source; - - if (arg >= PCIDRIVER_INT_MAXSOURCES) - return -EFAULT; - - irq_source = arg; - atomic_set(&(privdata->irq_outstanding[irq_source]), 0); - - return 0; -#else - mod_info("Asked to wait for interrupt but interrupts are not enabled in the driver\n"); - return -EFAULT; -#endif -} - -/** - * - * This function handles all ioctl file operations. - * Generally, the data of the ioctl is copied from userspace to kernelspace, a separate - * function is called to handle the ioctl itself, then the data is copied back to userspace. - * - * @returns -EFAULT when an invalid memory pointer is passed - * - */ -#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,11) -int pcidriver_ioctl(struct inode *inode, struct file *filp, unsigned int cmd, unsigned long arg) -#else -long pcidriver_ioctl(struct file *filp, unsigned int cmd, unsigned long arg) -#endif -{ - pcidriver_privdata_t *privdata = filp->private_data; - - /* Select the appropiate command */ - switch (cmd) { - case PCIDRIVER_IOC_MMAP_MODE: - return ioctl_mmap_mode(privdata, arg); - - case PCIDRIVER_IOC_MMAP_AREA: - return ioctl_mmap_area(privdata, arg); - - case PCIDRIVER_IOC_PCI_CFG_RD: - case PCIDRIVER_IOC_PCI_CFG_WR: - return ioctl_pci_config_read_write(privdata, cmd, arg); - - case PCIDRIVER_IOC_PCI_INFO: - return ioctl_pci_info(privdata, arg); - - case PCIDRIVER_IOC_KMEM_ALLOC: - return ioctl_kmem_alloc(privdata, arg); - - case PCIDRIVER_IOC_KMEM_FREE: - return ioctl_kmem_free(privdata, arg); - - case PCIDRIVER_IOC_KMEM_SYNC: - return ioctl_kmem_sync(privdata, arg); - - case PCIDRIVER_IOC_UMEM_SGMAP: - return ioctl_umem_sgmap(privdata, arg); - - case PCIDRIVER_IOC_UMEM_SGUNMAP: - return ioctl_umem_sgunmap(privdata, arg); - - case PCIDRIVER_IOC_UMEM_SGGET: - return ioctl_umem_sgget(privdata, arg); - - case PCIDRIVER_IOC_UMEM_SYNC: - return ioctl_umem_sync(privdata, arg); - - case PCIDRIVER_IOC_WAITI: - return ioctl_wait_interrupt(privdata, arg); - - case PCIDRIVER_IOC_CLEAR_IOQ: - return ioctl_clear_ioq(privdata, arg); - - default: - return -EINVAL; - } -} diff --git a/driver/ioctl.h b/driver/ioctl.h deleted file mode 100644 index 696fb8b..0000000 --- a/driver/ioctl.h +++ /dev/null @@ -1,5 +0,0 @@ -#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,11) -int pcidriver_ioctl(struct inode *inode, struct file *filp, unsigned int cmd, unsigned long arg); -#else -long pcidriver_ioctl(struct file *filp, unsigned int cmd, unsigned long arg); -#endif diff --git a/driver/kmem.c b/driver/kmem.c deleted file mode 100644 index b323272..0000000 --- a/driver/kmem.c +++ /dev/null @@ -1,657 +0,0 @@ -/** - * - * @file kmem.c - * @brief This file contains all functions dealing with kernel memory. - * @author Guillermo Marcus - * @date 2009-04-05 - * - */ -#include <linux/version.h> -#include <linux/string.h> -#include <linux/types.h> -#include <linux/list.h> -#include <linux/interrupt.h> -#include <linux/pci.h> -#include <linux/cdev.h> -#include <linux/wait.h> -#include <linux/mm.h> -#include <linux/pagemap.h> - -#include "config.h" /* compile-time configuration */ -#include "compat.h" /* compatibility definitions for older linux */ -#include "pciDriver.h" /* external interface for the driver */ -#include "common.h" /* internal definitions for all parts */ -#include "kmem.h" /* prototypes for kernel memory */ -#include "sysfs.h" /* prototypes for sysfs */ - -/* VM_RESERVED is removed in 3.7-rc1 */ -#ifndef VM_RESERVED -# define VM_RESERVED (VM_DONTEXPAND | VM_DONTDUMP) -#endif - -/** - * - * Allocates new kernel memory including the corresponding management structure, makes - * it available via sysfs if possible. - * - */ -int pcidriver_kmem_alloc(pcidriver_privdata_t *privdata, kmem_handle_t *kmem_handle) -{ - int flags; - pcidriver_kmem_entry_t *kmem_entry; - void *retptr; - - if (kmem_handle->flags&KMEM_FLAG_REUSE) { - kmem_entry = pcidriver_kmem_find_entry_use(privdata, kmem_handle->use, kmem_handle->item); - if (kmem_entry) { - unsigned long flags = kmem_handle->flags; - - if (flags&KMEM_FLAG_TRY) { - kmem_handle->type = kmem_entry->type; - kmem_handle->size = kmem_entry->size; - kmem_handle->align = kmem_entry->align; - } else { - if (kmem_handle->type != kmem_entry->type) { - mod_info("Invalid type of reusable kmem_entry, currently: %lu, but requested: %lu\n", kmem_entry->type, kmem_handle->type); - return -EINVAL; - } - - if ((kmem_handle->type&PCILIB_KMEM_TYPE_MASK) == PCILIB_KMEM_TYPE_PAGE) { - kmem_handle->size = kmem_entry->size; - } else if (kmem_handle->size != kmem_entry->size) { - mod_info("Invalid size of reusable kmem_entry, currently: %lu, but requested: %lu\n", kmem_entry->size, kmem_handle->size); - return -EINVAL; - } - - if (kmem_handle->align != kmem_entry->align) { - mod_info("Invalid alignment of reusable kmem_entry, currently: %lu, but requested: %lu\n", kmem_entry->align, kmem_handle->align); - return -EINVAL; - } - - if (((kmem_entry->mode&KMEM_MODE_EXCLUSIVE)?1:0) != ((flags&KMEM_FLAG_EXCLUSIVE)?1:0)) { - mod_info("Invalid mode of reusable kmem_entry\n"); - return -EINVAL; - } - } - - - if ((kmem_entry->mode&KMEM_MODE_COUNT)==KMEM_MODE_COUNT) { - mod_info("Reuse counter of kmem_entry is overflown"); - return -EBUSY; - } - - - kmem_handle->handle_id = kmem_entry->id; - kmem_handle->pa = (unsigned long)(kmem_entry->dma_handle); - - kmem_handle->flags = KMEM_FLAG_REUSED; - if (kmem_entry->refs&KMEM_REF_HW) kmem_handle->flags |= KMEM_FLAG_REUSED_HW; - if (kmem_entry->mode&KMEM_MODE_PERSISTENT) kmem_handle->flags |= KMEM_FLAG_REUSED_PERSISTENT; - - kmem_entry->mode += 1; - if (flags&KMEM_FLAG_HW) { - if ((kmem_entry->refs&KMEM_REF_HW)==0) - pcidriver_module_get(privdata); - - kmem_entry->refs |= KMEM_REF_HW; - } - if (flags&KMEM_FLAG_PERSISTENT) kmem_entry->mode |= KMEM_MODE_PERSISTENT; - - privdata->kmem_cur_id = kmem_entry->id; - - return 0; - } - - if (kmem_handle->flags&KMEM_FLAG_TRY) return -ENOENT; - } - - /* First, allocate zeroed memory for the kmem_entry */ - if ((kmem_entry = kcalloc(1, sizeof(pcidriver_kmem_entry_t), GFP_KERNEL)) == NULL) - goto kmem_alloc_entry_fail; - - /* Initialize the kmem_entry */ - kmem_entry->id = atomic_inc_return(&privdata->kmem_count) - 1; - privdata->kmem_cur_id = kmem_entry->id; - kmem_handle->handle_id = kmem_entry->id; - - kmem_entry->use = kmem_handle->use; - kmem_entry->item = kmem_handle->item; - kmem_entry->type = kmem_handle->type; - kmem_entry->align = kmem_handle->align; - kmem_entry->direction = PCI_DMA_NONE; - - /* Initialize sysfs if possible */ - if (pcidriver_sysfs_initialize_kmem(privdata, kmem_entry->id, &(kmem_entry->sysfs_attr)) != 0) - goto kmem_alloc_mem_fail; - - /* ...and allocate the DMA memory */ - /* note this is a memory pair, referencing the same area: the cpu address (cpua) - * and the PCI bus address (pa). The CPU and PCI addresses may not be the same. - * The CPU sees only CPU addresses, while the device sees only PCI addresses. - * CPU address is used for the mmap (internal to the driver), and - * PCI address is the address passed to the DMA Controller in the device. - */ - switch (kmem_entry->type&PCILIB_KMEM_TYPE_MASK) { - case PCILIB_KMEM_TYPE_CONSISTENT: - retptr = pci_alloc_consistent( privdata->pdev, kmem_handle->size, &(kmem_entry->dma_handle) ); - break; - case PCILIB_KMEM_TYPE_REGION: - retptr = ioremap(kmem_handle->pa, kmem_handle->size); - kmem_entry->dma_handle = kmem_handle->pa; - if (kmem_entry->type == PCILIB_KMEM_TYPE_REGION_S2C) { - kmem_entry->direction = PCI_DMA_TODEVICE; - } else if (kmem_entry->type == PCILIB_KMEM_TYPE_REGION_C2S) { - kmem_entry->direction = PCI_DMA_FROMDEVICE; - } - break; - case PCILIB_KMEM_TYPE_PAGE: - flags = GFP_KERNEL; - - if (kmem_handle->size == 0) - kmem_handle->size = PAGE_SIZE; - else if (kmem_handle->size%PAGE_SIZE) - goto kmem_alloc_mem_fail; - - retptr = (void*)__get_free_pages(flags, get_order(kmem_handle->size)); - kmem_entry->dma_handle = 0; - - if (retptr) { - if (kmem_entry->type == PCILIB_KMEM_TYPE_DMA_S2C_PAGE) { - kmem_entry->direction = PCI_DMA_TODEVICE; - kmem_entry->dma_handle = pci_map_single(privdata->pdev, retptr, kmem_handle->size, PCI_DMA_TODEVICE); - if (pci_dma_mapping_error(privdata->pdev, kmem_entry->dma_handle)) { - free_pages((unsigned long)retptr, get_order(kmem_handle->size)); - goto kmem_alloc_mem_fail; - } - } else if (kmem_entry->type == PCILIB_KMEM_TYPE_DMA_C2S_PAGE) { - kmem_entry->direction = PCI_DMA_FROMDEVICE; - kmem_entry->dma_handle = pci_map_single(privdata->pdev, retptr, kmem_handle->size, PCI_DMA_FROMDEVICE); - if (pci_dma_mapping_error(privdata->pdev, kmem_entry->dma_handle)) { - free_pages((unsigned long)retptr, get_order(kmem_handle->size)); - goto kmem_alloc_mem_fail; - - } - } - } - - break; - default: - goto kmem_alloc_mem_fail; - } - - - if (retptr == NULL) - goto kmem_alloc_mem_fail; - - kmem_entry->size = kmem_handle->size; - kmem_entry->cpua = (unsigned long)retptr; - kmem_handle->pa = (unsigned long)(kmem_entry->dma_handle); - - kmem_entry->mode = 1; - if (kmem_handle->flags&KMEM_FLAG_REUSE) { - kmem_entry->mode |= KMEM_MODE_REUSABLE; - if (kmem_handle->flags&KMEM_FLAG_EXCLUSIVE) kmem_entry->mode |= KMEM_MODE_EXCLUSIVE; - if (kmem_handle->flags&KMEM_FLAG_PERSISTENT) kmem_entry->mode |= KMEM_MODE_PERSISTENT; - } - - kmem_entry->refs = 0; - if (kmem_handle->flags&KMEM_FLAG_HW) { - pcidriver_module_get(privdata); - - kmem_entry->refs |= KMEM_REF_HW; - } - - kmem_handle->flags = 0; - - set_pages_reserved_compat(kmem_entry->cpua, kmem_entry->size); - - /* Add the kmem_entry to the list of the device */ - spin_lock( &(privdata->kmemlist_lock) ); - list_add_tail( &(kmem_entry->list), &(privdata->kmem_list) ); - spin_unlock( &(privdata->kmemlist_lock) ); - - return 0; - -kmem_alloc_mem_fail: - kfree(kmem_entry); -kmem_alloc_entry_fail: - return -ENOMEM; -} - -static int pcidriver_kmem_free_check(pcidriver_privdata_t *privdata, kmem_handle_t *kmem_handle, pcidriver_kmem_entry_t *kmem_entry) { - if ((kmem_handle->flags & KMEM_FLAG_FORCE) == 0) { - if (kmem_entry->mode&KMEM_MODE_COUNT) - kmem_entry->mode -= 1; - - if (kmem_handle->flags&KMEM_FLAG_HW) { - if (kmem_entry->refs&KMEM_REF_HW) - pcidriver_module_put(privdata); - - kmem_entry->refs &= ~KMEM_REF_HW; - } - - if (kmem_handle->flags&KMEM_FLAG_PERSISTENT) - kmem_entry->mode &= ~KMEM_MODE_PERSISTENT; - - if (kmem_handle->flags&KMEM_FLAG_REUSE) - return 0; - - if (kmem_entry->refs) { - kmem_entry->mode += 1; - mod_info("can't free referenced kmem_entry\n"); - return -EBUSY; - } - - if (kmem_entry->mode & KMEM_MODE_PERSISTENT) { - kmem_entry->mode += 1; - mod_info("can't free persistent kmem_entry\n"); - return -EBUSY; - } - - if (((kmem_entry->mode&KMEM_MODE_EXCLUSIVE)==0)&&(kmem_entry->mode&KMEM_MODE_COUNT)&&((kmem_handle->flags&KMEM_FLAG_EXCLUSIVE)==0)) - return 0; - } else { - if (kmem_entry->refs&KMEM_REF_HW) - pcidriver_module_put(privdata); - - while (!atomic_add_negative(-1, &(privdata->refs))) pcidriver_module_put(privdata); - atomic_inc(&(privdata->refs)); - - } - - return 1; -} - -static int pcidriver_kmem_free_use(pcidriver_privdata_t *privdata, kmem_handle_t *kmem_handle) -{ - int err; - int failed = 0; - struct list_head *ptr, *next; - pcidriver_kmem_entry_t *kmem_entry; - - /* iterate safely over the entries and delete them */ - list_for_each_safe(ptr, next, &(privdata->kmem_list)) { - kmem_entry = list_entry(ptr, pcidriver_kmem_entry_t, list); - if (kmem_entry->use == kmem_handle->use) { - err = pcidriver_kmem_free_check(privdata, kmem_handle, kmem_entry); - if (err > 0) - pcidriver_kmem_free_entry(privdata, kmem_entry); /* spin lock inside! */ - else - failed = 1; - } - } - - if (failed) { - mod_info("Some kmem_entries for use %lx are still referenced\n", kmem_handle->use); - return -EBUSY; - } - - return 0; -} - -/** - * - * Called via sysfs, frees kernel memory and the corresponding management structure - * - */ -int pcidriver_kmem_free( pcidriver_privdata_t *privdata, kmem_handle_t *kmem_handle ) -{ - int err; - pcidriver_kmem_entry_t *kmem_entry; - - if (kmem_handle->flags&KMEM_FLAG_MASS) { - kmem_handle->flags &= ~KMEM_FLAG_MASS; - return pcidriver_kmem_free_use(privdata, kmem_handle); - } - - /* Find the associated kmem_entry for this buffer */ - if ((kmem_entry = pcidriver_kmem_find_entry(privdata, kmem_handle)) == NULL) - return -EINVAL; /* kmem_handle is not valid */ - - err = pcidriver_kmem_free_check(privdata, kmem_handle, kmem_entry); - - if (err > 0) - return pcidriver_kmem_free_entry(privdata, kmem_entry); - - return err; -} - -/** - * - * Called when cleaning up, frees all kernel memory and their corresponding management structure - * - */ -int pcidriver_kmem_free_all(pcidriver_privdata_t *privdata) -{ -// int failed = 0; - struct list_head *ptr, *next; - pcidriver_kmem_entry_t *kmem_entry; - - /* iterate safely over the entries and delete them */ - list_for_each_safe(ptr, next, &(privdata->kmem_list)) { - kmem_entry = list_entry(ptr, pcidriver_kmem_entry_t, list); - /*if (kmem_entry->refs) - failed = 1; - else*/ - pcidriver_kmem_free_entry(privdata, kmem_entry); /* spin lock inside! */ - } -/* - if (failed) { - mod_info("Some kmem_entries are still referenced\n"); - return -EBUSY; - } -*/ - return 0; -} - - -/** - * - * Synchronize memory to/from the device (or in both directions). - * - */ -int pcidriver_kmem_sync_entry( pcidriver_privdata_t *privdata, pcidriver_kmem_entry_t *kmem_entry, int direction) -{ - if (kmem_entry->direction == PCI_DMA_NONE) - return -EINVAL; - -#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,11) - switch (direction) { - case PCILIB_KMEM_SYNC_TODEVICE: - pci_dma_sync_single_for_device( privdata->pdev, kmem_entry->dma_handle, kmem_entry->size, kmem_entry->direction ); - break; - case PCILIB_KMEM_SYNC_FROMDEVICE: - pci_dma_sync_single_for_cpu( privdata->pdev, kmem_entry->dma_handle, kmem_entry->size, kmem_entry->direction ); - break; - case PCILIB_KMEM_SYNC_BIDIRECTIONAL: - pci_dma_sync_single_for_device( privdata->pdev, kmem_entry->dma_handle, kmem_entry->size, kmem_entry->direction ); - pci_dma_sync_single_for_cpu( privdata->pdev, kmem_entry->dma_handle, kmem_entry->size, kmem_entry->direction ); - break; - default: - return -EINVAL; /* wrong direction parameter */ - } -#else - switch (direction) { - case PCILIB_KMEM_SYNC_TODEVICE: - pci_dma_sync_single( privdata->pdev, kmem_entry->dma_handle, kmem_entry->size, kmem_entry->direction ); - break; - case PCILIB_KMEM_SYNC_FROMDEVICE: - pci_dma_sync_single( privdata->pdev, kmem_entry->dma_handle, kmem_entry->size, kmem_entry->direction ); - break; - case PCILIB_KMEM_SYNC_BIDIRECTIONAL: - pci_dma_sync_single( privdata->pdev, kmem_entry->dma_handle, kmem_entry->size, kmem_entry->direction ); - break; - default: - return -EINVAL; /* wrong direction parameter */ - } -#endif - - return 0; /* success */ -} - -/** - * - * Synchronize memory to/from the device (or in both directions). - * - */ -int pcidriver_kmem_sync( pcidriver_privdata_t *privdata, kmem_sync_t *kmem_sync ) -{ - pcidriver_kmem_entry_t *kmem_entry; - - /* Find the associated kmem_entry for this buffer */ - if ((kmem_entry = pcidriver_kmem_find_entry(privdata, &(kmem_sync->handle))) == NULL) - return -EINVAL; /* kmem_handle is not valid */ - - return pcidriver_kmem_sync_entry(privdata, kmem_entry, kmem_sync->dir); -} - -/** - * - * Free the given kmem_entry and its memory. - * - */ -int pcidriver_kmem_free_entry(pcidriver_privdata_t *privdata, pcidriver_kmem_entry_t *kmem_entry) -{ - pcidriver_sysfs_remove(privdata, &(kmem_entry->sysfs_attr)); - - /* Go over the pages of the kmem buffer, and mark them as not reserved */ -#if 0 -#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,15) - /* - * This code is DISABLED. - * Apparently, it is not needed to unreserve them. Doing so here - * hangs the machine. Why? - * - * Uhm.. see links: - * - * http://lwn.net/Articles/161204/ - * http://lists.openfabrics.org/pipermail/general/2007-March/034101.html - * - * I insist, this should be enabled, but doing so hangs the machine. - * Literature supports the point, and there is even a similar problem (see link) - * But this is not the case. It seems right to me. but obviously is not. - * - * Anyway, this goes away in kernel >=2.6.15. - */ - unsigned long start = __pa(kmem_entry->cpua) >> PAGE_SHIFT; - unsigned long end = __pa(kmem_entry->cpua + kmem_entry->size) >> PAGE_SHIFT; - unsigned long i; - for(i=start;i<end;i++) { - struct page *kpage = pfn_to_page(i); - ClearPageReserved(kpage); - } -#endif -#endif - - /* Release DMA memory */ - switch (kmem_entry->type&PCILIB_KMEM_TYPE_MASK) { - case PCILIB_KMEM_TYPE_CONSISTENT: - pci_free_consistent( privdata->pdev, kmem_entry->size, (void *)(kmem_entry->cpua), kmem_entry->dma_handle ); - break; - case PCILIB_KMEM_TYPE_REGION: - iounmap((void *)(kmem_entry->cpua)); - break; - case PCILIB_KMEM_TYPE_PAGE: - if (kmem_entry->dma_handle) { - if (kmem_entry->type == PCILIB_KMEM_TYPE_DMA_S2C_PAGE) { - pci_unmap_single(privdata->pdev, kmem_entry->dma_handle, kmem_entry->size, PCI_DMA_TODEVICE); - } else if (kmem_entry->type == PCILIB_KMEM_TYPE_DMA_C2S_PAGE) { - pci_unmap_single(privdata->pdev, kmem_entry->dma_handle, kmem_entry->size, PCI_DMA_FROMDEVICE); - } - } - free_pages((unsigned long)kmem_entry->cpua, get_order(kmem_entry->size)); - break; - } - - - /* Remove the kmem list entry */ - spin_lock( &(privdata->kmemlist_lock) ); - list_del( &(kmem_entry->list) ); - spin_unlock( &(privdata->kmemlist_lock) ); - - /* Release kmem_entry memory */ - kfree(kmem_entry); - - return 0; -} - -/** - * - * Find the corresponding kmem_entry for the given kmem_handle. - * - */ -pcidriver_kmem_entry_t *pcidriver_kmem_find_entry(pcidriver_privdata_t *privdata, kmem_handle_t *kmem_handle) -{ - struct list_head *ptr; - pcidriver_kmem_entry_t *entry, *result = NULL; - - /* should I implement it better using the handle_id? */ - - spin_lock(&(privdata->kmemlist_lock)); - list_for_each(ptr, &(privdata->kmem_list)) { - entry = list_entry(ptr, pcidriver_kmem_entry_t, list); - - if (entry->id == kmem_handle->handle_id) { - result = entry; - break; - } - } - - spin_unlock(&(privdata->kmemlist_lock)); - return result; -} - -/** - * - * find the corresponding kmem_entry for the given id. - * - */ -pcidriver_kmem_entry_t *pcidriver_kmem_find_entry_id(pcidriver_privdata_t *privdata, int id) -{ - struct list_head *ptr; - pcidriver_kmem_entry_t *entry, *result = NULL; - - spin_lock(&(privdata->kmemlist_lock)); - list_for_each(ptr, &(privdata->kmem_list)) { - entry = list_entry(ptr, pcidriver_kmem_entry_t, list); - - if (entry->id == id) { - result = entry; - break; - } - } - - spin_unlock(&(privdata->kmemlist_lock)); - return result; -} - -/** - * - * find the corresponding kmem_entry for the given use and item. - * - */ -pcidriver_kmem_entry_t *pcidriver_kmem_find_entry_use(pcidriver_privdata_t *privdata, unsigned long use, unsigned long item) -{ - struct list_head *ptr; - pcidriver_kmem_entry_t *entry, *result = NULL; - - spin_lock(&(privdata->kmemlist_lock)); - list_for_each(ptr, &(privdata->kmem_list)) { - entry = list_entry(ptr, pcidriver_kmem_entry_t, list); - - if ((entry->use == use)&&(entry->item == item)&&(entry->mode&KMEM_MODE_REUSABLE)) { - result = entry; - break; - } - } - - spin_unlock(&(privdata->kmemlist_lock)); - return result; -} - - -void pcidriver_kmem_mmap_close(struct vm_area_struct *vma) { - unsigned long vma_size; - pcidriver_kmem_entry_t *kmem_entry = (pcidriver_kmem_entry_t*)vma->vm_private_data; - if (kmem_entry) { -/* - if (kmem_entry->id == 0) { - mod_info("refs: %p %p %lx\n", vma, vma->vm_private_data, kmem_entry->refs); - mod_info("kmem_size: %lu vma_size: %lu, s: %lx, e: %lx\n", kmem_entry->size, (vma->vm_end - vma->vm_start), vma->vm_start, vma->vm_end); - } -*/ - - vma_size = (vma->vm_end - vma->vm_start); - - if (kmem_entry->refs&KMEM_REF_COUNT) { - kmem_entry->refs -= vma_size / PAGE_SIZE; - } - } -} - -static struct vm_operations_struct pcidriver_kmem_mmap_ops = { - .close = pcidriver_kmem_mmap_close -}; - -/** - * - * mmap() kernel memory to userspace. - * - */ -int pcidriver_mmap_kmem(pcidriver_privdata_t *privdata, struct vm_area_struct *vma) -{ - unsigned long vma_size; - pcidriver_kmem_entry_t *kmem_entry; - int ret; - - mod_info_dbg("Entering mmap_kmem\n"); - - /* FIXME: Is this really right? Always just the latest one? Can't we identify one? */ - /* Get latest entry on the kmem_list */ - kmem_entry = pcidriver_kmem_find_entry_id(privdata, privdata->kmem_cur_id); - if (!kmem_entry) { - mod_info("Trying to mmap a kernel memory buffer without creating it first!\n"); - return -EFAULT; - } - - mod_info_dbg("Got kmem_entry with id: %d\n", kmem_entry->id); - - /* Check sizes */ - vma_size = (vma->vm_end - vma->vm_start); - - if ((vma_size > kmem_entry->size) && - ((kmem_entry->size < PAGE_SIZE) && (vma_size != PAGE_SIZE))) { - mod_info("kem_entry size(%lu) and vma size do not match(%lu)\n", kmem_entry->size, vma_size); - return -EINVAL; - } - - /* reference counting */ - if ((kmem_entry->mode&KMEM_MODE_EXCLUSIVE)&&(kmem_entry->refs&KMEM_REF_COUNT)) { - mod_info("can't make second mmaping for exclusive kmem_entry\n"); - return -EBUSY; - } - if (((kmem_entry->refs&KMEM_REF_COUNT) + (vma_size / PAGE_SIZE)) > KMEM_REF_COUNT) { - mod_info("maximal amount of references is reached by kmem_entry\n"); - return -EBUSY; - } - - kmem_entry->refs += vma_size / PAGE_SIZE; - - vma->vm_flags |= (VM_RESERVED); - -#ifdef pgprot_noncached - // This is coherent memory, so it must not be cached. - vma->vm_page_prot = pgprot_noncached(vma->vm_page_prot); -#endif - - mod_info_dbg("Mapping address %08lx / PFN %08lx\n", - virt_to_phys((void*)kmem_entry->cpua), - page_to_pfn(virt_to_page((void*)kmem_entry->cpua))); - - if ((kmem_entry->type&PCILIB_KMEM_TYPE_MASK) == PCILIB_KMEM_TYPE_REGION) { - ret = remap_pfn_range_compat( - vma, - vma->vm_start, - kmem_entry->dma_handle, - (vma_size < kmem_entry->size)?vma_size:kmem_entry->size, - vma->vm_page_prot); - } else { - ret = remap_pfn_range_cpua_compat( - vma, - vma->vm_start, - kmem_entry->cpua, - (vma_size < kmem_entry->size)?vma_size:kmem_entry->size, - vma->vm_page_prot ); - } - - if (ret) { - mod_info("kmem remap failed: %d (%lx)\n", ret,kmem_entry->cpua); - kmem_entry->refs -= 1; - return -EAGAIN; - } - - vma->vm_ops = &pcidriver_kmem_mmap_ops; - vma->vm_private_data = (void*)kmem_entry; - - return ret; -} diff --git a/driver/kmem.h b/driver/kmem.h deleted file mode 100644 index 503620e..0000000 --- a/driver/kmem.h +++ /dev/null @@ -1,9 +0,0 @@ -int pcidriver_kmem_alloc( pcidriver_privdata_t *privdata, kmem_handle_t *kmem_handle ); -int pcidriver_kmem_free( pcidriver_privdata_t *privdata, kmem_handle_t *kmem_handle ); -int pcidriver_kmem_sync_entry( pcidriver_privdata_t *privdata, pcidriver_kmem_entry_t *kmem_entry, int direction ); -int pcidriver_kmem_sync( pcidriver_privdata_t *privdata, kmem_sync_t *kmem_sync ); -int pcidriver_kmem_free_all( pcidriver_privdata_t *privdata ); -pcidriver_kmem_entry_t *pcidriver_kmem_find_entry( pcidriver_privdata_t *privdata, kmem_handle_t *kmem_handle ); -pcidriver_kmem_entry_t *pcidriver_kmem_find_entry_id( pcidriver_privdata_t *privdata, int id ); -pcidriver_kmem_entry_t *pcidriver_kmem_find_entry_use(pcidriver_privdata_t *privdata, unsigned long use, unsigned long item); -int pcidriver_kmem_free_entry( pcidriver_privdata_t *privdata, pcidriver_kmem_entry_t *kmem_entry ); diff --git a/driver/pciDriver.h b/driver/pciDriver.h deleted file mode 100644 index 67a80f2..0000000 --- a/driver/pciDriver.h +++ /dev/null @@ -1,217 +0,0 @@ -#ifndef PCIDRIVER_H_ -#define PCIDRIVER_H_ - -/** - * This is a full rewrite of the pciDriver. - * New default is to support kernel 2.6, using kernel 2.6 APIs. - * - * This header defines the interface to the outside world. - * - * $Revision: 1.6 $ - * $Date: 2008-01-24 14:21:36 $ - * - */ - -/* - * Change History: - * - * $Log: not supported by cvs2svn $ - * Revision 1.5 2008-01-11 10:15:14 marcus - * Removed unused interrupt code. - * Added intSource to the wait interrupt call. - * - * Revision 1.4 2006/11/17 18:44:42 marcus - * Type of SG list can now be selected at runtime. Added type to sglist. - * - * Revision 1.3 2006/11/17 16:23:02 marcus - * Added slot number to the PCI info IOctl. - * - * Revision 1.2 2006/11/13 12:29:09 marcus - * Added a IOctl call, to confiure the interrupt response. (testing pending). - * Basic interrupts are now supported. - * - * Revision 1.1 2006/10/10 14:46:52 marcus - * Initial commit of the new pciDriver for kernel 2.6 - * - * Revision 1.7 2006/10/06 15:18:06 marcus - * Updated PCI info and PCI cmd - * - * Revision 1.6 2006/09/25 16:51:07 marcus - * Added PCI config IOctls, and implemented basic mmap functions. - * - * Revision 1.5 2006/09/18 17:13:12 marcus - * backup commit. - * - * Revision 1.4 2006/09/15 15:44:41 marcus - * backup commit. - * - * Revision 1.3 2006/08/15 11:40:02 marcus - * backup commit. - * - * Revision 1.2 2006/08/12 18:28:42 marcus - * Sync with the laptop - * - * Revision 1.1 2006/08/11 15:30:46 marcus - * Sync with the laptop - * - */ - -#include <linux/ioctl.h> -#include "../pcilib_types.h" - -/* Identifies the PCI-E Xilinx ML605 */ -#define PCIE_XILINX_VENDOR_ID 0x10ee -#define PCIE_ML605_DEVICE_ID 0x6024 - -/* Identifies the PCI-E IPE Camera */ -#define PCIE_IPECAMERA_DEVICE_ID 0x6081 -#define PCIE_KAPTURE_DEVICE_ID 0x6028 -//#define PCIE_IPECAMERA_DEVICE_ID 0x6018 - - -/* Possible values for ioctl commands */ - -/* PCI mmap areas */ -#define PCIDRIVER_BAR0 0 -#define PCIDRIVER_BAR1 1 -#define PCIDRIVER_BAR2 2 -#define PCIDRIVER_BAR3 3 -#define PCIDRIVER_BAR4 4 -#define PCIDRIVER_BAR5 5 - -/* mmap mode of the device */ -#define PCIDRIVER_MMAP_PCI 0 -#define PCIDRIVER_MMAP_KMEM 1 - -/* Direction of a DMA operation */ -#define PCIDRIVER_DMA_BIDIRECTIONAL 0 -#define PCIDRIVER_DMA_TODEVICE PCILIB_KMEM_SYNC_TODEVICE -#define PCIDRIVER_DMA_FROMDEVICE PCILIB_KMEM_SYNC_FROMDEVICE - -/* Possible sizes in a PCI command */ -#define PCIDRIVER_PCI_CFG_SZ_BYTE 1 -#define PCIDRIVER_PCI_CFG_SZ_WORD 2 -#define PCIDRIVER_PCI_CFG_SZ_DWORD 3 - -/* Possible types of SG lists */ -#define PCIDRIVER_SG_NONMERGED 0 -#define PCIDRIVER_SG_MERGED 1 - -/* Maximum number of interrupt sources */ -#define PCIDRIVER_INT_MAXSOURCES 16 - - -#define KMEM_FLAG_REUSE 1 /**< Try to reuse existing buffer with the same use & item */ -#define KMEM_FLAG_EXCLUSIVE 2 /**< Allow only a single application accessing a specified use & item */ -#define KMEM_FLAG_PERSISTENT 4 /**< Sets persistent mode */ -#define KMEM_FLAG_HW 8 /**< The buffer may be accessed by hardware, the hardware access will not occur any more if passed to _free function */ -#define KMEM_FLAG_FORCE 16 /**< Force memory cleanup even if references are present */ -#define KMEM_FLAG_MASS 32 /**< Apply to all buffers of selected use */ -#define KMEM_FLAG_TRY 64 /**< Do not allocate buffers, try to reuse and fail if not possible */ - -#define KMEM_FLAG_REUSED 1 /**< Indicates if buffer with specified use & item was already allocated and reused */ -#define KMEM_FLAG_REUSED_PERSISTENT 4 /**< Indicates that reused buffer was persistent before the call */ -#define KMEM_FLAG_REUSED_HW 8 /**< Indicates that reused buffer had a HW reference before the call */ - - -/* Types */ -typedef struct { - unsigned long type; - unsigned long pa; - unsigned long size; - unsigned long align; - unsigned long use; - unsigned long item; - int flags; - int handle_id; -} kmem_handle_t; - -typedef struct { - unsigned long addr; - unsigned long size; -} umem_sgentry_t; - -typedef struct { - int handle_id; - int type; - int nents; - umem_sgentry_t *sg; -} umem_sglist_t; - -typedef struct { - unsigned long vma; - unsigned long size; - int handle_id; - int dir; -} umem_handle_t; - -typedef struct { - kmem_handle_t handle; - int dir; -} kmem_sync_t; - -typedef struct { - unsigned long count; - unsigned long timeout; // microseconds - unsigned int source; -} interrupt_wait_t; - -typedef struct { - int size; - int addr; - union { - unsigned char byte; - unsigned short word; - unsigned int dword; /* not strict C, but if not can have problems */ - } val; -} pci_cfg_cmd; - -typedef struct { - unsigned short vendor_id; - unsigned short device_id; - unsigned short bus; - unsigned short slot; - unsigned short func; - unsigned short devfn; - unsigned char interrupt_pin; - unsigned char interrupt_line; - unsigned int irq; - unsigned long bar_start[6]; - unsigned long bar_length[6]; - unsigned long bar_flags[6]; -} pcilib_board_info_t; - - -/* ioctl interface */ -/* See documentation for a detailed usage explanation */ - -/* - * one of the problems of ioctl, is that requires a type definition. - * This type is only 8-bits wide, and half-documented in - * <linux-src>/Documentation/ioctl-number.txt. - * previous SHL -> 'S' definition, conflicts with several devices, - * so I changed it to be pci -> 'p', in the range 0xA0-AF - */ -#define PCIDRIVER_IOC_MAGIC 'p' -#define PCIDRIVER_IOC_BASE 0xA0 - -#define PCIDRIVER_IOC_MMAP_MODE _IO( PCIDRIVER_IOC_MAGIC, PCIDRIVER_IOC_BASE + 0 ) -#define PCIDRIVER_IOC_MMAP_AREA _IO( PCIDRIVER_IOC_MAGIC, PCIDRIVER_IOC_BASE + 1 ) -#define PCIDRIVER_IOC_KMEM_ALLOC _IOWR( PCIDRIVER_IOC_MAGIC, PCIDRIVER_IOC_BASE + 2, kmem_handle_t * ) -#define PCIDRIVER_IOC_KMEM_FREE _IOW ( PCIDRIVER_IOC_MAGIC, PCIDRIVER_IOC_BASE + 3, kmem_handle_t * ) -#define PCIDRIVER_IOC_KMEM_SYNC _IOWR( PCIDRIVER_IOC_MAGIC, PCIDRIVER_IOC_BASE + 4, kmem_sync_t * ) -#define PCIDRIVER_IOC_UMEM_SGMAP _IOWR( PCIDRIVER_IOC_MAGIC, PCIDRIVER_IOC_BASE + 5, umem_handle_t * ) -#define PCIDRIVER_IOC_UMEM_SGUNMAP _IOW( PCIDRIVER_IOC_MAGIC, PCIDRIVER_IOC_BASE + 6, umem_handle_t * ) -#define PCIDRIVER_IOC_UMEM_SGGET _IOWR( PCIDRIVER_IOC_MAGIC, PCIDRIVER_IOC_BASE + 7, umem_sglist_t * ) -#define PCIDRIVER_IOC_UMEM_SYNC _IOW( PCIDRIVER_IOC_MAGIC, PCIDRIVER_IOC_BASE + 8, umem_handle_t * ) -#define PCIDRIVER_IOC_WAITI _IO( PCIDRIVER_IOC_MAGIC, PCIDRIVER_IOC_BASE + 9 ) - -/* And now, the methods to access the PCI configuration area */ -#define PCIDRIVER_IOC_PCI_CFG_RD _IOWR( PCIDRIVER_IOC_MAGIC, PCIDRIVER_IOC_BASE + 10, pci_cfg_cmd * ) -#define PCIDRIVER_IOC_PCI_CFG_WR _IOWR( PCIDRIVER_IOC_MAGIC, PCIDRIVER_IOC_BASE + 11, pci_cfg_cmd * ) -#define PCIDRIVER_IOC_PCI_INFO _IOWR( PCIDRIVER_IOC_MAGIC, PCIDRIVER_IOC_BASE + 12, pcilib_board_info_t * ) - -/* Clear interrupt queues */ -#define PCIDRIVER_IOC_CLEAR_IOQ _IO( PCIDRIVER_IOC_MAGIC, PCIDRIVER_IOC_BASE + 13 ) - -#endif diff --git a/driver/sysfs.c b/driver/sysfs.c deleted file mode 100644 index abc1c8a..0000000 --- a/driver/sysfs.c +++ /dev/null @@ -1,308 +0,0 @@ -/** - * - * @file sysfs.c - * @brief This file contains the functions providing the SysFS-interface. - * @author Guillermo Marcus - * @date 2010-03-01 - * - */ -#include <linux/version.h> -#include <linux/string.h> -#include <linux/types.h> -#include <linux/list.h> -#include <linux/interrupt.h> -#include <linux/pci.h> -#include <linux/cdev.h> -#include <linux/wait.h> -#include <linux/mm.h> -#include <linux/pagemap.h> -#include <linux/kernel.h> - -#include "compat.h" -#include "config.h" -#include "pciDriver.h" -#include "common.h" -#include "umem.h" -#include "kmem.h" -#include "sysfs.h" - -static SYSFS_GET_FUNCTION(pcidriver_show_kmem_entry); -static SYSFS_GET_FUNCTION(pcidriver_show_umem_entry); - -/** - * - * Initializes the sysfs attributes for an kmem/umem-entry - * - */ -static int _pcidriver_sysfs_initialize(pcidriver_privdata_t *privdata, - int id, - struct class_device_attribute *sysfs_attr, - const char *fmtstring, - SYSFS_GET_FUNCTION((*callback))) -{ - /* sysfs attributes for kmem buffers don’t make sense before 2.6.13, as - we have no mmap support before */ -#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,13) - char namebuffer[16]; - - /* allocate space for the name of the attribute */ - snprintf(namebuffer, sizeof(namebuffer), fmtstring, id); - - if ((sysfs_attr->attr.name = kstrdup(namebuffer, GFP_KERNEL)) == NULL) - return -ENOMEM; - - sysfs_attr->attr.mode = S_IRUGO; -#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,24) - // DS: Shall we lock now while accessing driver data structures??? - sysfs_attr->attr.owner = THIS_MODULE; -#endif - sysfs_attr->show = callback; - sysfs_attr->store = NULL; - - /* name and add attribute */ - if (class_device_create_file(privdata->class_dev, sysfs_attr) != 0) - return -ENXIO; /* Device not configured. Not the really best choice, but hm. */ -#endif - - return 0; -} - -int pcidriver_sysfs_initialize_kmem(pcidriver_privdata_t *privdata, int id, struct class_device_attribute *sysfs_attr) -{ - return _pcidriver_sysfs_initialize(privdata, id, sysfs_attr, "kbuf%d", pcidriver_show_kmem_entry); -} - -int pcidriver_sysfs_initialize_umem(pcidriver_privdata_t *privdata, int id, struct class_device_attribute *sysfs_attr) -{ - return _pcidriver_sysfs_initialize(privdata, id, sysfs_attr, "umem%d", pcidriver_show_umem_entry); -} - -/** - * - * Removes the file from sysfs and frees the allocated (kstrdup()) memory. - * - */ -void pcidriver_sysfs_remove(pcidriver_privdata_t *privdata, struct class_device_attribute *sysfs_attr) -{ -#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,13) - class_device_remove_file(privdata->class_dev, sysfs_attr); - kfree(sysfs_attr->attr.name); -#endif -} - -static SYSFS_GET_FUNCTION(pcidriver_show_kmem_entry) -{ -#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,13) - pcidriver_privdata_t *privdata = SYSFS_GET_PRIVDATA; - - /* As we can be sure that attr.name contains a filename which we - * created (see _pcidriver_sysfs_initialize), we do not need to have - * sanity checks but can directly call simple_strtol() */ - int id = simple_strtol(attr->attr.name + strlen("kbuf"), NULL, 10); - pcidriver_kmem_entry_t *entry = pcidriver_kmem_find_entry_id(privdata, id); - if (entry) { - unsigned long addr = entry->cpua; - unsigned long dma_addr = entry->dma_handle; - - if (entry->size >= 16) { - pcidriver_kmem_sync_entry(privdata, entry, PCILIB_KMEM_SYNC_FROMDEVICE); - return snprintf(buf, PAGE_SIZE, "buffer: %d\naddr: %lx\nhw addr: %llx\nbus addr: %lx\ntype: %lx\nuse: 0x%lx\nitem: %lu\nsize: %lu\nrefs: %lu\nhw ref: %i\nmode: 0x%lx\ndata: %8x %8x %8x %8x\n", id, addr, virt_to_phys((void*)addr), dma_addr, entry->type, entry->use, entry->item, entry->size, entry->refs&KMEM_REF_COUNT, (entry->refs&KMEM_REF_HW)?1:0, entry->mode, *(u32*)(entry->cpua), *(u32*)(entry->cpua + 4), *(u32*)(entry->cpua + 8), *(u32*)(entry->cpua + 12)); - } else - return snprintf(buf, PAGE_SIZE, "buffer: %d\naddr: %lx\nhw addr: %llx\nbus addr: %lx\ntype: %lx\nuse: 0x%lx\nitem: %lu\nsize: %lu\nrefs: %lu\nhw ref: %i\nmode: 0x%lx\n", id, addr, virt_to_phys((void*)addr), dma_addr, entry->type, entry->use, entry->item, entry->size, entry->refs&KMEM_REF_COUNT, (entry->refs&KMEM_REF_HW)?1:0, entry->mode); - } else - return snprintf(buf, PAGE_SIZE, "I am in the kmem_entry show function for buffer %d\n", id); -#else - return 0; -#endif -} - -static SYSFS_GET_FUNCTION(pcidriver_show_umem_entry) -{ -#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,13) -#if 0 - pcidriver_privdata_t *privdata = (pcidriver_privdata_t *)cls->class_data; - - return snprintf(buf, PAGE_SIZE, "I am in the umem_entry show function, class_device_kobj_name: %s\n", cls->kobj.name); -#endif - return 0; -#else - return 0; -#endif -} - -#ifdef ENABLE_IRQ -SYSFS_GET_FUNCTION(pcidriver_show_irq_count) -{ - pcidriver_privdata_t *privdata = SYSFS_GET_PRIVDATA; - - return snprintf(buf, PAGE_SIZE, "%d\n", privdata->irq_count); -} - -SYSFS_GET_FUNCTION(pcidriver_show_irq_queues) -{ - pcidriver_privdata_t *privdata = SYSFS_GET_PRIVDATA; - int i, offset; - - /* output will be truncated to PAGE_SIZE */ - offset = snprintf(buf, PAGE_SIZE, "Queue\tOutstanding IRQs\n"); - for (i = 0; i < PCIDRIVER_INT_MAXSOURCES; i++) - offset += snprintf(buf+offset, PAGE_SIZE-offset, "%d\t%d\n", i, atomic_read(&(privdata->irq_outstanding[i])) ); - - return (offset > PAGE_SIZE ? PAGE_SIZE : offset+1); -} -#endif - -SYSFS_GET_FUNCTION(pcidriver_show_mmap_mode) -{ - pcidriver_privdata_t *privdata = SYSFS_GET_PRIVDATA; - - return snprintf(buf, PAGE_SIZE, "%d\n", privdata->mmap_mode); -} - -SYSFS_SET_FUNCTION(pcidriver_store_mmap_mode) -{ - pcidriver_privdata_t *privdata = SYSFS_GET_PRIVDATA; - int mode = -1; - - /* Set the mmap-mode if it is either PCIDRIVER_MMAP_PCI or PCIDRIVER_MMAP_KMEM */ - if (sscanf(buf, "%d", &mode) == 1 && - (mode == PCIDRIVER_MMAP_PCI || mode == PCIDRIVER_MMAP_KMEM)) - privdata->mmap_mode = mode; - - return strlen(buf); -} - -SYSFS_GET_FUNCTION(pcidriver_show_mmap_area) -{ - pcidriver_privdata_t *privdata = SYSFS_GET_PRIVDATA; - - return snprintf(buf, PAGE_SIZE, "%d\n", privdata->mmap_area); -} - -SYSFS_SET_FUNCTION(pcidriver_store_mmap_area) -{ - pcidriver_privdata_t *privdata = SYSFS_GET_PRIVDATA; - int temp = -1; - - sscanf(buf, "%d", &temp); - - if ((temp >= PCIDRIVER_BAR0) && (temp <= PCIDRIVER_BAR5)) - privdata->mmap_area = temp; - - return strlen(buf); -} - -SYSFS_GET_FUNCTION(pcidriver_show_kmem_count) -{ - pcidriver_privdata_t *privdata = SYSFS_GET_PRIVDATA; - - return snprintf(buf, PAGE_SIZE, "%d\n", atomic_read(&(privdata->kmem_count))); -} - -SYSFS_SET_FUNCTION(pcidriver_store_kmem_alloc) -{ - pcidriver_privdata_t *privdata = SYSFS_GET_PRIVDATA; - kmem_handle_t kmem_handle; - - /* FIXME: guillermo: is validation of parsing an unsigned int enough? */ - if (sscanf(buf, "%lu", &kmem_handle.size) == 1) - pcidriver_kmem_alloc(privdata, &kmem_handle); - - return strlen(buf); -} - -SYSFS_SET_FUNCTION(pcidriver_store_kmem_free) -{ - pcidriver_privdata_t *privdata = SYSFS_GET_PRIVDATA; - unsigned int id; - pcidriver_kmem_entry_t *kmem_entry; - - /* Parse the ID of the kernel memory to be freed, check bounds */ - if (sscanf(buf, "%u", &id) != 1 || - (id >= atomic_read(&(privdata->kmem_count)))) - goto err; - - if ((kmem_entry = pcidriver_kmem_find_entry_id(privdata,id)) == NULL) - goto err; - - pcidriver_kmem_free_entry(privdata, kmem_entry ); -err: - return strlen(buf); -} - -SYSFS_GET_FUNCTION(pcidriver_show_kbuffers) -{ - pcidriver_privdata_t *privdata = SYSFS_GET_PRIVDATA; - int offset = 0; - struct list_head *ptr; - pcidriver_kmem_entry_t *entry; - - /* print the header */ - offset += snprintf(buf, PAGE_SIZE, "kbuf#\tcpu addr\tsize\n"); - - spin_lock(&(privdata->kmemlist_lock)); - list_for_each(ptr, &(privdata->kmem_list)) { - entry = list_entry(ptr, pcidriver_kmem_entry_t, list); - - /* print entry info */ - if (offset > PAGE_SIZE) { - spin_unlock( &(privdata->kmemlist_lock) ); - return PAGE_SIZE; - } - - offset += snprintf(buf+offset, PAGE_SIZE-offset, "%3d\t%08lx\t%lu\n", entry->id, (unsigned long)(entry->dma_handle), entry->size ); - } - - spin_unlock(&(privdata->kmemlist_lock)); - - /* output will be truncated to PAGE_SIZE */ - return (offset > PAGE_SIZE ? PAGE_SIZE : offset+1); -} - -SYSFS_GET_FUNCTION(pcidriver_show_umappings) -{ - int offset = 0; - pcidriver_privdata_t *privdata = SYSFS_GET_PRIVDATA; - struct list_head *ptr; - pcidriver_umem_entry_t *entry; - - /* print the header */ - offset += snprintf(buf, PAGE_SIZE, "umap#\tn_pages\tsg_ents\n"); - - spin_lock( &(privdata->umemlist_lock) ); - list_for_each( ptr, &(privdata->umem_list) ) { - entry = list_entry(ptr, pcidriver_umem_entry_t, list ); - - /* print entry info */ - if (offset > PAGE_SIZE) { - spin_unlock( &(privdata->umemlist_lock) ); - return PAGE_SIZE; - } - - offset += snprintf(buf+offset, PAGE_SIZE-offset, "%3d\t%lu\t%lu\n", entry->id, - (unsigned long)(entry->nr_pages), (unsigned long)(entry->nents)); - } - - spin_unlock( &(privdata->umemlist_lock) ); - - /* output will be truncated to PAGE_SIZE */ - return (offset > PAGE_SIZE ? PAGE_SIZE : offset+1); -} - -SYSFS_SET_FUNCTION(pcidriver_store_umem_unmap) -{ - pcidriver_privdata_t *privdata = SYSFS_GET_PRIVDATA; - pcidriver_umem_entry_t *umem_entry; - unsigned int id; - - if (sscanf(buf, "%u", &id) != 1 || - (id >= atomic_read(&(privdata->umem_count)))) - goto err; - - if ((umem_entry = pcidriver_umem_find_entry_id(privdata, id)) == NULL) - goto err; - - pcidriver_umem_sgunmap(privdata, umem_entry); -err: - return strlen(buf); -} diff --git a/driver/sysfs.h b/driver/sysfs.h deleted file mode 100644 index 4c413f0..0000000 --- a/driver/sysfs.h +++ /dev/null @@ -1,23 +0,0 @@ -#ifndef _PCIDRIVER_SYSFS_H -#define _PCIDRIVER_SYSFS_H -int pcidriver_sysfs_initialize_kmem(pcidriver_privdata_t *privdata, int id, struct class_device_attribute *sysfs_attr); -int pcidriver_sysfs_initialize_umem(pcidriver_privdata_t *privdata, int id, struct class_device_attribute *sysfs_attr); -void pcidriver_sysfs_remove(pcidriver_privdata_t *privdata, struct class_device_attribute *sysfs_attr); - -#ifdef ENABLE_IRQ -SYSFS_GET_FUNCTION(pcidriver_show_irq_count); -SYSFS_GET_FUNCTION(pcidriver_show_irq_queues); -#endif - -/* prototypes for sysfs operations */ -SYSFS_GET_FUNCTION(pcidriver_show_mmap_mode); -SYSFS_SET_FUNCTION(pcidriver_store_mmap_mode); -SYSFS_GET_FUNCTION(pcidriver_show_mmap_area); -SYSFS_SET_FUNCTION(pcidriver_store_mmap_area); -SYSFS_GET_FUNCTION(pcidriver_show_kmem_count); -SYSFS_GET_FUNCTION(pcidriver_show_kbuffers); -SYSFS_SET_FUNCTION(pcidriver_store_kmem_alloc); -SYSFS_SET_FUNCTION(pcidriver_store_kmem_free); -SYSFS_GET_FUNCTION(pcidriver_show_umappings); -SYSFS_SET_FUNCTION(pcidriver_store_umem_unmap); -#endif diff --git a/driver/umem.c b/driver/umem.c deleted file mode 100644 index 7a8dcc1..0000000 --- a/driver/umem.c +++ /dev/null @@ -1,438 +0,0 @@ -/** - * - * @file umem.c - * @brief This file contains the functions handling user space memory. - * @author Guillermo Marcus - * @date 2009-04-05 - * - */ -#include <linux/version.h> -#include <linux/string.h> -#include <linux/types.h> -#include <linux/list.h> -#include <linux/interrupt.h> -#include <linux/pci.h> -#include <linux/cdev.h> -#include <linux/wait.h> -#include <linux/mm.h> -#include <linux/pagemap.h> -#include <linux/sched.h> - -#include "config.h" /* compile-time configuration */ -#include "compat.h" /* compatibility definitions for older linux */ -#include "pciDriver.h" /* external interface for the driver */ -#include "common.h" /* internal definitions for all parts */ -#include "umem.h" /* prototypes for kernel memory */ -#include "sysfs.h" /* prototypes for sysfs */ - -/** - * - * Reserve a new scatter/gather list and map it from memory to PCI bus addresses. - * - */ -int pcidriver_umem_sgmap(pcidriver_privdata_t *privdata, umem_handle_t *umem_handle) -{ - int i, res, nr_pages; - struct page **pages; - struct scatterlist *sg = NULL; - pcidriver_umem_entry_t *umem_entry; - unsigned int nents; - unsigned long count,offset,length; - - /* - * We do some checks first. Then, the following is necessary to create a - * Scatter/Gather list from a user memory area: - * - Determine the number of pages - * - Get the pages for the memory area - * - Lock them. - * - Create a scatter/gather list of the pages - * - Map the list from memory to PCI bus addresses - * - * Then, we: - * - Create an entry on the umem list of the device, to cache the mapping. - * - Create a sysfs attribute that gives easy access to the SG list - */ - - /* zero-size?? */ - if (umem_handle->size == 0) - return -EINVAL; - - /* Direction is better ignoring during mapping. */ - /* We assume bidirectional buffers always, except when sync'ing */ - - /* calculate the number of pages */ - nr_pages = ((umem_handle->vma & ~PAGE_MASK) + umem_handle->size + ~PAGE_MASK) >> PAGE_SHIFT; - - mod_info_dbg("nr_pages computed: %u\n", nr_pages); - - /* Allocate space for the page information */ - /* This can be very big, so we use vmalloc */ - if ((pages = vmalloc(nr_pages * sizeof(*pages))) == NULL) - return -ENOMEM; - - mod_info_dbg("allocated space for the pages.\n"); - - /* Allocate space for the scatterlist */ - /* We do not know how many entries will be, but the maximum is nr_pages. */ - /* This can be very big, so we use vmalloc */ - if ((sg = vmalloc(nr_pages * sizeof(*sg))) == NULL) - goto umem_sgmap_pages; - - sg_init_table(sg, nr_pages); - - mod_info_dbg("allocated space for the SG list.\n"); - - /* Get the page information */ - down_read(¤t->mm->mmap_sem); - res = get_user_pages( - current, - current->mm, - umem_handle->vma, - nr_pages, - 1, - 0, /* do not force, FIXME: shall I? */ - pages, - NULL ); - up_read(¤t->mm->mmap_sem); - - /* Error, not all pages mapped */ - if (res < (int)nr_pages) { - mod_info("Could not map all user pages (%d of %d)\n", res, nr_pages); - /* If only some pages could be mapped, we release those. If a real - * error occured, we set nr_pages to 0 */ - nr_pages = (res > 0 ? res : 0); - goto umem_sgmap_unmap; - } - - mod_info_dbg("Got the pages (%d).\n", res); - - /* Lock the pages, then populate the SG list with the pages */ - /* page0 is different */ - if ( !PageReserved(pages[0]) ) - compat_lock_page(pages[0]); - - offset = (umem_handle->vma & ~PAGE_MASK); - length = (umem_handle->size > (PAGE_SIZE-offset) ? (PAGE_SIZE-offset) : umem_handle->size); - - sg_set_page(&sg[0], pages[0], length, offset); - - count = umem_handle->size - length; - for(i=1;i<nr_pages;i++) { - /* Lock page first */ - if ( !PageReserved(pages[i]) ) - compat_lock_page(pages[i]); - - /* Populate the list */ - sg_set_page(&sg[i], pages[i], ((count > PAGE_SIZE) ? PAGE_SIZE : count), 0); - count -= sg[i].length; - } - - /* Use the page list to populate the SG list */ - /* SG entries may be merged, res is the number of used entries */ - /* We have originally nr_pages entries in the sg list */ - if ((nents = pci_map_sg(privdata->pdev, sg, nr_pages, PCI_DMA_BIDIRECTIONAL)) == 0) - goto umem_sgmap_unmap; - - mod_info_dbg("Mapped SG list (%d entries).\n", nents); - - /* Add an entry to the umem_list of the device, and update the handle with the id */ - /* Allocate space for the new umem entry */ - if ((umem_entry = kmalloc(sizeof(*umem_entry), GFP_KERNEL)) == NULL) - goto umem_sgmap_entry; - - /* Fill entry to be added to the umem list */ - umem_entry->id = atomic_inc_return(&privdata->umem_count) - 1; - umem_entry->nr_pages = nr_pages; /* Will be needed when unmapping */ - umem_entry->pages = pages; - umem_entry->nents = nents; - umem_entry->sg = sg; - - if (pcidriver_sysfs_initialize_umem(privdata, umem_entry->id, &(umem_entry->sysfs_attr)) != 0) - goto umem_sgmap_name_fail; - - /* Add entry to the umem list */ - spin_lock( &(privdata->umemlist_lock) ); - list_add_tail( &(umem_entry->list), &(privdata->umem_list) ); - spin_unlock( &(privdata->umemlist_lock) ); - - /* Update the Handle with the Handle ID of the entry */ - umem_handle->handle_id = umem_entry->id; - - return 0; - -umem_sgmap_name_fail: - kfree(umem_entry); -umem_sgmap_entry: - pci_unmap_sg( privdata->pdev, sg, nr_pages, PCI_DMA_BIDIRECTIONAL ); -umem_sgmap_unmap: - /* release pages */ - if (nr_pages > 0) { - for(i=0;i<nr_pages;i++) { - if (PageLocked(pages[i])) - compat_unlock_page(pages[i]); - if (!PageReserved(pages[i])) - set_page_dirty(pages[i]); - page_cache_release(pages[i]); - } - } - vfree(sg); -umem_sgmap_pages: - vfree(pages); - return -ENOMEM; - -} - -/** - * - * Unmap a scatter/gather list - * - */ -int pcidriver_umem_sgunmap(pcidriver_privdata_t *privdata, pcidriver_umem_entry_t *umem_entry) -{ - int i; - pcidriver_sysfs_remove(privdata, &(umem_entry->sysfs_attr)); - - /* Unmap user memory */ - pci_unmap_sg( privdata->pdev, umem_entry->sg, umem_entry->nr_pages, PCI_DMA_BIDIRECTIONAL ); - - /* Release the pages */ - if (umem_entry->nr_pages > 0) { - for(i=0;i<(umem_entry->nr_pages);i++) { - /* Mark pages as Dirty and unlock it */ - if ( !PageReserved( umem_entry->pages[i] )) { - SetPageDirty( umem_entry->pages[i] ); - compat_unlock_page(umem_entry->pages[i]); - } - /* and release it from the cache */ - page_cache_release( umem_entry->pages[i] ); - } - } - - /* Remove the umem list entry */ - spin_lock( &(privdata->umemlist_lock) ); - list_del( &(umem_entry->list) ); - spin_unlock( &(privdata->umemlist_lock) ); - - /* Release SG list and page list memory */ - /* These two are in the vm area of the kernel */ - vfree(umem_entry->pages); - vfree(umem_entry->sg); - - /* Release umem_entry memory */ - kfree(umem_entry); - - return 0; -} - -/** - * - * Unmap all scatter/gather lists. - * - */ -int pcidriver_umem_sgunmap_all(pcidriver_privdata_t *privdata) -{ - struct list_head *ptr, *next; - pcidriver_umem_entry_t *umem_entry; - - /* iterate safely over the entries and delete them */ - list_for_each_safe( ptr, next, &(privdata->umem_list) ) { - umem_entry = list_entry(ptr, pcidriver_umem_entry_t, list ); - pcidriver_umem_sgunmap( privdata, umem_entry ); /* spin lock inside! */ - } - - return 0; -} - -/** - * - * Copies the scatter/gather list from kernelspace to userspace. - * - */ -int pcidriver_umem_sgget(pcidriver_privdata_t *privdata, umem_sglist_t *umem_sglist) -{ - int i; - pcidriver_umem_entry_t *umem_entry; - struct scatterlist *sg; - int idx = 0; - dma_addr_t cur_addr; - unsigned int cur_size; - - /* Find the associated umem_entry for this buffer */ - umem_entry = pcidriver_umem_find_entry_id( privdata, umem_sglist->handle_id ); - if (umem_entry == NULL) - return -EINVAL; /* umem_handle is not valid */ - - /* Check if passed SG list is enough */ - if (umem_sglist->nents < umem_entry->nents) - return -EINVAL; /* sg has not enough entries */ - - /* Copy the SG list to the user format */ -#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,24) - if (umem_sglist->type == PCIDRIVER_SG_MERGED) { - for_each_sg(umem_entry->sg, sg, umem_entry->nents, i ) { - if (i==0) { - umem_sglist->sg[0].addr = sg_dma_address( sg ); - umem_sglist->sg[0].size = sg_dma_len( sg ); - idx = 0; - } - else { - cur_addr = sg_dma_address( sg ); - cur_size = sg_dma_len( sg ); - - /* Check if entry fits after current entry */ - if (cur_addr == (umem_sglist->sg[idx].addr + umem_sglist->sg[idx].size)) { - umem_sglist->sg[idx].size += cur_size; - continue; - } - - /* Skip if the entry is zero-length (yes, it can happen.... at the end of the list) */ - if (cur_size == 0) - continue; - - /* None of the above, add new entry */ - idx++; - umem_sglist->sg[idx].addr = cur_addr; - umem_sglist->sg[idx].size = cur_size; - } - } - /* Set the used size of the SG list */ - umem_sglist->nents = idx+1; - } else { - for_each_sg(umem_entry->sg, sg, umem_entry->nents, i ) { - mod_info("entry: %d\n",i); - umem_sglist->sg[i].addr = sg_dma_address( sg ); - umem_sglist->sg[i].size = sg_dma_len( sg ); - } - - /* Set the used size of the SG list */ - /* Check if the last one is zero-length */ - if ( umem_sglist->sg[ umem_entry->nents - 1].size == 0) - umem_sglist->nents = umem_entry->nents -1; - else - umem_sglist->nents = umem_entry->nents; - } -#else - if (umem_sglist->type == PCIDRIVER_SG_MERGED) { - /* Merge entries that are contiguous into a single entry */ - /* Non-optimal but fast for most cases */ - /* First one always true */ - sg=umem_entry->sg; - umem_sglist->sg[0].addr = sg_dma_address( sg ); - umem_sglist->sg[0].size = sg_dma_len( sg ); - sg++; - idx = 0; - - /* Iterate over the SG entries */ - for(i=1; i< umem_entry->nents; i++, sg++ ) { - cur_addr = sg_dma_address( sg ); - cur_size = sg_dma_len( sg ); - - /* Check if entry fits after current entry */ - if (cur_addr == (umem_sglist->sg[idx].addr + umem_sglist->sg[idx].size)) { - umem_sglist->sg[idx].size += cur_size; - continue; - } - - /* Skip if the entry is zero-length (yes, it can happen.... at the end of the list) */ - if (cur_size == 0) - continue; - - /* None of the above, add new entry */ - idx++; - umem_sglist->sg[idx].addr = cur_addr; - umem_sglist->sg[idx].size = cur_size; - } - /* Set the used size of the SG list */ - umem_sglist->nents = idx+1; - } else { - /* Assume pci_map_sg made a good job (ehem..) and just copy it. - * actually, now I assume it just gives them plainly to me. */ - for(i=0, sg=umem_entry->sg ; i< umem_entry->nents; i++, sg++ ) { - umem_sglist->sg[i].addr = sg_dma_address( sg ); - umem_sglist->sg[i].size = sg_dma_len( sg ); - } - /* Set the used size of the SG list */ - /* Check if the last one is zero-length */ - if ( umem_sglist->sg[ umem_entry->nents - 1].size == 0) - umem_sglist->nents = umem_entry->nents -1; - else - umem_sglist->nents = umem_entry->nents; - } -#endif - - return 0; -} - -/** - * - * Sync user space memory from/to device - * - */ -int pcidriver_umem_sync( pcidriver_privdata_t *privdata, umem_handle_t *umem_handle ) -{ - pcidriver_umem_entry_t *umem_entry; - - /* Find the associated umem_entry for this buffer */ - umem_entry = pcidriver_umem_find_entry_id( privdata, umem_handle->handle_id ); - if (umem_entry == NULL) - return -EINVAL; /* umem_handle is not valid */ - -#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,11) - switch (umem_handle->dir) { - case PCIDRIVER_DMA_TODEVICE: - pci_dma_sync_sg_for_device( privdata->pdev, umem_entry->sg, umem_entry->nents, PCI_DMA_TODEVICE ); - break; - case PCIDRIVER_DMA_FROMDEVICE: - pci_dma_sync_sg_for_cpu( privdata->pdev, umem_entry->sg, umem_entry->nents, PCI_DMA_FROMDEVICE ); - break; - case PCIDRIVER_DMA_BIDIRECTIONAL: - pci_dma_sync_sg_for_device( privdata->pdev, umem_entry->sg, umem_entry->nents, PCI_DMA_BIDIRECTIONAL ); - pci_dma_sync_sg_for_cpu( privdata->pdev, umem_entry->sg, umem_entry->nents, PCI_DMA_BIDIRECTIONAL ); - break; - default: - return -EINVAL; /* wrong direction parameter */ - } -#else - switch (umem_handle->dir) { - case PCIDRIVER_DMA_TODEVICE: - pci_dma_sync_sg( privdata->pdev, umem_entry->sg, umem_entry->nents, PCI_DMA_TODEVICE ); - break; - case PCIDRIVER_DMA_FROMDEVICE: - pci_dma_sync_sg( privdata->pdev, umem_entry->sg, umem_entry->nents, PCI_DMA_FROMDEVICE ); - break; - case PCIDRIVER_DMA_BIDIRECTIONAL: - pci_dma_sync_sg( privdata->pdev, umem_entry->sg, umem_entry->nents, PCI_DMA_BIDIRECTIONAL ); - break; - default: - return -EINVAL; /* wrong direction parameter */ - } -#endif - - return 0; -} - -/* - * - * Get the pcidriver_umem_entry_t structure for the given id. - * - * @param id ID of the umem entry to search for - * - */ -pcidriver_umem_entry_t *pcidriver_umem_find_entry_id(pcidriver_privdata_t *privdata, int id) -{ - struct list_head *ptr; - pcidriver_umem_entry_t *entry; - - spin_lock(&(privdata->umemlist_lock)); - list_for_each(ptr, &(privdata->umem_list)) { - entry = list_entry(ptr, pcidriver_umem_entry_t, list ); - - if (entry->id == id) { - spin_unlock( &(privdata->umemlist_lock) ); - return entry; - } - } - - spin_unlock(&(privdata->umemlist_lock)); - return NULL; -} diff --git a/driver/umem.h b/driver/umem.h deleted file mode 100644 index d16c466..0000000 --- a/driver/umem.h +++ /dev/null @@ -1,5 +0,0 @@ -int pcidriver_umem_sgmap( pcidriver_privdata_t *privdata, umem_handle_t *umem_handle ); -int pcidriver_umem_sgunmap( pcidriver_privdata_t *privdata, pcidriver_umem_entry_t *umem_entry ); -int pcidriver_umem_sgget( pcidriver_privdata_t *privdata, umem_sglist_t *umem_sglist ); -int pcidriver_umem_sync( pcidriver_privdata_t *privdata, umem_handle_t *umem_handle ); -pcidriver_umem_entry_t *pcidriver_umem_find_entry_id( pcidriver_privdata_t *privdata, int id ); diff --git a/error.c b/error.c deleted file mode 100644 index b4f6e2e..0000000 --- a/error.c +++ /dev/null @@ -1,27 +0,0 @@ -#define _PCILIB_ERROR_C - -#include <stdio.h> -#include <stdarg.h> - -#include "error.h" - -static void pcilib_print_error(const char *msg, ...) { - va_list va; - - va_start(va, msg); - vprintf(msg, va); - va_end(va); - printf("\n"); -} - -void (*pcilib_error)(const char *msg, ...) = pcilib_print_error; -void (*pcilib_warning)(const char *msg, ...) = pcilib_print_error; - -int pcilib_set_error_handler(void (*err)(const char *msg, ...), void (*warn)(const char *msg, ...)) { - if (err) pcilib_error = err; - else pcilib_error = pcilib_print_error; - if (warn) pcilib_warning = warn; - else pcilib_warning = pcilib_print_error; - - return 0; -} diff --git a/error.h b/error.h deleted file mode 100644 index 20d1c09..0000000 --- a/error.h +++ /dev/null @@ -1,34 +0,0 @@ -#ifndef _PCILIB_ERROR_H -#define _PCILIB_ERROR_H - -#include <errno.h> - -enum { - PCILIB_ERROR_SUCCESS = 0, - PCILIB_ERROR_MEMORY = ENOMEM, - PCILIB_ERROR_INVALID_REQUEST = EBADR, - PCILIB_ERROR_INVALID_ADDRESS = EFAULT, - PCILIB_ERROR_INVALID_BANK = ENOENT, - PCILIB_ERROR_INVALID_DATA = EILSEQ, - PCILIB_ERROR_INVALID_STATE = EBADFD, - PCILIB_ERROR_INVALID_ARGUMENT = EINVAL, - PCILIB_ERROR_TIMEOUT = ETIME, - PCILIB_ERROR_FAILED = EBADE, - PCILIB_ERROR_VERIFY = EREMOTEIO, - PCILIB_ERROR_NOTSUPPORTED = ENOTSUP, - PCILIB_ERROR_NOTFOUND = ESRCH, - PCILIB_ERROR_OUTOFRANGE = ERANGE, - PCILIB_ERROR_NOTAVAILABLE = ENAVAIL, - PCILIB_ERROR_NOTINITIALIZED = EBADFD, - PCILIB_ERROR_TOOBIG = EFBIG, - PCILIB_ERROR_OVERWRITTEN = ESTALE, - PCILIB_ERROR_BUSY = EBUSY -} pcilib_errot_t; - - -#ifndef _PCILIB_ERROR_C -extern void (*pcilib_error)(const char *msg, ...); -extern void (*pcilib_warning)(const char *msg, ...); -#endif /* _PCILIB_ERROR_C */ - -#endif /* _PCILIB_ERROR_H */ diff --git a/event.c b/event.c deleted file mode 100644 index d9d3ff3..0000000 --- a/event.c +++ /dev/null @@ -1,450 +0,0 @@ -#define _POSIX_C_SOURCE 199309L -#include <stdio.h> -#include <string.h> -#include <strings.h> -#include <stdlib.h> -#include <stdint.h> -#include <stdarg.h> -#include <fcntl.h> -#include <unistd.h> -#include <sys/ioctl.h> -#include <sys/mman.h> -#include <arpa/inet.h> -#include <errno.h> -#include <assert.h> -#include <time.h> - -#include "pci.h" - -#include "tools.h" -#include "error.h" - -#ifndef __timespec_defined -struct timespec { - time_t tv_sec; - long tv_nsec; -}; -#endif /* __timespec_defined */ - - -pcilib_event_t pcilib_find_event(pcilib_t *ctx, const char *event) { - int i; - - pcilib_model_description_t *model_info = pcilib_get_model_description(ctx); - pcilib_event_description_t *events = model_info->events; - - for (i = 0; events[i].name; i++) { - if (!strcasecmp(events[i].name, event)) return events[i].evid; - } - - return (pcilib_event_t)-1; -} - -pcilib_event_data_type_t pcilib_find_event_data_type(pcilib_t *ctx, pcilib_event_t event, const char *data_type) { - int i; - - pcilib_model_description_t *model_info = pcilib_get_model_description(ctx); - pcilib_event_data_type_description_t *data_types = model_info->data_types; - - for (i = 0; data_types[i].name; i++) { - if ((data_types[i].evid&event)&&(!strcasecmp(data_types[i].name, data_type))) return data_types[i].data_type; - } - - return (pcilib_event_data_type_t)-1; -} - -int pcilib_init_event_engine(pcilib_t *ctx) { - pcilib_event_api_description_t *api; - pcilib_model_description_t *model_info = pcilib_get_model_description(ctx); - - api = model_info->event_api; - -// api = pcilib_model[model].event_api; - if ((api)&&(api->init)) { - ctx->event_ctx = api->init(ctx); - if (ctx->event_ctx) { - ctx->event_ctx->pcilib = ctx; - } - } - - return 0; -} - -int pcilib_reset(pcilib_t *ctx) { - pcilib_event_api_description_t *api; - - pcilib_model_description_t *model_info = pcilib_get_model_description(ctx); - - api = model_info->event_api; - if (!api) { - pcilib_error("Event API is not supported by the selected model"); - return PCILIB_ERROR_NOTSUPPORTED; - } - - if (api->reset) - return api->reset(ctx->event_ctx); - - return 0; -} - -int pcilib_configure_rawdata_callback(pcilib_t *ctx, pcilib_event_rawdata_callback_t callback, void *user) { - pcilib_event_api_description_t *api; - - pcilib_model_description_t *model_info = pcilib_get_model_description(ctx); - - api = model_info->event_api; - if (!api) { - pcilib_error("Event API is not supported by the selected model"); - return PCILIB_ERROR_NOTSUPPORTED; - } - - ctx->event_ctx->params.rawdata.callback = callback; - ctx->event_ctx->params.rawdata.user = user; - - return 0; -} - -int pcilib_configure_autostop(pcilib_t *ctx, size_t max_events, pcilib_timeout_t duration) { - pcilib_event_api_description_t *api; - - pcilib_model_description_t *model_info = pcilib_get_model_description(ctx); - - api = model_info->event_api; - if (!api) { - pcilib_error("Event API is not supported by the selected model"); - return PCILIB_ERROR_NOTSUPPORTED; - } - - ctx->event_ctx->params.autostop.max_events = max_events; - ctx->event_ctx->params.autostop.duration = duration; - - return 0; -} - -int pcilib_configure_autotrigger(pcilib_t *ctx, pcilib_timeout_t interval, pcilib_event_t event, size_t trigger_size, void *trigger_data) { - /* To support hardware without autotriggering, we need to provide in event.c a code - to generate multiple triggers in a thread (available in cli). The function should - be re-enabled afterwards: just set parameters and let implementation decide if it - can make triggering in hardware or will use our emulation */ - - return PCILIB_ERROR_NOTSUPPORTED; -} - -int pcilib_configure_preprocessing_threads(pcilib_t *ctx, size_t max_threads) { - pcilib_event_api_description_t *api; - - pcilib_model_description_t *model_info = pcilib_get_model_description(ctx); - - api = model_info->event_api; - if (!api) { - pcilib_error("Event API is not supported by the selected model"); - return PCILIB_ERROR_NOTSUPPORTED; - } - - ctx->event_ctx->params.parallel.max_threads = max_threads; - - return 0; -} - -int pcilib_start(pcilib_t *ctx, pcilib_event_t event_mask, pcilib_event_flags_t flags) { - pcilib_event_api_description_t *api; - - pcilib_model_description_t *model_info = pcilib_get_model_description(ctx); - - api = model_info->event_api; - if (!api) { - pcilib_error("Event API is not supported by the selected model"); - return PCILIB_ERROR_NOTSUPPORTED; - } - - if (api->start) - return api->start(ctx->event_ctx, event_mask, flags); - - return 0; -} - -int pcilib_stop(pcilib_t *ctx, pcilib_event_flags_t flags) { - pcilib_event_api_description_t *api; - - pcilib_model_description_t *model_info = pcilib_get_model_description(ctx); - - api = model_info->event_api; - if (!api) { - pcilib_error("Event API is not supported by the selected model"); - return PCILIB_ERROR_NOTSUPPORTED; - } - - if (api->stop) - return api->stop(ctx->event_ctx, flags); - - return 0; -} - -int pcilib_stream(pcilib_t *ctx, pcilib_event_callback_t callback, void *user) { - pcilib_event_api_description_t *api; - - pcilib_model_description_t *model_info = pcilib_get_model_description(ctx); - - api = model_info->event_api; - if (!api) { - pcilib_error("Event API is not supported by the selected model"); - return PCILIB_ERROR_NOTSUPPORTED; - } - - if (api->stream) - return api->stream(ctx->event_ctx, callback, user); - - if (api->next_event) { - pcilib_error("Streaming using next_event API is not implemented yet"); - } - - pcilib_error("Event enumeration is not suppored by API"); - return PCILIB_ERROR_NOTSUPPORTED; -} -/* -typedef struct { - pcilib_event_id_t event_id; - pcilib_event_info_t *info; -} pcilib_return_event_callback_context_t; - -static int pcilib_return_event_callback(pcilib_event_id_t event_id, pcilib_event_info_t *info, void *user) { - pcilib_return_event_callback_context_t *ctx = (pcilib_return_event_callback_context_t*)user; - ctx->event_id = event_id; - ctx->info = info; -} -*/ - -int pcilib_get_next_event(pcilib_t *ctx, pcilib_timeout_t timeout, pcilib_event_id_t *evid, size_t info_size, pcilib_event_info_t *info) { - pcilib_event_api_description_t *api; -// pcilib_return_event_callback_context_t user; - - pcilib_model_description_t *model_info = pcilib_get_model_description(ctx); - - api = model_info->event_api; - if (!api) { - pcilib_error("Event API is not supported by the selected model"); - return PCILIB_ERROR_NOTSUPPORTED; - } - - if (api->next_event) - return api->next_event(ctx->event_ctx, timeout, evid, info_size, info); - -/* - if (api->stream) { - err = api->stream(ctx->event_ctx, 1, timeout, pcilib_return_event_callback, &user); - if (err) return err; - - if (evid) *evid = user->event_id; - if (info) *info = user->info; - - return 0; - } -*/ - - pcilib_error("Event enumeration is not suppored by API"); - return PCILIB_ERROR_NOTSUPPORTED; -} - -int pcilib_trigger(pcilib_t *ctx, pcilib_event_t event, size_t trigger_size, void *trigger_data) { - pcilib_event_api_description_t *api; - - pcilib_model_description_t *model_info = pcilib_get_model_description(ctx); - - api = model_info->event_api; - if (!api) { - pcilib_error("Event API is not supported by the selected model"); - return PCILIB_ERROR_NOTSUPPORTED; - } - - if (api->trigger) - return api->trigger(ctx->event_ctx, event, trigger_size, trigger_data); - - pcilib_error("Self triggering is not supported by the selected model"); - return PCILIB_ERROR_NOTSUPPORTED; -} - - -void *pcilib_get_data_with_argument(pcilib_t *ctx, pcilib_event_id_t event_id, pcilib_event_data_type_t data_type, size_t arg_size, void *arg, size_t *size) { - int err; - void *res = NULL; - pcilib_model_description_t *model_info = pcilib_get_model_description(ctx); - - pcilib_event_api_description_t *api = model_info->event_api; - if (!api) { - if (size) *size = (size_t)PCILIB_ERROR_NOTSUPPORTED; - pcilib_error("Event API is not supported by the selected model"); - return NULL; - } - - if (api->get_data) { - err = api->get_data(ctx->event_ctx, event_id, data_type, arg_size, arg, size, &res); - if (err) { - if (size) *size = (size_t)err; - return NULL; - } - return res; - } - - if (size) *size = (size_t)PCILIB_ERROR_NOTSUPPORTED; - return NULL; -} - -int pcilib_copy_data_with_argument(pcilib_t *ctx, pcilib_event_id_t event_id, pcilib_event_data_type_t data_type, size_t arg_size, void *arg, size_t size, void *buf, size_t *retsize) { - int err; - void *res = buf; - pcilib_model_description_t *model_info = pcilib_get_model_description(ctx); - - pcilib_event_api_description_t *api = model_info->event_api; - if (!api) { - pcilib_error("Event API is not supported by the selected model"); - return PCILIB_ERROR_NOTSUPPORTED; - } - - if (api->get_data) { - err = api->get_data(ctx->event_ctx, event_id, data_type, arg_size, arg, &size, &res); - if (err) return err; - - if (buf != res) memcpy(buf, res, size); - - if (retsize) *retsize = size; - return 0; - } - - return PCILIB_ERROR_NOTSUPPORTED; -} - - -void *pcilib_get_data(pcilib_t *ctx, pcilib_event_id_t event_id, pcilib_event_data_type_t data_type, size_t *size) { - int err; - void *res = NULL; - pcilib_model_description_t *model_info = pcilib_get_model_description(ctx); - - pcilib_event_api_description_t *api = model_info->event_api; - if (!api) { - pcilib_error("Event API is not supported by the selected model"); - if (size) *size = (size_t)PCILIB_ERROR_NOTSUPPORTED; - return NULL; - } - - if (api->get_data) { - err = api->get_data(ctx->event_ctx, event_id, data_type, 0, NULL, size, &res); - if (err) { - if (size) *size = (size_t)err; - return NULL; - } - return res; - } - - if (size) *size = (size_t)PCILIB_ERROR_NOTSUPPORTED; - return NULL; -} - -int pcilib_copy_data(pcilib_t *ctx, pcilib_event_id_t event_id, pcilib_event_data_type_t data_type, size_t size, void *buf, size_t *ret_size) { - int err; - void *res = buf; - pcilib_model_description_t *model_info = pcilib_get_model_description(ctx); - - pcilib_event_api_description_t *api = model_info->event_api; - if (!api) { - pcilib_error("Event API is not supported by the selected model"); - return PCILIB_ERROR_NOTSUPPORTED; - } - - if (api->get_data) { - err = api->get_data(ctx->event_ctx, event_id, data_type, 0, NULL, &size, &res); - if (err) return err; - - if (buf != res) memcpy(buf, res, size); - - if (ret_size) *ret_size = size; - return 0; - } - - return PCILIB_ERROR_NOTSUPPORTED; -} - -int pcilib_return_data(pcilib_t *ctx, pcilib_event_id_t event_id, pcilib_event_data_type_t data_type, void *data) { - pcilib_model_description_t *model_info = pcilib_get_model_description(ctx); - - pcilib_event_api_description_t *api = model_info->event_api; - if (!api) { - pcilib_error("Event API is not supported by the selected model"); - return PCILIB_ERROR_NOTSUPPORTED; - } - - if (api->return_data) - return api->return_data(ctx->event_ctx, event_id, data_type, data); - - return 0; -} - - -typedef struct { - pcilib_t *ctx; - - size_t *size; - void **data; -} pcilib_grab_callback_user_data_t; - - -static int pcilib_grab_callback(pcilib_event_t event, pcilib_event_id_t event_id, void *vuser) { - int err; - void *data; - size_t size; - int allocated = 0; - - pcilib_grab_callback_user_data_t *user = (pcilib_grab_callback_user_data_t*)vuser; - - data = pcilib_get_data(user->ctx, event_id, PCILIB_EVENT_DATA, &size); - if (!data) { - pcilib_error("Error getting event data"); - return -(int)size; - } - - if (*(user->data)) { - if ((user->size)&&(*(user->size) < size)) { - pcilib_error("The supplied buffer does not have enough space to hold the event data. Buffer size is %z, but %z is required", user->size, size); - return -PCILIB_ERROR_MEMORY; - } - - *(user->size) = size; - } else { - *(user->data) = malloc(size); - if (!*(user->data)) { - pcilib_error("Memory allocation (%i bytes) for event data is failed"); - return -PCILIB_ERROR_MEMORY; - } - if (*(user->size)) *(user->size) = size; - allocated = 1; - } - - memcpy(*(user->data), data, size); - - err = pcilib_return_data(user->ctx, event_id, PCILIB_EVENT_DATA, data); - if (err) { - if (allocated) { - free(*(user->data)); - *(user->data) = NULL; - } - pcilib_error("The event data had been overwritten before it was returned, data corruption may occur"); - return -err; - } - - return PCILIB_STREAMING_CONTINUE; -} - -int pcilib_grab(pcilib_t *ctx, pcilib_event_t event_mask, size_t *size, void **data, pcilib_timeout_t timeout) { - int err; - pcilib_event_id_t eid; - - pcilib_grab_callback_user_data_t user = {ctx, size, data}; - - err = pcilib_start(ctx, event_mask, PCILIB_EVENT_FLAGS_DEFAULT); - if (!err) err = pcilib_trigger(ctx, event_mask, 0, NULL); - if (!err) { - err = pcilib_get_next_event(ctx, timeout, &eid, 0, NULL); - if (!err) pcilib_grab_callback(event_mask, eid, &user); - } - pcilib_stop(ctx, PCILIB_EVENT_FLAGS_DEFAULT); - return err; -} diff --git a/event.h b/event.h deleted file mode 100644 index 0675b94..0000000 --- a/event.h +++ /dev/null @@ -1,69 +0,0 @@ -#ifndef _PCILIB_EVENT_H -#define _PCILIB_EVENT_H - -#include "pcilib.h" - - -/* - * get_data: This call is used by get_data and copy_data functions of public - * interface. When copy_data is the caller, the data parameter will be passed. - * Therefore, depending on data the parameter, the function should behave - * diferently. If get get_data function is used (buf == NULL), the caller is - * expected to call return_data afterwards. Otherwise, if buf != NULL and - * copy_data is used, the return call will not be executed. - * Still, the get_data function is not obliged to return the data in the - * passed buf, but a reference to the staticaly allocated memory may be - * returned instead. The copy can be managed by the envelope function. - */ - -struct pcilib_event_api_description_s { - const char *title; - - pcilib_context_t *(*init)(pcilib_t *ctx); - void (*free)(pcilib_context_t *ctx); - - pcilib_dma_context_t *(*init_dma)(pcilib_context_t *ctx); - - int (*reset)(pcilib_context_t *ctx); - - int (*start)(pcilib_context_t *ctx, pcilib_event_t event_mask, pcilib_event_flags_t flags); - int (*stop)(pcilib_context_t *ctx, pcilib_event_flags_t flags); - int (*trigger)(pcilib_context_t *ctx, pcilib_event_t event, size_t trigger_size, void *trigger_data); - - int (*stream)(pcilib_context_t *ctx, pcilib_event_callback_t callback, void *user); - int (*next_event)(pcilib_context_t *ctx, pcilib_timeout_t timeout, pcilib_event_id_t *evid, size_t info_size, pcilib_event_info_t *info); - - int (*get_data)(pcilib_context_t *ctx, pcilib_event_id_t event_id, pcilib_event_data_type_t data_type, size_t arg_size, void *arg, size_t *size, void **data); - int (*return_data)(pcilib_context_t *ctx, pcilib_event_id_t event_id, pcilib_event_data_type_t data_type, void *data); -}; - - -typedef struct { - size_t max_events; - pcilib_timeout_t duration; -} pcilib_autostop_parameters_t; - -typedef struct { - pcilib_event_rawdata_callback_t callback; - void *user; -} pcilib_rawdata_parameters_t; - -typedef struct { - size_t max_threads; -} pcilib_parallel_parameters_t; - -typedef struct { - pcilib_autostop_parameters_t autostop; - pcilib_rawdata_parameters_t rawdata; - pcilib_parallel_parameters_t parallel; -} pcilib_event_parameters_t; - -struct pcilib_event_context_s { - pcilib_event_parameters_t params; - pcilib_t *pcilib; -}; - - -int pcilib_init_event_engine(pcilib_t *ctx); - -#endif /* _PCILIB_EVENT_H */ diff --git a/ipecamera/events.c b/events.c index ef85403..f942f0d 100644 --- a/ipecamera/events.c +++ b/events.c @@ -11,11 +11,11 @@ #include <ufodecode.h> -#include "../tools.h" -#include "../error.h" +#include <pcilib.h> +#include <pcilib/tools.h> +#include <pcilib/error.h> -#include "pcilib.h" -#include "public.h" +#include "ipecamera.h" #include "private.h" #include "events.h" diff --git a/ipecamera/events.h b/events.h index 5268c81..5268c81 100644 --- a/ipecamera/events.h +++ b/events.h diff --git a/ipecamera/ipecamera.h b/ipecamera.h index 673eea1..42994ba 100644 --- a/ipecamera/ipecamera.h +++ b/ipecamera.h @@ -35,4 +35,5 @@ typedef struct { int ipecamera_set_buffer_size(ipecamera_t *ctx, int size); + #endif /* _IPECAMERA_H */ diff --git a/ipecamera/CMakeLists.txt b/ipecamera/CMakeLists.txt deleted file mode 100644 index 5b536f2..0000000 --- a/ipecamera/CMakeLists.txt +++ /dev/null @@ -1,12 +0,0 @@ -include_directories( - ${CMAKE_SOURCE_DIR} - ${UFODECODE_INCLUDE_DIRS} -) - -set(HEADERS ${HEADERS} ipecamera.h model.h reader.h events.h data.h public.h private.h) - -add_library(ipecamera STATIC ipecamera.c model.c reader.c events.c data.c) - -install(FILES ipecamera.h - DESTINATION include -) @@ -1,55 +0,0 @@ -#include <stdio.h> -#include <string.h> -#include <strings.h> -#include <stdlib.h> -#include <stdint.h> -#include <stdarg.h> -#include <fcntl.h> -#include <unistd.h> -#include <sys/ioctl.h> -#include <sys/mman.h> -#include <arpa/inet.h> -#include <errno.h> -#include <assert.h> - -#include "pci.h" - -#include "tools.h" -#include "error.h" - -int pcilib_wait_irq(pcilib_t *ctx, pcilib_irq_hw_source_t source, pcilib_timeout_t timeout, size_t *count) { - int err; - - interrupt_wait_t arg = { 0 }; - - arg.source = source; - arg.timeout = timeout; - - if (count) arg.count = 1; - - err = ioctl(ctx->handle, PCIDRIVER_IOC_WAITI, &arg); - if (err) { - pcilib_error("PCIDRIVER_IOC_WAITI ioctl have failed"); - return PCILIB_ERROR_FAILED; - } - - if (!arg.count) return PCILIB_ERROR_TIMEOUT; - - if (count) *count = arg.count; - - return 0; -} - -int pcilib_clear_irq(pcilib_t *ctx, pcilib_irq_hw_source_t source) { - int err; - - err = ioctl(ctx->handle, PCIDRIVER_IOC_CLEAR_IOQ, source); - if (err) { - pcilib_error("PCIDRIVER_IOC_CLEAR_IOQ ioctl have failed"); - return PCILIB_ERROR_FAILED; - } - - return 0; -} - - @@ -1,5 +0,0 @@ -#ifndef _PCILIB_IRQ_H -#define _PCILIB_IRQ_H - - -#endif /* _PCILIB_IRQ_H */ diff --git a/kapture/CMakeLists.txt b/kapture/CMakeLists.txt deleted file mode 100644 index af74edd..0000000 --- a/kapture/CMakeLists.txt +++ /dev/null @@ -1,9 +0,0 @@ -include_directories( - ${CMAKE_SOURCE_DIR} - ${UFODECODE_INCLUDE_DIRS} -) - -set(HEADERS ${HEADERS} model.h) - -add_library(kapture STATIC kapture.c) - diff --git a/kapture/kapture.c b/kapture/kapture.c deleted file mode 100644 index 4384592..0000000 --- a/kapture/kapture.c +++ /dev/null @@ -1,62 +0,0 @@ -#define _KAPTURE_C -#include <stdio.h> -#include <stdlib.h> -#include <unistd.h> -#include <string.h> -#include <sys/time.h> -#include <pthread.h> -#include <assert.h> - -#include "../tools.h" -#include "../error.h" -#include "../event.h" - -#include "pcilib.h" -#include "model.h" -#include "kapture.h" -#include "private.h" - - -pcilib_context_t *kapture_init(pcilib_t *vctx) { - kapture_t *ctx = malloc(sizeof(kapture_t)); - - if (ctx) { - memset(ctx, 0, sizeof(kapture_t)); - } - - return ctx; -} - -void kapture_free(pcilib_context_t *vctx) { - if (vctx) { - kapture_t *ctx = (kapture_t*)vctx; - kapture_stop(vctx, PCILIB_EVENT_FLAGS_DEFAULT); - free(ctx); - } -} - -int kapture_reset(pcilib_context_t *ctx) { -} - -int kapture_start(pcilib_context_t *ctx, pcilib_event_t event_mask, pcilib_event_flags_t flags) { -} - -int kapture_stop(pcilib_context_t *ctx, pcilib_event_flags_t flags) { -} - -int kapture_trigger(pcilib_context_t *ctx, pcilib_event_t event, size_t trigger_size, void *trigger_data) { -} - -int kapture_stream(pcilib_context_t *ctx, pcilib_event_callback_t callback, void *user) { -} - -int kapture_next_event(pcilib_context_t *ctx, pcilib_timeout_t timeout, pcilib_event_id_t *evid, size_t info_size, pcilib_event_info_t *info) { -} - -int kapture_get(pcilib_context_t *ctx, pcilib_event_id_t event_id, pcilib_event_data_type_t data_type, size_t arg_size, void *arg, size_t *size, void **data) { -} - -int kapture_return(pcilib_context_t *ctx, pcilib_event_id_t event_id, pcilib_event_data_type_t data_type, void *data) { -} - - diff --git a/kapture/kapture.h b/kapture/kapture.h deleted file mode 100644 index 3944b8c..0000000 --- a/kapture/kapture.h +++ /dev/null @@ -1,6 +0,0 @@ -#ifndef _KAPTURE_H -#define _KAPTURE_H - -typedef struct kapture_s kapture_t; - -#endif /* _KAPTURE_H */ diff --git a/kapture/model.h b/kapture/model.h deleted file mode 100644 index b45969a..0000000 --- a/kapture/model.h +++ /dev/null @@ -1,81 +0,0 @@ -#ifndef _KAPTURE_MODEL_H -#define _KAPTURE_MODEL_H - -#include <stdio.h> - -#include "../pcilib.h" - - -#define KAPTURE_REGISTER_SPACE 0x9000 - -#ifdef _KAPTURE_C -pcilib_register_bank_description_t kapture_register_banks[] = { -// { PCILIB_REGISTER_BANK0, PCILIB_BAR0, 0x0200, PCILIB_DEFAULT_PROTOCOL , KAPTURE_REGISTER_SPACE, KAPTURE_REGISTER_SPACE, PCILIB_LITTLE_ENDIAN, 32, PCILIB_LITTLE_ENDIAN, "0x%lx", "fpga", "KAPTURE Registers" }, - { PCILIB_REGISTER_BANK_DMA, PCILIB_BAR0, 0x0200, PCILIB_DEFAULT_PROTOCOL , 0, 0, PCILIB_LITTLE_ENDIAN, 32, PCILIB_LITTLE_ENDIAN, "0x%lx", "dma", "DMA Registers"}, - { 0, 0, 0, 0, 0, 0, 0, 0, 0, NULL, NULL, NULL } -}; - -pcilib_register_description_t kapture_registers[] = { -{0, 0, 0, 0, 0, 0, 0, 0, NULL, NULL} -}; - -pcilib_register_range_t kapture_register_ranges[] = { - {0, 0, 0, 0} -}; - -pcilib_event_description_t kapture_events[] = { - {PCILIB_EVENT0, "event", ""}, - {0, NULL, NULL} -}; - -pcilib_event_data_type_description_t kapture_data_types[] = { - {PCILIB_EVENT_RAW_DATA, PCILIB_EVENT0, "raw", "raw data from kapture" }, - {0, 0, NULL, NULL} -}; - -#else -extern pcilib_register_description_t kapture_registers[]; -extern pcilib_register_bank_description_t kapture_register_banks[]; -extern pcilib_register_range_t kapture_register_ranges[]; -extern pcilib_event_description_t kapture_events[]; -extern pcilib_event_data_type_description_t kapture_data_types[]; -#endif - - -pcilib_context_t *kapture_init(pcilib_t *pcilib); -void kapture_free(pcilib_context_t *ctx); - -int kapture_reset(pcilib_context_t *ctx); -int kapture_start(pcilib_context_t *ctx, pcilib_event_t event_mask, pcilib_event_flags_t flags); -int kapture_stop(pcilib_context_t *ctx, pcilib_event_flags_t flags); -int kapture_trigger(pcilib_context_t *ctx, pcilib_event_t event, size_t trigger_size, void *trigger_data); -int kapture_stream(pcilib_context_t *vctx, pcilib_event_callback_t callback, void *user); -int kapture_next_event(pcilib_context_t *vctx, pcilib_timeout_t timeout, pcilib_event_id_t *evid, size_t info_size, pcilib_event_info_t *info); -int kapture_get(pcilib_context_t *ctx, pcilib_event_id_t event_id, pcilib_event_data_type_t data_type, size_t arg_size, void *arg, size_t *size, void **buf); -int kapture_return(pcilib_context_t *ctx, pcilib_event_id_t event_id, pcilib_event_data_type_t data_type, void *data); - -#ifdef _KAPTURE_C -pcilib_event_api_description_t kapture_api = { - "kapture", - - kapture_init, - kapture_free, - - NULL, - - kapture_reset, - kapture_start, - kapture_stop, - kapture_trigger, - - kapture_stream, - kapture_next_event, - kapture_get, - kapture_return -}; -#else -extern pcilib_event_api_description_t kapture_api; -#endif - - -#endif /* _KAPTURE_MODEL_H */ diff --git a/kapture/private.h b/kapture/private.h deleted file mode 100644 index bf084c3..0000000 --- a/kapture/private.h +++ /dev/null @@ -1,10 +0,0 @@ -#ifndef _KAPTURE_PRIVATE_H -#define _KAPTURE_PRIVATE_H - -struct kapture_s { - pcilib_context_t event; - -}; - - -#endif /* _KAPTURE_PRIVATE_H */ diff --git a/kernel.h b/kernel.h deleted file mode 100644 index 161d2aa..0000000 --- a/kernel.h +++ /dev/null @@ -1,81 +0,0 @@ -/* - * Extract from kernel headers - * iomap.h - */ - -/* - * IO resources have these defined flags. - */ -#define IORESOURCE_BITS 0x000000ff /* Bus-specific bits */ - -#define IORESOURCE_TYPE_BITS 0x00000f00 /* Resource type */ -#define IORESOURCE_IO 0x00000100 -#define IORESOURCE_MEM 0x00000200 -#define IORESOURCE_IRQ 0x00000400 -#define IORESOURCE_DMA 0x00000800 - -#define IORESOURCE_PREFETCH 0x00001000 /* No side effects */ -#define IORESOURCE_READONLY 0x00002000 -#define IORESOURCE_CACHEABLE 0x00004000 -#define IORESOURCE_RANGELENGTH 0x00008000 -#define IORESOURCE_SHADOWABLE 0x00010000 - -#define IORESOURCE_SIZEALIGN 0x00020000 /* size indicates alignment */ -#define IORESOURCE_STARTALIGN 0x00040000 /* start field is alignment */ - -#define IORESOURCE_MEM_64 0x00100000 - -#define IORESOURCE_EXCLUSIVE 0x08000000 /* Userland may not map this resource */ -#define IORESOURCE_DISABLED 0x10000000 -#define IORESOURCE_UNSET 0x20000000 -#define IORESOURCE_AUTO 0x40000000 -#define IORESOURCE_BUSY 0x80000000 /* Driver has marked this resource busy */ - -/* PnP IRQ specific bits (IORESOURCE_BITS) */ -#define IORESOURCE_IRQ_HIGHEDGE (1<<0) -#define IORESOURCE_IRQ_LOWEDGE (1<<1) -#define IORESOURCE_IRQ_HIGHLEVEL (1<<2) -#define IORESOURCE_IRQ_LOWLEVEL (1<<3) -#define IORESOURCE_IRQ_SHAREABLE (1<<4) -#define IORESOURCE_IRQ_OPTIONAL (1<<5) - -/* PnP DMA specific bits (IORESOURCE_BITS) */ -#define IORESOURCE_DMA_TYPE_MASK (3<<0) -#define IORESOURCE_DMA_8BIT (0<<0) -#define IORESOURCE_DMA_8AND16BIT (1<<0) -#define IORESOURCE_DMA_16BIT (2<<0) - -#define IORESOURCE_DMA_MASTER (1<<2) -#define IORESOURCE_DMA_BYTE (1<<3) -#define IORESOURCE_DMA_WORD (1<<4) - -#define IORESOURCE_DMA_SPEED_MASK (3<<6) -#define IORESOURCE_DMA_COMPATIBLE (0<<6) -#define IORESOURCE_DMA_TYPEA (1<<6) -#define IORESOURCE_DMA_TYPEB (2<<6) -#define IORESOURCE_DMA_TYPEF (3<<6) - -/* PnP memory I/O specific bits (IORESOURCE_BITS) */ -#define IORESOURCE_MEM_WRITEABLE (1<<0) /* dup: IORESOURCE_READONLY */ -#define IORESOURCE_MEM_CACHEABLE (1<<1) /* dup: IORESOURCE_CACHEABLE */ -#define IORESOURCE_MEM_RANGELENGTH (1<<2) /* dup: IORESOURCE_RANGELENGTH */ -#define IORESOURCE_MEM_TYPE_MASK (3<<3) -#define IORESOURCE_MEM_8BIT (0<<3) -#define IORESOURCE_MEM_16BIT (1<<3) -#define IORESOURCE_MEM_8AND16BIT (2<<3) -#define IORESOURCE_MEM_32BIT (3<<3) -#define IORESOURCE_MEM_SHADOWABLE (1<<5) /* dup: IORESOURCE_SHADOWABLE */ -#define IORESOURCE_MEM_EXPANSIONROM (1<<6) - -/* PnP I/O specific bits (IORESOURCE_BITS) */ -#define IORESOURCE_IO_16BIT_ADDR (1<<0) -#define IORESOURCE_IO_FIXED (1<<1) - -/* PCI ROM control bits (IORESOURCE_BITS) */ -#define IORESOURCE_ROM_ENABLE (1<<0) /* ROM is enabled, same as PCI_ROM_ADDRESS_ENABLE */ -#define IORESOURCE_ROM_SHADOW (1<<1) /* ROM is copy at C000:0 */ -#define IORESOURCE_ROM_COPY (1<<2) /* ROM is alloc'd copy, resource field overlaid */ -#define IORESOURCE_ROM_BIOS_COPY (1<<3) /* ROM is BIOS copy, resource field overlaid */ - -/* PCI control bits. Shares IORESOURCE_BITS with above PCI ROM. */ -#define IORESOURCE_PCI_FIXED (1<<4) /* Do not move resource */ @@ -1,310 +0,0 @@ -#include <stdio.h> -#include <string.h> -#include <strings.h> -#include <stdlib.h> -#include <stdint.h> -#include <stdarg.h> -#include <fcntl.h> -#include <unistd.h> -#include <sys/ioctl.h> -#include <sys/mman.h> -#include <arpa/inet.h> -#include <errno.h> -#include <assert.h> - -#include "pcilib.h" -#include "pci.h" -#include "kmem.h" -#include "error.h" - -int pcilib_clean_kernel_memory(pcilib_t *ctx, pcilib_kmem_use_t use, pcilib_kmem_flags_t flags) { - kmem_handle_t kh = {0}; - kh.use = use; - kh.flags = flags|KMEM_FLAG_MASS; - - return ioctl(ctx->handle, PCIDRIVER_IOC_KMEM_FREE, &kh); -} - - -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); - kh.handle_id = kbuf->buf.blocks[i].handle_id; - kh.pa = kbuf->buf.blocks[i].pa; - kh.flags = flags; - - return ioctl(ctx->handle, PCIDRIVER_IOC_KMEM_FREE, &kh); -} - -static void pcilib_cancel_kernel_memory(pcilib_t *ctx, pcilib_kmem_list_t *kbuf, pcilib_kmem_flags_t flags, int last_flags) { - int ret; - - if (!kbuf->buf.n_blocks) return; - - // consistency error during processing of last block, special treatment could be needed - if (last_flags) { - pcilib_kmem_flags_t failed_flags = flags; - - if (last_flags&KMEM_FLAG_REUSED_PERSISTENT) flags&=~PCILIB_KMEM_FLAG_PERSISTENT; - if (last_flags&KMEM_FLAG_REUSED_HW) flags&=~PCILIB_KMEM_FLAG_HARDWARE; - - if (failed_flags != flags) { - ret = pcilib_free_kernel_buffer(ctx, kbuf, --kbuf->buf.n_blocks, failed_flags); - if (ret) pcilib_error("PCIDRIVER_IOC_KMEM_FREE ioctl have failed"); - } - } - - pcilib_free_kernel_memory(ctx, kbuf, flags); -} - -pcilib_kmem_handle_t *pcilib_alloc_kernel_memory(pcilib_t *ctx, pcilib_kmem_type_t type, size_t nmemb, size_t size, size_t alignment, pcilib_kmem_use_t use, pcilib_kmem_flags_t flags) { - int err = 0; - const char *error = NULL; - - int ret; - int i; - void *addr; - - pcilib_tristate_t reused = PCILIB_TRISTATE_NO; - int persistent = -1; - int hardware = -1; - - kmem_handle_t kh = {0}; - - pcilib_kmem_list_t *kbuf = (pcilib_kmem_list_t*)malloc(sizeof(pcilib_kmem_list_t) + nmemb * sizeof(pcilib_kmem_addr_t)); - if (!kbuf) { - pcilib_error("Memory allocation has failed"); - return NULL; - } - - memset(kbuf, 0, sizeof(pcilib_kmem_list_t) + nmemb * sizeof(pcilib_kmem_addr_t)); - - ret = ioctl( ctx->handle, PCIDRIVER_IOC_MMAP_MODE, PCIDRIVER_MMAP_KMEM ); - if (ret) { - pcilib_error("PCIDRIVER_IOC_MMAP_MODE ioctl have failed"); - return NULL; - } - - kh.type = type; - kh.size = size; - kh.align = alignment; - kh.use = use; - - if ((type&PCILIB_KMEM_TYPE_MASK) == PCILIB_KMEM_TYPE_REGION) { - kh.align = 0; - } else if ((type&PCILIB_KMEM_TYPE_MASK) != PCILIB_KMEM_TYPE_PAGE) { - kh.size += alignment; - } - - for ( i = 0; i < nmemb; i++) { - kh.item = i; - kh.flags = flags; - - if ((type&PCILIB_KMEM_TYPE_MASK) == PCILIB_KMEM_TYPE_REGION) { - kh.pa = alignment + i * size; - } - - ret = ioctl(ctx->handle, PCIDRIVER_IOC_KMEM_ALLOC, &kh); - if (ret) { - kbuf->buf.n_blocks = i; - error = "PCIDRIVER_IOC_KMEM_ALLOC ioctl have failed"; - break; - } - - kbuf->buf.blocks[i].handle_id = kh.handle_id; - kbuf->buf.blocks[i].pa = kh.pa; - kbuf->buf.blocks[i].size = kh.size; - - if (!i) reused = (kh.flags&KMEM_FLAG_REUSED)?PCILIB_TRISTATE_YES:PCILIB_TRISTATE_NO; - - if (kh.flags&KMEM_FLAG_REUSED) { - if (!i) reused = PCILIB_TRISTATE_YES; - else if (!reused) reused = PCILIB_TRISTATE_PARTIAL; - - if (persistent) { - if (persistent < 0) { - /*if (((flags&PCILIB_KMEM_FLAG_PERSISTENT) == 0)&&(kh.flags&KMEM_FLAG_REUSED_PERSISTENT)) err = PCILIB_ERROR_INVALID_STATE; - else*/ persistent = (kh.flags&KMEM_FLAG_REUSED_PERSISTENT)?1:0; - } else if ((kh.flags&KMEM_FLAG_REUSED_PERSISTENT) == 0) err = PCILIB_ERROR_INVALID_STATE; - } else if (kh.flags&KMEM_FLAG_REUSED_PERSISTENT) err = PCILIB_ERROR_INVALID_STATE; - - if (hardware) { - if (hardware < 0) { - /*if (((flags&PCILIB_KMEM_FLAG_HARDWARE) == 0)&&(kh.flags&KMEM_FLAG_REUSED_HW)) err = PCILIB_ERROR_INVALID_STATE; - else*/ hardware = (kh.flags&KMEM_FLAG_REUSED_HW)?1:0; - } else if ((kh.flags&KMEM_FLAG_REUSED_HW) == 0) err = PCILIB_ERROR_INVALID_STATE; - } else if (kh.flags&KMEM_FLAG_REUSED_HW) err = PCILIB_ERROR_INVALID_STATE; - - } else { - if (!i) reused = PCILIB_TRISTATE_NO; - else if (reused) reused = PCILIB_TRISTATE_PARTIAL; - - if ((persistent > 0)&&((flags&PCILIB_KMEM_FLAG_PERSISTENT) == 0)) err = PCILIB_ERROR_INVALID_STATE; - if ((hardware > 0)&&((flags&PCILIB_KMEM_FLAG_HARDWARE) == 0)) err = PCILIB_ERROR_INVALID_STATE; - } - - if (err) { - kbuf->buf.n_blocks = i + 1; - break; - } - - if ((kh.align)&&((kh.type&PCILIB_KMEM_TYPE_MASK) != PCILIB_KMEM_TYPE_PAGE)) { - if (kh.pa % kh.align) kbuf->buf.blocks[i].alignment_offset = kh.align - kh.pa % kh.align; - kbuf->buf.blocks[i].size -= kh.align; - } - - addr = mmap( 0, kbuf->buf.blocks[i].size + kbuf->buf.blocks[i].alignment_offset, PROT_WRITE | PROT_READ, MAP_SHARED, ctx->handle, 0 ); - if ((!addr)||(addr == MAP_FAILED)) { - kbuf->buf.n_blocks = i + 1; - error = "Failed to mmap allocated kernel memory"; - break; - } - - kbuf->buf.blocks[i].ua = addr; -// if (use == PCILIB_KMEM_USE_DMA_PAGES) { -// memset(addr, 10, kbuf->buf.blocks[i].size + kbuf->buf.blocks[i].alignment_offset); -// } - - kbuf->buf.blocks[i].mmap_offset = kh.pa & ctx->page_mask; - } - - //This is possible in the case of error (nothing is allocated yet) or if buffers are not reused - if (persistent < 0) persistent = 0; - if (hardware < 0) hardware = 0; - - if (err||error) { - pcilib_kmem_flags_t free_flags = 0; - - // for the sake of simplicity always clean partialy reused buffers - if ((persistent == PCILIB_TRISTATE_PARTIAL)||((persistent <= 0)&&(flags&PCILIB_KMEM_FLAG_PERSISTENT))) { - free_flags |= PCILIB_KMEM_FLAG_PERSISTENT; - } - - if ((hardware <= 0)&&(flags&PCILIB_KMEM_FLAG_HARDWARE)) { - free_flags |= PCILIB_KMEM_FLAG_HARDWARE; - } - - // do not clean if we have reused peresistent buffers - // we don't care about -1, because it will be the value only if no buffers actually allocated - if ((!persistent)||(reused != PCILIB_TRISTATE_YES)) { - pcilib_cancel_kernel_memory(ctx, kbuf, free_flags, err?kh.flags:0); - } - - if (!error) error = "Reused buffers are inconsistent"; - pcilib_error(error); - - return NULL; - } - - if (nmemb == 1) { - memcpy(&kbuf->buf.addr, &kbuf->buf.blocks[0], sizeof(pcilib_kmem_addr_t)); - } - - kbuf->buf.reused = reused|(persistent?PCILIB_KMEM_REUSE_PERSISTENT:0)|(hardware?PCILIB_KMEM_REUSE_HARDWARE:0); - kbuf->buf.n_blocks = nmemb; - - kbuf->prev = NULL; - kbuf->next = ctx->kmem_list; - if (ctx->kmem_list) ctx->kmem_list->prev = kbuf; - ctx->kmem_list = kbuf; - - return (pcilib_kmem_handle_t*)kbuf; -} - -void pcilib_free_kernel_memory(pcilib_t *ctx, pcilib_kmem_handle_t *k, pcilib_kmem_flags_t flags) { - int ret, err = 0; - int i; - pcilib_kmem_list_t *kbuf = (pcilib_kmem_list_t*)k; - - // if linked in to the list - if (kbuf->next) kbuf->next->prev = kbuf->prev; - if (kbuf->prev) kbuf->prev->next = kbuf->next; - else if (ctx->kmem_list == kbuf) ctx->kmem_list = kbuf->next; - - for (i = 0; i < kbuf->buf.n_blocks; i++) { - ret = pcilib_free_kernel_buffer(ctx, kbuf, i, flags); - if ((ret)&&(!err)) err = ret; - } - - free(kbuf); - - if (err) { - pcilib_error("PCIDRIVER_IOC_KMEM_FREE ioctl have failed"); - } -} - -/* -int pcilib_kmem_sync(pcilib_t *ctx, pcilib_kmem_handle_t *k, pcilib_kmem_sync_direction_t dir) { - int i; - int ret; - pcilib_kmem_list_t *kbuf = (pcilib_kmem_list_t*)k; - - for (i = 0; i < kbuf->buf.n_blocks; i++) { - ret = pcilib_kmem_sync_block(ctx, k, dir, i); - if (ret) { - pcilib_error("PCIDRIVER_IOC_KMEM_SYNC ioctl have failed"); - return PCILIB_ERROR_FAILED; - } - } - - return 0; -} -*/ - -int pcilib_kmem_sync_block(pcilib_t *ctx, pcilib_kmem_handle_t *k, pcilib_kmem_sync_direction_t dir, size_t block) { - int ret; - kmem_sync_t ks; - pcilib_kmem_list_t *kbuf = (pcilib_kmem_list_t*)k; - - ks.dir = dir; - ks.handle.handle_id = kbuf->buf.blocks[block].handle_id; - ks.handle.pa = kbuf->buf.blocks[block].pa; - ret = ioctl(ctx->handle, PCIDRIVER_IOC_KMEM_SYNC, &ks); - if (ret) { - pcilib_error("PCIDRIVER_IOC_KMEM_SYNC ioctl have failed"); - return PCILIB_ERROR_FAILED; - } - - return 0; -} - -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; -} - -uintptr_t pcilib_kmem_get_pa(pcilib_t *ctx, pcilib_kmem_handle_t *k) { - pcilib_kmem_list_t *kbuf = (pcilib_kmem_list_t*)k; - return kbuf->buf.addr.pa + kbuf->buf.addr.alignment_offset; -} - -uintptr_t pcilib_kmem_get_ba(pcilib_t *ctx, pcilib_kmem_handle_t *k) { - pcilib_kmem_list_t *kbuf = (pcilib_kmem_list_t*)k; - return kbuf->buf.addr.pa + kbuf->buf.addr.alignment_offset; -} - -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; -} - -uintptr_t pcilib_kmem_get_block_pa(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].pa + kbuf->buf.blocks[block].alignment_offset; -} - -uintptr_t pcilib_kmem_get_block_ba(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].pa + kbuf->buf.blocks[block].alignment_offset; -} - -size_t pcilib_kmem_get_block_size(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].size; -} - -pcilib_kmem_reuse_state_t pcilib_kmem_is_reused(pcilib_t *ctx, pcilib_kmem_handle_t *k) { - pcilib_kmem_list_t *kbuf = (pcilib_kmem_list_t*)k; - return kbuf->buf.reused; -} @@ -1,80 +0,0 @@ -#ifndef _PCILIB_KMEM_H -#define _PCILIB_KMEM_H - -#include "pcilib.h" - -typedef struct pcilib_kmem_list_s pcilib_kmem_list_t; - -#include "tools.h" - -typedef enum { - PCILIB_KMEM_FLAG_REUSE = KMEM_FLAG_REUSE, - PCILIB_KMEM_FLAG_EXCLUSIVE = KMEM_FLAG_EXCLUSIVE, - PCILIB_KMEM_FLAG_PERSISTENT = KMEM_FLAG_PERSISTENT, - PCILIB_KMEM_FLAG_HARDWARE = KMEM_FLAG_HW, - PCILIB_KMEM_FLAG_FORCE = KMEM_FLAG_FORCE, - PCILIB_KMEM_FLAG_TRY = KMEM_FLAG_TRY -} pcilib_kmem_flags_t; - - -typedef enum { - PCILIB_KMEM_REUSE_ALLOCATED = PCILIB_TRISTATE_NO, - PCILIB_KMEM_REUSE_REUSED = PCILIB_TRISTATE_YES, - PCILIB_KMEM_REUSE_PARTIAL = PCILIB_TRISTATE_PARTIAL, - PCILIB_KMEM_REUSE_PERSISTENT = 0x100, - PCILIB_KMEM_REUSE_HARDWARE = 0x200 -} pcilib_kmem_reuse_state_t; - - -typedef struct { - int handle_id; - pcilib_kmem_reuse_state_t reused; - - uintptr_t pa; -// uintptr_t va; - void *ua; - size_t size; - - size_t alignment_offset; - size_t mmap_offset; -} pcilib_kmem_addr_t; - -/** - * single allocation - we set only addr, n_blocks = 0 - * multiple allocation - addr is not set, blocks are set, n_blocks > 0 - * sgmap allocation - addr contains ua, but pa's are set in blocks, n_blocks > 0 - */ -typedef struct { - pcilib_kmem_addr_t addr; - - pcilib_kmem_reuse_state_t reused; - - size_t n_blocks; - pcilib_kmem_addr_t blocks[]; -} pcilib_kmem_buffer_t; - -typedef void pcilib_kmem_handle_t; - - -struct pcilib_kmem_list_s { - pcilib_kmem_list_t *next, *prev; - - pcilib_kmem_buffer_t buf; // variable size, should be last item in struct -}; - -pcilib_kmem_handle_t *pcilib_alloc_kernel_memory(pcilib_t *ctx, pcilib_kmem_type_t type, size_t nmemb, size_t size, size_t alignment, pcilib_kmem_use_t use, pcilib_kmem_flags_t flags); -void pcilib_free_kernel_memory(pcilib_t *ctx, pcilib_kmem_handle_t *k, pcilib_kmem_flags_t flags); -//int pcilib_kmem_sync(pcilib_t *ctx, pcilib_kmem_handle_t *k, pcilib_kmem_sync_direction_t dir); -int pcilib_kmem_sync_block(pcilib_t *ctx, pcilib_kmem_handle_t *k, pcilib_kmem_sync_direction_t dir, size_t block); -void *pcilib_kmem_get_ua(pcilib_t *ctx, pcilib_kmem_handle_t *k); -uintptr_t pcilib_kmem_get_pa(pcilib_t *ctx, pcilib_kmem_handle_t *k); -uintptr_t pcilib_kmem_get_ba(pcilib_t *ctx, pcilib_kmem_handle_t *k); -void *pcilib_kmem_get_block_ua(pcilib_t *ctx, pcilib_kmem_handle_t *k, size_t block); -uintptr_t pcilib_kmem_get_block_pa(pcilib_t *ctx, pcilib_kmem_handle_t *k, size_t block); -uintptr_t pcilib_kmem_get_block_ba(pcilib_t *ctx, pcilib_kmem_handle_t *k, size_t block); -size_t pcilib_kmem_get_block_size(pcilib_t *ctx, pcilib_kmem_handle_t *k, size_t block); -pcilib_kmem_reuse_state_t pcilib_kmem_is_reused(pcilib_t *ctx, pcilib_kmem_handle_t *k); - -int pcilib_clean_kernel_memory(pcilib_t *ctx, pcilib_kmem_use_t use, pcilib_kmem_flags_t flags); - -#endif /* _PCILIB_KMEM_H */ diff --git a/misc/50-pcidriver.rules b/misc/50-pcidriver.rules deleted file mode 100644 index 1283c3b..0000000 --- a/misc/50-pcidriver.rules +++ /dev/null @@ -1 +0,0 @@ -KERNEL=="fpga*", NAME="%k", GROUP="users", MODE="0660" diff --git a/ipecamera/model.h b/model.c index 60226f0..539f774 100644 --- a/ipecamera/model.h +++ b/model.c @@ -1,32 +1,39 @@ -#ifndef _IPECAMERA_MODEL_H -#define _IPECAMERA_MODEL_H - #include <stdio.h> -#include "../pcilib.h" -#include "public.h" +#include <pcilib.h> +#include <pcilib/model.h> + +#include "base.h" +#include "cmosis.h" +#include "model.h" + +enum ipecamera_protocol_s { + IPECAMERA_PROTOCOL_CMOSIS = PCILIB_REGISTER_PROTOCOL0, +}; -//#define IPECAMERA_DEBUG -#define IPECAMERA_DMA_R3 -#define IPECAMERA_DMA_ADDRESS 0 -#define IPECAMERA_DMA_PACKET_LENGTH 4096 +static const pcilib_register_protocol_api_description_t ipecamera_cmosis_protocol_api = + { NULL, NULL, ipecamera_cmosis_read, ipecamera_cmosis_write }; -//#define IPECAMERA_REGISTER_SPACE 0xfeaffc00 -#define IPECAMERA_REGISTER_SPACE 0x9000 -#define IPECAMERA_REGISTER_WRITE (IPECAMERA_REGISTER_SPACE + 0) -#define IPECAMERA_REGISTER_READ (IPECAMERA_REGISTER_WRITE + 16) +/* +static const pcilib_dma_description_t ipecamera_dma = + { &ipe_dma_api, ipe_dma_banks, ipe_dma_registers, ipe_dma_engines, NULL, NULL, "ipedma", "DMA engine developed by M. Caselle" }; +*/ -#ifdef _IPECAMERA_MODEL_C -pcilib_register_bank_description_t ipecamera_register_banks[] = { - { PCILIB_REGISTER_BANK0, PCILIB_BAR0, 128, IPECAMERA_REGISTER_PROTOCOL, IPECAMERA_REGISTER_READ , IPECAMERA_REGISTER_WRITE, PCILIB_LITTLE_ENDIAN, 8 , PCILIB_LITTLE_ENDIAN, "%lu" , "cmosis", "CMOSIS CMV2000 Registers" }, - { PCILIB_REGISTER_BANK1, PCILIB_BAR0, 0x0200, PCILIB_DEFAULT_PROTOCOL , IPECAMERA_REGISTER_SPACE, IPECAMERA_REGISTER_SPACE, PCILIB_LITTLE_ENDIAN, 32, PCILIB_LITTLE_ENDIAN, "0x%lx", "fpga", "IPECamera Registers" }, -// { PCILIB_REGISTER_BANK_DMA, PCILIB_BAR0, 0xA000, PCILIB_DEFAULT_PROTOCOL , 0, 0, PCILIB_LITTLE_ENDIAN, 32, PCILIB_LITTLE_ENDIAN, "0x%lx", "dma", "DMA Registers"}, - { PCILIB_REGISTER_BANK_DMA, PCILIB_BAR0, 0x0200, PCILIB_DEFAULT_PROTOCOL , 0, 0, PCILIB_LITTLE_ENDIAN, 32, PCILIB_LITTLE_ENDIAN, "0x%lx", "dma", "DMA Registers"}, +static const pcilib_register_protocol_description_t ipecamera_protocols[] = { +// {IPECAMERA_PROTOCOL_FPGA, &pcilib_default_protocol_api, "ipecamera", NULL, "cmosis", "Protocol to access FPGA registers"}, + {IPECAMERA_PROTOCOL_CMOSIS, &ipecamera_cmosis_protocol_api, NULL, NULL, "cmosis", "Protocol to access CMOSIS registers"}, + { 0 } +}; + +static const pcilib_register_bank_description_t ipecamera_banks[] = { + { PCILIB_REGISTER_BANK0, IPECAMERA_PROTOCOL_CMOSIS, PCILIB_BAR0, IPECAMERA_CMOSIS_REGISTER_READ , IPECAMERA_CMOSIS_REGISTER_WRITE, 8, 128, PCILIB_LITTLE_ENDIAN, PCILIB_LITTLE_ENDIAN, "%lu" , "cmosis", "CMOSIS CMV2000 Registers" }, + { PCILIB_REGISTER_BANK1, PCILIB_REGISTER_PROTOCOL_DEFAULT, PCILIB_BAR0, IPECAMERA_REGISTER_SPACE, IPECAMERA_REGISTER_SPACE, 32, 0x0200, PCILIB_LITTLE_ENDIAN, PCILIB_LITTLE_ENDIAN, "0x%lx", "fpga", "IPECamera Registers" }, +// { PCILIB_REGISTER_BANK_DMA, PCILIB_REGISTER_PROTOCOL_DEFAULT, PCILIB_BAR0, 0, 0, 32, 0x0200, PCILIB_LITTLE_ENDIAN, PCILIB_LITTLE_ENDIAN, "0x%lx", "dma", "DMA Registers"}, { 0, 0, 0, 0, 0, 0, 0, 0, 0, NULL, NULL, NULL } }; -pcilib_register_description_t ipecamera_registers[] = { +static const pcilib_register_description_t ipecamera_registers[] = { {1, 0, 16, 1088, 0, PCILIB_REGISTER_RW, PCILIB_REGISTER_STANDARD, PCILIB_REGISTER_BANK0, "cmosis_number_lines", ""}, {3, 0, 16, 0, 0, PCILIB_REGISTER_RW, PCILIB_REGISTER_STANDARD, PCILIB_REGISTER_BANK0, "cmosis_start1", ""}, {5, 0, 16, 0, 0, PCILIB_REGISTER_RW, PCILIB_REGISTER_STANDARD, PCILIB_REGISTER_BANK0, "cmosis_start2", ""}, @@ -72,7 +79,6 @@ pcilib_register_description_t ipecamera_registers[] = { {111, 0, 1, 1, 0, PCILIB_REGISTER_RW, PCILIB_REGISTER_STANDARD, PCILIB_REGISTER_BANK0, "cmosis_bit_mode", ""}, {112, 0, 2, 0, 0, PCILIB_REGISTER_RW, PCILIB_REGISTER_STANDARD, PCILIB_REGISTER_BANK0, "cmosis_adc_resolution", ""}, {115, 0, 1, 1, 0, PCILIB_REGISTER_RW, PCILIB_REGISTER_STANDARD, PCILIB_REGISTER_BANK0, "cmosis_special_115", ""}, -/*{126, 0, 16, 0, PCILIB_REGISTER_RW, PCILIB_REGISTER_STANDARD, PCILIB_REGISTER_BANK0, "temp", ""},*/ {0x00, 0, 32, 0, 0, PCILIB_REGISTER_RW, PCILIB_REGISTER_STANDARD, PCILIB_REGISTER_BANK1, "spi_conf_input", ""}, {0x10, 0, 32, 0, 0, PCILIB_REGISTER_R, PCILIB_REGISTER_STANDARD, PCILIB_REGISTER_BANK1, "spi_conf_output", ""}, {0x20, 0, 32, 0, 0, PCILIB_REGISTER_RW, PCILIB_REGISTER_STANDARD, PCILIB_REGISTER_BANK1, "spi_clk_speed", ""}, @@ -125,36 +131,25 @@ pcilib_register_description_t ipecamera_registers[] = { {0, 0, 0, 0, 0, 0, 0, 0, NULL, NULL} }; -pcilib_register_range_t ipecamera_register_ranges[] = { +static const pcilib_register_range_t ipecamera_ranges[] = { // {0xF000, 0xF000 + 128, PCILIB_REGISTER_BANK0, 0}, // {0x9000, 0x9FFF, PCILIB_REGISTER_BANK1, -0x9000}, {0, 0, 0, 0} }; -pcilib_event_description_t ipecamera_events[] = { +static const pcilib_event_description_t ipecamera_events[] = { {PCILIB_EVENT0, "new_frame", ""}, {0, NULL, NULL} }; -pcilib_event_data_type_description_t ipecamera_data_types[] = { - {IPECAMERA_IMAGE_DATA, PCILIB_EVENT0, "image", "16 bit pixel data" }, - {IPECAMERA_RAW_DATA, PCILIB_EVENT0, "raw", "raw data from camera" }, - {IPECAMERA_CHANGE_MASK, PCILIB_EVENT0, "cmask", "change mask" }, +static const pcilib_event_data_type_description_t ipecamera_data_types[] = { + {IPECAMERA_IMAGE_DATA, PCILIB_EVENT0, "image", "16 bit pixel data" }, + {IPECAMERA_RAW_DATA, PCILIB_EVENT0, "raw", "raw data from camera" }, + {IPECAMERA_CHANGE_MASK, PCILIB_EVENT0, "cmask", "change mask" }, {0, 0, NULL, NULL} }; -#else -extern pcilib_register_description_t ipecamera_registers[]; -extern pcilib_register_bank_description_t ipecamera_register_banks[]; -extern pcilib_register_range_t ipecamera_register_ranges[]; -extern pcilib_event_description_t ipecamera_events[]; -extern pcilib_event_data_type_description_t ipecamera_data_types[]; -#endif - -#ifdef _IPECAMERA_IMAGE_C pcilib_event_api_description_t ipecamera_image_api = { - "ipecamera", - ipecamera_init, ipecamera_free, @@ -164,17 +159,37 @@ pcilib_event_api_description_t ipecamera_image_api = { ipecamera_start, ipecamera_stop, ipecamera_trigger, - + ipecamera_stream, ipecamera_next_event, ipecamera_get, ipecamera_return }; -#else -extern pcilib_event_api_description_t ipecamera_image_api; -#endif -int ipecamera_read(pcilib_t *ctx, pcilib_register_bank_description_t *bank, pcilib_register_addr_t addr, pcilib_register_value_t *value); -int ipecamera_write(pcilib_t *ctx, pcilib_register_bank_description_t *bank, pcilib_register_addr_t addr, pcilib_register_value_t value); -#endif /* _IPECAMERA_MODEL_H */ +static const pcilib_model_description_t ipecamera_models[] = {{ + PCILIB_EVENT_INTERFACE_VERSION, + &ipecamera_image_api, + &pcilib_ipedma, + ipecamera_registers, + ipecamera_banks, + ipecamera_protocols, + ipecamera_ranges, + ipecamera_events, + ipecamera_data_types, + "ipecamera", + "IPE Camera" +}, { 0 }}; + + +const pcilib_model_description_t *pcilib_get_event_model(pcilib_t *pcilib, unsigned short vendor_id, unsigned short device_id, const char *model) { + // Enumeration call + if ((!vendor_id)&&(!device_id)&&(!model)) { + return ipecamera_models; + } + + if ((vendor_id != 0x10ee)&&((!model)||(strcasecmp(model, "ipecamera")))) + return NULL; + + return &ipecamera_models[0]; +} @@ -0,0 +1,18 @@ +#ifndef _IPECAMERA_MODEL_H +#define _IPECAMERA_MODEL_H + +#include <stdio.h> +#include <pcilib/model.h> + +//#define IPECAMERA_DEBUG + +#define IPECAMERA_DMA_ADDRESS 0 /**< Address of DMA engine to use for communication */ +#define IPECAMERA_DMA_PACKET_LENGTH 4096 /**< IPECamera always use buffers of fixed size adding padding in the end. + This is used to compute expected amount of data for each frame */ +#define IPECAMERA_REGISTER_SPACE 0x9000 +#define IPECAMERA_CMOSIS_REGISTER_WRITE (IPECAMERA_REGISTER_SPACE + 0) +#define IPECAMERA_CMOSIS_REGISTER_READ (IPECAMERA_REGISTER_SPACE + 16) + +const pcilib_model_description_t *pcilib_get_event_model(pcilib_t *pcilib, unsigned short vendor_id, unsigned short device_id, const char *model); + +#endif /* _IPECAMERA_MODEL_H */ @@ -1,473 +0,0 @@ -#define _PCILIB_PCI_C -//#define PCILIB_FILE_IO -#define _POSIX_C_SOURCE 199309L - -#include <stdio.h> -#include <string.h> -#include <strings.h> -#include <stdlib.h> -#include <stdint.h> -#include <fcntl.h> -#include <unistd.h> -#include <sys/ioctl.h> -#include <sys/mman.h> -#include <arpa/inet.h> -#include <errno.h> -#include <assert.h> - -#include "pcilib.h" -#include "pci.h" -#include "kernel.h" -#include "tools.h" -#include "error.h" - -#include "ipecamera/model.h" -#include "kapture/model.h" - - -pcilib_t *pcilib_open(const char *device, pcilib_model_t model) { - pcilib_t *ctx = malloc(sizeof(pcilib_t)); - - if (ctx) { - memset(ctx, 0, sizeof(pcilib_t)); - - ctx->handle = open(device, O_RDWR); - if (ctx->handle < 0) { - pcilib_error("Error opening device (%s)", device); - free(ctx); - return NULL; - } - - ctx->page_mask = (uintptr_t)-1; - ctx->model = model; - - if (!model) model = pcilib_get_model(ctx); - - memcpy(&ctx->model_info, pcilib_model + model, sizeof(pcilib_model_description_t)); - - pcilib_init_event_engine(ctx); - } - - return ctx; -} - -pcilib_model_description_t *pcilib_get_model_description(pcilib_t *ctx) { - return &ctx->model_info; -} - -const pcilib_board_info_t *pcilib_get_board_info(pcilib_t *ctx) { - int ret; - - if (ctx->page_mask == (uintptr_t)-1) { - ret = ioctl( ctx->handle, PCIDRIVER_IOC_PCI_INFO, &ctx->board_info ); - if (ret) { - pcilib_error("PCIDRIVER_IOC_PCI_INFO ioctl have failed"); - return NULL; - } - - ctx->page_mask = pcilib_get_page_mask(); - } - - return &ctx->board_info; -} - - - -pcilib_context_t *pcilib_get_implementation_context(pcilib_t *ctx) { - return ctx->event_ctx; -} - -pcilib_model_t pcilib_get_model(pcilib_t *ctx) { - if (ctx->model == PCILIB_MODEL_DETECT) { -// unsigned short vendor_id; -// unsigned short device_id; - - //return PCILIB_MODEL_PCI; - - const pcilib_board_info_t *board_info = pcilib_get_board_info(ctx); - if (!board_info) return PCILIB_MODEL_PCI; - - if ((board_info->vendor_id == PCIE_XILINX_VENDOR_ID)&&(board_info->device_id == PCIE_IPECAMERA_DEVICE_ID)) - ctx->model = PCILIB_MODEL_IPECAMERA; - else if ((board_info->vendor_id == PCIE_XILINX_VENDOR_ID)&&(board_info->device_id == PCIE_KAPTURE_DEVICE_ID)) - ctx->model = PCILIB_MODEL_IPECAMERA; - else - ctx->model = PCILIB_MODEL_PCI; - } - - return ctx->model; -} - -static pcilib_bar_t pcilib_detect_bar(pcilib_t *ctx, uintptr_t addr, size_t size) { - int n = 0; - pcilib_bar_t i; - - const pcilib_board_info_t *board_info = pcilib_get_board_info(ctx); - if (!board_info) return PCILIB_BAR_INVALID; - - for (i = 0; i < PCILIB_MAX_BANKS; i++) { - if (board_info->bar_length[i] > 0) { - if ((addr >= board_info->bar_start[i])&&((board_info->bar_start[i] + board_info->bar_length[i]) >= (addr + size))) return i; - - if (n) n = -1; - else n = i + 1; - } - } - - if (n > 0) return n - 1; - - return PCILIB_BAR_INVALID; -} - -int pcilib_detect_address(pcilib_t *ctx, pcilib_bar_t *bar, uintptr_t *addr, size_t size) { - const pcilib_board_info_t *board_info = pcilib_get_board_info(ctx); - if (!board_info) return PCILIB_ERROR_NOTFOUND; - - if (*bar == PCILIB_BAR_DETECT) { - *bar = pcilib_detect_bar(ctx, *addr, size); - if (*bar == PCILIB_BAR_INVALID) { - pcilib_error("The requested data block at address 0x%x with size %zu does not belongs to any available memory bank", *addr, size); - return PCILIB_ERROR_NOTFOUND; - } - if (*addr < board_info->bar_start[*bar]) - *addr += board_info->bar_start[*bar]; - } else { - if ((*addr < board_info->bar_start[*bar])||((board_info->bar_start[*bar] + board_info->bar_length[*bar]) < (((uintptr_t)*addr) + size))) { - if ((board_info->bar_length[*bar]) >= (((uintptr_t)*addr) + size)) { - *addr += board_info->bar_start[*bar]; - } else { - pcilib_error("The requested data block at address 0x%x with size %zu does not belong the specified memory bank (Bar %i: starting at 0x%x with size 0x%x)", *addr, size, *bar, board_info->bar_start[*bar], board_info->bar_length[*bar]); - return PCILIB_ERROR_NOTFOUND; - } - } - } - - *addr -= board_info->bar_start[*bar]; - *addr += board_info->bar_start[*bar] & ctx->page_mask; - - return 0; -} - -void *pcilib_map_bar(pcilib_t *ctx, pcilib_bar_t bar) { - void *res; - int ret; - - const pcilib_board_info_t *board_info = pcilib_get_board_info(ctx); - if (!board_info) return NULL; - - if (ctx->bar_space[bar]) return ctx->bar_space[bar]; - - ret = ioctl( ctx->handle, PCIDRIVER_IOC_MMAP_MODE, PCIDRIVER_MMAP_PCI ); - if (ret) { - pcilib_error("PCIDRIVER_IOC_MMAP_MODE ioctl have failed", bar); - return NULL; - } - - ret = ioctl( ctx->handle, PCIDRIVER_IOC_MMAP_AREA, PCIDRIVER_BAR0 + bar ); - if (ret) { - pcilib_error("PCIDRIVER_IOC_MMAP_AREA ioctl have failed for bank %i", bar); - return NULL; - } - -#ifdef PCILIB_FILE_IO - file_io_handle = open("/root/data", O_RDWR); - res = mmap( 0, board_info->bar_length[bar], PROT_WRITE | PROT_READ, MAP_SHARED, ctx->file_io_handle, 0 ); -#else - res = mmap( 0, board_info->bar_length[bar], PROT_WRITE | PROT_READ, MAP_SHARED, ctx->handle, 0 ); -#endif - if ((!res)||(res == MAP_FAILED)) { - pcilib_error("Failed to mmap data bank %i", bar); - return NULL; - } - - - return res; -} - -void pcilib_unmap_bar(pcilib_t *ctx, pcilib_bar_t bar, void *data) { - const pcilib_board_info_t *board_info = pcilib_get_board_info(ctx); - if (!board_info) return; - - if (ctx->bar_space[bar]) return; - - munmap(data, board_info->bar_length[bar]); -#ifdef PCILIB_FILE_IO - close(ctx->file_io_handle); -#endif -} - -int pcilib_map_register_space(pcilib_t *ctx) { - int err; - pcilib_register_bank_t i; - - if (!ctx->reg_bar_mapped) { - pcilib_model_description_t *model_info = pcilib_get_model_description(ctx); - pcilib_register_bank_description_t *banks = model_info->banks; - - for (i = 0; ((banks)&&(banks[i].access)); i++) { -// uint32_t buf[2]; - void *reg_space; - pcilib_bar_t bar = banks[i].bar; - - if (bar == PCILIB_BAR_DETECT) { - uintptr_t addr = banks[0].read_addr; - - err = pcilib_detect_address(ctx, &bar, &addr, 1); - if (err) return err; - - if (!ctx->bar_space[bar]) { - reg_space = pcilib_map_bar(ctx, bar); -// pcilib_memcpy(&buf, reg_space, 8); - - if (reg_space) { - ctx->bar_space[bar] = reg_space; - } else { - return PCILIB_ERROR_FAILED; - } - } - } else if (!ctx->bar_space[bar]) { - reg_space = pcilib_map_bar(ctx, bar); - if (reg_space) { - ctx->bar_space[bar] = reg_space; - } else { - return PCILIB_ERROR_FAILED; - } -// pcilib_memcpy(&buf, reg_space, 8); - - } - if (!i) ctx->reg_bar = bar; - } - - ctx->reg_bar_mapped = 1; - } - - return 0; -} - -int pcilib_map_data_space(pcilib_t *ctx, uintptr_t addr) { - int err; - pcilib_bar_t i; - - if (!ctx->data_bar_mapped) { - const pcilib_board_info_t *board_info = pcilib_get_board_info(ctx); - if (!board_info) return PCILIB_ERROR_FAILED; - - err = pcilib_map_register_space(ctx); - if (err) { - pcilib_error("Error mapping register space"); - return err; - } - - int data_bar = -1; - - for (i = 0; i < PCILIB_MAX_BANKS; i++) { - if ((ctx->bar_space[i])||(!board_info->bar_length[i])) continue; - - if (addr) { - if (board_info->bar_start[i] == addr) { - data_bar = i; - break; - } - } else { - if (data_bar >= 0) { - data_bar = -1; - break; - } - - data_bar = i; - } - } - - - if (data_bar < 0) { - if (addr) pcilib_error("Unable to find the specified data space (%lx)", addr); - else pcilib_error("Unable to find the data space"); - return PCILIB_ERROR_NOTFOUND; - } - - ctx->data_bar = data_bar; - - if (!ctx->bar_space[data_bar]) { - char *data_space = pcilib_map_bar(ctx, data_bar); - if (data_space) ctx->bar_space[data_bar] = data_space; - else { - pcilib_error("Unable to map the data space"); - return PCILIB_ERROR_FAILED; - } - } - - ctx->data_bar_mapped = 0; - } - - return 0; -} - -/* -static void pcilib_unmap_register_space(pcilib_t *ctx) { - if (ctx->reg_space) { - pcilib_unmap_bar(ctx, ctx->reg_bar, ctx->reg_space); - ctx->reg_space = NULL; - } -} - -static void pcilib_unmap_data_space(pcilib_t *ctx) { - if (ctx->data_space) { - pcilib_unmap_bar(ctx, ctx->data_bar, ctx->data_space); - ctx->data_space = NULL; - } -} -*/ - -char *pcilib_resolve_register_address(pcilib_t *ctx, pcilib_bar_t bar, uintptr_t addr) { - if (bar == PCILIB_BAR_DETECT) { - // First checking the default register bar - size_t offset = addr - ctx->board_info.bar_start[ctx->reg_bar]; - if ((addr > ctx->board_info.bar_start[ctx->reg_bar])&&(offset < ctx->board_info.bar_length[ctx->reg_bar])) { - if (!ctx->bar_space[ctx->reg_bar]) { - pcilib_error("The register bar is not mapped"); - return NULL; - } - - return ctx->bar_space[ctx->reg_bar] + offset + (ctx->board_info.bar_start[ctx->reg_bar] & ctx->page_mask); - } - - // Otherwise trying to detect - bar = pcilib_detect_bar(ctx, addr, 1); - if (bar != PCILIB_BAR_INVALID) { - size_t offset = addr - ctx->board_info.bar_start[bar]; - if ((offset < ctx->board_info.bar_length[bar])&&(ctx->bar_space[bar])) { - if (!ctx->bar_space[bar]) { - pcilib_error("The requested bar (%i) is not mapped", bar); - return NULL; - } - return ctx->bar_space[bar] + offset + (ctx->board_info.bar_start[bar] & ctx->page_mask); - } - } - } else { - if (!ctx->bar_space[bar]) { - pcilib_error("The requested bar (%i) is not mapped", bar); - return NULL; - } - - if (addr < ctx->board_info.bar_length[bar]) { - return ctx->bar_space[bar] + addr + (ctx->board_info.bar_start[bar] & ctx->page_mask); - } - - if ((addr >= ctx->board_info.bar_start[bar])&&(addr < (ctx->board_info.bar_start[bar] + ctx->board_info.bar_length[ctx->reg_bar]))) { - return ctx->bar_space[bar] + (addr - ctx->board_info.bar_start[bar]) + (ctx->board_info.bar_start[bar] & ctx->page_mask); - } - } - - return NULL; -} - -char *pcilib_resolve_data_space(pcilib_t *ctx, uintptr_t addr, size_t *size) { - int err; - - err = pcilib_map_data_space(ctx, addr); - if (err) { - pcilib_error("Failed to map the specified address space (%lx)", addr); - return NULL; - } - - if (size) *size = ctx->board_info.bar_length[ctx->data_bar]; - - return ctx->bar_space[ctx->data_bar] + (ctx->board_info.bar_start[ctx->data_bar] & ctx->page_mask); -} - - -void pcilib_close(pcilib_t *ctx) { - pcilib_bar_t i; - - if (ctx) { - pcilib_model_description_t *model_info = pcilib_get_model_description(ctx); - pcilib_event_api_description_t *eapi = model_info->event_api; - pcilib_dma_api_description_t *dapi = model_info->dma_api; - - if ((eapi)&&(eapi->free)) eapi->free(ctx->event_ctx); - if ((dapi)&&(dapi->free)) dapi->free(ctx->dma_ctx); - - if (ctx->model_info.registers != model_info->registers) { - free(ctx->model_info.registers); - ctx->model_info.registers = pcilib_model[ctx->model].registers; - } - - if (ctx->kmem_list) { - pcilib_warning("Not all kernel buffers are properly cleaned"); - - while (ctx->kmem_list) { - pcilib_free_kernel_memory(ctx, ctx->kmem_list, 0); - } - } - - for (i = 0; i < PCILIB_MAX_BANKS; i++) { - if (ctx->bar_space[i]) { - char *ptr = ctx->bar_space[i]; - ctx->bar_space[i] = NULL; - pcilib_unmap_bar(ctx, i, ptr); - } - } - close(ctx->handle); - - free(ctx); - } -} - -int pcilib_read(pcilib_t *ctx, pcilib_bar_t bar, uintptr_t addr, size_t size, void *buf) { - void *data; - - pcilib_detect_address(ctx, &bar, &addr, size); - data = pcilib_map_bar(ctx, bar); - - pcilib_memcpy(buf, data + addr, size); - - pcilib_unmap_bar(ctx, bar, data); - - return 0; -} - -int pcilib_write(pcilib_t *ctx, pcilib_bar_t bar, uintptr_t addr, size_t size, void *buf) { - void *data; - - pcilib_detect_address(ctx, &bar, &addr, size); - data = pcilib_map_bar(ctx, bar); - - pcilib_memcpy(data + addr, buf, size); - - pcilib_unmap_bar(ctx, bar, data); - - return 0; -} - - -int pcilib_read_fifo(pcilib_t *ctx, pcilib_bar_t bar, uintptr_t addr, uint8_t fifo_size, size_t n, void *buf) { - int i; - void *data; - - pcilib_detect_address(ctx, &bar, &addr, fifo_size); - data = pcilib_map_bar(ctx, bar); - - for (i = 0; i < n; i++) { - pcilib_memcpy(buf + i * fifo_size, data + addr, fifo_size); - } - - pcilib_unmap_bar(ctx, bar, data); - - return 0; -} - -int pcilib_write_fifo(pcilib_t *ctx, pcilib_bar_t bar, uintptr_t addr, uint8_t fifo_size, size_t n, void *buf) { - int i; - void *data; - - pcilib_detect_address(ctx, &bar, &addr, fifo_size); - data = pcilib_map_bar(ctx, bar); - - for (i = 0; i < n; i++) { - pcilib_memcpy(data + addr, buf + i * fifo_size, fifo_size); - } - - pcilib_unmap_bar(ctx, bar, data); - - return 0; -} @@ -1,85 +0,0 @@ -#ifndef _PCITOOL_PCI_H -#define _PCITOOL_PCI_H - -#define PCILIB_DEFAULT_CPU_COUNT 2 -#define PCILIB_EVENT_TIMEOUT 1000000 /**< us */ -#define PCILIB_TRIGGER_TIMEOUT 100000 /**< us */ -#define PCILIB_DMA_TIMEOUT 10000 /**< us */ -#define PCILIB_DMA_SKIP_TIMEOUT 1000000 /**< us */ -#define PCILIB_REGISTER_TIMEOUT 10000 /**< us */ - -#include "driver/pciDriver.h" -#include "pcilib_types.h" - -#include "pcilib.h" -#include "register.h" -#include "kmem.h" -#include "irq.h" -#include "dma.h" -#include "event.h" - -struct pcilib_s { - int handle; - - uintptr_t page_mask; - pcilib_board_info_t board_info; - pcilib_dma_info_t dma_info; - pcilib_model_t model; - - char *bar_space[PCILIB_MAX_BANKS]; - - int reg_bar_mapped; - pcilib_bar_t reg_bar; -// char *reg_space; - - int data_bar_mapped; - pcilib_bar_t data_bar; -// char *data_space; -// size_t data_size; - - pcilib_kmem_list_t *kmem_list; - - size_t num_reg, alloc_reg; - pcilib_model_description_t model_info; - - pcilib_dma_context_t *dma_ctx; - pcilib_context_t *event_ctx; - -#ifdef PCILIB_FILE_IO - int file_io_handle; -#endif /* PCILIB_FILE_IO */ -}; - -#ifdef _PCILIB_PCI_C -# include "ipecamera/model.h" -# include "kapture/model.h" -# include "dma/nwl.h" -# include "dma/ipe.h" -# include "default.h" - -pcilib_model_description_t pcilib_model[4] = { - { 4, PCILIB_HOST_ENDIAN, NULL, NULL, NULL, NULL, NULL, NULL }, - { 4, PCILIB_HOST_ENDIAN, NULL, NULL, NULL, NULL, NULL, NULL }, - { 4, PCILIB_LITTLE_ENDIAN, ipecamera_registers, ipecamera_register_banks, ipecamera_register_ranges, ipecamera_events, ipecamera_data_types, &ipe_dma_api, &ipecamera_image_api }, - { 4, PCILIB_LITTLE_ENDIAN, kapture_registers, kapture_register_banks, kapture_register_ranges, kapture_events, kapture_data_types, &ipe_dma_api, &kapture_api }, -}; - -pcilib_protocol_description_t pcilib_protocol[3] = { - { pcilib_default_read, pcilib_default_write }, - { ipecamera_read, ipecamera_write }, - { NULL, NULL } -}; -#else -extern pcilib_model_description_t pcilib_model[]; -extern pcilib_protocol_description_t pcilib_protocol[]; -#endif /* _PCILIB_PCI_C */ - -const pcilib_board_info_t *pcilib_get_board_info(pcilib_t *ctx); -const pcilib_dma_info_t *pcilib_get_dma_info(pcilib_t *ctx); - -int pcilib_map_register_space(pcilib_t *ctx); -int pcilib_map_data_space(pcilib_t *ctx, uintptr_t addr); -int pcilib_detect_address(pcilib_t *ctx, pcilib_bar_t *bar, uintptr_t *addr, size_t size); - - -#endif /* _PCITOOL_PCI_H */ diff --git a/pcilib.h b/pcilib.h deleted file mode 100644 index 12d5252..0000000 --- a/pcilib.h +++ /dev/null @@ -1,380 +0,0 @@ -#ifndef _PCITOOL_PCILIB_H -#define _PCITOOL_PCILIB_H - -#define PCILIB_MAX_BANKS 6 -#define PCILIB_MAX_DMA_ENGINES 32 - -#include <sys/time.h> -#include <stdint.h> - -#define pcilib_memcpy pcilib_memcpy32 -#define pcilib_datacpy pcilib_datacpy32 - -typedef struct pcilib_s pcilib_t; -typedef struct pcilib_event_context_s pcilib_context_t; -typedef struct pcilib_dma_context_s pcilib_dma_context_t; - - -typedef struct pcilib_dma_api_description_s pcilib_dma_api_description_t; -typedef struct pcilib_event_api_description_s pcilib_event_api_description_t; -typedef struct pcilib_protocol_description_s pcilib_protocol_description_t; -typedef unsigned int pcilib_irq_hw_source_t; -typedef uint32_t pcilib_irq_source_t; - -typedef uint8_t pcilib_bar_t; /**< Type holding the PCI Bar number */ -typedef uint8_t pcilib_register_t; /**< Type holding the register ID within the Bank */ -typedef uint32_t pcilib_register_addr_t; /**< Type holding the register ID within the Bank */ -typedef uint8_t pcilib_register_bank_t; /**< Type holding the register bank number */ -typedef uint8_t pcilib_register_bank_addr_t; /**< Type holding the register bank number */ -typedef uint8_t pcilib_register_size_t; /**< Type holding the size in bits of the register */ -typedef uint32_t pcilib_register_value_t; /**< Type holding the register value */ -typedef uint8_t pcilib_dma_engine_addr_t; -typedef uint8_t pcilib_dma_engine_t; -typedef uint64_t pcilib_event_id_t; -typedef uint32_t pcilib_event_t; -typedef uint64_t pcilib_timeout_t; /**< In microseconds */ - -typedef enum { - PCILIB_HOST_ENDIAN = 0, - PCILIB_LITTLE_ENDIAN, - PCILIB_BIG_ENDIAN -} pcilib_endianess_t; - -typedef enum { - PCILIB_MODEL_DETECT, - PCILIB_MODEL_PCI, - PCILIB_MODEL_IPECAMERA, - PCILIB_MODEL_KAPTURE -} pcilib_model_t; - -typedef enum { - PCILIB_REGISTER_R = 1, - PCILIB_REGISTER_W = 2, - PCILIB_REGISTER_RW = 3, - PCILIB_REGISTER_W1C = 4, /**< writting 1 resets the flag */ - PCILIB_REGISTER_RW1C = 5 -} pcilib_register_mode_t; - -typedef enum { - PCILIB_DEFAULT_PROTOCOL, - IPECAMERA_REGISTER_PROTOCOL -} pcilib_register_protocol_t; - -typedef enum { - PCILIB_EVENT_DATA = 0, /**< default data format */ - PCILIB_EVENT_RAW_DATA = 1 /**< raw data */ -} pcilib_event_data_type_t; - -typedef enum { - PCILIB_DMA_FLAGS_DEFAULT = 0, - PCILIB_DMA_FLAG_EOP = 1, /**< last buffer of the packet */ - PCILIB_DMA_FLAG_WAIT = 2, /**< wait completion of write operation / wait for data during read operation */ - PCILIB_DMA_FLAG_MULTIPACKET = 4, /**< read multiple packets */ - PCILIB_DMA_FLAG_PERSISTENT = 8, /**< do not stop DMA engine on application termination / permanently close DMA engine on dma_stop */ - PCILIB_DMA_FLAG_IGNORE_ERRORS = 16 /**< do not crash on errors, but return appropriate error codes */ -} pcilib_dma_flags_t; - -typedef enum { - PCILIB_STREAMING_STOP = 0, /**< stop streaming */ - PCILIB_STREAMING_CONTINUE = 1, /**< wait the default DMA timeout for a new data */ - PCILIB_STREAMING_WAIT = 2, /**< wait the specified timeout for a new data */ - PCILIB_STREAMING_CHECK = 3, /**< do not wait for the data, bail out imideatly if no data ready */ - PCILIB_STREAMING_FAIL = 4, /**< fail if data is not available on timeout */ - PCILIB_STREAMING_REQ_FRAGMENT = 5, /**< only fragment of a packet is read, wait for next fragment and fail if no data during DMA timeout */ - PCILIB_STREAMING_REQ_PACKET = 6, /**< wait for next packet and fail if no data during the specified timeout */ - PCILIB_STREAMING_TIMEOUT_MASK = 3 /**< mask specifying all timeout modes */ -} pcilib_streaming_action_t; - - -typedef enum { - PCILIB_EVENT_FLAGS_DEFAULT = 0, - PCILIB_EVENT_FLAG_RAW_DATA_ONLY = 1, /**< Do not parse data, just read raw and pass it to rawdata callback. If passed to rawdata callback, idicates the data is not identified as event (most probably just padding) */ - PCILIB_EVENT_FLAG_STOP_ONLY = 1, /**< Do not cleanup, just stop acquiring new frames, the cleanup should be requested afterwards */ - PCILIB_EVENT_FLAG_EOF = 2, /**< Indicates that it is the last part of the frame (not required) */ - PCILIB_EVENT_FLAG_PREPROCESS = 4 /**< Enables preprocessing of the raw data (decoding frames, etc.) */ -} pcilib_event_flags_t; - -typedef enum { - PCILIB_EVENT_INFO_FLAG_BROKEN = 1 /**< Indicates broken frames (if this flag is fales, the frame still can be broken) */ -} pcilib_event_info_flags_t; - -typedef enum { - PCILIB_REGISTER_STANDARD = 0, - PCILIB_REGISTER_FIFO, - PCILIB_REGISTER_BITS -} pcilib_register_type_t; - -#define PCILIB_BAR_DETECT ((pcilib_bar_t)-1) -#define PCILIB_BAR_INVALID ((pcilib_bar_t)-1) -#define PCILIB_BAR0 0 -#define PCILIB_BAR1 1 -#define PCILIB_DMA_ENGINE_INVALID ((pcilib_dma_engine_t)-1) -#define PCILIB_DMA_ENGINE_ALL ((pcilib_dma_engine_t)-1) -#define PCILIB_DMA_FLAGS_DEFAULT ((pcilib_dma_flags_t)0) -#define PCILIB_DMA_ENGINE_ADDR_INVALID ((pcilib_dma_engine_addr_t)-1) -#define PCILIB_REGISTER_INVALID ((pcilib_register_t)-1) -#define PCILIB_ADDRESS_INVALID ((uintptr_t)-1) -#define PCILIB_REGISTER_BANK_INVALID ((pcilib_register_bank_t)-1) -#define PCILIB_REGISTER_BANK0 0 -#define PCILIB_REGISTER_BANK1 1 -#define PCILIB_REGISTER_BANK2 2 -#define PCILIB_REGISTER_BANK3 3 -#define PCILIB_REGISTER_BANK_DMA 128 -#define PCILIB_EVENT0 1 -#define PCILIB_EVENT1 2 -#define PCILIB_EVENT2 4 -#define PCILIB_EVENT3 8 -#define PCILIB_EVENTS_ALL ((pcilib_event_t)-1) -#define PCILIB_EVENT_INVALID ((pcilib_event_t)-1) -#define PCILIB_EVENT_DATA_TYPE_INVALID ((pcilib_event_data_type_t)-1) -#define PCILIB_TIMEOUT_INFINITE ((pcilib_timeout_t)-1) -#define PCILIB_TIMEOUT_IMMEDIATE 0 -#define PCILIB_IRQ_TYPE_ALL 0 -#define PCILIB_IRQ_SOURCE_DEFAULT 0 -#define PCILIB_REGISTER_NO_BITS 0 -#define PCILIB_REGISTER_ALL_BITS ((pcilib_register_value_t)-1) - -typedef struct { - pcilib_event_t type; - uint64_t seqnum; /**< we will add seqnum_overflow if required */ - uint64_t offset; /**< nanoseconds */ - struct timeval timestamp; /**< most accurate timestamp */ - pcilib_event_info_flags_t flags; /**< flags */ -} pcilib_event_info_t; - -/**< - * Callback function called when new data is read by DMA streaming function - * @ctx - DMA Engine context - * @flags - DMA Flags - * @bufsize - size of data in bytes - * @buf - data - * @returns - * <0 - error, stop streaming (the value is negative error code) - * 0 - stop streaming (PCILIB_STREAMING_STOP) - * 1 - wait DMA timeout and return gracefuly if no data (PCILIB_STREAMING_CONTINUE) - * 2 - wait the specified timeout and return gracefuly if no data (PCILIB_STREAMING_WAIT) - * 3 - check if more data is available without waiting, return gracefuly if not (PCILIB_STREAMING_CHECK) - * 5 - wait DMA timeout and fail if no data (PCILIB_STREAMING_REQ_FRAGMENT) - * 6 - wait the specified timeout and fail if no data (PCILIB_STREAMING_REQ_PACKET) - */ -typedef int (*pcilib_dma_callback_t)(void *ctx, pcilib_dma_flags_t flags, size_t bufsize, void *buf); -typedef int (*pcilib_event_callback_t)(pcilib_event_id_t event_id, pcilib_event_info_t *info, void *user); -typedef int (*pcilib_event_rawdata_callback_t)(pcilib_event_id_t event_id, pcilib_event_info_t *info, pcilib_event_flags_t flags, size_t size, void *data, void *user); - -typedef struct { - pcilib_register_bank_addr_t addr; - - pcilib_bar_t bar; // optional - size_t size; - - pcilib_register_protocol_t protocol; - - uintptr_t read_addr; // or offset if bar specified - uintptr_t write_addr; // or offset if bar specified - uint8_t raw_endianess; - - uint8_t access; - uint8_t endianess; - - const char *format; - const char *name; - const char *description; -} pcilib_register_bank_description_t; - -typedef struct { - pcilib_register_addr_t addr; - pcilib_register_size_t offset; - pcilib_register_size_t bits; - pcilib_register_value_t defvalue; - pcilib_register_value_t rwmask; /**< 1 - read before write bits, 0 - zero should be written to preserve value - Used to define how external bits of PCILIB_REGISTER_BITS registers are treated. - Currently it is a bit confusing, we may find a better way in the next release */ - pcilib_register_mode_t mode; - pcilib_register_type_t type; - - pcilib_register_bank_t bank; - - const char *name; - const char *description; -} pcilib_register_description_t; - -/** - * Default mappings - */ -typedef struct { - uintptr_t start; - uintptr_t end; - pcilib_register_bank_addr_t bank; - long addr_shift; -} pcilib_register_range_t; - -typedef struct { - pcilib_event_t evid; - const char *name; - const char *description; -} pcilib_event_description_t; - -typedef struct { - pcilib_event_data_type_t data_type; - pcilib_event_t evid; - const char *name; - const char *description; -} pcilib_event_data_type_description_t; - -typedef enum { - PCILIB_DMA_IRQ = 1, - PCILIB_EVENT_IRQ = 2 -} pcilib_irq_type_t; - -typedef enum { - PCILIB_DMA_TO_DEVICE = 1, - PCILIB_DMA_FROM_DEVICE = 2, - PCILIB_DMA_BIDIRECTIONAL = 3 -} pcilib_dma_direction_t; - -typedef enum { - PCILIB_DMA_TYPE_BLOCK, - PCILIB_DMA_TYPE_PACKET, - PCILIB_DMA_TYPE_UNKNOWN -} pcilib_dma_engine_type_t; - -typedef struct { - pcilib_dma_engine_addr_t addr; - pcilib_dma_engine_type_t type; - pcilib_dma_direction_t direction; - size_t addr_bits; -} pcilib_dma_engine_description_t; - -typedef struct { - pcilib_dma_engine_description_t *engines[PCILIB_MAX_DMA_ENGINES + 1]; -} pcilib_dma_info_t; - -typedef struct { - uint8_t access; - uint8_t endianess; - - pcilib_register_description_t *registers; - pcilib_register_bank_description_t *banks; - pcilib_register_range_t *ranges; - pcilib_event_description_t *events; - pcilib_event_data_type_description_t *data_types; - - pcilib_dma_api_description_t *dma_api; - pcilib_event_api_description_t *event_api; -} pcilib_model_description_t; - -int pcilib_set_error_handler(void (*err)(const char *msg, ...), void (*warn)(const char *msg, ...)); - -pcilib_model_t pcilib_get_model(pcilib_t *ctx); -pcilib_model_description_t *pcilib_get_model_description(pcilib_t *ctx); -pcilib_context_t *pcilib_get_implementation_context(pcilib_t *ctx); - -pcilib_t *pcilib_open(const char *device, pcilib_model_t model); -void pcilib_close(pcilib_t *ctx); - -int pcilib_start_dma(pcilib_t *ctx, pcilib_dma_engine_t dma, pcilib_dma_flags_t flags); -int pcilib_stop_dma(pcilib_t *ctx, pcilib_dma_engine_t dma, pcilib_dma_flags_t flags); - - // Interrupt API is preliminary and can be significantly changed in future -int pcilib_enable_irq(pcilib_t *ctx, pcilib_irq_type_t irq_type, pcilib_dma_flags_t flags); -int pcilib_acknowledge_irq(pcilib_t *ctx, pcilib_irq_type_t irq_type, pcilib_irq_source_t irq_source); -int pcilib_disable_irq(pcilib_t *ctx, pcilib_dma_flags_t flags); - -int pcilib_wait_irq(pcilib_t *ctx, pcilib_irq_hw_source_t source, pcilib_timeout_t timeout, size_t *count); -int pcilib_clear_irq(pcilib_t *ctx, pcilib_irq_hw_source_t source); - -void *pcilib_map_bar(pcilib_t *ctx, pcilib_bar_t bar); -void pcilib_unmap_bar(pcilib_t *ctx, pcilib_bar_t bar, void *data); -char *pcilib_resolve_register_address(pcilib_t *ctx, pcilib_bar_t bar, uintptr_t addr); // addr is offset if bar is specified -char *pcilib_resolve_data_space(pcilib_t *ctx, uintptr_t addr, size_t *size); - -pcilib_register_bank_t pcilib_find_bank_by_addr(pcilib_t *ctx, pcilib_register_bank_addr_t bank); -pcilib_register_bank_t pcilib_find_bank_by_name(pcilib_t *ctx, const char *bankname); -pcilib_register_bank_t pcilib_find_bank(pcilib_t *ctx, const char *bank); -pcilib_register_t pcilib_find_register(pcilib_t *ctx, const char *bank, const char *reg); -pcilib_event_t pcilib_find_event(pcilib_t *ctx, const char *event); -pcilib_event_data_type_t pcilib_find_event_data_type(pcilib_t *ctx, pcilib_event_t event, const char *data_type); -pcilib_dma_engine_t pcilib_find_dma_by_addr(pcilib_t *ctx, pcilib_dma_direction_t direction, pcilib_dma_engine_addr_t dma); - -int pcilib_read(pcilib_t *ctx, pcilib_bar_t bar, uintptr_t addr, size_t size, void *buf); -int pcilib_write(pcilib_t *ctx, pcilib_bar_t bar, uintptr_t addr, size_t size, void *buf); -int pcilib_write_fifo(pcilib_t *ctx, pcilib_bar_t bar, uintptr_t addr, uint8_t fifo_size, size_t n, void *buf); -int pcilib_read_fifo(pcilib_t *ctx, pcilib_bar_t bar, uintptr_t addr, uint8_t fifo_size, size_t n, void *buf); - -int pcilib_skip_dma(pcilib_t *ctx, pcilib_dma_engine_t dma); -int pcilib_stream_dma(pcilib_t *ctx, pcilib_dma_engine_t dma, uintptr_t addr, size_t size, pcilib_dma_flags_t flags, pcilib_timeout_t timeout, pcilib_dma_callback_t cb, void *cbattr); -int pcilib_push_dma(pcilib_t *ctx, pcilib_dma_engine_t dma, uintptr_t addr, size_t size, pcilib_dma_flags_t flags, pcilib_timeout_t timeout, void *buf, size_t *written_bytes); -int pcilib_read_dma(pcilib_t *ctx, pcilib_dma_engine_t dma, uintptr_t addr, size_t size, void *buf, size_t *read_bytes); -int pcilib_read_dma_custom(pcilib_t *ctx, pcilib_dma_engine_t dma, uintptr_t addr, size_t size, pcilib_dma_flags_t flags, pcilib_timeout_t timeout, void *buf, size_t *read_bytes); -int pcilib_write_dma(pcilib_t *ctx, pcilib_dma_engine_t dma, uintptr_t addr, size_t size, void *buf, size_t *written_bytes); -double pcilib_benchmark_dma(pcilib_t *ctx, pcilib_dma_engine_addr_t dma, uintptr_t addr, size_t size, size_t iterations, pcilib_dma_direction_t direction); - -int pcilib_read_register_space(pcilib_t *ctx, const char *bank, pcilib_register_addr_t addr, size_t n, pcilib_register_value_t *buf); -int pcilib_write_register_space(pcilib_t *ctx, const char *bank, pcilib_register_addr_t addr, size_t n, pcilib_register_value_t *buf); -int pcilib_read_register_by_id(pcilib_t *ctx, pcilib_register_t reg, pcilib_register_value_t *value); -int pcilib_write_register_by_id(pcilib_t *ctx, pcilib_register_t reg, pcilib_register_value_t value); -int pcilib_read_register(pcilib_t *ctx, const char *bank, const char *regname, pcilib_register_value_t *value); -int pcilib_write_register(pcilib_t *ctx, const char *bank, const char *regname, pcilib_register_value_t value); - -int pcilib_reset(pcilib_t *ctx); -int pcilib_trigger(pcilib_t *ctx, pcilib_event_t event, size_t trigger_size, void *trigger_data); - -/* - * The recording of new events will be stopped after reaching max_events records - * or when the specified amount of time is elapsed. However, the @pcilib_stop - * function should be called still. - * NOTE: This options may not be respected if the PCILIB_EVENT_FLAG_RAW_DATA_ONLY - * is specified. - */ -int pcilib_configure_autostop(pcilib_t *ctx, size_t max_events, pcilib_timeout_t duration); - -/* - * Request auto-triggering while grabbing - */ -int pcilib_configure_autotrigger(pcilib_t *ctx, pcilib_timeout_t interval, pcilib_event_t event, size_t trigger_size, void *trigger_data); -/* - * Request streaming the rawdata from the event engine. It is fastest way to acuqire data. - * No memory copies will be performed and DMA buffers will be directly passed to the user - * callback. However, to prevent data loss, no processing should be done on the data. The - * user callback is only expected to copy data into the appropriate place and return control - * to the event engine. - * The performance can be boosted further by disabling any data processing within the event - * engine. Just pass PCILIB_EVENT_FLAG_RAW_DATA_ONLY flag to the @pcilib_start function. - */ -int pcilib_configure_rawdata_callback(pcilib_t *ctx, pcilib_event_rawdata_callback_t callback, void *user); - -/* - * Configures maximal number of preprocessing threads. Actual amount of threads - * may be bigger. For instance, additionaly a real-time reader thread will be - * executed for most of hardware - */ -int pcilib_configure_preprocessing_threads(pcilib_t *ctx, size_t max_threads); - - -int pcilib_start(pcilib_t *ctx, pcilib_event_t event_mask, pcilib_event_flags_t flags); -int pcilib_stop(pcilib_t *ctx, pcilib_event_flags_t flags); - -int pcilib_stream(pcilib_t *ctx, pcilib_event_callback_t callback, void *user); -int pcilib_get_next_event(pcilib_t *ctx, pcilib_timeout_t timeout, pcilib_event_id_t *evid, size_t info_size, pcilib_event_info_t *info); - -int pcilib_copy_data(pcilib_t *ctx, pcilib_event_id_t event_id, pcilib_event_data_type_t data_type, size_t size, void *buf, size_t *retsize); -int pcilib_copy_data_with_argument(pcilib_t *ctx, pcilib_event_id_t event_id, pcilib_event_data_type_t data_type, size_t arg_size, void *arg, size_t size, void *buf, size_t *retsize); -void *pcilib_get_data(pcilib_t *ctx, pcilib_event_id_t event_id, pcilib_event_data_type_t data_type, size_t *size_or_err); -void *pcilib_get_data_with_argument(pcilib_t *ctx, pcilib_event_id_t event_id, pcilib_event_data_type_t data_type, size_t arg_size, void *arg, size_t *size_or_err); - -/* - * This function is provided to find potentially corrupted data. If the data is overwritten by - * the time return_data is called it will return error. - */ -int pcilib_return_data(pcilib_t *ctx, pcilib_event_id_t event_id, pcilib_event_data_type_t data_type, void *data); - - - -/* - * @param data - will be allocated and shuld be freed if NULL, otherwise used and size should contain correct size. - * In case of failure the content of data is undefined. - * @param timeout - will be autotriggered if NULL - */ -int pcilib_grab(pcilib_t *ctx, pcilib_event_t event_mask, size_t *size, void **data, pcilib_timeout_t timeout); - -#endif /* _PCITOOL_PCILIB_H */ diff --git a/pcilib_types.h b/pcilib_types.h deleted file mode 100644 index 52c0879..0000000 --- a/pcilib_types.h +++ /dev/null @@ -1,44 +0,0 @@ -#ifndef _PCILIB_TYPES_H -#define _PCILIB_TYPES_H - -#define KMEM_REF_HW 0x80000000 /**< Special reference to indicate hardware access */ -#define KMEM_REF_COUNT 0x0FFFFFFF /**< Mask of reference counter (mmap/munmap), couting in mmaped memory pages */ - -#define KMEM_MODE_REUSABLE 0x80000000 /**< Indicates reusable buffer */ -#define KMEM_MODE_EXCLUSIVE 0x40000000 /**< Only a single process is allowed to mmap the buffer */ -#define KMEM_MODE_PERSISTENT 0x20000000 /**< Persistent mode instructs kmem_free to preserve buffer in memory */ -#define KMEM_MODE_COUNT 0x0FFFFFFF /**< Mask of reuse counter (alloc/free) */ - -#define PCILIB_KMEM_TYPE_MASK 0xFFFF0000 - -typedef enum { - PCILIB_KMEM_TYPE_CONSISTENT = 0x00000, - PCILIB_KMEM_TYPE_PAGE = 0x10000, - PCILIB_KMEM_TYPE_DMA_S2C_PAGE = 0x10001, - PCILIB_KMEM_TYPE_DMA_C2S_PAGE = 0x10002, - PCILIB_KMEM_TYPE_REGION = 0x20000, - PCILIB_KMEM_TYPE_REGION_S2C = 0x20001, - PCILIB_KMEM_TYPE_REGION_C2S = 0x20002 -} pcilib_kmem_type_t; - -typedef enum { - PCILIB_KMEM_USE_STANDARD = 0, - PCILIB_KMEM_USE_DMA_RING = 1, - PCILIB_KMEM_USE_DMA_PAGES = 2, - PCILIB_KMEM_USE_USER = 0x10 -} pcilib_kmem_use_t; - -typedef enum { - PCILIB_KMEM_SYNC_BIDIRECTIONAL = 0, - PCILIB_KMEM_SYNC_TODEVICE = 1, - PCILIB_KMEM_SYNC_FROMDEVICE = 2 -} pcilib_kmem_sync_direction_t; - - -#define PCILIB_KMEM_USE(type, subtype) (((type) << 16)|(subtype)) - - -//pcilib_alloc_kmem_buffer(pcilib_t *ctx, size_t size, size_t alignment) - - -#endif /* _PCILIB_TYPES_H */ diff --git a/pcitool/CMakeLists.txt b/pcitool/CMakeLists.txt deleted file mode 100644 index 6dc7942..0000000 --- a/pcitool/CMakeLists.txt +++ /dev/null @@ -1,8 +0,0 @@ -include_directories( - ${CMAKE_SOURCE_DIR} -) - -set(HEADERS ${HEADERS} sysinfo.h formaters.h) - -add_library(pcitool STATIC sysinfo.c formaters.c) - diff --git a/pcitool/formaters.c b/pcitool/formaters.c deleted file mode 100644 index 91b8c77..0000000 --- a/pcitool/formaters.c +++ /dev/null @@ -1,47 +0,0 @@ -#include <stdio.h> - -void PrintTime(size_t duration) { - if (duration > 999999999999) printf("%4.1lf""d", 1.*duration/86400000000); - else if (duration > 99999999999) printf("%4.1lf""h", 1.*duration/3600000000); - else if (duration > 9999999999) printf("%4.2lf""h", 1.*duration/3600000000); - else if (duration > 999999999) printf("%4.1lf""m", 1.*duration/60000000); - else if (duration > 99999999) printf("%4.2lf""m", 1.*duration/60000000); - else if (duration > 9999999) printf("%4.1lf""s", 1.*duration/1000000); - else if (duration > 999999) printf("%4.2lf""s", 1.*duration/1000000); - else if (duration > 999) printf("%3lu""ms", duration/1000); - else printf("%3lu""us", duration); -} - -void PrintNumber(size_t num) { - if (num > 999999999999999999) printf("%3lue", num/1000000000000000000); - else if (num > 999999999999999) printf("%3lup", num/1000000000000000); - else if (num > 999999999999) printf("%3lut", num/1000000000000); - else if (num > 999999999) printf("%3lug", num/1000000000); - else if (num > 999999) printf("%3lum", num/1000000); - else if (num > 9999) printf("%3luk", num/1000); - else printf("%4lu", num); -} - -void PrintSize(size_t num) { - if (num >= 112589990684263) printf("%4.1lf PB", 1.*num/1125899906842624); - else if (num >= 109951162778) printf("%4.1lf TB", 1.*num/1099511627776); - else if (num >= 107374183) printf("%4.1lf GB", 1.*num/1073741824); - else if (num >= 1048576) printf("%4lu MB", num/1048576); - else if (num >= 1024) printf("%4lu KB", num/1024); - else printf("%5lu B", num); -} - -void PrintPercent(size_t num, size_t total) { - if (num >= total) printf(" 100"); - else printf("%4.1lf", 100.*num/total); - -} - -char *GetPrintSize(char *str, size_t size) { - if (size >= 1073741824) sprintf(str, "%.1lf GB", 1.*size / 1073741824); - else if (size >= 1048576) sprintf(str, "%.1lf MB", 1.*size / 1048576); - else if (size >= 1024) sprintf(str, "%lu KB", size / 1024); - else sprintf(str, "%lu B ", size); - - return str; -} diff --git a/pcitool/formaters.h b/pcitool/formaters.h deleted file mode 100644 index c854da5..0000000 --- a/pcitool/formaters.h +++ /dev/null @@ -1,12 +0,0 @@ -#ifndef _PCITOOL_FORMATERS_H -#define _PCITOOL_FORMATERS_H - -void PrintTime(size_t duration); -void PrintNumber(size_t num); -void PrintSize(size_t num); -void PrintPercent(size_t num, size_t total); -char *GetPrintSize(char *str, size_t size); - - -#endif /* _PCITOOL_FORMATERS_H */ - diff --git a/pcitool/sysinfo.c b/pcitool/sysinfo.c deleted file mode 100644 index d6f57fe..0000000 --- a/pcitool/sysinfo.c +++ /dev/null @@ -1,172 +0,0 @@ -#include <stdio.h> -#include <stdlib.h> -#include <sys/types.h> -#include <sys/stat.h> -#include <fcntl.h> -#include <unistd.h> -#include <string.h> -#include <strings.h> - -#define MEMINFO_FILE "/proc/meminfo" -#define MTAB_FILE "/etc/mtab" - -#define BAD_OPEN_MESSAGE \ -"Error: /proc must be mounted\n" \ -" To mount /proc at boot you need an /etc/fstab line like:\n" \ -" /proc /proc proc defaults\n" \ -" In the meantime, run \"mount /proc /proc -t proc\"\n" - -/* This macro opens filename only if necessary and seeks to 0 so - * that successive calls to the functions are more efficient. - * It also reads the current contents of the file into the global buf. - */ -#define FILE_TO_BUF(filename) do{ \ - static int fd, local_n; \ - if ((fd = open(filename, O_RDONLY)) == -1) { \ - fputs(BAD_OPEN_MESSAGE, stderr); \ - fflush(NULL); \ - _exit(102); \ - } \ - lseek(fd, 0L, SEEK_SET); \ - if ((local_n = read(fd, buf, sizeof buf - 1)) < 0) { \ - perror(filename); \ - fflush(NULL); \ - _exit(103); \ - } \ - buf[local_n] = '\0'; \ - close(fd); \ -}while(0) - - -typedef struct mem_table_struct { - const char *name; /* memory type name */ - unsigned long *slot; /* slot in return struct */ -} mem_table_struct; - -static int compare_mem_table_structs(const void *a, const void *b){ - return strcmp(((const mem_table_struct*)a)->name,((const mem_table_struct*)b)->name); -} - -size_t get_free_memory(void){ - char buf[4096]; - unsigned long kb_main_buffers, kb_main_cached, kb_main_free; - char namebuf[16]; /* big enough to hold any row name */ - mem_table_struct findme = { namebuf, NULL}; - mem_table_struct *found; - char *head; - char *tail; - - const mem_table_struct mem_table[] = { - {"Buffers", &kb_main_buffers}, // important - {"Cached", &kb_main_cached}, // important - {"MemFree", &kb_main_free}, // important - }; - const int mem_table_count = sizeof(mem_table)/sizeof(mem_table_struct); - - FILE_TO_BUF(MEMINFO_FILE); - - head = buf; - for(;;){ - tail = strchr(head, ':'); - if(!tail) break; - *tail = '\0'; - if(strlen(head) >= sizeof(namebuf)){ - head = tail+1; - goto nextline; - } - strcpy(namebuf,head); - found = bsearch(&findme, mem_table, mem_table_count, - sizeof(mem_table_struct), compare_mem_table_structs - ); - head = tail+1; - if(!found) goto nextline; - *(found->slot) = strtoul(head,&tail,10); -nextline: - tail = strchr(head, '\n'); - if(!tail) break; - head = tail+1; - } - - return (kb_main_buffers + kb_main_cached + kb_main_free) * 1024; -} - - -int get_file_fs(const char *fname, size_t size, char *fs) { - int err = 0; - char buf[4096]; - char *fn; - - char *head; - char *tail; - - size_t len, max = 0; - struct stat st; - - if ((!fname)||(!fs)||(size < 3)) return -1; - - if (*fname == '/') { - fn = (char*)fname; - } else { - if (!getcwd(buf, 4095)) return -1; - fn = malloc(strlen(fname) + strlen(buf) + 2); - if (!fn) return -1; - sprintf(fn, "%s/%s", buf, fname); - } - - if (!stat(fn, &st)) { - if (S_ISBLK(st.st_mode)) { - strcpy(fs, "raw"); - goto clean; - } - } - - FILE_TO_BUF(MTAB_FILE); - - head = buf; - for(;;){ - head = strchr(head, ' '); - if(!head) break; - - head += 1; - tail = strchr(head, ' '); - if(!tail) break; - - *tail = '\0'; - - len = strlen(head); - if((len <= max)||(strncmp(head, fn, len))) { - head = tail+1; - goto nextline; - } - - head = tail + 1; - tail = strchr(head, ' '); - if(!tail) break; - - *tail = '\0'; - - if (!strncasecmp(head,"root",4)) { - head = tail+1; - goto nextline; - } - - max = len; - - if (strlen(head) >= size) err = -1; - else { - err = 0; - strcpy(fs, head); - } - - head = tail+1; -nextline: - tail = strchr(head, '\n'); - if(!tail) break; - head = tail+1; - } - -clean: - if (fn != fname) free(fn); - - return err; -} diff --git a/pcitool/sysinfo.h b/pcitool/sysinfo.h deleted file mode 100644 index d5636a7..0000000 --- a/pcitool/sysinfo.h +++ /dev/null @@ -1,7 +0,0 @@ -#ifndef _PCITOOL_SYSINFO_H -#define _PCITOOL_SYSINFO_H - -size_t get_free_memory(); -int get_file_fs(const char *fname, size_t size, char *fs); - -#endif /* _PCITOOL_SYSINFO_H */ diff --git a/ipecamera/private.h b/private.h index cf2d689..a0611f3 100644 --- a/ipecamera/private.h +++ b/private.h @@ -1,9 +1,11 @@ #ifndef _IPECAMERA_PRIVATE_H #define _IPECAMERA_PRIVATE_H +#include <pthread.h> +#include <pcilib/model.h> #include "ipecamera.h" -#define IPECAMERA_BUG_EXTRA_DATA +//#define IPECAMERA_BUG_EXTRA_DATA #define IPECAMERA_BUG_MULTIFRAME_PACKETS //**< this is by design, start of packet comes directly after the end of last one in streaming mode */ //#define IPECAMERA_BUG_INCOMPLETE_PACKETS #define IPECAMERA_BUG_POSTPONED_READ @@ -12,6 +14,9 @@ //#define IPECAMERA_ANNOUNCE_READY //**< announce new event only after the reconstruction is done */ +#define IPECAMERA_REGISTER_TIMEOUT 10000 //**< us */ +#define IPECAMERA_DMA_TIMEOUT 50000 //**< us */ + #define IPECAMERA_DEFAULT_BUFFER_SIZE 64 //**< should be power of 2 */ #define IPECAMERA_RESERVE_BUFFERS 2 //**< Return Frame is Lost error, if requested frame will be overwritten after specified number of frames #define IPECAMERA_SLEEP_TIME 250000 //**< Michele thinks 250 should be enough, but reset failing in this case */ @@ -114,18 +119,17 @@ struct ipecamera_s { size_t buffer_size; /**< How many images to store */ size_t buffer_pos; /**< Current image offset in the buffer, due to synchronization reasons should not be used outside of reader_thread */ size_t cur_size; /**< Already written part of data in bytes */ - size_t raw_size; /**< Size of raw data in bytes */ - size_t full_size; /**< Size of raw data including the padding */ - size_t padded_size; /**< Size of buffer for raw data, including the padding for performance */ - size_t cur_raw_size; /**< Size of raw data in bytes */ - size_t cur_full_size; /**< Size of raw data including the padding */ - size_t cur_padded_size; /**< Size of buffer for raw data, including the padding for performance */ + size_t raw_size; /**< Expected maximum size of raw data in bytes */ + size_t full_size; /**< Expected maximum size of raw data including the padding */ + size_t padded_size; /**< Expected maximum size of buffer for raw data, including additional padding due to the ipecamera bugs */ + size_t cur_raw_size; /**< Expected size (for currently configured ROI) of raw data in bytes */ + size_t cur_full_size; /**< Expected size (for currently configured ROI) of raw data including the padding */ + size_t cur_padded_size; /**< Expected size (for currently configured ROI) of buffer for raw data, including additional padding due to the ipecamera bugs */ size_t image_size; /**< Size of a single image in bytes */ size_t max_frames; /**< Maximal number of frames what may be buffered in camera DDR memory */ int firmware; /**< Firmware version */ - int fr_mode; /**< Fast Reject mode */ int cmosis_outputs; /**< Number of active cmosis outputs: 4 or 16 */ int width, height; diff --git a/ipecamera/reader.c b/reader.c index cad5da8..db700cd 100644 --- a/ipecamera/reader.c +++ b/reader.c @@ -13,10 +13,10 @@ #include <ufodecode.h> -#include "../tools.h" -#include "../error.h" +#include <pcilib.h> +#include <pcilib/tools.h> +#include <pcilib/error.h> -#include "pcilib.h" #include "model.h" #include "private.h" #include "reader.h" @@ -75,7 +75,7 @@ static inline int ipecamera_new_frame(ipecamera_t *ctx) { return 1; } - if (pcilib_check_deadline(&ctx->autostop.timestamp, PCILIB_DMA_TIMEOUT)) { + if (pcilib_check_deadline(&ctx->autostop.timestamp, 0)) { ctx->run_reader = 0; return 1; } @@ -119,18 +119,18 @@ static int ipecamera_data_callback(void *user, pcilib_dma_flags_t flags, size_t if (!ctx->cur_size) { #if defined(IPECAMERA_BUG_INCOMPLETE_PACKETS)||defined(IPECAMERA_BUG_MULTIFRAME_PACKETS) size_t startpos; - for (startpos = 0; (startpos + sizeof(frame_magic)) < bufsize; startpos += sizeof(uint32_t)) { + for (startpos = 0; (startpos + sizeof(frame_magic)) <= bufsize; startpos += sizeof(uint32_t)) { if (!memcmp(buf + startpos, frame_magic, sizeof(frame_magic))) break; } - if ((startpos + sizeof(frame_magic)) >= bufsize) { + if ((startpos + sizeof(frame_magic)) > bufsize) { #ifdef IPECAMERA_DEBUG_RAW_PACKETS FILE *f = fopen(fname, "w"); if (f) fclose(f); #endif /* IPECAMERA_DEBUG_RAW_PACKETS */ if (invalid_frame_id != ctx->event_id) { -// pcilib_warning("No frame magic in DMA packet of %u bytes, current event %lu (got %lu)", bufsize, ctx->event_id, invalid_frame_id); +// pcilib_warning("No frame magic in DMA packet of %u bytes, current event %lu", bufsize, ctx->event_id); invalid_frame_id = ctx->event_id; } @@ -159,9 +159,6 @@ static int ipecamera_data_callback(void *user, pcilib_dma_flags_t flags, size_t ctx->frame[ctx->buffer_pos].event.info.seqnum = ((uint32_t*)buf)[6] & 0x1FFFFFF; ctx->frame[ctx->buffer_pos].event.info.offset = (((uint32_t*)buf)[7] & 0xFFFFFF) * 80; - -// ctx->frame[ctx->buffer_pos].event.info.seqnum = ctx->event_id + 1; - gettimeofday(&ctx->frame[ctx->buffer_pos].event.info.timestamp, NULL); } else { // pcilib_warning("Frame magic is not found, ignoring broken data..."); @@ -186,8 +183,6 @@ static int ipecamera_data_callback(void *user, pcilib_dma_flags_t flags, size_t eof = 1; } -// printf("%lu %lu %lu - %u\n", ctx->event_id, ctx->cur_size, ctx->cur_raw_size, eof); - // just rip of padding bufsize = ctx->cur_raw_size - ctx->cur_size; @@ -208,13 +203,14 @@ static int ipecamera_data_callback(void *user, pcilib_dma_flags_t flags, size_t return -PCILIB_ERROR_TOOBIG; } - memcpy(ctx->buffer + ctx->buffer_pos * ctx->padded_size + ctx->cur_size, buf, bufsize); + if (bufsize) + memcpy(ctx->buffer + ctx->buffer_pos * ctx->padded_size + ctx->cur_size, buf, bufsize); } ctx->cur_size += bufsize; // printf("%i: %i %i\n", ctx->buffer_pos, ctx->cur_size, bufsize); - if (ctx->cur_size >= ctx->full_size) { + if (ctx->cur_size >= ctx->cur_raw_size) { eof = 1; } @@ -246,14 +242,14 @@ void *ipecamera_reader_thread(void *user) { ipecamera_t *ctx = (ipecamera_t*)user; while (ctx->run_reader) { - err = pcilib_stream_dma(ctx->event.pcilib, ctx->rdma, 0, 0, PCILIB_DMA_FLAG_MULTIPACKET, 10 * PCILIB_DMA_TIMEOUT, &ipecamera_data_callback, user); + err = pcilib_stream_dma(ctx->event.pcilib, ctx->rdma, 0, 0, PCILIB_DMA_FLAG_MULTIPACKET, IPECAMERA_DMA_TIMEOUT, &ipecamera_data_callback, user); if (err) { if (err == PCILIB_ERROR_TIMEOUT) { if (ctx->cur_size >= ctx->cur_raw_size) ipecamera_new_frame(ctx); #ifdef IPECAMERA_BUG_INCOMPLETE_PACKETS else if (ctx->cur_size > 0) ipecamera_new_frame(ctx); #endif /* IPECAMERA_BUG_INCOMPLETE_PACKETS */ - if (pcilib_check_deadline(&ctx->autostop.timestamp, 10 * PCILIB_DMA_TIMEOUT)) { + if (pcilib_check_deadline(&ctx->autostop.timestamp, 0)) { ctx->run_reader = 0; break; } diff --git a/ipecamera/reader.h b/reader.h index 5d631c0..5d631c0 100644 --- a/ipecamera/reader.h +++ b/reader.h diff --git a/register.c b/register.c deleted file mode 100644 index 7fc689b..0000000 --- a/register.c +++ /dev/null @@ -1,362 +0,0 @@ -#include <stdio.h> -#include <string.h> -#include <strings.h> -#include <stdlib.h> -#include <stdint.h> -#include <stdarg.h> -#include <fcntl.h> -#include <unistd.h> -#include <sys/ioctl.h> -#include <sys/mman.h> -#include <arpa/inet.h> -#include <errno.h> -#include <assert.h> - -#include "pci.h" - -#include "tools.h" -#include "error.h" - -int pcilib_add_registers(pcilib_t *ctx, size_t n, pcilib_register_description_t *registers) { - pcilib_register_description_t *regs; - size_t size, n_present = 0; - - if (!n) { - for (n = 0; registers[n].bits; n++); - } - - if (ctx->model_info.registers == pcilib_model[ctx->model].registers) { - for (n_present = 0; ctx->model_info.registers[n_present].bits; n_present++); - for (size = 1024; size < 2 * (n + n_present + 1); size<<=1); - regs = (pcilib_register_description_t*)malloc(size * sizeof(pcilib_register_description_t)); - if (!regs) return PCILIB_ERROR_MEMORY; - - ctx->model_info.registers = regs; - ctx->num_reg = n + n_present; - ctx->alloc_reg = size; - - memcpy(ctx->model_info.registers, pcilib_model[ctx->model].registers, (n_present + 1) * sizeof(pcilib_register_description_t)); - } else { - n_present = ctx->num_reg; - if ((n_present + n + 1) > ctx->alloc_reg) { - for (size = ctx->alloc_reg; size < 2 * (n + n_present + 1); size<<=1); - - regs = (pcilib_register_description_t*)realloc(ctx->model_info.registers, size * sizeof(pcilib_register_description_t)); - if (!regs) return PCILIB_ERROR_MEMORY; - - ctx->model_info.registers = regs; - ctx->alloc_reg = size; - } - ctx->num_reg += n; - } - - memcpy(ctx->model_info.registers + ctx->num_reg, ctx->model_info.registers + n_present, sizeof(pcilib_register_description_t)); - memcpy(ctx->model_info.registers + n_present, registers, n * sizeof(pcilib_register_description_t)); - - return 0; -} - -pcilib_register_bank_t pcilib_find_bank_by_addr(pcilib_t *ctx, pcilib_register_bank_addr_t bank) { - pcilib_register_bank_t i; - pcilib_model_description_t *model_info = pcilib_get_model_description(ctx); - pcilib_register_bank_description_t *banks = model_info->banks; - - for (i = 0; banks[i].access; i++) - if (banks[i].addr == bank) return i; - - return -1; -} - -pcilib_register_bank_t pcilib_find_bank_by_name(pcilib_t *ctx, const char *bankname) { - pcilib_register_bank_t i; - pcilib_model_description_t *model_info = pcilib_get_model_description(ctx); - pcilib_register_bank_description_t *banks = model_info->banks; - - for (i = 0; banks[i].access; i++) - if (!strcasecmp(banks[i].name, bankname)) return i; - - return -1; -} - -pcilib_register_bank_t pcilib_find_bank(pcilib_t *ctx, const char *bank) { - pcilib_register_bank_t res; - unsigned long addr; - - if (!bank) { - pcilib_model_description_t *model_info = pcilib_get_model_description(ctx); - pcilib_register_bank_description_t *banks = model_info->banks; - if ((banks)&&(banks[0].access)) return (pcilib_register_bank_t)0; - return -1; - } - - if (pcilib_isxnumber(bank)&&(sscanf(bank,"%lx", &addr) == 1)) { - res = pcilib_find_bank_by_addr(ctx, addr); - if (res != PCILIB_REGISTER_BANK_INVALID) return res; - } - - return pcilib_find_bank_by_name(ctx, bank); -} - - // FIXME create hash during map_register space -pcilib_register_t pcilib_find_register(pcilib_t *ctx, const char *bank, const char *reg) { - pcilib_register_t i; - pcilib_register_bank_t bank_id; - pcilib_register_bank_addr_t bank_addr = 0; - - pcilib_model_description_t *model_info = pcilib_get_model_description(ctx); - pcilib_register_description_t *registers = model_info->registers; - - if (bank) { - bank_id = pcilib_find_bank(ctx, bank); - if (bank_id == PCILIB_REGISTER_BANK_INVALID) { - pcilib_error("Invalid bank (%s) is specified", bank); - return -1; - } - - bank_addr = model_info->banks[bank_id].addr; - } - - for (i = 0; registers[i].bits; i++) { - if ((!strcasecmp(registers[i].name, reg))&&((!bank)||(registers[i].bank == bank_addr))) return i; - } - - if ((ctx->model_info.dma_api)&&(!ctx->dma_ctx)&&(pcilib_get_dma_info(ctx))) { - registers = model_info->registers; - - for (; registers[i].bits; i++) { - if ((!strcasecmp(registers[i].name, reg))&&((!bank)||(registers[i].bank == bank_addr))) return i; - } - } - - return (pcilib_register_t)-1; -}; - -static int pcilib_read_register_space_internal(pcilib_t *ctx, pcilib_register_bank_t bank, pcilib_register_addr_t addr, size_t n, pcilib_register_size_t offset, pcilib_register_size_t bits, pcilib_register_value_t *buf) { - int err; - size_t i; - - pcilib_model_description_t *model_info = pcilib_get_model_description(ctx); - pcilib_register_bank_description_t *b = model_info->banks + bank; - - int access = b->access / 8; - - assert(bits < 8 * sizeof(pcilib_register_value_t)); - - if (((addr + n) > b->size)||(((addr + n) == b->size)&&(bits))) { - if ((b->format)&&(strchr(b->format, 'x'))) - pcilib_error("Accessing register (%u regs at addr 0x%x) out of register space (%u registers total)", bits?(n+1):n, addr, b->size); - else - pcilib_error("Accessing register (%u regs at addr %u) out of register space (%u registers total)", bits?(n+1):n, addr, b->size); - return PCILIB_ERROR_OUTOFRANGE; - } - - err = pcilib_map_register_space(ctx); - if (err) { - pcilib_error("Failed to map the register space"); - return err; - } - - //n += bits / b->access; - //bits %= b->access; - - for (i = 0; i < n; i++) { - err = pcilib_protocol[b->protocol].read(ctx, b, addr + i * access, buf + i); - if (err) break; - } - - if ((bits > 0)&&(!err)) { - pcilib_register_value_t val = 0; - err = pcilib_protocol[b->protocol].read(ctx, b, addr + n * access, &val); - - val = (val >> offset)&BIT_MASK(bits); - memcpy(buf + n, &val, sizeof(pcilib_register_value_t)); - } - - return err; -} - -int pcilib_read_register_space(pcilib_t *ctx, const char *bank, pcilib_register_addr_t addr, size_t n, pcilib_register_value_t *buf) { - pcilib_register_bank_t bank_id = pcilib_find_bank(ctx, bank); - if (bank_id == PCILIB_REGISTER_BANK_INVALID) { - if (bank) pcilib_error("Invalid register bank is specified (%s)", bank); - else pcilib_error("Register bank should be specified"); - return PCILIB_ERROR_INVALID_BANK; - } - - return pcilib_read_register_space_internal(ctx, bank_id, addr, n, 0, 0, buf); -} - -int pcilib_read_register_by_id(pcilib_t *ctx, pcilib_register_t reg, pcilib_register_value_t *value) { - int err; - size_t i, n; - pcilib_register_size_t bits; - pcilib_register_value_t res; - pcilib_register_bank_t bank; - pcilib_register_description_t *r; - pcilib_register_bank_description_t *b; - pcilib_model_description_t *model_info = pcilib_get_model_description(ctx); - - r = model_info->registers + reg; - - bank = pcilib_find_bank_by_addr(ctx, r->bank); - if (bank == PCILIB_REGISTER_BANK_INVALID) return PCILIB_ERROR_INVALID_BANK; - - b = model_info->banks + bank; - - n = r->bits / b->access; - bits = r->bits % b->access; - - pcilib_register_value_t buf[n + 1]; - err = pcilib_read_register_space_internal(ctx, bank, r->addr, n, r->offset, bits, buf); - - if ((b->endianess == PCILIB_BIG_ENDIAN)||((b->endianess == PCILIB_HOST_ENDIAN)&&(ntohs(1) == 1))) { - pcilib_error("Big-endian byte order support is not implemented"); - return PCILIB_ERROR_NOTSUPPORTED; - } else { - res = 0; - if (bits) ++n; - for (i = 0; i < n; i++) { - res |= buf[i] << (i * b->access); - } - } - - *value = res; - - return err; -} - - -int pcilib_read_register(pcilib_t *ctx, const char *bank, const char *regname, pcilib_register_value_t *value) { - int reg; - - reg = pcilib_find_register(ctx, bank, regname); - if (reg < 0) { - pcilib_error("Register (%s) is not found", regname); - return PCILIB_ERROR_NOTFOUND; - } - - return pcilib_read_register_by_id(ctx, reg, value); -} - - -static int pcilib_write_register_space_internal(pcilib_t *ctx, pcilib_register_bank_t bank, pcilib_register_addr_t addr, size_t n, pcilib_register_size_t offset, pcilib_register_size_t bits, pcilib_register_value_t rwmask, pcilib_register_value_t *buf) { - int err; - size_t i; - - pcilib_model_description_t *model_info = pcilib_get_model_description(ctx); - pcilib_register_bank_description_t *b = model_info->banks + bank; - - int access = b->access / 8; - - assert(bits < 8 * sizeof(pcilib_register_value_t)); - - if (((addr + n) > b->size)||(((addr + n) == b->size)&&(bits))) { - if ((b->format)&&(strchr(b->format, 'x'))) - pcilib_error("Accessing register (%u regs at addr 0x%x) out of register space (%u registers total)", bits?(n+1):n, addr, b->size); - else - pcilib_error("Accessing register (%u regs at addr %u) out of register space (%u registers total)", bits?(n+1):n, addr, b->size); - return PCILIB_ERROR_OUTOFRANGE; - } - - err = pcilib_map_register_space(ctx); - if (err) { - pcilib_error("Failed to map the register space"); - return err; - } - - //n += bits / b->access; - //bits %= b->access; - - for (i = 0; i < n; i++) { - err = pcilib_protocol[b->protocol].write(ctx, b, addr + i * access, buf[i]); - if (err) break; - } - - if ((bits > 0)&&(!err)) { - pcilib_register_value_t val = (buf[n]&BIT_MASK(bits))<<offset; - pcilib_register_value_t mask = BIT_MASK(bits)<<offset; - - if (~mask&rwmask) { - pcilib_register_value_t rval; - - err = pcilib_protocol[b->protocol].read(ctx, b, addr + n * access, &rval); - if (err) return err; - - val |= (rval & rwmask & ~mask); - } - - err = pcilib_protocol[b->protocol].write(ctx, b, addr + n * access, val); - } - - return err; -} - -int pcilib_write_register_space(pcilib_t *ctx, const char *bank, pcilib_register_addr_t addr, size_t n, pcilib_register_value_t *buf) { - pcilib_register_bank_t bank_id = pcilib_find_bank(ctx, bank); - if (bank_id == PCILIB_REGISTER_BANK_INVALID) { - if (bank) pcilib_error("Invalid register bank is specified (%s)", bank); - else pcilib_error("Register bank should be specified"); - return PCILIB_ERROR_INVALID_BANK; - } - - return pcilib_write_register_space_internal(ctx, bank_id, addr, n, 0, 0, 0, buf); -} - - -int pcilib_write_register_by_id(pcilib_t *ctx, pcilib_register_t reg, pcilib_register_value_t value) { - int err; - size_t i, n; - pcilib_register_size_t bits; - pcilib_register_bank_t bank; - pcilib_register_value_t res; - pcilib_register_description_t *r; - pcilib_register_bank_description_t *b; - pcilib_model_description_t *model_info = pcilib_get_model_description(ctx); - - r = model_info->registers + reg; - - bank = pcilib_find_bank_by_addr(ctx, r->bank); - if (bank == PCILIB_REGISTER_BANK_INVALID) return PCILIB_ERROR_INVALID_BANK; - - b = model_info->banks + bank; - - n = r->bits / b->access; - bits = r->bits % b->access; - - pcilib_register_value_t buf[n + 1]; - memset(buf, 0, (n + 1) * sizeof(pcilib_register_value_t)); - - if ((b->endianess == PCILIB_BIG_ENDIAN)||((b->endianess == PCILIB_HOST_ENDIAN)&&(ntohs(1) == 1))) { - pcilib_error("Big-endian byte order support is not implemented"); - return PCILIB_ERROR_NOTSUPPORTED; - } else { - if (b->access == sizeof(pcilib_register_value_t) * 8) { - buf[0] = value; - } else { - for (i = 0, res = value; (res > 0)&&(i <= n); ++i) { - buf[i] = res & BIT_MASK(b->access); - res >>= b->access; - } - - if (res) { - pcilib_error("Value %i is too big to fit in the register %s", value, r->name); - return PCILIB_ERROR_OUTOFRANGE; - } - } - } - - err = pcilib_write_register_space_internal(ctx, bank, r->addr, n, r->offset, bits, r->rwmask, buf); - return err; -} - -int pcilib_write_register(pcilib_t *ctx, const char *bank, const char *regname, pcilib_register_value_t value) { - int reg; - - reg = pcilib_find_register(ctx, bank, regname); - if (reg < 0) { - pcilib_error("Register (%s) is not found", regname); - return PCILIB_ERROR_NOTFOUND; - } - - return pcilib_write_register_by_id(ctx, reg, value); -} diff --git a/register.h b/register.h deleted file mode 100644 index b81ae12..0000000 --- a/register.h +++ /dev/null @@ -1,14 +0,0 @@ -#ifndef _PCILIB_REGISTER_H -#define _PCILIB_REGISTER_H - -#include "pcilib.h" - -struct pcilib_protocol_description_s { - int (*read)(pcilib_t *ctx, pcilib_register_bank_description_t *bank, pcilib_register_addr_t addr, pcilib_register_value_t *value); - int (*write)(pcilib_t *ctx, pcilib_register_bank_description_t *bank, pcilib_register_addr_t addr, pcilib_register_value_t value); -}; - - // we don't copy strings, they should be statically allocated -int pcilib_add_registers(pcilib_t *ctx, size_t n, pcilib_register_description_t *registers); - -#endif /* _PCILIB_REGISTER_H */ diff --git a/tests/ipecamera/autotrigger.sh b/tests/autotrigger.sh index 5f8b4db..b7318c8 100755 --- a/tests/ipecamera/autotrigger.sh +++ b/tests/autotrigger.sh @@ -1,8 +1,9 @@ #! /bin/bash function pci { - PCILIB_PATH="../../" - LD_LIBRARY_PATH="$PCILIB_PATH" $PCILIB_PATH/pci $* + PCILIB_PATH=`which pci` + #LD_LIBRARY_PATH="$PCILIB_PATH" + $PCILIB_PATH/pci $* } echo "Starting the grabber" diff --git a/tests/ipecamera/debug/incomplete.sh b/tests/debug/incomplete.sh index 5c80198..090e638 100755 --- a/tests/ipecamera/debug/incomplete.sh +++ b/tests/debug/incomplete.sh @@ -1,8 +1,9 @@ #! /bin/bash function pci { - PCILIB_PATH="/root/pcitool" - LD_LIBRARY_PATH="$PCILIB_PATH" $PCILIB_PATH/pci $* + PCILIB_PATH=`which pci` + #LD_LIBRARY_PATH="$PCILIB_PATH" + $PCILIB_PATH/pci $* } rm -f images.raw diff --git a/tests/dma/debug/test-iommu.sh b/tests/dma/debug/test-iommu.sh deleted file mode 100755 index 74e3ece..0000000 --- a/tests/dma/debug/test-iommu.sh +++ /dev/null @@ -1,19 +0,0 @@ -#! /bin/bash - -i=1 -while [ 1 ]; do - pci --start-dma dma1r - for name in /sys/class/fpga/fpga0/kbuf*; do - bus_addr=0x`cat $name | grep "bus addr" | cut -d ':' -f 2 | sed -e 's/\s\+//g'` - if [ $((bus_addr % 4096)) -ne 0 ]; then - - echo "Failed at iteration $i, $name" - echo "----------------------" - cat $name - exit - fi - - done - pci --stop-dma dma1r - i=$((i + 1)) -done diff --git a/tests/dma/ipe/bench.sh b/tests/dma/ipe/bench.sh deleted file mode 100755 index aa7ec25..0000000 --- a/tests/dma/ipe/bench.sh +++ /dev/null @@ -1,40 +0,0 @@ -#!/bin/bash - -size=65536 - -function pci { - PCILIB_PATH=`pwd`/../../.. - LD_LIBRARY_PATH="$PCILIB_PATH" $PCILIB_PATH/pci -m kapture $* -} - - -rm -f bench.out - -echo "Stopping DMA and skipping exiting data..." -pci --stop-dma dma0r -echo "Starting DMA..." -pci --start-dma dma0r -echo "Enabling data generation..." -pci -w 0x4 0x1 - -# Clean DMA buffers -#while [ $? -eq 0 ]; do -# pci -r dma0 -s 65536 &> /dev/null -#done - -echo "Reading the data from DMA..." -for i in `seq 1 100`; do - pci -r dma0 --multipacket -s $size -o bench.out - if [ $? -ne 0 ]; then - echo "Stopping DMA due to the error..." - pci --stop-dma dma0r - exit - fi -done - -echo "Stopping DMA..." -pci --stop-dma dma0r - -../../../apps/check_counter bench.out - -#pci -r 0 -s 32 diff --git a/tests/dma/nwl/bench.sh b/tests/dma/nwl/bench.sh deleted file mode 100755 index b36c251..0000000 --- a/tests/dma/nwl/bench.sh +++ /dev/null @@ -1,30 +0,0 @@ -#!/bin/bash - -function pci { - PCILIB_PATH="/root/pcitool" - LD_LIBRARY_PATH="$PCILIB_PATH" $PCILIB_PATH/pci $* -} - -size=16 -bytes=`expr $size "*" 4` - -pci -w xrawdata_packet_length $bytes -pci -w xrawdata_enable_loopback 0 -pci -w xrawdata_enable_generator 0 - -pci --start-dma dma1 - -while [ $? -eq 0 ]; do - pci -r dma1 -s 65536 &> /dev/null -done - -pci -w xrawdata_enable_loopback 1 - -for i in `seq 1 10`; do - pci -w dma1 -s $size "*$i" - pci -r dma1 -s $size -o bench.out -done - -pci --stop-dma dma1 - -pci -w xrawdata_enable_loopback 0 diff --git a/tests/dma/nwl/cleanup.sh b/tests/dma/nwl/cleanup.sh deleted file mode 100755 index 5ef568e..0000000 --- a/tests/dma/nwl/cleanup.sh +++ /dev/null @@ -1,13 +0,0 @@ -#!/bin/bash - -function pci { - PCILIB_PATH="/root/pcitool" - LD_LIBRARY_PATH="$PCILIB_PATH" $PCILIB_PATH/pci $* -} - -pci --start-dma dma1r -pci -w dma1r_reset_request 1 -pci -w dma1r_reset 1 -pci -r dma1r_running - -pci --free-kernel-memory dma diff --git a/tests/dma/xilinx/xilinx_dma.sh b/tests/dma/xilinx/xilinx_dma.sh deleted file mode 100755 index 6aada8b..0000000 --- a/tests/dma/xilinx/xilinx_dma.sh +++ /dev/null @@ -1,121 +0,0 @@ -#! /bin/bash - -BAR=0 -USE=1 -ITERATIONS=2 -BUFFERS=16 - -function pci { - PCILIB_PATH=`pwd`/.. - LD_LIBRARY_PATH="$PCILIB_PATH" $PCILIB_PATH/pci $* -} - - -function reset { - pci -b $BAR -w 0 1 - usleep 1000 - pci -b $BAR -w 0 0 - pci -b $BAR -w 4 0 -} - -function read_cfg { -# echo $1 1>&2 - pci -a config -r 0x$1 | awk '{ print $2; }' -} - -function parse_config { - info=0x`pci -b $BAR -r 0 | awk '{ print $2; }'` - model=`printf "%X" $((info>>24))` - if [ $model -eq 14 ]; then - model="Xilinx Virtex-6" - else - model="Xilinx $model" - fi - version=$(((info >> 8) & 0xFF)) - data_width=$((16 * (2 ** ((info >> 16) & 0xF)))) - - echo "$model, build $version, $data_width bits" - - - next=`read_cfg 34 | cut -c 7-8` - - while [ $next -ne 0 ]; do - cap=`read_cfg $next` - capid=`echo $cap | cut -c 7-8` - if [ $capid -eq 10 ]; then - addr=`printf "%X" $((0x$next + 12))` - pcie_link1=`read_cfg $addr` - addr=`printf "%X" $((0x$next + 16))` - pcie_link2=`read_cfg $addr` - - link_speed=$((((0x$pcie_link2 & 0xF0000) >> 16))) - link_width=$((((0x$pcie_link2 & 0x3F00000) >> 20))) - - dev_link_speed=$((((0x$pcie_link1 & 0xF)))) - dev_link_width=$((((0x$pcie_link1 & 0x3F0) >> 4))) - fi - next=`echo $cap | cut -c 5-6` - done - - echo "Link: PCIe gen$link_speed x$link_width" - if [ $link_speed -ne $dev_link_speed -o $link_width -ne $dev_link_width ]; then - echo " * But device capable of gen$dev_link_speed x$dev_link_width" - fi - - info=0x`read_cfg 40` - max_tlp=$((2 ** (5 + ((info & 0xE0) >> 5)))) - echo "TLP: 32 dwords (transfering 32 TLP per request)" - if [ $max_tlp -ne 32 ]; then - echo " * But device is able to transfer TLP up to $max_tlp bytes" - fi - - # 2500 MT/s, but PCIe gen1 and gen2 uses 10 bit encoding - speed=$((link_width * link_speed * 2500 / 10)) -} - -reset -parse_config - -pci --enable-irq -pci --acknowledge-irq - -pci --free-kernel-memory $USE -pci --alloc-kernel-memory $USE --type c2s -s $BUFFERS -bus=`pci --list-kernel-memory 00100001 | awk '{ print $4; }' | grep 00` -#ptr=`pci --list-kernel-memory 00100001 | awk '{ print $2; }' | grep 00` - -# TLP size -pci -b $BAR -w 0x0C 0x20 -# TLP count -pci -b $BAR -w 0x10 0x20 -# Data -pci -b $BAR -w 0x14 0x13131313 - -dmaperf=0 -for i in `seq 1 $ITERATIONS`; do - for addr in $bus; do - pci -b $BAR -w 0x08 0x$addr - -#Trigger - pci -b $BAR -w 0x04 0x01 - pci --wait-irq -# pci -b $BAR -w 0x04 0x00 - - status=`pci -b $BAR -r 0x04 | awk '{print $2; }' | cut -c 5-8` - if [ $status != "0101" ]; then - echo "Read failed, invalid status: $status" - fi - - dmaperf=$((dmaperf + 0x`pci -b $BAR -r 0x28 | awk '{print $2}'`)) - reset - done -done - -pci --free-kernel-memory $USE -pci --disable-irq - -echo -# Don't ask me about this formula -echo "Performance reported by FPGA: $((4096 * BUFFERS * ITERATIONS * $speed / $dmaperf / 8)) MB/s" - -#pci -b $BAR -r 0 -s 32 diff --git a/tests/dma/xilinx/xilinx_dma_static_mem.sh b/tests/dma/xilinx/xilinx_dma_static_mem.sh deleted file mode 100755 index e3ba0f5..0000000 --- a/tests/dma/xilinx/xilinx_dma_static_mem.sh +++ /dev/null @@ -1,117 +0,0 @@ -#! /bin/bash - -BAR=0 -USE=1 -ITERATIONS=1 -TLP_SIZE=32 -BUFFER_SIZE=8 - -function pci { - PCILIB_PATH=`pwd`/.. - LD_LIBRARY_PATH="$PCILIB_PATH" $PCILIB_PATH/pci $* -} - - -function reset { - pci -b $BAR -w 0 1 - usleep 1000 - pci -b $BAR -w 0 0 - pci -b $BAR -w 4 0 -} - -function read_cfg { -# echo $1 1>&2 - pci -a config -r 0x$1 | awk '{ print $2; }' -} - -function parse_config { - info=0x`pci -b $BAR -r 0 | awk '{ print $2; }'` - model=`printf "%X" $((info>>24))` - if [ $model -eq 14 ]; then - model="Xilinx Virtex-6" - else - model="Xilinx $model" - fi - version=$(((info >> 8) & 0xFF)) - data_width=$((16 * (2 ** ((info >> 16) & 0xF)))) - - echo "$model, build $version, $data_width bits" - - - next=`read_cfg 34 | cut -c 7-8` - - while [ $next -ne 0 ]; do - cap=`read_cfg $next` - capid=`echo $cap | cut -c 7-8` - if [ $capid -eq 10 ]; then - addr=`printf "%X" $((0x$next + 12))` - pcie_link1=`read_cfg $addr` - addr=`printf "%X" $((0x$next + 16))` - pcie_link2=`read_cfg $addr` - - link_speed=$((((0x$pcie_link2 & 0xF0000) >> 16))) - link_width=$((((0x$pcie_link2 & 0x3F00000) >> 20))) - - dev_link_speed=$((((0x$pcie_link1 & 0xF)))) - dev_link_width=$((((0x$pcie_link1 & 0x3F0) >> 4))) - fi - next=`echo $cap | cut -c 5-6` - done - - echo "Link: PCIe gen$link_speed x$link_width" - if [ $link_speed -ne $dev_link_speed -o $link_width -ne $dev_link_width ]; then - echo " * But device capable of gen$dev_link_speed x$dev_link_width" - fi - - info=0x`read_cfg 40` - max_tlp=$((2 ** (5 + ((info & 0xE0) >> 5)))) - echo "TLP: 32 dwords (transfering 32 TLP per request)" - if [ $max_tlp -ne $TLP_SIZE ]; then - echo " * But device is able to transfer TLP up to $max_tlp bytes" - fi - - # 2500 MT/s, but PCIe gen1 and gen2 uses 10 bit encoding - speed=$((link_width * link_speed * 2500 / 10)) -} - -reset -parse_config - -pci --enable-irq -pci --acknowledge-irq - -# TLP size -pci -b $BAR -w 0x0C 0x`echo "obase=16; $TLP_SIZE" | bc` -# TLP count -pci -b $BAR -w 0x10 0x`echo "obase=16; $BUFFER_SIZE * 1024 * 1024 / $TLP_SIZE / 4" | bc` -# Data -pci -b $BAR -w 0x14 0x13131313 - -bus="80000000" -dmaperf=0 -for i in `seq 1 $ITERATIONS`; do - for addr in $bus; do - pci -b $BAR -w 0x08 0x$addr - -#Trigger - pci -b $BAR -w 0x04 0x01 - pci --wait-irq - - status=`pci -b $BAR -r 0x04 | awk '{print $2; }' | cut -c 5-8` - if [ $status != "0101" ]; then - echo "Read failed, invalid status: $status" - fi - - dmaperf=$((dmaperf + 0x`pci -b $BAR -r 0x28 | awk '{print $2}'`)) - reset - done -done - -pci --free-kernel-memory $USE -pci --disable-irq - -echo -# Don't ask me about this formula -echo "Performance reported by FPGA: $(($BUFFER_SIZE * 1024 * 1024 * ITERATIONS * $speed / $dmaperf / 8)) MB/s" - -#pci -b $BAR -r 0 -s 32 diff --git a/tests/dump_file.sh b/tests/dump_file.sh deleted file mode 100755 index 6773a19..0000000 --- a/tests/dump_file.sh +++ /dev/null @@ -1,3 +0,0 @@ -#!/bin/bash - -hexdump -e ' "0x%08.8_ax: " 4/4 " 0x%08x " "\n" ' $1 | less diff --git a/tests/grab.sh b/tests/grab.sh deleted file mode 100755 index daf142e..0000000 --- a/tests/grab.sh +++ /dev/null @@ -1,24 +0,0 @@ -#! /bin/bash - -function pci { - PCILIB_PATH="/root/pcitool" - LD_LIBRARY_PATH="$PCILIB_PATH" $PCILIB_PATH/pci $* -} - -rm -f images.raw - - -echo "Starting the grabber" -pci -g -o images.raw --run-time 3000000 & -pid=$! - -usleep 1000000 - -for i in `seq 1 1000`; do - echo "Trigger $i" - pci --trigger - usleep 100000 -done - -echo "Waiting grabber to finish" -wait $pid diff --git a/tests/heb/DataTaking.sh b/tests/heb/DataTaking.sh deleted file mode 100755 index b6046d7..0000000 --- a/tests/heb/DataTaking.sh +++ /dev/null @@ -1,96 +0,0 @@ -#!/bin/bash - -#Channel 1 --> 05 -#Channel 2 --> 0B -#Channel 1&2 --> 0F -#Channel 3 --> 13 -#Channel 4 --> 23 -#Channel 3&4 --> 33 -#ALL --> 3F - -#rm *.out -pci -r dma1 --multipacket -o /dev/null - -echo "Start DMA ..... " -#pci --start-dma dma1 -sleep 0.2 - -echo "Data Reset ... " -pci -w 0x9040 000003f1 -sleep 0.1 -pci -w 0x9040 000003f0 - -sleep 0.1 -#echo "Pilot bunch emulator ..... " -#pci -w 0x9040 400003f0 -sleep 0.2 -pci -w 0x9040 03f0 -#pci -r 0x9000 -s 40 -#sleep 0.2 -echo "Start data pci. ..... " -pci -w 0x9040 00bf0 - -sleep 2 - -echo "Stop data acquis...... " -pci -w 0x9040 003f0 -pci -r 0x9000 -s 40 -sleep 0.1 -echo "Enable data transfer.... " -pci -w 0x9040 007f0 -exit -sleep 2 -pci -r dma1 -o run_num_$1.out --multipacket -sleep 2 - -pci -w 0x9040 003f0 -#echo "Status ... " - - - -pci -r 0x9000 -s 40 - - status=`pci -r 0x9050 -s 1 | awk '{print $2$3$4}'` - if [ "$status" != "85000021" ]; then - echo "--------------------------------->>>> ERROR! ... " - error=1 - exit - else - echo " Status 1 -> OK " - fi - - status=`pci -r 0x9000 -s 1 | awk '{print $2$3$4}'` - if [ "$status" != "01000021" ]; then - echo "--------------------------------->>>> ERROR! ... " - error=1 - exit - else - echo " Status 1 Readout -> OK " - fi - -status=`pci -r 0x9008 -s 1 | awk '{print $2$3$4}'` - if [ "$status" != "01000021" ]; then - echo "--------------------------------->>>> ERROR! ... " - error=1 - exit - else - echo " Status 2 Readout -> OK " - fi - -status=`pci -r 0x9010 -s 1 | awk '{print $2$3$4}'` - if [ "$status" != "01000021" ]; then - echo "--------------------------------->>>> ERROR! ... " - error=1 - exit - else - echo " Status 3 Readout -> OK " - fi - -status=`pci -r 0x9018 -s 1 | awk '{print $2$3$4}'` - if [ "$status" != "01000021" ]; then - echo "--------------------------------->>>> ERROR! ... " - error=1 - exit - else - echo " Status 4 Readout -> OK " - fi diff --git a/tests/heb/cfg/BoardOFF.sh b/tests/heb/cfg/BoardOFF.sh deleted file mode 100755 index 351bcb8..0000000 --- a/tests/heb/cfg/BoardOFF.sh +++ /dev/null @@ -1,11 +0,0 @@ -#!/bin/bash - - -echo " ************************************************************** " -echo " Board OFF" -echo " ************************************************************** " - -pci -w 0x9040 0x01 -sleep 0.5 - -pci --stop-dma dma1 diff --git a/tests/heb/cfg/BoardOn.sh b/tests/heb/cfg/BoardOn.sh deleted file mode 100755 index b14c73b..0000000 --- a/tests/heb/cfg/BoardOn.sh +++ /dev/null @@ -1,57 +0,0 @@ -#!/bin/bash - -echo " ************************************************************** " -echo " Start DMA" -echo " ************************************************************** " - -pci --start-dma dma1 -sleep 0.5 -pci --list-dma-engines - - -echo " ************************************************************** " -echo " Board ON procedure" -echo " ************************************************************** " - -pci -w 0x9040 0x01 -sleep 1 - -echo "switch ON the power supply --> FIRST <--" -echo "Press a key to continue ...." -read -n 1 -s - -echo "Switch ON T/Hs" -pci -w 0x9040 0x3C1 -pci -r 0x9040 -s1 - -echo "switch ON the power supply --> SECOND <--" -echo "Press a key to continue ...." -read -n 1 -s - -echo "Switch ON ADCs" -pci -w 0x9040 0x3F1 -pci -r 0x9040 -s1 -sleep 0.1 - - -pci -w 0x9040 0x3F0 -pci -r 0x9040 -s1 -sleep 1 - -echo " Status ................... " -pci -r 0x9000 -s 40 - - - -./PLL_conf_calib_3001.sh - -echo " Status ................... " -pci -r 0x9000 -s 40 - - -echo " ************************************************************** " -echo " Board Ready" -echo " ************************************************************** " - - -echo " --> remember to run: ./Set_Default.sh" diff --git a/tests/heb/cfg/README b/tests/heb/cfg/README deleted file mode 100644 index 125bc0d..0000000 --- a/tests/heb/cfg/README +++ /dev/null @@ -1,11 +0,0 @@ - - Initializing - ./BoardOn.sh - ./Set_Default.sh - - - Configuring the size - pci -w 9020 0x20 (linear scale) - - * Number of samples are determined by 0x9020 / 0x9028 (0x0e by default) - * For each sample is descibed by (184 / 2) * 128 bits - * Where most-significant bytes of 4 dwords (128 bit) are iterating - from 0x00 to 0xb8 with step 0x02 diff --git a/tests/heb/cfg/Set_ADC_1_Delay.sh b/tests/heb/cfg/Set_ADC_1_Delay.sh deleted file mode 100755 index bd8f980..0000000 --- a/tests/heb/cfg/Set_ADC_1_Delay.sh +++ /dev/null @@ -1,10 +0,0 @@ -#!/bin/bash - -echo "Set CH_4 clock ADC 1 delay... " - -upfix=000501 -fixed=4 - - hex_val=$(printf "%01x\n" $1) - echo "Set $hex_val --> Time value picosecond = `expr $1 "*" 150`." - pci -w 0x9060 $upfix$hex_val$fixed diff --git a/tests/heb/cfg/Set_ADC_2_Delay.sh b/tests/heb/cfg/Set_ADC_2_Delay.sh deleted file mode 100755 index d6cdf75..0000000 --- a/tests/heb/cfg/Set_ADC_2_Delay.sh +++ /dev/null @@ -1,10 +0,0 @@ -#!/bin/bash - -echo "Set CH_5 clock ADC 2 delay... " - -upfix=000501 -fixed=5 - - hex_val=$(printf "%01x\n" $1) - echo "Set $hex_val --> Time value picosecond = `expr $1 "*" 150`." - pci -w 0x9060 $upfix$hex_val$fixed diff --git a/tests/heb/cfg/Set_ADC_3_Delay.sh b/tests/heb/cfg/Set_ADC_3_Delay.sh deleted file mode 100755 index 567b977..0000000 --- a/tests/heb/cfg/Set_ADC_3_Delay.sh +++ /dev/null @@ -1,10 +0,0 @@ -#!/bin/bash - -echo "Set CH_6 clock ADC 3 delay... " - -upfix=000501 -fixed=6 - - hex_val=$(printf "%01x\n" $1) - echo "Set $hex_val --> Time value picosecond = `expr $1 "*" 150`." - pci -w 0x9060 $upfix$hex_val$fixed diff --git a/tests/heb/cfg/Set_ADC_4_Delay.sh b/tests/heb/cfg/Set_ADC_4_Delay.sh deleted file mode 100755 index d666595..0000000 --- a/tests/heb/cfg/Set_ADC_4_Delay.sh +++ /dev/null @@ -1,11 +0,0 @@ -#!/bin/bash - -echo "Set CH_7 clock ADC 4 delay... " - -upfix=000501 -fixed=7 - - hex_val=$(printf "%01x\n" $1) - echo "Set $hex_val --> Time value picosecond = `expr $1 "*" 150`." - pci -w 0x9060 $upfix$hex_val$fixed - diff --git a/tests/heb/cfg/Set_Default.sh b/tests/heb/cfg/Set_Default.sh deleted file mode 100755 index 0149bf0..0000000 --- a/tests/heb/cfg/Set_Default.sh +++ /dev/null @@ -1,30 +0,0 @@ -#!/bin/bash - -echo "Set Defaults delay value in the board... " - -./Set_FPGA_clock_delay.sh 0 -sleep 0.1 - - ./Set_Delay_chip.sh 16 16 16 16 -sleep 0.1 - -./Set_TH_Delay.sh 12 -sleep 0.1 - -./Set_ADC_1_Delay.sh 5 -sleep 0.1 - -./Set_ADC_2_Delay.sh 5 -sleep 0.1 - -./Set_ADC_3_Delay.sh 5 -sleep 0.1 - -./Set_ADC_4_Delay.sh 5 - -#pci -w 0x9020 200b20 -pci -w 0x9020 20 -pci -w 0x9028 e - -echo " DONE ................ " - diff --git a/tests/heb/cfg/Set_Delay_chip.sh b/tests/heb/cfg/Set_Delay_chip.sh deleted file mode 100755 index 3d15cad..0000000 --- a/tests/heb/cfg/Set_Delay_chip.sh +++ /dev/null @@ -1,11 +0,0 @@ -#!/bin/bash - - zero=0 - hex_val1=$(printf "%02x\n" $1) - hex_val2=$(printf "%02x\n" $2) - hex_val3=$(printf "%02x\n" $3) - hex_val4=$(printf "%02x\n" $4) - - pci -w 0x9080 $zero$hex_val4$hex_val3$hex_val2$hex_val1 - pci -r 0x9080 -s 1 - sleep 0.5 diff --git a/tests/heb/cfg/Set_FPGA_clock_delay.sh b/tests/heb/cfg/Set_FPGA_clock_delay.sh deleted file mode 100755 index f4d0f46..0000000 --- a/tests/heb/cfg/Set_FPGA_clock_delay.sh +++ /dev/null @@ -1,10 +0,0 @@ -#!/bin/bash - -echo "Set delay on T/Hs signals... " - -upfix=000501 -fixed=0 - - hex_val=$(printf "%01x\n" $1) - echo "Set $hex_val --> Time picosecond = `expr $1 "*" 150`." - pci -w 0x9060 $upfix$hex_val$fixed diff --git a/tests/heb/cfg/Set_TH_Delay.sh b/tests/heb/cfg/Set_TH_Delay.sh deleted file mode 100755 index 9a6e58f..0000000 --- a/tests/heb/cfg/Set_TH_Delay.sh +++ /dev/null @@ -1,10 +0,0 @@ -#!/bin/bash - -echo "Set delay on T/Hs signals... " - -upfix=000501 -fixed=3 - - hex_val=$(printf "%01x\n" $1) - echo "Set $hex_val --> Time picosecond = `expr $1 "*" 150`." - pci -w 0x9060 $upfix$hex_val$fixed diff --git a/tests/heb/debug/debug.sh b/tests/heb/debug/debug.sh deleted file mode 100755 index 2db21d4..0000000 --- a/tests/heb/debug/debug.sh +++ /dev/null @@ -1,45 +0,0 @@ -#! /bin/bash - -SCRIPT_PATH="`dirname \"$0\"`" -SCRIPT_PATH="`( cd \"$TESTS_PATH\" && pwd )`" -PCILIB_PATH=${SCRIPT_PATH%/tests/*} - -function pci { - LD_LIBRARY_PATH="$PCILIB_PATH" $PCILIB_PATH/pci $* -} - -function strip_bad_values { - LD_LIBRARY_PATH="$PCILIB_PATH" $PCILIB_PATH/apps/heb_strip_bad_values $* -} - -function request_data { - $PCILIB_PATH/tests/heb/debug/request_data.sh $* -} - -while [ 1 ]; do - from=`pci --list-dma-engines | grep C2S | sed -s 's/\s\+/ /g' | cut -d ' ' -f 6` - to=`pci --list-dma-engines | grep C2S | sed -s 's/\s\+/ /g' | cut -d ' ' -f 8` - - if [ $from -gt $to ]; then - buffers="`seq $from 255` `seq 0 $to`" - else - buffers=`seq $from $to` - fi - - echo $buffers - - rm data.out - for i in $buffers; do - pci --read-dma-buffer dma1r:$i -o data.out - done - - - error=`strip_bad_values data.out | head -n 1 | cut -f 1 -d ':'` - if [ $error != "0x1140" ]; then - echo "Problems found" - exit - else - echo "Fine" - request_data - fi -done diff --git a/tests/heb/debug/request_data.sh b/tests/heb/debug/request_data.sh deleted file mode 100755 index b751f5d..0000000 --- a/tests/heb/debug/request_data.sh +++ /dev/null @@ -1,27 +0,0 @@ -#!/bin/bash - -pci -r dma1 --multipacket -o /dev/null - -#echo "Data Reset ... " -pci -w 0x9040 000003f1 -sleep 0.1 -pci -w 0x9040 000003f0 - -sleep 0.1 -#echo "Pilot bunch emulator ..... " -#pci -w 0x9040 400003f0 -sleep 0.2 -pci -w 0x9040 03f0 -#pci -r 0x9000 -s 40 -#sleep 0.2 -#echo "Start data pci. ..... " -pci -w 0x9040 00bf0 - -sleep 2 - -#echo "Stop data acquis...... " -pci -w 0x9040 003f0 -pci -r 0x9000 -s 40 -sleep 0.1 -#echo "Enable data transfer.... " -pci -w 0x9040 007f0 diff --git a/tests/ipecamera/bench.sh b/tests/ipecamera/bench.sh deleted file mode 100755 index 09edae9..0000000 --- a/tests/ipecamera/bench.sh +++ /dev/null @@ -1,34 +0,0 @@ -#!/bin/bash - -function pci { - PCILIB_PATH="/root/pcitool" - LD_LIBRARY_PATH="$PCILIB_PATH" $PCILIB_PATH/pci $* -} - -size=16 -bytes=`expr $size "*" 4` - -rm -f bench.out -pci --stop-dma dma1 -pci --reset - -#pci -w xrawdata_packet_length $bytes - -pci --start-dma dma1 -pci -w control 0x1e5 -sleep 1 -pci -w control 0x1e1 - -sleep 1 -pci -w control 0x3e1 -for i in `seq 1 10`; do -# pci -w control 0x1e1 - pci -w dma1 -s $size "*$i" -# pci -w control 0x3e1 - usleep 100000 - pci -r dma1 -s $size -o bench.out -done - -pci -w control 0x1e1 -pci --stop-dma dma1 - diff --git a/tests/ipecamera/cfg/Reset_Init_all_reg_10bit.sh b/tests/ipecamera/cfg/Reset_Init_all_reg_10bit.sh deleted file mode 100755 index f4afa06..0000000 --- a/tests/ipecamera/cfg/Reset_Init_all_reg_10bit.sh +++ /dev/null @@ -1,326 +0,0 @@ -#!/bin/bash - -###################### by Michele Caselle and Uros Stafanovic ################################################## -############ Resent procedure and camera initialization for 10 -bit mode ###################################### - -error=0 -echo " Reset Readout and CMOSIS " -pci -w 0x9040 80000204 -sleep .1 -#echo " Release Reset for Readout" -#pci -w 0x9040 800001e0 -sleep .1 -##################### PLL SET ##################################### -val=f501 -pci -w 0x9000 $val -sleep 0.01 -#pci -r 0x9000 -s 10 -sleep 0.01 -value=`pci -r 0x9000 -s 8 | grep 9010 | awk '{print $2}' | cut -c 4-8` -if [ "$value" != "b$val" ]; then - echo "--------------------------------->>>> ERROR! read value: ${value:1:4}, written value: $val" - error=1 - # exit -fi -sleep 0.01 -echo " Start CMOSIS Configuration .." -pci -w 0x9000 f301 -sleep 0.01 -#pci -r 0x9000 -s 10 -sleep 0.01 -value=`pci -r 0x9000 -s 8 | grep 9010 | awk '{print $2}' | cut -c 4-8` -if [ "$value" != "bf301" ]; then - echo "--------------------------------->>>> ERROR! read value: ${value:1:4}, written value: $val" - error=1 - # exit -fi -sleep 0.01 -val=d207 -pci -w 0x9000 $val -sleep 0.01 -#pci -r 0x9000 -s 10 -sleep 0.01 -value=`pci -r 0x9000 -s 8 | grep 9010 | awk '{print $2}' | cut -c 4-8` -if [ "$value" != "b$val" ]; then - echo "--------------------------------->>>> ERROR! read value: ${value:1:4}, written value: $val" - error=1 - # exit -fi -sleep 0.01 - -# Michele 10 - 12 bit mode # -# ################################################################################################### -echo " 10 - bit mode, set Bit_mode " -val=ef00 ###################################################### -pci -w 0x9000 $val -sleep 0.01 -#pci -r 0x9000 -s 10 -sleep 0.01 -value=`pci -r 0x9000 -s 8 | grep 9010 | awk '{print $2}' | cut -c 4-8` -if [ "$value" != "b$val" ]; then - echo "--------------------------------->>>> ERROR! read value: ${value:1:4}, written value: $val" - error=1 - # exit -fi -sleep 0.01 -# Michele set ADC_resolution @ 12 bits -echo " 10 bit mode, set ADC resolution 10 bits " -val=f000 # qui for 10 - 11 - 12 bits ######################################################## -pci -w 0x9000 $val -sleep 0.01 -#pci -r 0x9000 -s 10 -sleep 0.01 -value=`pci -r 0x9000 -s 8 | grep 9010 | awk '{print $2}' | cut -c 4-8` -if [ "$value" != "b$val" ]; then - echo "--------------------------------->>>> ERROR! read value: ${value:1:4}, written value: $val" - error=1 - # exit -fi -sleep 0.01 - -# adc recommended 28=44 -val=e72c -pci -w 0x9000 $val -sleep 0.01 -#pci -r 0x9000 -s 10 -sleep 0.01 -value=`pci -r 0x9000 -s 8 | grep 9010 | awk '{print $2}' | cut -c 4-8` -if [ "$value" != "b$val" ]; then - echo "--------------------------------->>>> ERROR! read value: ${value:1:4}, written value: $val " - error=1 - # exit -fi -sleep 0.01 -# #################################################################################################### - -################# CAMERA CONFIGURATION ############################################ -val=e603 -pci -w 0x9000 $val -sleep 0.01 -#pci -r 0x9000 -s 10 -sleep 0.01 -value=`pci -r 0x9000 -s 8 | grep 9010 | awk '{print $2}' | cut -c 4-8` -if [ "$value" != "b$val" ]; then - echo "--------------------------------->>>> ERROR! read value: ${value:1:4}, written value: $val" - error=1 - # exit -fi -sleep 0.01 - -val=d404 -pci -w 0x9000 $val -sleep 0.01 -#pci -r 0x9000 -s 10 -sleep 0.01 -value=`pci -r 0x9000 -s 8 | grep 9010 | awk '{print $2}' | cut -c 4-8` -if [ "$value" != "b$val" ]; then - echo "--------------------------------->>>> ERROR! read value: ${value:1:4}, written value: $val" - error=1 - # exit -fi -sleep 0.01 -val=d501 -pci -w 0x9000 $val -sleep 0.01 -#pci -r 0x9000 -s 10 -sleep 0.01 -value=`pci -r 0x9000 -s 8 | grep 9010 | awk '{print $2}' | cut -c 4-8` -if [ "$value" != "b$val" ]; then - echo "--------------------------------->>>> ERROR! read value: ${value:1:4}, written value: $val" - error=1 - # exit -fi -sleep 0.01 -# recommended is d840 -val=d840 -pci -w 0x9000 $val -sleep 0.01 -#pci -r 0x9000 -s 10 -sleep 0.01 -value=`pci -r 0x9000 -s 8 | grep 9010 | awk '{print $2}' | cut -c 4-8` -if [ "$value" != "b$val" ]; then - echo "--------------------------------->>>> ERROR! read value: ${value:1:4}, written value: $val" - error=1 - # exit -fi -# sleep 0.01 -# recommended is db40 -val=db40 -pci -w 0x9000 $val -sleep 0.01 -#pci -r 0x9000 -s 10 -sleep 0.01 -value=`pci -r 0x9000 -s 8 | grep 9010 | awk '{print $2}' | cut -c 4-8` -if [ "$value" != "b$val" ]; then - echo "--------------------------------->>>> ERROR! read value: ${value:1:4}, written value: $val" - error=1 - # exit -fi -sleep 0.01 -val=de65 -# val=de0 -pci -w 0x9000 $val -sleep 0.01 -#pci -r 0x9000 -s 10 -sleep 0.01 -value=`pci -r 0x9000 -s 8 | grep 9010 | awk '{print $2}' | cut -c 4-8` -if [ "$value" != "b$val" ]; then - echo "--------------------------------->>>> ERROR! read value: ${value:1:4}, written value: $val" - error=1 - # exit -fi -sleep 0.01 -sleep 0.01 -val=df6a -pci -w 0x9000 $val -sleep 0.01 -#pci -r 0x9000 -s 10 -sleep 0.01 -value=`pci -r 0x9000 -s 8 | grep 9010 | awk '{print $2}' | cut -c 4-8` -if [ "$value" != "b$val" ]; then - echo "--------------------------------->>>> ERROR! read value: ${value:1:4}, written value: $val" - error=1 - # exit -fi -sleep 0.01 -echo " End CMOSIS Configuration .." -######################################################################################################## -echo " Write exp time......" - -######################################### EXP TIME ####################################################### -val=aa25 -pci -w 0x9000 $val -sleep 0.01 -#pci -r 0x9000 -s 10 -sleep 0.01 -value=`pci -r 0x9000 -s 8 | grep 9010 | awk '{print $2}' | cut -c 4-8` -if [ "$value" != "b$val" ]; then - echo "--------------------------------->>>> ERROR! read value: ${value:1:4}, written value: $val" - error=1 - # exit -fi -sleep 0.01 -# val=ab2c -val=ab00 -pci -w 0x9000 $val -sleep 0.01 -#pci -r 0x9000 -s 10 -sleep 0.01 -value=`pci -r 0x9000 -s 8 | grep 9010 | awk '{print $2}' | cut -c 4-8` -if [ "$value" != "b$val" ]; then - echo "--------------------------------->>>> ERROR! read value: ${value:1:4}, written value: $val" - error=1 - # exit -fi -sleep 0.01 -# val=acaa -val=ac00 -pci -w 0x9000 $val -sleep 0.01 -#pci -r 0x9000 -s 10 -sleep 0.01 -value=`pci -r 0x9000 -s 8 | grep 9010 | awk '{print $2}' | cut -c 4-8` -if [ "$value" != "b$val" ]; then - echo "--------------------------------->>>> ERROR! read value: ${value:1:4}, written value: $val" - error=1 - # exit -fi -#################################################################################################################### - -sleep 0.01 -#pci -w 0x9040 80000201 -sleep 0.01 -########################## WRITE THE READOUT NUMBER OF LINE ####################################################### -pci -w cmosis_number_lines 1088 -#pci -w number_lines 8 -sleep 0.01 -################################################################################################################# -pci --start-dma dma1 -sleep 0.01 -#VRAMP 6c is 108 -val=e26c -pci -w 0x9000 $val -sleep 0.01 -#pci -r 0x9000 -s 10 -sleep 0.01 -value=`pci -r 0x9000 -s 8 | grep 9010 | awk '{print $2}' | cut -c 4-8` -if [ "$value" != "b$val" ]; then - echo "--------------------------------->>>> ERROR! read value: ${value:1:4}, written value: $val" - error=1 - # exit -fi -sleep 0.01 -#VRAMP 6c is 108 -val=e36c -pci -w 0x9000 $val -sleep 0.01 -#pci -r 0x9000 -s 10 -sleep 0.01 -value=`pci -r 0x9000 -s 8 | grep 9010 | awk '{print $2}' | cut -c 4-8` -if [ "$value" != "b$val" ]; then - echo "--------------------------------->>>> ERROR! read value: ${value:1:4}, written value: $val" - error=1 - # exit -fi -sleep 0.01 -###################################### NUMBER OF OUTPUT ############################################################ -##pci -w 0x9000 0xc803 -sleep 0.01 -val=c800 -pci -w 0x9000 $val -#pci -r 0x9000 -s 10 -sleep 0.01 -value=`pci -r 0x9000 -s 8 | grep 9010 | awk '{print $2}' | cut -c 4-8` -if [ "$value" != "b$val" ]; then - echo "--------------------------------->>>> ERROR! read value: ${value:1:4}, written value: $val" - error=1 - # exit -fi -#pci -r 0x9000 -s 10 - -sleep 0.01 -#pci -w 0x9000 0xd011 -sleep 0.01 -#pci -r 0x9000 -s 10 - -sleep 0.01 -#pci -w 0x9000 0xd111 -######################################################################################################### -sleep 0.01 - - - -################################################## -#SET the max number of frame in DDR -pci -w 0x91a0 0x71 - -#echo " Reset Readout and CMOSIS " -pci -w 0x9040 0x80000204 -sleep .1 -echo " Release Reset for Readout" -pci -w 0x9040 0x80000201 -sleep .1 - -status=`pci -r 0x9050 -s 4 | awk '{print $2$3$4}'` -if [ "$status" != "8449ffff0f0010013ffff111" ]; then - echo "--------------------------------->>>> ERROR! in the camera status ... " - echo " $status " - error=1 - # exit -fi - -#echo "--> $status" - -if [ "$error" = "1" ]; then - echo " Error in the reset and initialization" -else - echo " Camera READY ........................... OK" -fi -echo - -echo "DMA reset ... " -pci --stop-dma dma1 -sleep 0.5 -pci --start-dma dma1 - - diff --git a/tests/ipecamera/cfg/Reset_Init_all_reg_10bit_4Mp.sh b/tests/ipecamera/cfg/Reset_Init_all_reg_10bit_4Mp.sh deleted file mode 100755 index 5a4e582..0000000 --- a/tests/ipecamera/cfg/Reset_Init_all_reg_10bit_4Mp.sh +++ /dev/null @@ -1,325 +0,0 @@ -#!/bin/bash - -###################### by Michele Caselle and Uros Stafanovic ################################################## -############ Resent procedure and camera initialization for 10 -bit mode ###################################### - -error=0 -echo " Reset Readout and CMOSIS " -pci -w 0x9040 80000204 -sleep .1 -#echo " Release Reset for Readout" -#pci -w 0x9040 800001e0 -sleep .1 -##################### PLL SET ##################################### -val=f501 -pci -w 0x9000 $val -sleep 0.01 -#pci -r 0x9000 -s 10 -sleep 0.01 -value=`pci -r 0x9000 -s 8 | grep 9010 | awk '{print $2}' | cut -c 4-8` -if [ "$value" != "b$val" ]; then - echo "--------------------------------->>>> ERROR! read value: ${value:1:4}, written value: $val" - error=1 - # exit -fi -sleep 0.01 -echo " Start CMOSIS Configuration .." -pci -w 0x9000 f301 -sleep 0.01 -#pci -r 0x9000 -s 10 -sleep 0.01 -value=`pci -r 0x9000 -s 8 | grep 9010 | awk '{print $2}' | cut -c 4-8` -if [ "$value" != "bf301" ]; then - echo "--------------------------------->>>> ERROR! read value: ${value:1:4}, written value: $val" - error=1 - # exit -fi -sleep 0.01 -val=d207 -pci -w 0x9000 $val -sleep 0.01 -#pci -r 0x9000 -s 10 -sleep 0.01 -value=`pci -r 0x9000 -s 8 | grep 9010 | awk '{print $2}' | cut -c 4-8` -if [ "$value" != "b$val" ]; then - echo "--------------------------------->>>> ERROR! read value: ${value:1:4}, written value: $val" - error=1 - # exit -fi -sleep 0.01 - -# Michele 10 - 12 bit mode # -# ################################################################################################### -echo " 10 - bit mode, set Bit_mode " -val=ef00 ###################################################### -pci -w 0x9000 $val -sleep 0.01 -#pci -r 0x9000 -s 10 -sleep 0.01 -value=`pci -r 0x9000 -s 8 | grep 9010 | awk '{print $2}' | cut -c 4-8` -if [ "$value" != "b$val" ]; then - echo "--------------------------------->>>> ERROR! read value: ${value:1:4}, written value: $val" - error=1 - # exit -fi -sleep 0.01 -# Michele set ADC_resolution @ 12 bits -echo " 10 bit mode, set ADC resolution 10 bits " -val=f000 # qui for 10 - 11 - 12 bits ######################################################## -pci -w 0x9000 $val -sleep 0.01 -#pci -r 0x9000 -s 10 -sleep 0.01 -value=`pci -r 0x9000 -s 8 | grep 9010 | awk '{print $2}' | cut -c 4-8` -if [ "$value" != "b$val" ]; then - echo "--------------------------------->>>> ERROR! read value: ${value:1:4}, written value: $val" - error=1 - # exit -fi -sleep 0.01 - -# adc recommended 28=44 -val=e72c -pci -w 0x9000 $val -sleep 0.01 -#pci -r 0x9000 -s 10 -sleep 0.01 -value=`pci -r 0x9000 -s 8 | grep 9010 | awk '{print $2}' | cut -c 4-8` -if [ "$value" != "b$val" ]; then - echo "--------------------------------->>>> ERROR! read value: ${value:1:4}, written value: $val " - error=1 - # exit -fi -sleep 0.01 -# #################################################################################################### - -################# CAMERA CONFIGURATION ############################################ -val=e603 -pci -w 0x9000 $val -sleep 0.01 -#pci -r 0x9000 -s 10 -sleep 0.01 -value=`pci -r 0x9000 -s 8 | grep 9010 | awk '{print $2}' | cut -c 4-8` -if [ "$value" != "b$val" ]; then - echo "--------------------------------->>>> ERROR! read value: ${value:1:4}, written value: $val" - error=1 - # exit -fi -sleep 0.01 - -val=d404 -pci -w 0x9000 $val -sleep 0.01 -#pci -r 0x9000 -s 10 -sleep 0.01 -value=`pci -r 0x9000 -s 8 | grep 9010 | awk '{print $2}' | cut -c 4-8` -if [ "$value" != "b$val" ]; then - echo "--------------------------------->>>> ERROR! read value: ${value:1:4}, written value: $val" - error=1 - # exit -fi -sleep 0.01 -val=d501 -pci -w 0x9000 $val -sleep 0.01 -#pci -r 0x9000 -s 10 -sleep 0.01 -value=`pci -r 0x9000 -s 8 | grep 9010 | awk '{print $2}' | cut -c 4-8` -if [ "$value" != "b$val" ]; then - echo "--------------------------------->>>> ERROR! read value: ${value:1:4}, written value: $val" - error=1 - # exit -fi -sleep 0.01 -# recommended is d840 -val=d840 -pci -w 0x9000 $val -sleep 0.01 -#pci -r 0x9000 -s 10 -sleep 0.01 -value=`pci -r 0x9000 -s 8 | grep 9010 | awk '{print $2}' | cut -c 4-8` -if [ "$value" != "b$val" ]; then - echo "--------------------------------->>>> ERROR! read value: ${value:1:4}, written value: $val" - error=1 - # exit -fi -# sleep 0.01 -# recommended is db40 -val=db40 -pci -w 0x9000 $val -sleep 0.01 -#pci -r 0x9000 -s 10 -sleep 0.01 -value=`pci -r 0x9000 -s 8 | grep 9010 | awk '{print $2}' | cut -c 4-8` -if [ "$value" != "b$val" ]; then - echo "--------------------------------->>>> ERROR! read value: ${value:1:4}, written value: $val" - error=1 - # exit -fi -sleep 0.01 -val=de65 -# val=de0 -pci -w 0x9000 $val -sleep 0.01 -#pci -r 0x9000 -s 10 -sleep 0.01 -value=`pci -r 0x9000 -s 8 | grep 9010 | awk '{print $2}' | cut -c 4-8` -if [ "$value" != "b$val" ]; then - echo "--------------------------------->>>> ERROR! read value: ${value:1:4}, written value: $val" - error=1 - # exit -fi -sleep 0.01 -sleep 0.01 -val=df6a -pci -w 0x9000 $val -sleep 0.01 -#pci -r 0x9000 -s 10 -sleep 0.01 -value=`pci -r 0x9000 -s 8 | grep 9010 | awk '{print $2}' | cut -c 4-8` -if [ "$value" != "b$val" ]; then - echo "--------------------------------->>>> ERROR! read value: ${value:1:4}, written value: $val" - error=1 - # exit -fi -sleep 0.01 -echo " End CMOSIS Configuration .." -######################################################################################################## -echo " Write exp time......" - -######################################### EXP TIME ####################################################### -val=aa25 -pci -w 0x9000 $val -sleep 0.01 -#pci -r 0x9000 -s 10 -sleep 0.01 -value=`pci -r 0x9000 -s 8 | grep 9010 | awk '{print $2}' | cut -c 4-8` -if [ "$value" != "b$val" ]; then - echo "--------------------------------->>>> ERROR! read value: ${value:1:4}, written value: $val" - error=1 - # exit -fi -sleep 0.01 -# val=ab2c -val=ab00 -pci -w 0x9000 $val -sleep 0.01 -#pci -r 0x9000 -s 10 -sleep 0.01 -value=`pci -r 0x9000 -s 8 | grep 9010 | awk '{print $2}' | cut -c 4-8` -if [ "$value" != "b$val" ]; then - echo "--------------------------------->>>> ERROR! read value: ${value:1:4}, written value: $val" - error=1 - # exit -fi -sleep 0.01 -# val=acaa -val=ac00 -pci -w 0x9000 $val -sleep 0.01 -#pci -r 0x9000 -s 10 -sleep 0.01 -value=`pci -r 0x9000 -s 8 | grep 9010 | awk '{print $2}' | cut -c 4-8` -if [ "$value" != "b$val" ]; then - echo "--------------------------------->>>> ERROR! read value: ${value:1:4}, written value: $val" - error=1 - # exit -fi -#################################################################################################################### - -sleep 0.01 -#pci -w 0x9040 80000201 -sleep 0.01 -########################## WRITE THE READOUT NUMBER OF LINE ####################################################### -pci -w cmosis_number_lines 2047 -#pci -w number_lines 8 -sleep 0.01 -################################################################################################################# -pci --start-dma dma1 -sleep 0.01 -#VRAMP 6c is 108 -val=e26c -pci -w 0x9000 $val -sleep 0.01 -#pci -r 0x9000 -s 10 -sleep 0.01 -value=`pci -r 0x9000 -s 8 | grep 9010 | awk '{print $2}' | cut -c 4-8` -if [ "$value" != "b$val" ]; then - echo "--------------------------------->>>> ERROR! read value: ${value:1:4}, written value: $val" - error=1 - # exit -fi -sleep 0.01 -#VRAMP 6c is 108 -val=e36c -pci -w 0x9000 $val -sleep 0.01 -#pci -r 0x9000 -s 10 -sleep 0.01 -value=`pci -r 0x9000 -s 8 | grep 9010 | awk '{print $2}' | cut -c 4-8` -if [ "$value" != "b$val" ]; then - echo "--------------------------------->>>> ERROR! read value: ${value:1:4}, written value: $val" - error=1 - # exit -fi -sleep 0.01 -###################################### NUMBER OF OUTPUT ############################################################ -##pci -w 0x9000 0xc803 -sleep 0.01 -val=c800 -pci -w 0x9000 $val -#pci -r 0x9000 -s 10 -sleep 0.01 -value=`pci -r 0x9000 -s 8 | grep 9010 | awk '{print $2}' | cut -c 4-8` -if [ "$value" != "b$val" ]; then - echo "--------------------------------->>>> ERROR! read value: ${value:1:4}, written value: $val" - error=1 - # exit -fi -#pci -r 0x9000 -s 10 - -sleep 0.01 -#pci -w 0x9000 0xd011 -sleep 0.01 -#pci -r 0x9000 -s 10 - -sleep 0.01 -#pci -w 0x9000 0xd111 -######################################################################################################### -sleep 0.01 - - - -################################################## -#SET the max number of frame in DDR -pci -w 0x91a0 0x71 - -#echo " Reset Readout and CMOSIS " -pci -w 0x9040 0x80000204 -sleep .1 -echo " Release Reset for Readout" -pci -w 0x9040 0x80000201 -sleep .1 - -status=`pci -r 0x9050 -s 4 | awk '{print $2$3$4}'` -if [ "$status" != "8449ffff0f0010013ffff111" ]; then - echo "--------------------------------->>>> ERROR! in the camera status ... " - error=1 - # exit -fi - -#echo "--> $status" - -if [ "$error" = "1" ]; then - echo " Error in the reset and initialization" -else - echo " Camera READY ........................... OK" -fi -echo - -echo "DMA reset ... " -pci --stop-dma dma1 -sleep 0.5 -pci --start-dma dma1 - - diff --git a/tests/ipecamera/cfg/Reset_Init_all_reg_11bit.sh b/tests/ipecamera/cfg/Reset_Init_all_reg_11bit.sh deleted file mode 100755 index 3c4af0e..0000000 --- a/tests/ipecamera/cfg/Reset_Init_all_reg_11bit.sh +++ /dev/null @@ -1,318 +0,0 @@ -#!/bin/bash - -###################### by Michele Caselle and Uros Stafanovic ################################################## -############ Resent procedure and camera initialization for 12 -bit mode ###################################### - -error=0 -echo " Reset Readout and CMOSIS " -pci -w 0x9040 1e4 -sleep .1 -echo " Release Reset for Readout" -pci -w 0x9040 1e0 -sleep .1 -##################### PLL SET ##################################### -val=f501 -pci -w 0x9000 $val -sleep 0.01 -#pci -r 0x9000 -s 10 -sleep 0.01 -value=`pci -r 0x9000 -s 8 | grep 9010 | awk '{print $2}' | cut -c 4-8` -if [ "$value" != "b$val" ]; then - echo "--------------------------------->>>> ERROR! read value: ${value:1:4}, written value: $val" - error =1 - # exit -fi -sleep 0.01 -echo " Start CMOSIS Configuration .." -pci -w 0x9000 f301 -sleep 0.01 -#pci -r 0x9000 -s 10 -sleep 0.01 -value=`pci -r 0x9000 -s 8 | grep 9010 | awk '{print $2}' | cut -c 4-8` -if [ "$value" != "bf301" ]; then - echo "--------------------------------->>>> ERROR! read value: ${value:1:4}, written value: $val" - error =1 - # exit -fi -sleep 0.01 -val=d207 -pci -w 0x9000 $val -sleep 0.01 -#pci -r 0x9000 -s 10 -sleep 0.01 -value=`pci -r 0x9000 -s 8 | grep 9010 | awk '{print $2}' | cut -c 4-8` -if [ "$value" != "b$val" ]; then - echo "--------------------------------->>>> ERROR! read value: ${value:1:4}, written value: $val" - error =1 - # exit -fi -sleep 0.01 - -# Michele 10 - 12 bit mode # -# ################################################################################################### -echo " 11 - bit mode, set Bit_mode " -val=ef00 ###################################################### -pci -w 0x9000 $val -sleep 0.01 -#pci -r 0x9000 -s 10 -sleep 0.01 -value=`pci -r 0x9000 -s 8 | grep 9010 | awk '{print $2}' | cut -c 4-8` -if [ "$value" != "b$val" ]; then - echo "--------------------------------->>>> ERROR! read value: ${value:1:4}, written value: $val" - error =1 - # exit -fi -sleep 0.01 -# Michele set ADC_resolution @ 12 bits -echo " 11 bit mode, set ADC resolution 11 bits " -val=f001 # qui for 10 - 11 - 12 bits ######################################################## -pci -w 0x9000 $val -sleep 0.01 -#pci -r 0x9000 -s 10 -sleep 0.01 -value=`pci -r 0x9000 -s 8 | grep 9010 | awk '{print $2}' | cut -c 4-8` -if [ "$value" != "b$val" ]; then - echo "--------------------------------->>>> ERROR! read value: ${value:1:4}, written value: $val" - error =1 - # exit -fi -sleep 0.01 - -# adc recommended 28=44 -val=e72c -pci -w 0x9000 $val -sleep 0.01 -#pci -r 0x9000 -s 10 -sleep 0.01 -value=`pci -r 0x9000 -s 8 | grep 9010 | awk '{print $2}' | cut -c 4-8` -if [ "$value" != "b$val" ]; then - echo "--------------------------------->>>> ERROR! read value: ${value:1:4}, written value: $val " - error =1 - # exit -fi -sleep 0.01 -# #################################################################################################### - -################# CAMERA CONFIGURATION ############################################ -val=e603 -pci -w 0x9000 $val -sleep 0.01 -#pci -r 0x9000 -s 10 -sleep 0.01 -value=`pci -r 0x9000 -s 8 | grep 9010 | awk '{print $2}' | cut -c 4-8` -if [ "$value" != "b$val" ]; then - echo "--------------------------------->>>> ERROR! read value: ${value:1:4}, written value: $val" - error =1 - # exit -fi -sleep 0.01 - -val=d404 -pci -w 0x9000 $val -sleep 0.01 -#pci -r 0x9000 -s 10 -sleep 0.01 -value=`pci -r 0x9000 -s 8 | grep 9010 | awk '{print $2}' | cut -c 4-8` -if [ "$value" != "b$val" ]; then - echo "--------------------------------->>>> ERROR! read value: ${value:1:4}, written value: $val" - error =1 - # exit -fi -sleep 0.01 -val=d501 -pci -w 0x9000 $val -sleep 0.01 -#pci -r 0x9000 -s 10 -sleep 0.01 -value=`pci -r 0x9000 -s 8 | grep 9010 | awk '{print $2}' | cut -c 4-8` -if [ "$value" != "b$val" ]; then - echo "--------------------------------->>>> ERROR! read value: ${value:1:4}, written value: $val" - error =1 - # exit -fi -sleep 0.01 -# recommended is d840 -val=d840 -pci -w 0x9000 $val -sleep 0.01 -#pci -r 0x9000 -s 10 -sleep 0.01 -value=`pci -r 0x9000 -s 8 | grep 9010 | awk '{print $2}' | cut -c 4-8` -if [ "$value" != "b$val" ]; then - echo "--------------------------------->>>> ERROR! read value: ${value:1:4}, written value: $val" - error =1 - # exit -fi -# sleep 0.01 -# recommended is db40 -val=db40 -pci -w 0x9000 $val -sleep 0.01 -#pci -r 0x9000 -s 10 -sleep 0.01 -value=`pci -r 0x9000 -s 8 | grep 9010 | awk '{print $2}' | cut -c 4-8` -if [ "$value" != "b$val" ]; then - echo "--------------------------------->>>> ERROR! read value: ${value:1:4}, written value: $val" - error =1 - # exit -fi -sleep 0.01 -val=de65 -# val=de0 -pci -w 0x9000 $val -sleep 0.01 -#pci -r 0x9000 -s 10 -sleep 0.01 -value=`pci -r 0x9000 -s 8 | grep 9010 | awk '{print $2}' | cut -c 4-8` -if [ "$value" != "b$val" ]; then - echo "--------------------------------->>>> ERROR! read value: ${value:1:4}, written value: $val" - error =1 - # exit -fi -sleep 0.01 -sleep 0.01 -val=df6a -pci -w 0x9000 $val -sleep 0.01 -#pci -r 0x9000 -s 10 -sleep 0.01 -value=`pci -r 0x9000 -s 8 | grep 9010 | awk '{print $2}' | cut -c 4-8` -if [ "$value" != "b$val" ]; then - echo "--------------------------------->>>> ERROR! read value: ${value:1:4}, written value: $val" - error =1 - # exit -fi -sleep 0.01 -echo " End CMOSIS Configuration .." -######################################################################################################## -echo " Write exp time......" - -######################################### EXP TIME ####################################################### -val=aa25 -pci -w 0x9000 $val -sleep 0.01 -#pci -r 0x9000 -s 10 -sleep 0.01 -value=`pci -r 0x9000 -s 8 | grep 9010 | awk '{print $2}' | cut -c 4-8` -if [ "$value" != "b$val" ]; then - echo "--------------------------------->>>> ERROR! read value: ${value:1:4}, written value: $val" - error =1 - # exit -fi -sleep 0.01 -# val=ab2c -val=ab02 -pci -w 0x9000 $val -sleep 0.01 -#pci -r 0x9000 -s 10 -sleep 0.01 -value=`pci -r 0x9000 -s 8 | grep 9010 | awk '{print $2}' | cut -c 4-8` -if [ "$value" != "b$val" ]; then - echo "--------------------------------->>>> ERROR! read value: ${value:1:4}, written value: $val" - error =1 - # exit -fi -sleep 0.01 -# val=acaa -val=ac00 -pci -w 0x9000 $val -sleep 0.01 -#pci -r 0x9000 -s 10 -sleep 0.01 -value=`pci -r 0x9000 -s 8 | grep 9010 | awk '{print $2}' | cut -c 4-8` -if [ "$value" != "b$val" ]; then - echo "--------------------------------->>>> ERROR! read value: ${value:1:4}, written value: $val" - error =1 - # exit -fi -#################################################################################################################### - -sleep 0.01 -pci -w 0x9040 201 -sleep 0.01 -########################## WRITE THE READOUT NUMBER OF LINE ####################################################### -pci -w cmosis_number_lines 1088 -#pci -w number_lines 8 -sleep 0.01 -################################################################################################################# -pci --start-dma dma1 -sleep 0.01 -#VRAMP 6c is 108 -val=e26c -pci -w 0x9000 $val -sleep 0.01 -#pci -r 0x9000 -s 10 -sleep 0.01 -value=`pci -r 0x9000 -s 8 | grep 9010 | awk '{print $2}' | cut -c 4-8` -if [ "$value" != "b$val" ]; then - echo "--------------------------------->>>> ERROR! read value: ${value:1:4}, written value: $val" - error =1 - # exit -fi -sleep 0.01 -#VRAMP 6c is 108 -val=e36c -pci -w 0x9000 $val -sleep 0.01 -#pci -r 0x9000 -s 10 -sleep 0.01 -value=`pci -r 0x9000 -s 8 | grep 9010 | awk '{print $2}' | cut -c 4-8` -if [ "$value" != "b$val" ]; then - echo "--------------------------------->>>> ERROR! read value: ${value:1:4}, written value: $val" - error =1 - # exit -fi -sleep 0.01 -######################################################################################################## -#pci -w 0x9000 0xc802 -##pci -w 0x9000 0xc803 -sleep 0.01 -val=c802 -pci -w 0x9000 $val -#pci -r 0x9000 -s 10 -sleep 0.01 -value=`pci -r 0x9000 -s 8 | grep 9010 | awk '{print $2}' | cut -c 4-8` -if [ "$value" != "b$val" ]; then - echo "--------------------------------->>>> ERROR! read value: ${value:1:4}, written value: $val" - error =1 - # exit -fi -#pci -r 0x9000 -s 10 - -################################################## -#SET the max number of frame in DDR -pci -w 0x91a0 0x1C - -sleep 0.01 -#pci -w 0x9000 0xd011 -sleep 0.01 -#pci -r 0x9000 -s 10 - -sleep 0.01 -#pci -w 0x9000 0xd111 -#pci -r 0x9000 -s 10 -######################################################################################################### -sleep 0.01 - -status=`pci -r 0x9050 -s 4 | awk '{print $2$3$4}'` -if [ "$status" != "8449ffff0f0010013ffff111" ]; then - echo "--------------------------------->>>> ERROR! in the camera status ... " - error =1 - # exit -fi - -#echo "--> $status" - -if [ "$error" = "1" ]; then - echo " Error in the resetand initialization" -else - echo " Camera READY ........ OK" -fi -echo - - -echo "DMA reset ... " -pci --stop-dma dma1 -sleep 0.5 -pci --start-dma dma1 - diff --git a/tests/ipecamera/cfg/Reset_Init_all_reg_12bit.sh b/tests/ipecamera/cfg/Reset_Init_all_reg_12bit.sh deleted file mode 100755 index b04f2cd..0000000 --- a/tests/ipecamera/cfg/Reset_Init_all_reg_12bit.sh +++ /dev/null @@ -1,323 +0,0 @@ -#!/bin/bash - -###################### by Michele Caselle and Uros Stafanovic ################################################## -############ Resent procedure and camera initialization for 12 -bit mode ###################################### - -error=0 -echo " Reset Readout and CMOSIS " -pci -w 0x9040 1e4 -sleep .1 -echo " Release Reset for Readout" -pci -w 0x9040 1e0 -sleep .1 -##################### PLL SET ##################################### -val=f501 -pci -w 0x9000 $val -sleep 0.01 -#pci -r 0x9000 -s 10 -sleep 0.01 -value=`pci -r 0x9000 -s 8 | grep 9010 | awk '{print $2}' | cut -c 4-8` -if [ "$value" != "b$val" ]; then - echo "--------------------------------->>>> ERROR! read value: ${value:1:4}, written value: $val" - error =1 - # exit -fi -sleep 0.01 -echo " Start CMOSIS Configuration .." -pci -w 0x9000 f301 -sleep 0.01 -#pci -r 0x9000 -s 10 -sleep 0.01 -value=`pci -r 0x9000 -s 8 | grep 9010 | awk '{print $2}' | cut -c 4-8` -if [ "$value" != "bf301" ]; then - echo "--------------------------------->>>> ERROR! read value: ${value:1:4}, written value: $val" - error =1 - # exit -fi -sleep 0.01 -val=d207 -pci -w 0x9000 $val -sleep 0.01 -#pci -r 0x9000 -s 10 -sleep 0.01 -value=`pci -r 0x9000 -s 8 | grep 9010 | awk '{print $2}' | cut -c 4-8` -if [ "$value" != "b$val" ]; then - echo "--------------------------------->>>> ERROR! read value: ${value:1:4}, written value: $val" - error =1 - # exit -fi -sleep 0.01 - -# Michele 10 - 12 bit mode # -# ################################################################################################### -echo " 12 - bit mode, set Bit_mode " -val=ef00 ###################################################### -pci -w 0x9000 $val -sleep 0.01 -#pci -r 0x9000 -s 10 -sleep 0.01 -value=`pci -r 0x9000 -s 8 | grep 9010 | awk '{print $2}' | cut -c 4-8` -if [ "$value" != "b$val" ]; then - echo "--------------------------------->>>> ERROR! read value: ${value:1:4}, written value: $val" - error =1 - # exit -fi -sleep 0.01 -# Michele set ADC_resolution @ 12 bits -echo " 12 bit mode, set ADC resolution 12 bits " -val=f002 # qui for 10 - 11 - 12 bits ######################################################## -pci -w 0x9000 $val -sleep 0.01 -#pci -r 0x9000 -s 10 -sleep 0.01 -value=`pci -r 0x9000 -s 8 | grep 9010 | awk '{print $2}' | cut -c 4-8` -if [ "$value" != "b$val" ]; then - echo "--------------------------------->>>> ERROR! read value: ${value:1:4}, written value: $val" - error =1 - # exit -fi -sleep 0.01 - -# adc recommended 28=44 -val=e72c -pci -w 0x9000 $val -sleep 0.01 -#pci -r 0x9000 -s 10 -sleep 0.01 -value=`pci -r 0x9000 -s 8 | grep 9010 | awk '{print $2}' | cut -c 4-8` -if [ "$value" != "b$val" ]; then - echo "--------------------------------->>>> ERROR! read value: ${value:1:4}, written value: $val " - error =1 - # exit -fi -sleep 0.01 -# #################################################################################################### - -################# CAMERA CONFIGURATION ############################################ -val=e603 -pci -w 0x9000 $val -sleep 0.01 -#pci -r 0x9000 -s 10 -sleep 0.01 -value=`pci -r 0x9000 -s 8 | grep 9010 | awk '{print $2}' | cut -c 4-8` -if [ "$value" != "b$val" ]; then - echo "--------------------------------->>>> ERROR! read value: ${value:1:4}, written value: $val" - error =1 - # exit -fi -sleep 0.01 - -val=d404 -pci -w 0x9000 $val -sleep 0.01 -#pci -r 0x9000 -s 10 -sleep 0.01 -value=`pci -r 0x9000 -s 8 | grep 9010 | awk '{print $2}' | cut -c 4-8` -if [ "$value" != "b$val" ]; then - echo "--------------------------------->>>> ERROR! read value: ${value:1:4}, written value: $val" - error =1 - # exit -fi -sleep 0.01 -val=d501 -pci -w 0x9000 $val -sleep 0.01 -#pci -r 0x9000 -s 10 -sleep 0.01 -value=`pci -r 0x9000 -s 8 | grep 9010 | awk '{print $2}' | cut -c 4-8` -if [ "$value" != "b$val" ]; then - echo "--------------------------------->>>> ERROR! read value: ${value:1:4}, written value: $val" - error =1 - # exit -fi -sleep 0.01 -# recommended is d840 -val=d840 -pci -w 0x9000 $val -sleep 0.01 -#pci -r 0x9000 -s 10 -sleep 0.01 -value=`pci -r 0x9000 -s 8 | grep 9010 | awk '{print $2}' | cut -c 4-8` -if [ "$value" != "b$val" ]; then - echo "--------------------------------->>>> ERROR! read value: ${value:1:4}, written value: $val" - error =1 - # exit -fi -# sleep 0.01 -# recommended is db40 -val=db40 -pci -w 0x9000 $val -sleep 0.01 -#pci -r 0x9000 -s 10 -sleep 0.01 -value=`pci -r 0x9000 -s 8 | grep 9010 | awk '{print $2}' | cut -c 4-8` -if [ "$value" != "b$val" ]; then - echo "--------------------------------->>>> ERROR! read value: ${value:1:4}, written value: $val" - error =1 - # exit -fi -sleep 0.01 -val=de65 -# val=de0 -pci -w 0x9000 $val -sleep 0.01 -#pci -r 0x9000 -s 10 -sleep 0.01 -value=`pci -r 0x9000 -s 8 | grep 9010 | awk '{print $2}' | cut -c 4-8` -if [ "$value" != "b$val" ]; then - echo "--------------------------------->>>> ERROR! read value: ${value:1:4}, written value: $val" - error =1 - # exit -fi -sleep 0.01 -sleep 0.01 -val=df6a -pci -w 0x9000 $val -sleep 0.01 -#pci -r 0x9000 -s 10 -sleep 0.01 -value=`pci -r 0x9000 -s 8 | grep 9010 | awk '{print $2}' | cut -c 4-8` -if [ "$value" != "b$val" ]; then - echo "--------------------------------->>>> ERROR! read value: ${value:1:4}, written value: $val" - error =1 - # exit -fi -sleep 0.01 -echo " End CMOSIS Configuration .." -######################################################################################################## -echo " Write exp time......" - -######################################### EXP TIME ####################################################### -val=aa0f -pci -w 0x9000 $val -sleep 0.01 -#pci -r 0x9000 -s 10 -sleep 0.01 -value=`pci -r 0x9000 -s 8 | grep 9010 | awk '{print $2}' | cut -c 4-8` -if [ "$value" != "b$val" ]; then - echo "--------------------------------->>>> ERROR! read value: ${value:1:4}, written value: $val" - error =1 - # exit -fi -sleep 0.01 -# val=ab2c -val=ab00 -pci -w 0x9000 $val -sleep 0.01 -#pci -r 0x9000 -s 10 -sleep 0.01 -value=`pci -r 0x9000 -s 8 | grep 9010 | awk '{print $2}' | cut -c 4-8` -if [ "$value" != "b$val" ]; then - echo "--------------------------------->>>> ERROR! read value: ${value:1:4}, written value: $val" - error =1 - # exit -fi -sleep 0.01 -# val=acaa -val=ac00 -pci -w 0x9000 $val -sleep 0.01 -#pci -r 0x9000 -s 10 -sleep 0.01 -value=`pci -r 0x9000 -s 8 | grep 9010 | awk '{print $2}' | cut -c 4-8` -if [ "$value" != "b$val" ]; then - echo "--------------------------------->>>> ERROR! read value: ${value:1:4}, written value: $val" - error =1 - # exit -fi -#################################################################################################################### - -sleep 0.01 -pci -w 0x9040 201 -sleep 0.01 -########################## WRITE THE READOUT NUMBER OF LINE ####################################################### -pci -w cmosis_number_lines 1088 -#pci -w number_lines 8 -sleep 0.01 -################################################################################################################# -pci --start-dma dma1 -sleep 0.01 -#VRAMP 6c is 108 -val=e26c -pci -w 0x9000 $val -sleep 0.01 -#pci -r 0x9000 -s 10 -sleep 0.01 -value=`pci -r 0x9000 -s 8 | grep 9010 | awk '{print $2}' | cut -c 4-8` -if [ "$value" != "b$val" ]; then - echo "--------------------------------->>>> ERROR! read value: ${value:1:4}, written value: $val" - error =1 - # exit -fi -sleep 0.01 -#VRAMP 6c is 108 -val=e36c -pci -w 0x9000 $val -sleep 0.01 -#pci -r 0x9000 -s 10 -sleep 0.01 -value=`pci -r 0x9000 -s 8 | grep 9010 | awk '{print $2}' | cut -c 4-8` -if [ "$value" != "b$val" ]; then - echo "--------------------------------->>>> ERROR! read value: ${value:1:4}, written value: $val" - error =1 - # exit -fi -sleep 0.01 -######################################################################################################## -#pci -w 0x9000 0xc802 -##pci -w 0x9000 0xc803 -sleep 0.01 -val=c802 -pci -w 0x9000 $val -#pci -r 0x9000 -s 10 -sleep 0.01 -value=`pci -r 0x9000 -s 8 | grep 9010 | awk '{print $2}' | cut -c 4-8` -if [ "$value" != "b$val" ]; then - echo "--------------------------------->>>> ERROR! read value: ${value:1:4}, written value: $val" - error =1 - # exit -fi -#pci -r 0x9000 -s 10 - -sleep 0.01 - -################################################## -#SET the max number of frame in DDR -pci -w 0x91a0 0x1C - - -#pci -w 0x9000 0xd011 -sleep 0.01 -pci -r 0x9000 -s 10 - -sleep 0.01 -#pci -w 0x9000 0xd111 -sleep 0.01 -pci -r 0x9000 -s 10 -######################################################################################################### -sleep 0.1 - -status=`pci -r 0x9050 -s 4 | awk '{print $2$3$4}'` -if [ "$status" != "844950280f0010013ffff111" ]; then - - echo "--------------------------------->>>> ERROR! in the camera status ... " - echo $status - error=1 - # exit -fi - -#echo "--> $status" - -if [ "$error" = "1" ]; then - echo " Error in the resetand initialization" -else - echo " Camera READY ........ OK" -fi -echo - - - -echo "DMA reset ... " -pci --stop-dma dma1 -sleep 0.5 -pci --start-dma dma1 diff --git a/tests/ipecamera/frame.sh b/tests/ipecamera/frame.sh deleted file mode 100755 index 679817b..0000000 --- a/tests/ipecamera/frame.sh +++ /dev/null @@ -1,36 +0,0 @@ -#!/bin/bash - -TESTS_PATH="`dirname \"$0\"`" -TESTS_PATH="`( cd \"$TESTS_PATH\" && pwd )`" - -function pci { - PCILIB_PATH=$TESTS_PATH/.. - LD_LIBRARY_PATH="$PCILIB_PATH" $PCILIB_PATH/pci $* -} - -pci --stop-dma dma1 -#pci --reset - -echo "Set packet size 1024 .. " -pci -w cmosis_number_lines 1088 -#pci -w xrawdata_packet_length 4096 -pci --start-dma dma1 -usleep 1000 - -echo "Send frame request ... " -pci -w control 1e9 -usleep 100000 -pci -w control 1e1 -usleep 100000 - -echo "Enable Readout ... " -pci -w control 3e1 - -usleep 100000 - -pci -r dma1 -o bench.out --multipacket - -pci -w control 1e1 - -pci --stop-dma dma1 - diff --git a/tests/ipecamera/frame_req.sh b/tests/ipecamera/frame_req.sh deleted file mode 100755 index bce89c3..0000000 --- a/tests/ipecamera/frame_req.sh +++ /dev/null @@ -1,27 +0,0 @@ -#!/bin/bash - -function pci { - PCILIB_PATH="/root/pcitool" - LD_LIBRARY_PATH="$PCILIB_PATH" $PCILIB_PATH/pci $* -} - -#pci --stop-dma dma1 -#pci --reset - -echo "Set packet size 1024 .. " -pci -w cmosis_number_lines 1088 -#pci -w xrawdata_packet_length 4096 -pci --start-dma dma1 -usleep 1000 - -echo "Send frame request ... " -pci -w control 1e9 -usleep 100000 -pci -w control 1e1 -usleep 100000 - -echo "Enable Readout 3... " -pci -w control 3e1 -usleep 1000000 -pci -w control 1e1 - diff --git a/tests/ipecamera/grab-hwtrigger.sh b/tests/ipecamera/grab-hwtrigger.sh deleted file mode 100755 index 0279ab4..0000000 --- a/tests/ipecamera/grab-hwtrigger.sh +++ /dev/null @@ -1,20 +0,0 @@ -#! /bin/bash - -function pci { - PCILIB_PATH="/root/pcitool" - LD_LIBRARY_PATH="$PCILIB_PATH" $PCILIB_PATH/pci $* -} - -function enable_hw_trigger { - usleep 100000 - pci -w control 0xa01 -} - -rm -f images.raw - -enable_hw_trigger & -pid=$! - -echo "Starting the grabber" -pci -g -o images.raw --run-time 60000000 --verbose 10 -o /dev/null -wait $pid diff --git a/tests/ipecamera/stimuli.sh b/tests/ipecamera/stimuli.sh deleted file mode 100755 index 33e99e1..0000000 --- a/tests/ipecamera/stimuli.sh +++ /dev/null @@ -1,30 +0,0 @@ -#!/bin/bash - -function pci { - PCILIB_PATH="/root/pcitool" - LD_LIBRARY_PATH="$PCILIB_PATH" $PCILIB_PATH/pci $* -} - -rm -f bench.out - -echo "Set FFFF the frame space .." -pci -w 0x9180 fff - -echo "Set the number of frames .." -pci -w reg9170 55 - -pci --start-dma dma1 - -echo "Send frame request ... " -pci -w control 1f1 -usleep 100000 -pci -w control 1e1 - - -echo "Enable Readout ... " -pci -w control 3e1 -pci -r dma1 -o bench.out --multipacket -pci -w control 1e1 - -pci --stop-dma dma1 - diff --git a/tests/ipecamera/tests/loopback-test.sh b/tests/ipecamera/tests/loopback-test.sh deleted file mode 100755 index 1c033cc..0000000 --- a/tests/ipecamera/tests/loopback-test.sh +++ /dev/null @@ -1,87 +0,0 @@ -#! /bin/bash - -TESTS_PATH="`dirname \"$0\"`" -TESTS_PATH="`( cd \"$TESTS_PATH\" && pwd )`" - -function pci { - PCILIB_PATH=$TESTS_PATH/.. - LD_LIBRARY_PATH="$PCILIB_PATH" $PCILIB_PATH/pci $* -} - -function compare { - PCILIB_PATH=$TESTS_PATH/.. - LD_LIBRARY_PATH="$PCILIB_PATH" $PCILIB_PATH/apps/compare_to_value $* -} - -#size=`expr 1024 "*" 1024` -size=`expr 1024 "*" 1` -multiplier=2 -wait=0 - -/root/pcitool/tests/ipecamera/frame.sh &> /dev/null -rm -f bench.out - -pci --stop-dma dma1 -pci --start-dma dma1 - -pci -r dma1 -s 16777216 --multipacket -o /dev/null &> /dev/null - -pci -r dma1 -s 1024 -o /dev/null | grep -i "Error (62)" &> /dev/null -if [ $? -ne 0 ]; then - echo "There is data on dma..." - exit -fi - -failed=0 -send=0 -errors=0 -err_num=0 - -print_iters=`expr 2 + 1024 '*' 100 / $size` - -read_size=`expr $multiplier '*' $size` -echo "Starting..." -i=1 - -pci -w 0x9040 0x201 - -while [ 1 ]; do - if [ $wait -gt 0 ]; then - pci -w 0x9040 0x1 - fi - - pci -w dma1 -s $size "*0x$i" - rm -f /tmp/camera-test.out - pci -r dma1 --wait --multipacket -s $read_size -o /tmp/camera-test.out -t 1000000 &> /dev/null - if [ $wait -gt 0 ]; then - wrdone=0 - while [ $wrdone -eq 0 ]; do -# pci --list-dma-engines - pci --list-dma-engines | grep "DMA1 S2C" | grep "SD" #&> /dev/null - wrdone=$? - done - pci -w 0x9040 0x201 - fi - - res=`compare /tmp/camera-test.out $read_size "$i" 6 2 6` - if [ $? -eq 0 ]; then - err_cnt=`echo $res | cut -f 1 -d ' '` - if [ "$err_cnt" -ne 0 ]; then - pci -r dma1 --wait --multipacket -o /tmp/camera-test.out -t 1000000 &> /dev/null - cp /tmp/camera-test.out /tmp/camera-test.out.$err_num - err_num=$(($err_num + 1)) - fi - byte_cnt=`echo $res | cut -f 3 -d ' '` - send=$(($send + $byte_cnt * 4)) - errors=$(($errors + $err_cnt * 4)) - else - failed=$(($failed + 1)) - fi - - i=$((i + 1)) - if [ $i -eq $print_iters ]; then - echo "Data send: $send bytes, Errors: $errors bytes, Failed exchanges: $failed" -# pci -r 0x9070 -s 4 - i=1 - fi -done diff --git a/tests/ipecamera/tests/run-and-decode-test.sh b/tests/ipecamera/tests/run-and-decode-test.sh deleted file mode 100755 index d355475..0000000 --- a/tests/ipecamera/tests/run-and-decode-test.sh +++ /dev/null @@ -1,103 +0,0 @@ -#! /bin/bash - -location=/mnt/fast/ -#location="./" -duration=10000000 -wait_frame=1000000 - -TESTS_PATH="`dirname \"$0\"`" -TESTS_PATH="`( cd \"$TESTS_PATH\" && pwd )`" - -function pci { - PCILIB_PATH=$TESTS_PATH/.. - LD_LIBRARY_PATH="$PCILIB_PATH" $PCILIB_PATH/pci $* -} - -function stop { - usleep $duration - pci -w control 0x201 &> /dev/null -} - -function reset { - pci -r 0x9000 -s 256 > $1.status - $TESTS_PATH/ipecamera/Reset_Init_all_reg_10bit.sh &> $1.reset -} - - -$TESTS_PATH/ipecamera/cfg/Reset_Init_all_reg_10bit.sh &> /dev/null -$TESTS_PATH/ipecamera/frame.sh &> /dev/null -rm -f bench.out - -pci --stop-dma -pci --start-dma dma1 - - -pci -r dma1 -s 16777216 --multipacket -o /dev/null &> /dev/null - -pci -r dma1 -s 1 | grep -i "Error (62)" &> /dev/null -if [ $? -ne 0 ]; then - echo "There is data on dma..." - exit -fi - -echo "Starting ... " - -decode_failures=0 -failures=0 -failed=0 -frames=0 -fpga_failures=0 -cmosis_failures=0 -frame_rate_failures=0 - -iter=0 -while [ 1 ]; do - pci -w control 0xa01 &> /dev/null - stop & - - output="$location/test$iter.out" - rm -f $output - pci -r dma1 -o $output --wait --multipacket -t $wait_frame &> /dev/null - - killall -9 usleep &> /dev/null - usleep 100000 - pci -w control 0x201 &> /dev/null - - if [ -f $output ]; then - result=`ipedec -d -v --continue $output 2>&1 | grep -iE "failed|decoded"` - cur_failed=`echo $result | wc -l` - cur_decoded=`echo $result | tail -n 1 | grep -i decoded` - if [ $? -ne 0 -o $cur_failed -eq 0 ]; then - ipedec -d -v --continue $output > $output.decode - decode_failures=$(($decode_failures + 1)) - reset $output - else - cur_failed=$(($cur_failed - 1)) - cur_frames=`echo $cur_decoded | cut -f 2 -d ' '` - failed=$(($failed + $cur_failed)) - frames=$(($frames + $cur_frames)) - fpga_status=`pci -r 0x9054 | awk '{print $2;}' | cut -c 2` - cmosis_status=`pci -r 0x9050 | awk '{print $2;}' | cut -c 3-4` - if [ "$fpga_status" != "f" ]; then - fpga_failures=$(($fpga_failures + 1)) - reset $output - elif [ "$cmosis_status" == "7d" ]; then - cmosis_failures=$(($cmosis_failures + 1)) - reset $output - elif [ $cur_frames -lt 10 ]; then - frame_rate_failures=$(($frame_rate_failures + 1)) - reset $output - elif [ $cur_failed -eq 0 ]; then - rm -f $output - else - reset $output - fi - fi - else - failures=$(($failures + 1)) - reset $output - fi - - echo "Frames: $frames, Failed Frames: $failed, Failed Exchanges: $failures, Failed Decodings: $decode_failures, FPGA Failures: $fpga_failures, CMOSIS Failures: $cmosis_failures, Low Frame Rate: $frame_rate_failures" - iter=`expr $iter + 1` -done diff --git a/tests/new_device.sh b/tests/new_device.sh deleted file mode 100755 index 3545321..0000000 --- a/tests/new_device.sh +++ /dev/null @@ -1,3 +0,0 @@ -#! /bin/bash - -echo "10ee 6028" > /sys/bus/pci/drivers/pciDriver/new_id diff --git a/tools.c b/tools.c deleted file mode 100644 index e0789fb..0000000 --- a/tools.c +++ /dev/null @@ -1,354 +0,0 @@ -#define _POSIX_C_SOURCE 200112L -#define _GNU_SOURCE - -#include <stdio.h> -#include <string.h> -#include <unistd.h> -#include <stdint.h> -#include <assert.h> -#include <ctype.h> -#include <time.h> -#include <sched.h> -#include <arpa/inet.h> -#include <sys/time.h> - -#include "tools.h" -#include "error.h" - -int pcilib_isnumber(const char *str) { - int i = 0; - for (i = 0; str[i]; i++) - if (!isdigit(str[i])) return 0; - return 1; -} - -int pcilib_isxnumber(const char *str) { - int i = 0; - - if ((str[0] == '0')&&((str[1] == 'x')||(str[1] == 'X'))) i += 2; - - for (; str[i]; i++) - if (!isxdigit(str[i])) return 0; - - return 1; -} - -int pcilib_isnumber_n(const char *str, size_t len) { - int i = 0; - for (i = 0; (str[i])&&(i < len); i++) - if (!isdigit(str[i])) return 0; - return 1; -} - -int pcilib_isxnumber_n(const char *str, size_t len) { - int i = 0; - - if ((len > 1)&&(str[0] == '0')&&((str[1] == 'x')||(str[1] == 'X'))) i += 2; - - for (; (str[i])&&(i < len); i++) - if (!isxdigit(str[i])) return 0; - - return 1; -} - - -uint16_t pcilib_swap16(uint16_t x) { - return (((x<<8)&0xFFFF) | ((x>>8)&0xFFFF)); -} - -uint32_t pcilib_swap32(uint32_t x) { - return ((x & 0xFF) << 24) | \ - ((x & 0xFF00) << 8) | \ - ((x & 0xFF0000) >> 8) | \ - ((x & 0xFF000000) >> 24); -} - -uint64_t pcilib_swap64(uint64_t x) { - return (((uint64_t)(x) << 56) | \ - (((uint64_t)(x) << 40) & 0xff000000000000ULL) | \ - (((uint64_t)(x) << 24) & 0xff0000000000ULL) | \ - (((uint64_t)(x) << 8) & 0xff00000000ULL) | \ - (((uint64_t)(x) >> 8) & 0xff000000ULL) | \ - (((uint64_t)(x) >> 24) & 0xff0000ULL) | \ - (((uint64_t)(x) >> 40) & 0xff00ULL) | \ - ((uint64_t)(x) >> 56)); -} - -void pcilib_swap(void *dst, void *src, size_t size, size_t n) { - int i; - switch (size) { - case 1: - if (src != dst) memcpy(dst, src, n); - break; - case 2: - for (i = 0; i < n; i++) { - ((uint16_t*)dst)[i] = pcilib_swap16(((uint16_t*)src)[i]); - } - break; - case 4: - for (i = 0; i < n; i++) { - ((uint32_t*)dst)[i] = pcilib_swap32(((uint32_t*)src)[i]); - } - break; - case 8: - for (i = 0; i < n; i++) { - ((uint64_t*)dst)[i] = pcilib_swap64(((uint64_t*)src)[i]); - } - break; - default: - pcilib_error("Invalid word size: %i", size); - } -} - -void *pcilib_memcpy8(void * dst, void const * src, size_t len) { - int i; - for (i = 0; i < len; i++) ((char*)dst)[i] = ((char*)src)[i]; - return dst; -} - -void *pcilib_memcpy32(void * dst, void const * src, size_t len) { - uint32_t * plDst = (uint32_t *) dst; - uint32_t const * plSrc = (uint32_t const *) src; - - while (len >= 4) { -// *plDst = ntohl(*plSrc); - *plDst = *plSrc; - plSrc++; - plDst++; - len -= 4; - } - - char * pcDst = (char *) plDst; - char const * pcSrc = (char const *) plSrc; - - while (len--) { - *pcDst++ = *pcSrc++; - } - - return (dst); -} - - -void *pcilib_memcpy64(void * dst, void const * src, size_t len) { - uint64_t * plDst = (uint64_t *) dst; - uint64_t const * plSrc = (uint64_t const *) src; - - while (len >= 8) { - *plDst++ = *plSrc++; - len -= 8; - } - - char * pcDst = (char *) plDst; - char const * pcSrc = (char const *) plSrc; - - while (len--) { - *pcDst++ = *pcSrc++; - } - - return (dst); -} - -/* -void *memcpy128(void * dst, void const * src, size_t len) { - - long pos = - (len>>2); - char * plDst = (char *) dst - 4 * pos; - char const * plSrc = (char const *) src - 4 * pos; - - if (pos) { - __asm__ __volatile__ ( - "1: \n\t" - "mov (%0,%2,4), %%edi \n\t" - "mov %%edi, (%1,%2,4) \n\t" - "inc %2 \n\t" - "jnz 1b \n\t" - : - : "r" (plSrc), "r" (plDst), "r" (pos) - : "%edi" - ); - } - - - - long pos = - ((len>>4)<<4); - char * plDst = (char *) dst - pos; - char const * plSrc = (char const *) src - pos; - - if (pos) { - __asm__ __volatile__ ( - "1: \n\t" -// "movdqa (%0,%2), %%xmm0 \n\t" - "mov (%0,%2), %%esi \n\t" - "movd %%esi, %%xmm0 \n\t" - "mov 4(%0,%2), %%esi \n\t" - "movd %%esi, %%xmm1 \n\t" - "mov 8(%0,%2), %%esi \n\t" - "movd %%esi, %%xmm2 \n\t" - "mov 12(%0,%2), %%esi \n\t" - "movd %%esi, %%xmm3 \n\t" - "pslldq $4, %%xmm1 \n\t" - "por %%xmm1, %%xmm0 \n\t" - "pslldq $8, %%xmm2 \n\t" - "por %%xmm2, %%xmm0 \n\t" - "pslldq $12, %%xmm3 \n\t" - "por %%xmm3, %%xmm0 \n\t" - - "movntdq %%xmm0, (%1,%2) \n\t" - "add $16, %2 \n\t" - "jnz 1b \n\t" - : - : "r" (plSrc), "r" (plDst), "r" (pos) - : "%rsi" - ); - } - - - - len &= 0x3; - - char * pcDst = (char *) plDst; - char const * pcSrc = (char const *) plSrc; - - while (len--) { - *pcDst++ = *pcSrc++; - } - - return (dst); -} -*/ - -void *pcilib_datacpy32(void * dst, void const * src, uint8_t size, size_t n, pcilib_endianess_t endianess) { - uint32_t * plDst = (uint32_t *) dst; - uint32_t const * plSrc = (uint32_t const *) src; - - int swap = 0; - - if (endianess) - swap = (endianess == PCILIB_BIG_ENDIAN)?(ntohs(1)!=1):(ntohs(1)==1); - - assert(size == 4); // only 32 bit at the moment - - if (swap) { - while (n > 0) { - *plDst = ntohl(*plSrc); - ++plSrc; - ++plDst; - --n; - } - } else { - while (n > 0) { - *plDst = *plSrc; - ++plSrc; - ++plDst; - --n; - } - } - - return dst; -} - -int pcilib_get_page_mask() { - int pagesize,pagemask,temp; - - pagesize = sysconf(_SC_PAGESIZE); - - for( pagemask=0, temp = pagesize; temp != 1; ) { - temp = (temp >> 1); - pagemask = (pagemask << 1)+1; - } - return pagemask; -} - -int pcilib_get_cpu_count() { - int err; - - int cpu_count; - cpu_set_t mask; - - err = sched_getaffinity(getpid(), sizeof(mask), &mask); - if (err) return 1; - -#ifdef CPU_COUNT - cpu_count = CPU_COUNT(&mask); -#else - for (cpu_count = 0; cpu_count < CPU_SETSIZE; cpu_count++) { - if (!CPU_ISSET(cpu_count, &mask)) break; - } -#endif - - if (!cpu_count) cpu_count = PCILIB_DEFAULT_CPU_COUNT; - return cpu_count; -} - - -int pcilib_add_timeout(struct timeval *tv, pcilib_timeout_t timeout) { - tv->tv_usec += timeout%1000000; - if (tv->tv_usec > 999999) { - tv->tv_usec -= 1000000; - tv->tv_sec += 1 + timeout/1000000; - } else { - tv->tv_sec += timeout/1000000; - } - - return 0; -} - -int pcilib_calc_deadline(struct timeval *tv, pcilib_timeout_t timeout) { - gettimeofday(tv, NULL); - pcilib_add_timeout(tv, timeout); - - return 0; -} - -int pcilib_check_deadline(struct timeval *tve, pcilib_timeout_t timeout) { - int64_t res; - struct timeval tvs; - - if (!tve->tv_sec) return 0; - - gettimeofday(&tvs, NULL); - res = ((tve->tv_sec - tvs.tv_sec)*1000000 + (tve->tv_usec - tvs.tv_usec)); - // Hm... Some problems comparing signed and unsigned. So, sign check first - if ((res < 0)||(res < timeout)) { - return 1; - } - - return 0; -} - -pcilib_timeout_t pcilib_calc_time_to_deadline(struct timeval *tve) { - int64_t res; - struct timeval tvs; - - gettimeofday(&tvs, NULL); - res = ((tve->tv_sec - tvs.tv_sec)*1000000 + (tve->tv_usec - tvs.tv_usec)); - - if (res < 0) return 0; - return res; -} - -int pcilib_sleep_until_deadline(struct timeval *tv) { - struct timespec wait; - pcilib_timeout_t duration; - - duration = pcilib_calc_time_to_deadline(tv); - if (duration > 0) { - wait.tv_sec = duration / 1000000; - wait.tv_nsec = 1000 * (duration % 1000000); - nanosleep(&wait, NULL); - } - - return 0; -} - -pcilib_timeout_t pcilib_timediff(struct timeval *tvs, struct timeval *tve) { - return ((tve->tv_sec - tvs->tv_sec)*1000000 + (tve->tv_usec - tvs->tv_usec)); -} - -int pcilib_timecmp(struct timeval *tv1, struct timeval *tv2) { - if (tv1->tv_sec > tv2->tv_sec) return 1; - else if (tv1->tv_sec < tv2->tv_sec) return -1; - else if (tv1->tv_usec > tv2->tv_usec) return 1; - else if (tv1->tv_usec < tv2->tv_usec) return -1; - return 0; -} diff --git a/tools.h b/tools.h deleted file mode 100644 index 28f8b0a..0000000 --- a/tools.h +++ /dev/null @@ -1,46 +0,0 @@ -#ifndef _PCITOOL_TOOLS_H -#define _PCITOOL_TOOLS_H - -#include <stdio.h> -#include <stdint.h> - -#define BIT_MASK(bits) ((1ll << (bits)) - 1) - -#define min2(a, b) (((a)<(b))?(a):(b)) - -typedef enum { - PCILIB_TRISTATE_NO = 0, - PCILIB_TRISTATE_PARTIAL = 1, - PCILIB_TRISTATE_YES = 2 -} pcilib_tristate_t; - -#include "pci.h" - -int pcilib_isnumber(const char *str); -int pcilib_isxnumber(const char *str); -int pcilib_isnumber_n(const char *str, size_t len); -int pcilib_isxnumber_n(const char *str, size_t len); - -uint16_t pcilib_swap16(uint16_t x); -uint32_t pcilib_swap32(uint32_t x); -uint64_t pcilib_swap64(uint64_t x); -void pcilib_swap(void *dst, void *src, size_t size, size_t n); - -void * pcilib_memcpy8(void * dst, void const * src, size_t len); -void * pcilib_memcpy32(void * dst, void const * src, size_t len); -void * pcilib_memcpy64(void * dst, void const * src, size_t len); -void * pcilib_datacpy32(void * dst, void const * src, uint8_t size, size_t n, pcilib_endianess_t endianess); - -int pcilib_get_page_mask(); -int pcilib_get_cpu_count(); - - -int pcilib_add_timeout(struct timeval *tv, pcilib_timeout_t timeout); -int pcilib_calc_deadline(struct timeval *tv, pcilib_timeout_t timeout); -int pcilib_check_deadline(struct timeval *tve, pcilib_timeout_t timeout); -pcilib_timeout_t pcilib_calc_time_to_deadline(struct timeval *tve); -int pcilib_sleep_until_deadline(struct timeval *tv); -int pcilib_timecmp(struct timeval *tv1, struct timeval *tv2); -pcilib_timeout_t pcilib_timediff(struct timeval *tve, struct timeval *tvs); - -#endif /* _PCITOOL_TOOS_H */ |