From c39ac7a604d9f01f602f88f5770b5832e79fcdde Mon Sep 17 00:00:00 2001 From: "Suren A. Chilingaryan" Date: Tue, 5 May 2015 17:09:46 +0200 Subject: Add doxygen configuration --- .bzrignore | 2 + BUGS | 5 - CMakeLists.txt | 6 +- NOTES | 311 ----------------------------------------------------- README | 11 -- ToDo | 23 ---- docs/BUGS | 5 + docs/Doxyfile.in | 209 +++++++++++++++++++++++++++++++++++ docs/NOTES | 311 +++++++++++++++++++++++++++++++++++++++++++++++++++++ docs/README | 11 ++ docs/ToDo | 23 ++++ misc/pcitool.pc.in | 12 +++ pcitool.pc.in | 12 --- 13 files changed, 577 insertions(+), 364 deletions(-) delete mode 100644 BUGS delete mode 100644 NOTES delete mode 100644 README delete mode 100644 ToDo create mode 100644 docs/BUGS create mode 100644 docs/Doxyfile.in create mode 100644 docs/NOTES create mode 100644 docs/README create mode 100644 docs/ToDo create mode 100644 misc/pcitool.pc.in delete mode 100644 pcitool.pc.in diff --git a/.bzrignore b/.bzrignore index 5f9fdaa..fdc70db 100644 --- a/.bzrignore +++ b/.bzrignore @@ -29,3 +29,5 @@ pcitool.pc config.h pcitool/pci version.h +Doxyfile +html diff --git a/BUGS b/BUGS deleted file mode 100644 index 4b0c1cc..0000000 --- a/BUGS +++ /dev/null @@ -1,5 +0,0 @@ -IPECamera Hardware Bugs -======================= - 1. Strange sequence writting CMOSIS registers - 2. Sometimes during DMA streaming register accesses fail - 3. The lower 12-bit of bus address are ignored by all hardware diff --git a/CMakeLists.txt b/CMakeLists.txt index aa64112..f397c6b 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -65,14 +65,16 @@ endif(NOT DEFINED LOCALE_INSTALL_DIR) set(PCILIB_PLUGIN_DIR "${LIB_INSTALL_DIR}/pcilib" CACHE PATH "Directory to install plugins") set(PCILIB_DATA_DIR "${DATA_INSTALL_DIR}/pcilib" CACHE PATH "Directory to install data files") set(PCILIB_MODEL_DIR "${PCILIB_DATA_DIR}/models" CACHE PATH "Directory to install XML models") +set(PCILIB_DOC_DIR "${CMAKE_CURRENT_BINARY_DIR}/docs/" CACHE PATH "Directory to install documentation") set(PCILIB_DEBUG_DIR "." CACHE PATH "Directory to write debug information") -configure_file(${CMAKE_CURRENT_SOURCE_DIR}/pcitool.pc.in ${CMAKE_CURRENT_BINARY_DIR}/pcitool.pc) +configure_file(${CMAKE_CURRENT_SOURCE_DIR}/misc/pcitool.pc.in ${CMAKE_CURRENT_BINARY_DIR}/misc/pcitool.pc) configure_file(${CMAKE_CURRENT_SOURCE_DIR}/pcilib/config.h.in ${CMAKE_CURRENT_BINARY_DIR}/pcilib/config.h) configure_file(${CMAKE_CURRENT_SOURCE_DIR}/pcilib/version.h.in ${CMAKE_CURRENT_BINARY_DIR}/pcilib/version.h) +configure_file(${CMAKE_CURRENT_SOURCE_DIR}/docs/Doxyfile.in ${CMAKE_CURRENT_BINARY_DIR}/docs/Doxyfile) install(FILES - ${CMAKE_CURRENT_BINARY_DIR}/pcitool.pc + ${CMAKE_CURRENT_BINARY_DIR}/misc/pcitool.pc DESTINATION ${LIB_INSTALL_DIR}/pkgconfig ) diff --git a/NOTES b/NOTES deleted file mode 100644 index d87bbfc..0000000 --- a/NOTES +++ /dev/null @@ -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 = on = 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 diff --git a/README b/README deleted file mode 100644 index 1cbf8ee..0000000 --- a/README +++ /dev/null @@ -1,11 +0,0 @@ -Supported environmental variables -================================= - PCILIB_PLUGIN_DIR - override path to directory with plugins - - PCILIB_DEBUG_DMA - Enable DMA debugging - PCILIB_DEBUG_MISSING_EVENTS - Enable debugging of missing events (frames for instance) - IPECAMERA_DEBUG_BROKEN_FRAMES - Store broken frames in the specified directory (variable may specify directory) - IPECAMERA_DEBUG_RAW_PACKETS - Store all raw packets read from DMA grouped in frames (variable may specify directory) - IPECAMERA_DEBUG_RAW_FRAMES - Store all raw frames (variable may specify directory) - IPECAMERA_DEBUG_HARDWARE - Produce various debugging information about ipecamera operation - \ No newline at end of file diff --git a/ToDo b/ToDo deleted file mode 100644 index 4c2c783..0000000 --- a/ToDo +++ /dev/null @@ -1,23 +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. Protect mmap operation (multiple kernel calls) with some locking mechanism - 4. Allow overriding of registers and banks (performance?). - -Normal Priority (it would make just few things a bit easier) -=============== - 1. Implement software registers (stored in kernel-memory) - 2. Implement pcilib_configure_autotrigger - 3. Provide OR and AND operations on registers in cli - 4. Support writting a data from a binary file in cli - -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 - 6. Support FIFO reads/writes from/to registers - diff --git a/docs/BUGS b/docs/BUGS new file mode 100644 index 0000000..4b0c1cc --- /dev/null +++ b/docs/BUGS @@ -0,0 +1,5 @@ +IPECamera Hardware Bugs +======================= + 1. Strange sequence writting CMOSIS registers + 2. Sometimes during DMA streaming register accesses fail + 3. The lower 12-bit of bus address are ignored by all hardware diff --git a/docs/Doxyfile.in b/docs/Doxyfile.in new file mode 100644 index 0000000..1910d8b --- /dev/null +++ b/docs/Doxyfile.in @@ -0,0 +1,209 @@ +# Doxyfile 1.3.3 + +#--------------------------------------------------------------------------- +# General configuration options +#--------------------------------------------------------------------------- +PROJECT_NAME = pcilib +PROJECT_NUMBER = +OUTPUT_DIRECTORY = ${PCILIB_DOC_DIR} +OUTPUT_LANGUAGE = English +USE_WINDOWS_ENCODING = NO +EXTRACT_ALL = YES +EXTRACT_PRIVATE = NO +EXTRACT_STATIC = NO +EXTRACT_LOCAL_CLASSES = YES +HIDE_UNDOC_MEMBERS = NO +HIDE_UNDOC_CLASSES = NO +HIDE_FRIEND_COMPOUNDS = NO +HIDE_IN_BODY_DOCS = NO +BRIEF_MEMBER_DESC = YES +REPEAT_BRIEF = YES +ALWAYS_DETAILED_SEC = NO +INLINE_INHERITED_MEMB = NO +FULL_PATH_NAMES = NO +STRIP_FROM_PATH = +INTERNAL_DOCS = NO +CASE_SENSE_NAMES = YES +SHORT_NAMES = NO +HIDE_SCOPE_NAMES = NO +SHOW_INCLUDE_FILES = YES +JAVADOC_AUTOBRIEF = NO +MULTILINE_CPP_IS_BRIEF = NO +DETAILS_AT_TOP = NO +INHERIT_DOCS = YES +INLINE_INFO = YES +SORT_MEMBER_DOCS = YES +DISTRIBUTE_GROUP_DOC = NO +TAB_SIZE = 8 +GENERATE_TODOLIST = YES +GENERATE_TESTLIST = YES +GENERATE_BUGLIST = YES +GENERATE_DEPRECATEDLIST= YES +ALIASES = +ENABLED_SECTIONS = +MAX_INITIALIZER_LINES = 30 +OPTIMIZE_OUTPUT_FOR_C = NO +OPTIMIZE_OUTPUT_JAVA = NO +SHOW_USED_FILES = YES +SUBGROUPING = YES +#--------------------------------------------------------------------------- +# configuration options related to warning and progress messages +#--------------------------------------------------------------------------- +QUIET = NO +WARNINGS = YES +WARN_IF_UNDOCUMENTED = NO +WARN_IF_DOC_ERROR = YES +WARN_FORMAT = "$file:$line: $text" +WARN_LOGFILE = +#--------------------------------------------------------------------------- +# configuration options related to the input files +#--------------------------------------------------------------------------- +INPUT = ${CMAKE_SOURCE_DIR}/pcilib/ +FILE_PATTERNS = *.h \ + *.c +RECURSIVE = NO +EXCLUDE = +EXCLUDE_SYMLINKS = NO +EXCLUDE_PATTERNS = +EXAMPLE_PATH = +EXAMPLE_PATTERNS = +EXAMPLE_RECURSIVE = NO +IMAGE_PATH = +INPUT_FILTER = +FILTER_SOURCE_FILES = NO +#--------------------------------------------------------------------------- +# configuration options related to source browsing +#--------------------------------------------------------------------------- +SOURCE_BROWSER = NO +INLINE_SOURCES = YES +STRIP_CODE_COMMENTS = YES +REFERENCED_BY_RELATION = YES +REFERENCES_RELATION = YES +VERBATIM_HEADERS = YES +#--------------------------------------------------------------------------- +# configuration options related to the alphabetical class index +#--------------------------------------------------------------------------- +ALPHABETICAL_INDEX = NO +COLS_IN_ALPHA_INDEX = 5 +IGNORE_PREFIX = +#--------------------------------------------------------------------------- +# configuration options related to the HTML output +#--------------------------------------------------------------------------- +GENERATE_HTML = YES +HTML_OUTPUT = html +HTML_FILE_EXTENSION = .html +HTML_HEADER = +HTML_FOOTER = +HTML_STYLESHEET = +HTML_ALIGN_MEMBERS = YES +GENERATE_HTMLHELP = NO +CHM_FILE = +HHC_LOCATION = +GENERATE_CHI = NO +BINARY_TOC = NO +TOC_EXPAND = NO +DISABLE_INDEX = NO +ENUM_VALUES_PER_LINE = 4 +GENERATE_TREEVIEW = NO +TREEVIEW_WIDTH = 250 +#--------------------------------------------------------------------------- +# configuration options related to the LaTeX output +#--------------------------------------------------------------------------- +GENERATE_LATEX = NO +LATEX_OUTPUT = latex +LATEX_CMD_NAME = latex +MAKEINDEX_CMD_NAME = makeindex +COMPACT_LATEX = NO +PAPER_TYPE = a4wide +EXTRA_PACKAGES = +LATEX_HEADER = +PDF_HYPERLINKS = NO +USE_PDFLATEX = NO +LATEX_BATCHMODE = NO +LATEX_HIDE_INDICES = NO +#--------------------------------------------------------------------------- +# configuration options related to the RTF output +#--------------------------------------------------------------------------- +GENERATE_RTF = NO +RTF_OUTPUT = rtf +COMPACT_RTF = NO +RTF_HYPERLINKS = NO +RTF_STYLESHEET_FILE = +RTF_EXTENSIONS_FILE = +#--------------------------------------------------------------------------- +# configuration options related to the man page output +#--------------------------------------------------------------------------- +GENERATE_MAN = NO +MAN_OUTPUT = man +MAN_EXTENSION = .3 +MAN_LINKS = NO +#--------------------------------------------------------------------------- +# configuration options related to the XML output +#--------------------------------------------------------------------------- +GENERATE_XML = NO +XML_OUTPUT = xml +XML_SCHEMA = +XML_DTD = +#--------------------------------------------------------------------------- +# configuration options for the AutoGen Definitions output +#--------------------------------------------------------------------------- +GENERATE_AUTOGEN_DEF = NO +#--------------------------------------------------------------------------- +# configuration options related to the Perl module output +#--------------------------------------------------------------------------- +GENERATE_PERLMOD = NO +PERLMOD_LATEX = NO +PERLMOD_PRETTY = YES +PERLMOD_MAKEVAR_PREFIX = +#--------------------------------------------------------------------------- +# Configuration options related to the preprocessor +#--------------------------------------------------------------------------- +ENABLE_PREPROCESSING = YES +MACRO_EXPANSION = NO +EXPAND_ONLY_PREDEF = NO +SEARCH_INCLUDES = YES +INCLUDE_PATH = +INCLUDE_FILE_PATTERNS = +PREDEFINED = +EXPAND_AS_DEFINED = +SKIP_FUNCTION_MACROS = YES +#--------------------------------------------------------------------------- +# Configuration::addtions related to external references +#--------------------------------------------------------------------------- +TAGFILES = +GENERATE_TAGFILE = +ALLEXTERNALS = NO +EXTERNAL_GROUPS = YES +PERL_PATH = /usr/bin/perl +#--------------------------------------------------------------------------- +# Configuration options related to the dot tool +#--------------------------------------------------------------------------- +CLASS_DIAGRAMS = YES +HIDE_UNDOC_RELATIONS = YES +HAVE_DOT = NO +CLASS_GRAPH = YES +COLLABORATION_GRAPH = YES +UML_LOOK = NO +TEMPLATE_RELATIONS = NO +INCLUDE_GRAPH = YES +INCLUDED_BY_GRAPH = YES +CALL_GRAPH = NO +GRAPHICAL_HIERARCHY = YES +DOT_IMAGE_FORMAT = png +DOT_PATH = +DOTFILE_DIRS = +MAX_DOT_GRAPH_WIDTH = 1024 +MAX_DOT_GRAPH_HEIGHT = 1024 +MAX_DOT_GRAPH_DEPTH = 0 +GENERATE_LEGEND = YES +DOT_CLEANUP = YES +#--------------------------------------------------------------------------- +# Configuration::addtions related to the search engine +#--------------------------------------------------------------------------- +SEARCHENGINE = NO +CGI_NAME = search.cgi +CGI_URL = +DOC_URL = +DOC_ABSPATH = +BIN_ABSPATH = /usr/local/bin/ +EXT_DOC_PATHS = diff --git a/docs/NOTES b/docs/NOTES new file mode 100644 index 0000000..d87bbfc --- /dev/null +++ b/docs/NOTES @@ -0,0 +1,311 @@ +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 = on = 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 diff --git a/docs/README b/docs/README new file mode 100644 index 0000000..1cbf8ee --- /dev/null +++ b/docs/README @@ -0,0 +1,11 @@ +Supported environmental variables +================================= + PCILIB_PLUGIN_DIR - override path to directory with plugins + + PCILIB_DEBUG_DMA - Enable DMA debugging + PCILIB_DEBUG_MISSING_EVENTS - Enable debugging of missing events (frames for instance) + IPECAMERA_DEBUG_BROKEN_FRAMES - Store broken frames in the specified directory (variable may specify directory) + IPECAMERA_DEBUG_RAW_PACKETS - Store all raw packets read from DMA grouped in frames (variable may specify directory) + IPECAMERA_DEBUG_RAW_FRAMES - Store all raw frames (variable may specify directory) + IPECAMERA_DEBUG_HARDWARE - Produce various debugging information about ipecamera operation + \ No newline at end of file diff --git a/docs/ToDo b/docs/ToDo new file mode 100644 index 0000000..4c2c783 --- /dev/null +++ b/docs/ToDo @@ -0,0 +1,23 @@ +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. Protect mmap operation (multiple kernel calls) with some locking mechanism + 4. Allow overriding of registers and banks (performance?). + +Normal Priority (it would make just few things a bit easier) +=============== + 1. Implement software registers (stored in kernel-memory) + 2. Implement pcilib_configure_autotrigger + 3. Provide OR and AND operations on registers in cli + 4. Support writting a data from a binary file in cli + +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 + 6. Support FIFO reads/writes from/to registers + diff --git a/misc/pcitool.pc.in b/misc/pcitool.pc.in new file mode 100644 index 0000000..7261c5f --- /dev/null +++ b/misc/pcitool.pc.in @@ -0,0 +1,12 @@ +prefix=${CMAKE_INSTALL_PREFIX} +exec_prefix=${BIN_INSTALL_DIR} +libdir=${LIB_INSTALL_DIR} +includedir=${INCLUDE_INSTALL_DIR} +plugindir=${PCILIB_PLUGIN_DIR} +modeldir=${PCILIB_MODEL_DIR} + +Name: ${TARNAME} +Description: User-space library to handle PCIe-devices +Version: ${PACKAGE_VERSION} +Libs: -L${LIB_INSTALL_DIR} -lpcilib +Cflags: -I${INCLUDE_INSTALL_DIR} diff --git a/pcitool.pc.in b/pcitool.pc.in deleted file mode 100644 index 7261c5f..0000000 --- a/pcitool.pc.in +++ /dev/null @@ -1,12 +0,0 @@ -prefix=${CMAKE_INSTALL_PREFIX} -exec_prefix=${BIN_INSTALL_DIR} -libdir=${LIB_INSTALL_DIR} -includedir=${INCLUDE_INSTALL_DIR} -plugindir=${PCILIB_PLUGIN_DIR} -modeldir=${PCILIB_MODEL_DIR} - -Name: ${TARNAME} -Description: User-space library to handle PCIe-devices -Version: ${PACKAGE_VERSION} -Libs: -L${LIB_INSTALL_DIR} -lpcilib -Cflags: -I${INCLUDE_INSTALL_DIR} -- cgit v1.2.3