From c2740578404b4e46d198de70af1cfd554033d99f Mon Sep 17 00:00:00 2001 From: Andreas Sandberg Date: Tue, 7 Jul 2015 10:03:13 +0100 Subject: ext: Add the NoMali GPU no-simulation library Add revision 9adf9d6e2d889a483a92136c96eb8a434d360561 of NoMali-model from https://github.com/ARM-software/nomali-model. This library implements the register interface of the Mali T6xx/T7xx series GPUs, but doesn't do any rendering. It can be used to hide the effects of software rendering. --- ext/nomali/.gitignore | 8 + ext/nomali/Doxyfile | 1785 ++++++++++++++++++++++++++++++++ ext/nomali/LICENSE | 202 ++++ ext/nomali/Makefile | 81 ++ ext/nomali/Rules.app.mk | 31 + ext/nomali/Rules.lib.mk | 31 + ext/nomali/SConscript | 63 ++ ext/nomali/doxygen.sed | 46 + ext/nomali/include/libnomali/nomali.h | 333 ++++++ ext/nomali/lib/Rules.mk | 55 + ext/nomali/lib/gpu.cc | 112 ++ ext/nomali/lib/gpu.hh | 205 ++++ ext/nomali/lib/gpublock.cc | 156 +++ ext/nomali/lib/gpublock.hh | 221 ++++ ext/nomali/lib/gpucontrol.cc | 177 ++++ ext/nomali/lib/gpucontrol.hh | 159 +++ ext/nomali/lib/jobcontrol.cc | 139 +++ ext/nomali/lib/jobcontrol.hh | 93 ++ ext/nomali/lib/jobslot.cc | 216 ++++ ext/nomali/lib/jobslot.hh | 208 ++++ ext/nomali/lib/mali_midg_regmap.h | 510 +++++++++ ext/nomali/lib/mali_midgard.cc | 92 ++ ext/nomali/lib/mali_midgard.hh | 70 ++ ext/nomali/lib/mali_t6xx.cc | 55 + ext/nomali/lib/mali_t6xx.hh | 61 ++ ext/nomali/lib/mali_t7xx.cc | 50 + ext/nomali/lib/mali_t7xx.hh | 50 + ext/nomali/lib/mmu.cc | 64 ++ ext/nomali/lib/mmu.hh | 57 + ext/nomali/lib/nomali_api.cc | 355 +++++++ ext/nomali/lib/regutils.hh | 103 ++ ext/nomali/lib/types.hh | 218 ++++ ext/nomali/tests/Rules.mk | 44 + ext/nomali/tests/nomali_test0.c | 53 + ext/nomali/tests/nomali_test_helpers.h | 46 + ext/nomali/tests/nomali_test_ints.c | 127 +++ ext/nomali/tests/test_helpers.c | 147 +++ ext/nomali/tests/test_helpers.h | 57 + 38 files changed, 6480 insertions(+) create mode 100644 ext/nomali/.gitignore create mode 100644 ext/nomali/Doxyfile create mode 100644 ext/nomali/LICENSE create mode 100644 ext/nomali/Makefile create mode 100644 ext/nomali/Rules.app.mk create mode 100644 ext/nomali/Rules.lib.mk create mode 100644 ext/nomali/SConscript create mode 100755 ext/nomali/doxygen.sed create mode 100644 ext/nomali/include/libnomali/nomali.h create mode 100644 ext/nomali/lib/Rules.mk create mode 100644 ext/nomali/lib/gpu.cc create mode 100644 ext/nomali/lib/gpu.hh create mode 100644 ext/nomali/lib/gpublock.cc create mode 100644 ext/nomali/lib/gpublock.hh create mode 100644 ext/nomali/lib/gpucontrol.cc create mode 100644 ext/nomali/lib/gpucontrol.hh create mode 100644 ext/nomali/lib/jobcontrol.cc create mode 100644 ext/nomali/lib/jobcontrol.hh create mode 100644 ext/nomali/lib/jobslot.cc create mode 100644 ext/nomali/lib/jobslot.hh create mode 100644 ext/nomali/lib/mali_midg_regmap.h create mode 100644 ext/nomali/lib/mali_midgard.cc create mode 100644 ext/nomali/lib/mali_midgard.hh create mode 100644 ext/nomali/lib/mali_t6xx.cc create mode 100644 ext/nomali/lib/mali_t6xx.hh create mode 100644 ext/nomali/lib/mali_t7xx.cc create mode 100644 ext/nomali/lib/mali_t7xx.hh create mode 100644 ext/nomali/lib/mmu.cc create mode 100644 ext/nomali/lib/mmu.hh create mode 100644 ext/nomali/lib/nomali_api.cc create mode 100644 ext/nomali/lib/regutils.hh create mode 100644 ext/nomali/lib/types.hh create mode 100644 ext/nomali/tests/Rules.mk create mode 100644 ext/nomali/tests/nomali_test0.c create mode 100644 ext/nomali/tests/nomali_test_helpers.h create mode 100644 ext/nomali/tests/nomali_test_ints.c create mode 100644 ext/nomali/tests/test_helpers.c create mode 100644 ext/nomali/tests/test_helpers.h (limited to 'ext') diff --git a/ext/nomali/.gitignore b/ext/nomali/.gitignore new file mode 100644 index 000000000..dc9c05a07 --- /dev/null +++ b/ext/nomali/.gitignore @@ -0,0 +1,8 @@ +/docs +/tests/nomali_test0 +/tests/nomali_test_ints +*~ +*.o +*.d +*.so +*.a diff --git a/ext/nomali/Doxyfile b/ext/nomali/Doxyfile new file mode 100644 index 000000000..607f82aab --- /dev/null +++ b/ext/nomali/Doxyfile @@ -0,0 +1,1785 @@ +# Doxyfile 1.7.6.1 + +# This file describes the settings to be used by the documentation system +# doxygen (www.doxygen.org) for a project. +# +# All text after a hash (#) is considered a comment and will be ignored. +# The format is: +# TAG = value [value, ...] +# For lists items can also be appended using: +# TAG += value [value, ...] +# Values that contain spaces should be placed between quotes (" "). + +#--------------------------------------------------------------------------- +# Project related configuration options +#--------------------------------------------------------------------------- + +# This tag specifies the encoding used for all characters in the config file +# that follow. The default is UTF-8 which is also the encoding used for all +# text before the first occurrence of this tag. Doxygen uses libiconv (or the +# iconv built into libc) for the transcoding. See +# http://www.gnu.org/software/libiconv for the list of possible encodings. + +DOXYFILE_ENCODING = UTF-8 + +# The PROJECT_NAME tag is a single word (or sequence of words) that should +# identify the project. Note that if you do not use Doxywizard you need +# to put quotes around the project name if it contains spaces. + +PROJECT_NAME = "NoMali Device Model" + +# The PROJECT_NUMBER tag can be used to enter a project or revision number. +# This could be handy for archiving the generated documentation or +# if some version control system is used. + +PROJECT_NUMBER = + +# Using the PROJECT_BRIEF tag one can provide an optional one line description +# for a project that appears at the top of each page and should give viewer +# a quick idea about the purpose of the project. Keep the description short. + +PROJECT_BRIEF = + +# With the PROJECT_LOGO tag one can specify an logo or icon that is +# included in the documentation. The maximum height of the logo should not +# exceed 55 pixels and the maximum width should not exceed 200 pixels. +# Doxygen will copy the logo to the output directory. + +PROJECT_LOGO = + +# The OUTPUT_DIRECTORY tag is used to specify the (relative or absolute) +# base path where the generated documentation will be put. +# If a relative path is entered, it will be relative to the location +# where doxygen was started. If left blank the current directory will be used. + +OUTPUT_DIRECTORY = docs/ + +# If the CREATE_SUBDIRS tag is set to YES, then doxygen will create +# 4096 sub-directories (in 2 levels) under the output directory of each output +# format and will distribute the generated files over these directories. +# Enabling this option can be useful when feeding doxygen a huge amount of +# source files, where putting all generated files in the same directory would +# otherwise cause performance problems for the file system. + +CREATE_SUBDIRS = NO + +# The OUTPUT_LANGUAGE tag is used to specify the language in which all +# documentation generated by doxygen is written. Doxygen will use this +# information to generate all constant output in the proper language. +# The default language is English, other supported languages are: +# Afrikaans, Arabic, Brazilian, Catalan, Chinese, Chinese-Traditional, +# Croatian, Czech, Danish, Dutch, Esperanto, Farsi, Finnish, French, German, +# Greek, Hungarian, Italian, Japanese, Japanese-en (Japanese with English +# messages), Korean, Korean-en, Lithuanian, Norwegian, Macedonian, Persian, +# Polish, Portuguese, Romanian, Russian, Serbian, Serbian-Cyrillic, Slovak, +# Slovene, Spanish, Swedish, Ukrainian, and Vietnamese. + +OUTPUT_LANGUAGE = English + +# If the BRIEF_MEMBER_DESC tag is set to YES (the default) Doxygen will +# include brief member descriptions after the members that are listed in +# the file and class documentation (similar to JavaDoc). +# Set to NO to disable this. + +BRIEF_MEMBER_DESC = YES + +# If the REPEAT_BRIEF tag is set to YES (the default) Doxygen will prepend +# the brief description of a member or function before the detailed description. +# Note: if both HIDE_UNDOC_MEMBERS and BRIEF_MEMBER_DESC are set to NO, the +# brief descriptions will be completely suppressed. + +REPEAT_BRIEF = YES + +# This tag implements a quasi-intelligent brief description abbreviator +# that is used to form the text in various listings. Each string +# in this list, if found as the leading text of the brief description, will be +# stripped from the text and the result after processing the whole list, is +# used as the annotated text. Otherwise, the brief description is used as-is. +# If left blank, the following values are used ("$name" is automatically +# replaced with the name of the entity): "The $name class" "The $name widget" +# "The $name file" "is" "provides" "specifies" "contains" +# "represents" "a" "an" "the" + +ABBREVIATE_BRIEF = + +# If the ALWAYS_DETAILED_SEC and REPEAT_BRIEF tags are both set to YES then +# Doxygen will generate a detailed section even if there is only a brief +# description. + +ALWAYS_DETAILED_SEC = NO + +# If the INLINE_INHERITED_MEMB tag is set to YES, doxygen will show all +# inherited members of a class in the documentation of that class as if those +# members were ordinary class members. Constructors, destructors and assignment +# operators of the base classes will not be shown. + +INLINE_INHERITED_MEMB = NO + +# If the FULL_PATH_NAMES tag is set to YES then Doxygen will prepend the full +# path before files name in the file list and in the header files. If set +# to NO the shortest path that makes the file name unique will be used. + +FULL_PATH_NAMES = YES + +# If the FULL_PATH_NAMES tag is set to YES then the STRIP_FROM_PATH tag +# can be used to strip a user-defined part of the path. Stripping is +# only done if one of the specified strings matches the left-hand part of +# the path. The tag can be used to show relative paths in the file list. +# If left blank the directory from which doxygen is run is used as the +# path to strip. + +STRIP_FROM_PATH = + +# The STRIP_FROM_INC_PATH tag can be used to strip a user-defined part of +# the path mentioned in the documentation of a class, which tells +# the reader which header file to include in order to use a class. +# If left blank only the name of the header file containing the class +# definition is used. Otherwise one should specify the include paths that +# are normally passed to the compiler using the -I flag. + +STRIP_FROM_INC_PATH = + +# If the SHORT_NAMES tag is set to YES, doxygen will generate much shorter +# (but less readable) file names. This can be useful if your file system +# doesn't support long names like on DOS, Mac, or CD-ROM. + +SHORT_NAMES = NO + +# If the JAVADOC_AUTOBRIEF tag is set to YES then Doxygen +# will interpret the first line (until the first dot) of a JavaDoc-style +# comment as the brief description. If set to NO, the JavaDoc +# comments will behave just like regular Qt-style comments +# (thus requiring an explicit @brief command for a brief description.) + +JAVADOC_AUTOBRIEF = NO + +# If the QT_AUTOBRIEF tag is set to YES then Doxygen will +# interpret the first line (until the first dot) of a Qt-style +# comment as the brief description. If set to NO, the comments +# will behave just like regular Qt-style comments (thus requiring +# an explicit \brief command for a brief description.) + +QT_AUTOBRIEF = NO + +# The MULTILINE_CPP_IS_BRIEF tag can be set to YES to make Doxygen +# treat a multi-line C++ special comment block (i.e. a block of //! or /// +# comments) as a brief description. This used to be the default behaviour. +# The new default is to treat a multi-line C++ comment block as a detailed +# description. Set this tag to YES if you prefer the old behaviour instead. + +MULTILINE_CPP_IS_BRIEF = NO + +# If the INHERIT_DOCS tag is set to YES (the default) then an undocumented +# member inherits the documentation from any documented member that it +# re-implements. + +INHERIT_DOCS = YES + +# If the SEPARATE_MEMBER_PAGES tag is set to YES, then doxygen will produce +# a new page for each member. If set to NO, the documentation of a member will +# be part of the file/class/namespace that contains it. + +SEPARATE_MEMBER_PAGES = NO + +# The TAB_SIZE tag can be used to set the number of spaces in a tab. +# Doxygen uses this value to replace tabs by spaces in code fragments. + +TAB_SIZE = 8 + +# This tag can be used to specify a number of aliases that acts +# as commands in the documentation. An alias has the form "name=value". +# For example adding "sideeffect=\par Side Effects:\n" will allow you to +# put the command \sideeffect (or @sideeffect) in the documentation, which +# will result in a user-defined paragraph with heading "Side Effects:". +# You can put \n's in the value part of an alias to insert newlines. + +ALIASES = + +ALIASES += errors="\par Errors:" +ALIASES += error=" - \ref" + + +# This tag can be used to specify a number of word-keyword mappings (TCL only). +# A mapping has the form "name=value". For example adding +# "class=itcl::class" will allow you to use the command class in the +# itcl::class meaning. + +TCL_SUBST = + +# Set the OPTIMIZE_OUTPUT_FOR_C tag to YES if your project consists of C +# sources only. Doxygen will then generate output that is more tailored for C. +# For instance, some of the names that are used will be different. The list +# of all members will be omitted, etc. + +OPTIMIZE_OUTPUT_FOR_C = NO + +# Set the OPTIMIZE_OUTPUT_JAVA tag to YES if your project consists of Java +# sources only. Doxygen will then generate output that is more tailored for +# Java. For instance, namespaces will be presented as packages, qualified +# scopes will look different, etc. + +OPTIMIZE_OUTPUT_JAVA = NO + +# Set the OPTIMIZE_FOR_FORTRAN tag to YES if your project consists of Fortran +# sources only. Doxygen will then generate output that is more tailored for +# Fortran. + +OPTIMIZE_FOR_FORTRAN = NO + +# Set the OPTIMIZE_OUTPUT_VHDL tag to YES if your project consists of VHDL +# sources. Doxygen will then generate output that is tailored for +# VHDL. + +OPTIMIZE_OUTPUT_VHDL = NO + +# Doxygen selects the parser to use depending on the extension of the files it +# parses. With this tag you can assign which parser to use for a given extension. +# Doxygen has a built-in mapping, but you can override or extend it using this +# tag. The format is ext=language, where ext is a file extension, and language +# is one of the parsers supported by doxygen: IDL, Java, Javascript, CSharp, C, +# C++, D, PHP, Objective-C, Python, Fortran, VHDL, C, C++. For instance to make +# doxygen treat .inc files as Fortran files (default is PHP), and .f files as C +# (default is Fortran), use: inc=Fortran f=C. Note that for custom extensions +# you also need to set FILE_PATTERNS otherwise the files are not read by doxygen. + +EXTENSION_MAPPING = + +# If you use STL classes (i.e. std::string, std::vector, etc.) but do not want +# to include (a tag file for) the STL sources as input, then you should +# set this tag to YES in order to let doxygen match functions declarations and +# definitions whose arguments contain STL classes (e.g. func(std::string); v.s. +# func(std::string) {}). This also makes the inheritance and collaboration +# diagrams that involve STL classes more complete and accurate. + +BUILTIN_STL_SUPPORT = NO + +# If you use Microsoft's C++/CLI language, you should set this option to YES to +# enable parsing support. + +CPP_CLI_SUPPORT = NO + +# Set the SIP_SUPPORT tag to YES if your project consists of sip sources only. +# Doxygen will parse them like normal C++ but will assume all classes use public +# instead of private inheritance when no explicit protection keyword is present. + +SIP_SUPPORT = NO + +# For Microsoft's IDL there are propget and propput attributes to indicate getter +# and setter methods for a property. Setting this option to YES (the default) +# will make doxygen replace the get and set methods by a property in the +# documentation. This will only work if the methods are indeed getting or +# setting a simple type. If this is not the case, or you want to show the +# methods anyway, you should set this option to NO. + +IDL_PROPERTY_SUPPORT = YES + +# If member grouping is used in the documentation and the DISTRIBUTE_GROUP_DOC +# tag is set to YES, then doxygen will reuse the documentation of the first +# member in the group (if any) for the other members of the group. By default +# all members of a group must be documented explicitly. + +DISTRIBUTE_GROUP_DOC = NO + +# Set the SUBGROUPING tag to YES (the default) to allow class member groups of +# the same type (for instance a group of public functions) to be put as a +# subgroup of that type (e.g. under the Public Functions section). Set it to +# NO to prevent subgrouping. Alternatively, this can be done per class using +# the \nosubgrouping command. + +SUBGROUPING = YES + +# When the INLINE_GROUPED_CLASSES tag is set to YES, classes, structs and +# unions are shown inside the group in which they are included (e.g. using +# @ingroup) instead of on a separate page (for HTML and Man pages) or +# section (for LaTeX and RTF). + +INLINE_GROUPED_CLASSES = NO + +# When the INLINE_SIMPLE_STRUCTS tag is set to YES, structs, classes, and +# unions with only public data fields will be shown inline in the documentation +# of the scope in which they are defined (i.e. file, namespace, or group +# documentation), provided this scope is documented. If set to NO (the default), +# structs, classes, and unions are shown on a separate page (for HTML and Man +# pages) or section (for LaTeX and RTF). + +INLINE_SIMPLE_STRUCTS = NO + +# When TYPEDEF_HIDES_STRUCT is enabled, a typedef of a struct, union, or enum +# is documented as struct, union, or enum with the name of the typedef. So +# typedef struct TypeS {} TypeT, will appear in the documentation as a struct +# with name TypeT. When disabled the typedef will appear as a member of a file, +# namespace, or class. And the struct will be named TypeS. This can typically +# be useful for C code in case the coding convention dictates that all compound +# types are typedef'ed and only the typedef is referenced, never the tag name. + +TYPEDEF_HIDES_STRUCT = NO + +# The SYMBOL_CACHE_SIZE determines the size of the internal cache use to +# determine which symbols to keep in memory and which to flush to disk. +# When the cache is full, less often used symbols will be written to disk. +# For small to medium size projects (<1000 input files) the default value is +# probably good enough. For larger projects a too small cache size can cause +# doxygen to be busy swapping symbols to and from disk most of the time +# causing a significant performance penalty. +# If the system has enough physical memory increasing the cache will improve the +# performance by keeping more symbols in memory. Note that the value works on +# a logarithmic scale so increasing the size by one will roughly double the +# memory usage. The cache size is given by this formula: +# 2^(16+SYMBOL_CACHE_SIZE). The valid range is 0..9, the default is 0, +# corresponding to a cache size of 2^16 = 65536 symbols. + +SYMBOL_CACHE_SIZE = 0 + +# Similar to the SYMBOL_CACHE_SIZE the size of the symbol lookup cache can be +# set using LOOKUP_CACHE_SIZE. This cache is used to resolve symbols given +# their name and scope. Since this can be an expensive process and often the +# same symbol appear multiple times in the code, doxygen keeps a cache of +# pre-resolved symbols. If the cache is too small doxygen will become slower. +# If the cache is too large, memory is wasted. The cache size is given by this +# formula: 2^(16+LOOKUP_CACHE_SIZE). The valid range is 0..9, the default is 0, +# corresponding to a cache size of 2^16 = 65536 symbols. + +LOOKUP_CACHE_SIZE = 0 + +#--------------------------------------------------------------------------- +# Build related configuration options +#--------------------------------------------------------------------------- + +# If the EXTRACT_ALL tag is set to YES doxygen will assume all entities in +# documentation are documented, even if no documentation was available. +# Private class members and static file members will be hidden unless +# the EXTRACT_PRIVATE and EXTRACT_STATIC tags are set to YES + +EXTRACT_ALL = NO + +# If the EXTRACT_PRIVATE tag is set to YES all private members of a class +# will be included in the documentation. + +EXTRACT_PRIVATE = NO + +# If the EXTRACT_STATIC tag is set to YES all static members of a file +# will be included in the documentation. + +EXTRACT_STATIC = NO + +# If the EXTRACT_LOCAL_CLASSES tag is set to YES classes (and structs) +# defined locally in source files will be included in the documentation. +# If set to NO only classes defined in header files are included. + +EXTRACT_LOCAL_CLASSES = YES + +# This flag is only useful for Objective-C code. When set to YES local +# methods, which are defined in the implementation section but not in +# the interface are included in the documentation. +# If set to NO (the default) only methods in the interface are included. + +EXTRACT_LOCAL_METHODS = NO + +# If this flag is set to YES, the members of anonymous namespaces will be +# extracted and appear in the documentation as a namespace called +# 'anonymous_namespace{file}', where file will be replaced with the base +# name of the file that contains the anonymous namespace. By default +# anonymous namespaces are hidden. + +EXTRACT_ANON_NSPACES = NO + +# If the HIDE_UNDOC_MEMBERS tag is set to YES, Doxygen will hide all +# undocumented members of documented classes, files or namespaces. +# If set to NO (the default) these members will be included in the +# various overviews, but no documentation section is generated. +# This option has no effect if EXTRACT_ALL is enabled. + +HIDE_UNDOC_MEMBERS = NO + +# If the HIDE_UNDOC_CLASSES tag is set to YES, Doxygen will hide all +# undocumented classes that are normally visible in the class hierarchy. +# If set to NO (the default) these classes will be included in the various +# overviews. This option has no effect if EXTRACT_ALL is enabled. + +HIDE_UNDOC_CLASSES = NO + +# If the HIDE_FRIEND_COMPOUNDS tag is set to YES, Doxygen will hide all +# friend (class|struct|union) declarations. +# If set to NO (the default) these declarations will be included in the +# documentation. + +HIDE_FRIEND_COMPOUNDS = NO + +# If the HIDE_IN_BODY_DOCS tag is set to YES, Doxygen will hide any +# documentation blocks found inside the body of a function. +# If set to NO (the default) these blocks will be appended to the +# function's detailed documentation block. + +HIDE_IN_BODY_DOCS = NO + +# The INTERNAL_DOCS tag determines if documentation +# that is typed after a \internal command is included. If the tag is set +# to NO (the default) then the documentation will be excluded. +# Set it to YES to include the internal documentation. + +INTERNAL_DOCS = NO + +# If the CASE_SENSE_NAMES tag is set to NO then Doxygen will only generate +# file names in lower-case letters. If set to YES upper-case letters are also +# allowed. This is useful if you have classes or files whose names only differ +# in case and if your file system supports case sensitive file names. Windows +# and Mac users are advised to set this option to NO. + +CASE_SENSE_NAMES = YES + +# If the HIDE_SCOPE_NAMES tag is set to NO (the default) then Doxygen +# will show members with their full class and namespace scopes in the +# documentation. If set to YES the scope will be hidden. + +HIDE_SCOPE_NAMES = NO + +# If the SHOW_INCLUDE_FILES tag is set to YES (the default) then Doxygen +# will put a list of the files that are included by a file in the documentation +# of that file. + +SHOW_INCLUDE_FILES = YES + +# If the FORCE_LOCAL_INCLUDES tag is set to YES then Doxygen +# will list include files with double quotes in the documentation +# rather than with sharp brackets. + +FORCE_LOCAL_INCLUDES = NO + +# If the INLINE_INFO tag is set to YES (the default) then a tag [inline] +# is inserted in the documentation for inline members. + +INLINE_INFO = YES + +# If the SORT_MEMBER_DOCS tag is set to YES (the default) then doxygen +# will sort the (detailed) documentation of file and class members +# alphabetically by member name. If set to NO the members will appear in +# declaration order. + +SORT_MEMBER_DOCS = YES + +# If the SORT_BRIEF_DOCS tag is set to YES then doxygen will sort the +# brief documentation of file, namespace and class members alphabetically +# by member name. If set to NO (the default) the members will appear in +# declaration order. + +SORT_BRIEF_DOCS = NO + +# If the SORT_MEMBERS_CTORS_1ST tag is set to YES then doxygen +# will sort the (brief and detailed) documentation of class members so that +# constructors and destructors are listed first. If set to NO (the default) +# the constructors will appear in the respective orders defined by +# SORT_MEMBER_DOCS and SORT_BRIEF_DOCS. +# This tag will be ignored for brief docs if SORT_BRIEF_DOCS is set to NO +# and ignored for detailed docs if SORT_MEMBER_DOCS is set to NO. + +SORT_MEMBERS_CTORS_1ST = NO + +# If the SORT_GROUP_NAMES tag is set to YES then doxygen will sort the +# hierarchy of group names into alphabetical order. If set to NO (the default) +# the group names will appear in their defined order. + +SORT_GROUP_NAMES = NO + +# If the SORT_BY_SCOPE_NAME tag is set to YES, the class list will be +# sorted by fully-qualified names, including namespaces. If set to +# NO (the default), the class list will be sorted only by class name, +# not including the namespace part. +# Note: This option is not very useful if HIDE_SCOPE_NAMES is set to YES. +# Note: This option applies only to the class list, not to the +# alphabetical list. + +SORT_BY_SCOPE_NAME = NO + +# If the STRICT_PROTO_MATCHING option is enabled and doxygen fails to +# do proper type resolution of all parameters of a function it will reject a +# match between the prototype and the implementation of a member function even +# if there is only one candidate or it is obvious which candidate to choose +# by doing a simple string match. By disabling STRICT_PROTO_MATCHING doxygen +# will still accept a match between prototype and implementation in such cases. + +STRICT_PROTO_MATCHING = NO + +# The GENERATE_TODOLIST tag can be used to enable (YES) or +# disable (NO) the todo list. This list is created by putting \todo +# commands in the documentation. + +GENERATE_TODOLIST = YES + +# The GENERATE_TESTLIST tag can be used to enable (YES) or +# disable (NO) the test list. This list is created by putting \test +# commands in the documentation. + +GENERATE_TESTLIST = YES + +# The GENERATE_BUGLIST tag can be used to enable (YES) or +# disable (NO) the bug list. This list is created by putting \bug +# commands in the documentation. + +GENERATE_BUGLIST = YES + +# The GENERATE_DEPRECATEDLIST tag can be used to enable (YES) or +# disable (NO) the deprecated list. This list is created by putting +# \deprecated commands in the documentation. + +GENERATE_DEPRECATEDLIST= YES + +# The ENABLED_SECTIONS tag can be used to enable conditional +# documentation sections, marked by \if sectionname ... \endif. + +ENABLED_SECTIONS = + +# The MAX_INITIALIZER_LINES tag determines the maximum number of lines +# the initial value of a variable or macro consists of for it to appear in +# the documentation. If the initializer consists of more lines than specified +# here it will be hidden. Use a value of 0 to hide initializers completely. +# The appearance of the initializer of individual variables and macros in the +# documentation can be controlled using \showinitializer or \hideinitializer +# command in the documentation regardless of this setting. + +MAX_INITIALIZER_LINES = 30 + +# Set the SHOW_USED_FILES tag to NO to disable the list of files generated +# at the bottom of the documentation of classes and structs. If set to YES the +# list will mention the files that were used to generate the documentation. + +SHOW_USED_FILES = YES + +# If the sources in your project are distributed over multiple directories +# then setting the SHOW_DIRECTORIES tag to YES will show the directory hierarchy +# in the documentation. The default is NO. + +SHOW_DIRECTORIES = NO + +# Set the SHOW_FILES tag to NO to disable the generation of the Files page. +# This will remove the Files entry from the Quick Index and from the +# Folder Tree View (if specified). The default is YES. + +SHOW_FILES = YES + +# Set the SHOW_NAMESPACES tag to NO to disable the generation of the +# Namespaces page. +# This will remove the Namespaces entry from the Quick Index +# and from the Folder Tree View (if specified). The default is YES. + +SHOW_NAMESPACES = YES + +# The FILE_VERSION_FILTER tag can be used to specify a program or script that +# doxygen should invoke to get the current version for each file (typically from +# the version control system). Doxygen will invoke the program by executing (via +# popen()) the command , where is the value of +# the FILE_VERSION_FILTER tag, and is the name of an input file +# provided by doxygen. Whatever the program writes to standard output +# is used as the file version. See the manual for examples. + +FILE_VERSION_FILTER = + +# The LAYOUT_FILE tag can be used to specify a layout file which will be parsed +# by doxygen. The layout file controls the global structure of the generated +# output files in an output format independent way. The create the layout file +# that represents doxygen's defaults, run doxygen with the -l option. +# You can optionally specify a file name after the option, if omitted +# DoxygenLayout.xml will be used as the name of the layout file. + +LAYOUT_FILE = + +# The CITE_BIB_FILES tag can be used to specify one or more bib files +# containing the references data. This must be a list of .bib files. The +# .bib extension is automatically appended if omitted. Using this command +# requires the bibtex tool to be installed. See also +# http://en.wikipedia.org/wiki/BibTeX for more info. For LaTeX the style +# of the bibliography can be controlled using LATEX_BIB_STYLE. To use this +# feature you need bibtex and perl available in the search path. + +CITE_BIB_FILES = + +#--------------------------------------------------------------------------- +# configuration options related to warning and progress messages +#--------------------------------------------------------------------------- + +# The QUIET tag can be used to turn on/off the messages that are generated +# by doxygen. Possible values are YES and NO. If left blank NO is used. + +QUIET = NO + +# The WARNINGS tag can be used to turn on/off the warning messages that are +# generated by doxygen. Possible values are YES and NO. If left blank +# NO is used. + +WARNINGS = YES + +# If WARN_IF_UNDOCUMENTED is set to YES, then doxygen will generate warnings +# for undocumented members. If EXTRACT_ALL is set to YES then this flag will +# automatically be disabled. + +WARN_IF_UNDOCUMENTED = NO + +# If WARN_IF_DOC_ERROR is set to YES, doxygen will generate warnings for +# potential errors in the documentation, such as not documenting some +# parameters in a documented function, or documenting parameters that +# don't exist or using markup commands wrongly. + +WARN_IF_DOC_ERROR = YES + +# The WARN_NO_PARAMDOC option can be enabled to get warnings for +# functions that are documented, but have no documentation for their parameters +# or return value. If set to NO (the default) doxygen will only warn about +# wrong or incomplete parameter documentation, but not about the absence of +# documentation. + +WARN_NO_PARAMDOC = NO + +# The WARN_FORMAT tag determines the format of the warning messages that +# doxygen can produce. The string should contain the $file, $line, and $text +# tags, which will be replaced by the file and line number from which the +# warning originated and the warning text. Optionally the format may contain +# $version, which will be replaced by the version of the file (if it could +# be obtained via FILE_VERSION_FILTER) + +WARN_FORMAT = "$file:$line: $text" + +# The WARN_LOGFILE tag can be used to specify a file to which warning +# and error messages should be written. If left blank the output is written +# to stderr. + +WARN_LOGFILE = + +#--------------------------------------------------------------------------- +# configuration options related to the input files +#--------------------------------------------------------------------------- + +# The INPUT tag can be used to specify the files and/or directories that contain +# documented source files. You may enter file names like "myfile.cpp" or +# directories like "/usr/src/myproject". Separate the files or directories +# with spaces. + +INPUT = include/ lib/ + +# This tag can be used to specify the character encoding of the source files +# that doxygen parses. Internally doxygen uses the UTF-8 encoding, which is +# also the default input encoding. Doxygen uses libiconv (or the iconv built +# into libc) for the transcoding. See http://www.gnu.org/software/libiconv for +# the list of possible encodings. + +INPUT_ENCODING = UTF-8 + +# If the value of the INPUT tag contains directories, you can use the +# FILE_PATTERNS tag to specify one or more wildcard pattern (like *.cpp +# and *.h) to filter out the source-files in the directories. If left +# blank the following patterns are tested: +# *.c *.cc *.cxx *.cpp *.c++ *.d *.java *.ii *.ixx *.ipp *.i++ *.inl *.h *.hh +# *.hxx *.hpp *.h++ *.idl *.odl *.cs *.php *.php3 *.inc *.m *.mm *.dox *.py +# *.f90 *.f *.for *.vhd *.vhdl + +FILE_PATTERNS = + +# The RECURSIVE tag can be used to turn specify whether or not subdirectories +# should be searched for input files as well. Possible values are YES and NO. +# If left blank NO is used. + +RECURSIVE = YES + +# The EXCLUDE tag can be used to specify files and/or directories that should be +# excluded from the INPUT source files. This way you can easily exclude a +# subdirectory from a directory tree whose root is specified with the INPUT tag. +# Note that relative paths are relative to the directory from which doxygen is +# run. + +EXCLUDE = + +# The EXCLUDE_SYMLINKS tag can be used to select whether or not files or +# directories that are symbolic links (a Unix file system feature) are excluded +# from the input. + +EXCLUDE_SYMLINKS = NO + +# If the value of the INPUT tag contains directories, you can use the +# EXCLUDE_PATTERNS tag to specify one or more wildcard patterns to exclude +# certain files from those directories. Note that the wildcards are matched +# against the file with absolute path, so to exclude all test directories +# for example use the pattern */test/* + +EXCLUDE_PATTERNS = + +# The EXCLUDE_SYMBOLS tag can be used to specify one or more symbol names +# (namespaces, classes, functions, etc.) that should be excluded from the +# output. The symbol name can be a fully qualified name, a word, or if the +# wildcard * is used, a substring. Examples: ANamespace, AClass, +# AClass::ANamespace, ANamespace::*Test + +EXCLUDE_SYMBOLS = + +# The EXAMPLE_PATH tag can be used to specify one or more files or +# directories that contain example code fragments that are included (see +# the \include command). + +EXAMPLE_PATH = + +# If the value of the EXAMPLE_PATH tag contains directories, you can use the +# EXAMPLE_PATTERNS tag to specify one or more wildcard pattern (like *.cpp +# and *.h) to filter out the source-files in the directories. If left +# blank all files are included. + +EXAMPLE_PATTERNS = + +# If the EXAMPLE_RECURSIVE tag is set to YES then subdirectories will be +# searched for input files to be used with the \include or \dontinclude +# commands irrespective of the value of the RECURSIVE tag. +# Possible values are YES and NO. If left blank NO is used. + +EXAMPLE_RECURSIVE = NO + +# The IMAGE_PATH tag can be used to specify one or more files or +# directories that contain image that are included in the documentation (see +# the \image command). + +IMAGE_PATH = + +# The INPUT_FILTER tag can be used to specify a program that doxygen should +# invoke to filter for each input file. Doxygen will invoke the filter program +# by executing (via popen()) the command , where +# is the value of the INPUT_FILTER tag, and is the name of an +# input file. Doxygen will then use the output that the filter program writes +# to standard output. +# If FILTER_PATTERNS is specified, this tag will be +# ignored. + +INPUT_FILTER = ./doxygen.sed + +# The FILTER_PATTERNS tag can be used to specify filters on a per file pattern +# basis. +# Doxygen will compare the file name with each pattern and apply the +# filter if there is a match. +# The filters are a list of the form: +# pattern=filter (like *.cpp=my_cpp_filter). See INPUT_FILTER for further +# info on how filters are used. If FILTER_PATTERNS is empty or if +# non of the patterns match the file name, INPUT_FILTER is applied. + +FILTER_PATTERNS = + +# If the FILTER_SOURCE_FILES tag is set to YES, the input filter (if set using +# INPUT_FILTER) will be used to filter the input files when producing source +# files to browse (i.e. when SOURCE_BROWSER is set to YES). + +FILTER_SOURCE_FILES = NO + +# The FILTER_SOURCE_PATTERNS tag can be used to specify source filters per file +# pattern. A pattern will override the setting for FILTER_PATTERN (if any) +# and it is also possible to disable source filtering for a specific pattern +# using *.ext= (so without naming a filter). This option only has effect when +# FILTER_SOURCE_FILES is enabled. + +FILTER_SOURCE_PATTERNS = + +#--------------------------------------------------------------------------- +# configuration options related to source browsing +#--------------------------------------------------------------------------- + +# If the SOURCE_BROWSER tag is set to YES then a list of source files will +# be generated. Documented entities will be cross-referenced with these sources. +# Note: To get rid of all source code in the generated output, make sure also +# VERBATIM_HEADERS is set to NO. + +SOURCE_BROWSER = NO + +# Setting the INLINE_SOURCES tag to YES will include the body +# of functions and classes directly in the documentation. + +INLINE_SOURCES = NO + +# Setting the STRIP_CODE_COMMENTS tag to YES (the default) will instruct +# doxygen to hide any special comment blocks from generated source code +# fragments. Normal C and C++ comments will always remain visible. + +STRIP_CODE_COMMENTS = YES + +# If the REFERENCED_BY_RELATION tag is set to YES +# then for each documented function all documented +# functions referencing it will be listed. + +REFERENCED_BY_RELATION = NO + +# If the REFERENCES_RELATION tag is set to YES +# then for each documented function all documented entities +# called/used by that function will be listed. + +REFERENCES_RELATION = NO + +# If the REFERENCES_LINK_SOURCE tag is set to YES (the default) +# and SOURCE_BROWSER tag is set to YES, then the hyperlinks from +# functions in REFERENCES_RELATION and REFERENCED_BY_RELATION lists will +# link to the source code. +# Otherwise they will link to the documentation. + +REFERENCES_LINK_SOURCE = YES + +# If the USE_HTAGS tag is set to YES then the references to source code +# will point to the HTML generated by the htags(1) tool instead of doxygen +# built-in source browser. The htags tool is part of GNU's global source +# tagging system (see http://www.gnu.org/software/global/global.html). You +# will need version 4.8.6 or higher. + +USE_HTAGS = NO + +# If the VERBATIM_HEADERS tag is set to YES (the default) then Doxygen +# will generate a verbatim copy of the header file for each class for +# which an include is specified. Set to NO to disable this. + +VERBATIM_HEADERS = YES + +#--------------------------------------------------------------------------- +# configuration options related to the alphabetical class index +#--------------------------------------------------------------------------- + +# If the ALPHABETICAL_INDEX tag is set to YES, an alphabetical index +# of all compounds will be generated. Enable this if the project +# contains a lot of classes, structs, unions or interfaces. + +ALPHABETICAL_INDEX = YES + +# If the alphabetical index is enabled (see ALPHABETICAL_INDEX) then +# the COLS_IN_ALPHA_INDEX tag can be used to specify the number of columns +# in which this list will be split (can be a number in the range [1..20]) + +COLS_IN_ALPHA_INDEX = 5 + +# In case all classes in a project start with a common prefix, all +# classes will be put under the same header in the alphabetical index. +# The IGNORE_PREFIX tag can be used to specify one or more prefixes that +# should be ignored while generating the index headers. + +IGNORE_PREFIX = + +#--------------------------------------------------------------------------- +# configuration options related to the HTML output +#--------------------------------------------------------------------------- + +# If the GENERATE_HTML tag is set to YES (the default) Doxygen will +# generate HTML output. + +GENERATE_HTML = YES + +# The HTML_OUTPUT tag is used to specify where the HTML docs will be put. +# If a relative path is entered the value of OUTPUT_DIRECTORY will be +# put in front of it. If left blank `html' will be used as the default path. + +HTML_OUTPUT = html + +# The HTML_FILE_EXTENSION tag can be used to specify the file extension for +# each generated HTML page (for example: .htm,.php,.asp). If it is left blank +# doxygen will generate files with .html extension. + +HTML_FILE_EXTENSION = .html + +# The HTML_HEADER tag can be used to specify a personal HTML header for +# each generated HTML page. If it is left blank doxygen will generate a +# standard header. Note that when using a custom header you are responsible +# for the proper inclusion of any scripts and style sheets that doxygen +# needs, which is dependent on the configuration options used. +# It is advised to generate a default header using "doxygen -w html +# header.html footer.html stylesheet.css YourConfigFile" and then modify +# that header. Note that the header is subject to change so you typically +# have to redo this when upgrading to a newer version of doxygen or when +# changing the value of configuration settings such as GENERATE_TREEVIEW! + +HTML_HEADER = + +# The HTML_FOOTER tag can be used to specify a personal HTML footer for +# each generated HTML page. If it is left blank doxygen will generate a +# standard footer. + +HTML_FOOTER = + +# The HTML_STYLESHEET tag can be used to specify a user-defined cascading +# style sheet that is used by each HTML page. It can be used to +# fine-tune the look of the HTML output. If the tag is left blank doxygen +# will generate a default style sheet. Note that doxygen will try to copy +# the style sheet file to the HTML output directory, so don't put your own +# style sheet in the HTML output directory as well, or it will be erased! + +HTML_STYLESHEET = + +# The HTML_EXTRA_FILES tag can be used to specify one or more extra images or +# other source files which should be copied to the HTML output directory. Note +# that these files will be copied to the base HTML output directory. Use the +# $relpath$ marker in the HTML_HEADER and/or HTML_FOOTER files to load these +# files. In the HTML_STYLESHEET file, use the file name only. Also note that +# the files will be copied as-is; there are no commands or markers available. + +HTML_EXTRA_FILES = + +# The HTML_COLORSTYLE_HUE tag controls the color of the HTML output. +# Doxygen will adjust the colors in the style sheet and background images +# according to this color. Hue is specified as an angle on a colorwheel, +# see http://en.wikipedia.org/wiki/Hue for more information. +# For instance the value 0 represents red, 60 is yellow, 120 is green, +# 180 is cyan, 240 is blue, 300 purple, and 360 is red again. +# The allowed range is 0 to 359. + +HTML_COLORSTYLE_HUE = 220 + +# The HTML_COLORSTYLE_SAT tag controls the purity (or saturation) of +# the colors in the HTML output. For a value of 0 the output will use +# grayscales only. A value of 255 will produce the most vivid colors. + +HTML_COLORSTYLE_SAT = 100 + +# The HTML_COLORSTYLE_GAMMA tag controls the gamma correction applied to +# the luminance component of the colors in the HTML output. Values below +# 100 gradually make the output lighter, whereas values above 100 make +# the output darker. The value divided by 100 is the actual gamma applied, +# so 80 represents a gamma of 0.8, The value 220 represents a gamma of 2.2, +# and 100 does not change the gamma. + +HTML_COLORSTYLE_GAMMA = 80 + +# If the HTML_TIMESTAMP tag is set to YES then the footer of each generated HTML +# page will contain the date and time when the page was generated. Setting +# this to NO can help when comparing the output of multiple runs. + +HTML_TIMESTAMP = YES + +# If the HTML_ALIGN_MEMBERS tag is set to YES, the members of classes, +# files or namespaces will be aligned in HTML using tables. If set to +# NO a bullet list will be used. + +HTML_ALIGN_MEMBERS = YES + +# If the HTML_DYNAMIC_SECTIONS tag is set to YES then the generated HTML +# documentation will contain sections that can be hidden and shown after the +# page has loaded. For this to work a browser that supports +# JavaScript and DHTML is required (for instance Mozilla 1.0+, Firefox +# Netscape 6.0+, Internet explorer 5.0+, Konqueror, or Safari). + +HTML_DYNAMIC_SECTIONS = NO + +# If the GENERATE_DOCSET tag is set to YES, additional index files +# will be generated that can be used as input for Apple's Xcode 3 +# integrated development environment, introduced with OSX 10.5 (Leopard). +# To create a documentation set, doxygen will generate a Makefile in the +# HTML output directory. Running make will produce the docset in that +# directory and running "make install" will install the docset in +# ~/Library/Developer/Shared/Documentation/DocSets so that Xcode will find +# it at startup. +# See http://developer.apple.com/tools/creatingdocsetswithdoxygen.html +# for more information. + +GENERATE_DOCSET = NO + +# When GENERATE_DOCSET tag is set to YES, this tag determines the name of the +# feed. A documentation feed provides an umbrella under which multiple +# documentation sets from a single provider (such as a company or product suite) +# can be grouped. + +DOCSET_FEEDNAME = "Doxygen generated docs" + +# When GENERATE_DOCSET tag is set to YES, this tag specifies a string that +# should uniquely identify the documentation set bundle. This should be a +# reverse domain-name style string, e.g. com.mycompany.MyDocSet. Doxygen +# will append .docset to the name. + +DOCSET_BUNDLE_ID = org.doxygen.Project + +# When GENERATE_PUBLISHER_ID tag specifies a string that should uniquely identify +# the documentation publisher. This should be a reverse domain-name style +# string, e.g. com.mycompany.MyDocSet.documentation. + +DOCSET_PUBLISHER_ID = org.doxygen.Publisher + +# The GENERATE_PUBLISHER_NAME tag identifies the documentation publisher. + +DOCSET_PUBLISHER_NAME = Publisher + +# If the GENERATE_HTMLHELP tag is set to YES, additional index files +# will be generated that can be used as input for tools like the +# Microsoft HTML help workshop to generate a compiled HTML help file (.chm) +# of the generated HTML documentation. + +GENERATE_HTMLHELP = NO + +# If the GENERATE_HTMLHELP tag is set to YES, the CHM_FILE tag can +# be used to specify the file name of the resulting .chm file. You +# can add a path in front of the file if the result should not be +# written to the html output directory. + +CHM_FILE = + +# If the GENERATE_HTMLHELP tag is set to YES, the HHC_LOCATION tag can +# be used to specify the location (absolute path including file name) of +# the HTML help compiler (hhc.exe). If non-empty doxygen will try to run +# the HTML help compiler on the generated index.hhp. + +HHC_LOCATION = + +# If the GENERATE_HTMLHELP tag is set to YES, the GENERATE_CHI flag +# controls if a separate .chi index file is generated (YES) or that +# it should be included in the master .chm file (NO). + +GENERATE_CHI = NO + +# If the GENERATE_HTMLHELP tag is set to YES, the CHM_INDEX_ENCODING +# is used to encode HtmlHelp index (hhk), content (hhc) and project file +# content. + +CHM_INDEX_ENCODING = + +# If the GENERATE_HTMLHELP tag is set to YES, the BINARY_TOC flag +# controls whether a binary table of contents is generated (YES) or a +# normal table of contents (NO) in the .chm file. + +BINARY_TOC = NO + +# The TOC_EXPAND flag can be set to YES to add extra items for group members +# to the contents of the HTML help documentation and to the tree view. + +TOC_EXPAND = NO + +# If the GENERATE_QHP tag is set to YES and both QHP_NAMESPACE and +# QHP_VIRTUAL_FOLDER are set, an additional index file will be generated +# that can be used as input for Qt's qhelpgenerator to generate a +# Qt Compressed Help (.qch) of the generated HTML documentation. + +GENERATE_QHP = NO + +# If the QHG_LOCATION tag is specified, the QCH_FILE tag can +# be used to specify the file name of the resulting .qch file. +# The path specified is relative to the HTML output folder. + +QCH_FILE = + +# The QHP_NAMESPACE tag specifies the namespace to use when generating +# Qt Help Project output. For more information please see +# http://doc.trolltech.com/qthelpproject.html#namespace + +QHP_NAMESPACE = org.doxygen.Project + +# The QHP_VIRTUAL_FOLDER tag specifies the namespace to use when generating +# Qt Help Project output. For more information please see +# http://doc.trolltech.com/qthelpproject.html#virtual-folders + +QHP_VIRTUAL_FOLDER = doc + +# If QHP_CUST_FILTER_NAME is set, it specifies the name of a custom filter to +# add. For more information please see +# http://doc.trolltech.com/qthelpproject.html#custom-filters + +QHP_CUST_FILTER_NAME = + +# The QHP_CUST_FILT_ATTRS tag specifies the list of the attributes of the +# custom filter to add. For more information please see +# +# Qt Help Project / Custom Filters. + +QHP_CUST_FILTER_ATTRS = + +# The QHP_SECT_FILTER_ATTRS tag specifies the list of the attributes this +# project's +# filter section matches. +# +# Qt Help Project / Filter Attributes. + +QHP_SECT_FILTER_ATTRS = + +# If the GENERATE_QHP tag is set to YES, the QHG_LOCATION tag can +# be used to specify the location of Qt's qhelpgenerator. +# If non-empty doxygen will try to run qhelpgenerator on the generated +# .qhp file. + +QHG_LOCATION = + +# If the GENERATE_ECLIPSEHELP tag is set to YES, additional index files +# will be generated, which together with the HTML files, form an Eclipse help +# plugin. To install this plugin and make it available under the help contents +# menu in Eclipse, the contents of the directory containing the HTML and XML +# files needs to be copied into the plugins directory of eclipse. The name of +# the directory within the plugins directory should be the same as +# the ECLIPSE_DOC_ID value. After copying Eclipse needs to be restarted before +# the help appears. + +GENERATE_ECLIPSEHELP = NO + +# A unique identifier for the eclipse help plugin. When installing the plugin +# the directory name containing the HTML and XML files should also have +# this name. + +ECLIPSE_DOC_ID = org.doxygen.Project + +# The DISABLE_INDEX tag can be used to turn on/off the condensed index (tabs) +# at top of each HTML page. The value NO (the default) enables the index and +# the value YES disables it. Since the tabs have the same information as the +# navigation tree you can set this option to NO if you already set +# GENERATE_TREEVIEW to YES. + +DISABLE_INDEX = NO + +# The GENERATE_TREEVIEW tag is used to specify whether a tree-like index +# structure should be generated to display hierarchical information. +# If the tag value is set to YES, a side panel will be generated +# containing a tree-like index structure (just like the one that +# is generated for HTML Help). For this to work a browser that supports +# JavaScript, DHTML, CSS and frames is required (i.e. any modern browser). +# Windows users are probably better off using the HTML help feature. +# Since the tree basically has the same information as the tab index you +# could consider to set DISABLE_INDEX to NO when enabling this option. + +GENERATE_TREEVIEW = NO + +# The ENUM_VALUES_PER_LINE tag can be used to set the number of enum values +# (range [0,1..20]) that doxygen will group on one line in the generated HTML +# documentation. Note that a value of 0 will completely suppress the enum +# values from appearing in the overview section. + +ENUM_VALUES_PER_LINE = 4 + +# By enabling USE_INLINE_TREES, doxygen will generate the Groups, Directories, +# and Class Hierarchy pages using a tree view instead of an ordered list. + +USE_INLINE_TREES = NO + +# If the treeview is enabled (see GENERATE_TREEVIEW) then this tag can be +# used to set the initial width (in pixels) of the frame in which the tree +# is shown. + +TREEVIEW_WIDTH = 250 + +# When the EXT_LINKS_IN_WINDOW option is set to YES doxygen will open +# links to external symbols imported via tag files in a separate window. + +EXT_LINKS_IN_WINDOW = NO + +# Use this tag to change the font size of Latex formulas included +# as images in the HTML documentation. The default is 10. Note that +# when you change the font size after a successful doxygen run you need +# to manually remove any form_*.png images from the HTML output directory +# to force them to be regenerated. + +FORMULA_FONTSIZE = 10 + +# Use the FORMULA_TRANPARENT tag to determine whether or not the images +# generated for formulas are transparent PNGs. Transparent PNGs are +# not supported properly for IE 6.0, but are supported on all modern browsers. +# Note that when changing this option you need to delete any form_*.png files +# in the HTML output before the changes have effect. + +FORMULA_TRANSPARENT = YES + +# Enable the USE_MATHJAX option to render LaTeX formulas using MathJax +# (see http://www.mathjax.org) which uses client side Javascript for the +# rendering instead of using prerendered bitmaps. Use this if you do not +# have LaTeX installed or if you want to formulas look prettier in the HTML +# output. When enabled you also need to install MathJax separately and +# configure the path to it using the MATHJAX_RELPATH option. + +USE_MATHJAX = NO + +# When MathJax is enabled you need to specify the location relative to the +# HTML output directory using the MATHJAX_RELPATH option. The destination +# directory should contain the MathJax.js script. For instance, if the mathjax +# directory is located at the same level as the HTML output directory, then +# MATHJAX_RELPATH should be ../mathjax. The default value points to the +# mathjax.org site, so you can quickly see the result without installing +# MathJax, but it is strongly recommended to install a local copy of MathJax +# before deployment. + +MATHJAX_RELPATH = http://www.mathjax.org/mathjax + +# The MATHJAX_EXTENSIONS tag can be used to specify one or MathJax extension +# names that should be enabled during MathJax rendering. + +MATHJAX_EXTENSIONS = + +# When the SEARCHENGINE tag is enabled doxygen will generate a search box +# for the HTML output. The underlying search engine uses javascript +# and DHTML and should work on any modern browser. Note that when using +# HTML help (GENERATE_HTMLHELP), Qt help (GENERATE_QHP), or docsets +# (GENERATE_DOCSET) there is already a search function so this one should +# typically be disabled. For large projects the javascript based search engine +# can be slow, then enabling SERVER_BASED_SEARCH may provide a better solution. + +SEARCHENGINE = YES + +# When the SERVER_BASED_SEARCH tag is enabled the search engine will be +# implemented using a PHP enabled web server instead of at the web client +# using Javascript. Doxygen will generate the search PHP script and index +# file to put on the web server. The advantage of the server +# based approach is that it scales better to large projects and allows +# full text search. The disadvantages are that it is more difficult to setup +# and does not have live searching capabilities. + +SERVER_BASED_SEARCH = NO + +#--------------------------------------------------------------------------- +# configuration options related to the LaTeX output +#--------------------------------------------------------------------------- + +# If the GENERATE_LATEX tag is set to YES (the default) Doxygen will +# generate Latex output. + +GENERATE_LATEX = NO + +# The LATEX_OUTPUT tag is used to specify where the LaTeX docs will be put. +# If a relative path is entered the value of OUTPUT_DIRECTORY will be +# put in front of it. If left blank `latex' will be used as the default path. + +LATEX_OUTPUT = latex + +# The LATEX_CMD_NAME tag can be used to specify the LaTeX command name to be +# invoked. If left blank `latex' will be used as the default command name. +# Note that when enabling USE_PDFLATEX this option is only used for +# generating bitmaps for formulas in the HTML output, but not in the +# Makefile that is written to the output directory. + +LATEX_CMD_NAME = latex + +# The MAKEINDEX_CMD_NAME tag can be used to specify the command name to +# generate index for LaTeX. If left blank `makeindex' will be used as the +# default command name. + +MAKEINDEX_CMD_NAME = makeindex + +# If the COMPACT_LATEX tag is set to YES Doxygen generates more compact +# LaTeX documents. This may be useful for small projects and may help to +# save some trees in general. + +COMPACT_LATEX = NO + +# The PAPER_TYPE tag can be used to set the paper type that is used +# by the printer. Possible values are: a4, letter, legal and +# executive. If left blank a4wide will be used. + +PAPER_TYPE = a4 + +# The EXTRA_PACKAGES tag can be to specify one or more names of LaTeX +# packages that should be included in the LaTeX output. + +EXTRA_PACKAGES = + +# The LATEX_HEADER tag can be used to specify a personal LaTeX header for +# the generated latex document. The header should contain everything until +# the first chapter. If it is left blank doxygen will generate a +# standard header. Notice: only use this tag if you know what you are doing! + +LATEX_HEADER = + +# The LATEX_FOOTER tag can be used to specify a personal LaTeX footer for +# the generated latex document. The footer should contain everything after +# the last chapter. If it is left blank doxygen will generate a +# standard footer. Notice: only use this tag if you know what you are doing! + +LATEX_FOOTER = + +# If the PDF_HYPERLINKS tag is set to YES, the LaTeX that is generated +# is prepared for conversion to pdf (using ps2pdf). The pdf file will +# contain links (just like the HTML output) instead of page references +# This makes the output suitable for online browsing using a pdf viewer. + +PDF_HYPERLINKS = YES + +# If the USE_PDFLATEX tag is set to YES, pdflatex will be used instead of +# plain latex in the generated Makefile. Set this option to YES to get a +# higher quality PDF documentation. + +USE_PDFLATEX = YES + +# If the LATEX_BATCHMODE tag is set to YES, doxygen will add the \\batchmode. +# command to the generated LaTeX files. This will instruct LaTeX to keep +# running if errors occur, instead of asking the user for help. +# This option is also used when generating formulas in HTML. + +LATEX_BATCHMODE = NO + +# If LATEX_HIDE_INDICES is set to YES then doxygen will not +# include the index chapters (such as File Index, Compound Index, etc.) +# in the output. + +LATEX_HIDE_INDICES = NO + +# If LATEX_SOURCE_CODE is set to YES then doxygen will include +# source code with syntax highlighting in the LaTeX output. +# Note that which sources are shown also depends on other settings +# such as SOURCE_BROWSER. + +LATEX_SOURCE_CODE = NO + +# The LATEX_BIB_STYLE tag can be used to specify the style to use for the +# bibliography, e.g. plainnat, or ieeetr. The default style is "plain". See +# http://en.wikipedia.org/wiki/BibTeX for more info. + +LATEX_BIB_STYLE = plain + +#--------------------------------------------------------------------------- +# configuration options related to the RTF output +#--------------------------------------------------------------------------- + +# If the GENERATE_RTF tag is set to YES Doxygen will generate RTF output +# The RTF output is optimized for Word 97 and may not look very pretty with +# other RTF readers or editors. + +GENERATE_RTF = NO + +# The RTF_OUTPUT tag is used to specify where the RTF docs will be put. +# If a relative path is entered the value of OUTPUT_DIRECTORY will be +# put in front of it. If left blank `rtf' will be used as the default path. + +RTF_OUTPUT = rtf + +# If the COMPACT_RTF tag is set to YES Doxygen generates more compact +# RTF documents. This may be useful for small projects and may help to +# save some trees in general. + +COMPACT_RTF = NO + +# If the RTF_HYPERLINKS tag is set to YES, the RTF that is generated +# will contain hyperlink fields. The RTF file will +# contain links (just like the HTML output) instead of page references. +# This makes the output suitable for online browsing using WORD or other +# programs which support those fields. +# Note: wordpad (write) and others do not support links. + +RTF_HYPERLINKS = NO + +# Load style sheet definitions from file. Syntax is similar to doxygen's +# config file, i.e. a series of assignments. You only have to provide +# replacements, missing definitions are set to their default value. + +RTF_STYLESHEET_FILE = + +# Set optional variables used in the generation of an rtf document. +# Syntax is similar to doxygen's config file. + +RTF_EXTENSIONS_FILE = + +#--------------------------------------------------------------------------- +# configuration options related to the man page output +#--------------------------------------------------------------------------- + +# If the GENERATE_MAN tag is set to YES (the default) Doxygen will +# generate man pages + +GENERATE_MAN = NO + +# The MAN_OUTPUT tag is used to specify where the man pages will be put. +# If a relative path is entered the value of OUTPUT_DIRECTORY will be +# put in front of it. If left blank `man' will be used as the default path. + +MAN_OUTPUT = man + +# The MAN_EXTENSION tag determines the extension that is added to +# the generated man pages (default is the subroutine's section .3) + +MAN_EXTENSION = .3 + +# If the MAN_LINKS tag is set to YES and Doxygen generates man output, +# then it will generate one additional man file for each entity +# documented in the real man page(s). These additional files +# only source the real man page, but without them the man command +# would be unable to find the correct page. The default is NO. + +MAN_LINKS = NO + +#--------------------------------------------------------------------------- +# configuration options related to the XML output +#--------------------------------------------------------------------------- + +# If the GENERATE_XML tag is set to YES Doxygen will +# generate an XML file that captures the structure of +# the code including all documentation. + +GENERATE_XML = NO + +# The XML_OUTPUT tag is used to specify where the XML pages will be put. +# If a relative path is entered the value of OUTPUT_DIRECTORY will be +# put in front of it. If left blank `xml' will be used as the default path. + +XML_OUTPUT = xml + +# The XML_SCHEMA tag can be used to specify an XML schema, +# which can be used by a validating XML parser to check the +# syntax of the XML files. + +XML_SCHEMA = + +# The XML_DTD tag can be used to specify an XML DTD, +# which can be used by a validating XML parser to check the +# syntax of the XML files. + +XML_DTD = + +# If the XML_PROGRAMLISTING tag is set to YES Doxygen will +# dump the program listings (including syntax highlighting +# and cross-referencing information) to the XML output. Note that +# enabling this will significantly increase the size of the XML output. + +XML_PROGRAMLISTING = YES + +#--------------------------------------------------------------------------- +# configuration options for the AutoGen Definitions output +#--------------------------------------------------------------------------- + +# If the GENERATE_AUTOGEN_DEF tag is set to YES Doxygen will +# generate an AutoGen Definitions (see autogen.sf.net) file +# that captures the structure of the code including all +# documentation. Note that this feature is still experimental +# and incomplete at the moment. + +GENERATE_AUTOGEN_DEF = NO + +#--------------------------------------------------------------------------- +# configuration options related to the Perl module output +#--------------------------------------------------------------------------- + +# If the GENERATE_PERLMOD tag is set to YES Doxygen will +# generate a Perl module file that captures the structure of +# the code including all documentation. Note that this +# feature is still experimental and incomplete at the +# moment. + +GENERATE_PERLMOD = NO + +# If the PERLMOD_LATEX tag is set to YES Doxygen will generate +# the necessary Makefile rules, Perl scripts and LaTeX code to be able +# to generate PDF and DVI output from the Perl module output. + +PERLMOD_LATEX = NO + +# If the PERLMOD_PRETTY tag is set to YES the Perl module output will be +# nicely formatted so it can be parsed by a human reader. +# This is useful +# if you want to understand what is going on. +# On the other hand, if this +# tag is set to NO the size of the Perl module output will be much smaller +# and Perl will parse it just the same. + +PERLMOD_PRETTY = YES + +# The names of the make variables in the generated doxyrules.make file +# are prefixed with the string contained in PERLMOD_MAKEVAR_PREFIX. +# This is useful so different doxyrules.make files included by the same +# Makefile don't overwrite each other's variables. + +PERLMOD_MAKEVAR_PREFIX = + +#--------------------------------------------------------------------------- +# Configuration options related to the preprocessor +#--------------------------------------------------------------------------- + +# If the ENABLE_PREPROCESSING tag is set to YES (the default) Doxygen will +# evaluate all C-preprocessor directives found in the sources and include +# files. + +ENABLE_PREPROCESSING = YES + +# If the MACRO_EXPANSION tag is set to YES Doxygen will expand all macro +# names in the source code. If set to NO (the default) only conditional +# compilation will be performed. Macro expansion can be done in a controlled +# way by setting EXPAND_ONLY_PREDEF to YES. + +MACRO_EXPANSION = NO + +# If the EXPAND_ONLY_PREDEF and MACRO_EXPANSION tags are both set to YES +# then the macro expansion is limited to the macros specified with the +# PREDEFINED and EXPAND_AS_DEFINED tags. + +EXPAND_ONLY_PREDEF = NO + +# If the SEARCH_INCLUDES tag is set to YES (the default) the includes files +# pointed to by INCLUDE_PATH will be searched when a #include is found. + +SEARCH_INCLUDES = YES + +# The INCLUDE_PATH tag can be used to specify one or more directories that +# contain include files that are not input files but should be processed by +# the preprocessor. + +INCLUDE_PATH = + +# You can use the INCLUDE_FILE_PATTERNS tag to specify one or more wildcard +# patterns (like *.h and *.hpp) to filter out the header-files in the +# directories. If left blank, the patterns specified with FILE_PATTERNS will +# be used. + +INCLUDE_FILE_PATTERNS = + +# The PREDEFINED tag can be used to specify one or more macro names that +# are defined before the preprocessor is started (similar to the -D option of +# gcc). The argument of the tag is a list of macros of the form: name +# or name=definition (no spaces). If the definition and the = are +# omitted =1 is assumed. To prevent a macro definition from being +# undefined via #undef or recursively expanded use the := operator +# instead of the = operator. + +PREDEFINED = + +# If the MACRO_EXPANSION and EXPAND_ONLY_PREDEF tags are set to YES then +# this tag can be used to specify a list of macro names that should be expanded. +# The macro definition that is found in the sources will be used. +# Use the PREDEFINED tag if you want to use a different macro definition that +# overrules the definition found in the source code. + +EXPAND_AS_DEFINED = + +# If the SKIP_FUNCTION_MACROS tag is set to YES (the default) then +# doxygen's preprocessor will remove all references to function-like macros +# that are alone on a line, have an all uppercase name, and do not end with a +# semicolon, because these will confuse the parser if not removed. + +SKIP_FUNCTION_MACROS = YES + +#--------------------------------------------------------------------------- +# Configuration::additions related to external references +#--------------------------------------------------------------------------- + +# The TAGFILES option can be used to specify one or more tagfiles. +# Optionally an initial location of the external documentation +# can be added for each tagfile. The format of a tag file without +# this location is as follows: +# +# TAGFILES = file1 file2 ... +# Adding location for the tag files is done as follows: +# +# TAGFILES = file1=loc1 "file2 = loc2" ... +# where "loc1" and "loc2" can be relative or absolute paths or +# URLs. If a location is present for each tag, the installdox tool +# does not have to be run to correct the links. +# Note that each tag file must have a unique name +# (where the name does NOT include the path) +# If a tag file is not located in the directory in which doxygen +# is run, you must also specify the path to the tagfile here. + +TAGFILES = + +# When a file name is specified after GENERATE_TAGFILE, doxygen will create +# a tag file that is based on the input files it reads. + +GENERATE_TAGFILE = + +# If the ALLEXTERNALS tag is set to YES all external classes will be listed +# in the class index. If set to NO only the inherited external classes +# will be listed. + +ALLEXTERNALS = NO + +# If the EXTERNAL_GROUPS tag is set to YES all external groups will be listed +# in the modules index. If set to NO, only the current project's groups will +# be listed. + +EXTERNAL_GROUPS = YES + +# The PERL_PATH should be the absolute path and name of the perl script +# interpreter (i.e. the result of `which perl'). + +PERL_PATH = /usr/bin/perl + +#--------------------------------------------------------------------------- +# Configuration options related to the dot tool +#--------------------------------------------------------------------------- + +# If the CLASS_DIAGRAMS tag is set to YES (the default) Doxygen will +# generate a inheritance diagram (in HTML, RTF and LaTeX) for classes with base +# or super classes. Setting the tag to NO turns the diagrams off. Note that +# this option also works with HAVE_DOT disabled, but it is recommended to +# install and use dot, since it yields more powerful graphs. + +CLASS_DIAGRAMS = YES + +# You can define message sequence charts within doxygen comments using the \msc +# command. Doxygen will then run the mscgen tool (see +# http://www.mcternan.me.uk/mscgen/) to produce the chart and insert it in the +# documentation. The MSCGEN_PATH tag allows you to specify the directory where +# the mscgen tool resides. If left empty the tool is assumed to be found in the +# default search path. + +MSCGEN_PATH = + +# If set to YES, the inheritance and collaboration graphs will hide +# inheritance and usage relations if the target is undocumented +# or is not a class. + +HIDE_UNDOC_RELATIONS = YES + +# If you set the HAVE_DOT tag to YES then doxygen will assume the dot tool is +# available from the path. This tool is part of Graphviz, a graph visualization +# toolkit from AT&T and Lucent Bell Labs. The other options in this section +# have no effect if this option is set to NO (the default) + +HAVE_DOT = NO + +# The DOT_NUM_THREADS specifies the number of dot invocations doxygen is +# allowed to run in parallel. When set to 0 (the default) doxygen will +# base this on the number of processors available in the system. You can set it +# explicitly to a value larger than 0 to get control over the balance +# between CPU load and processing speed. + +DOT_NUM_THREADS = 0 + +# By default doxygen will use the Helvetica font for all dot files that +# doxygen generates. When you want a differently looking font you can specify +# the font name using DOT_FONTNAME. You need to make sure dot is able to find +# the font, which can be done by putting it in a standard location or by setting +# the DOTFONTPATH environment variable or by setting DOT_FONTPATH to the +# directory containing the font. + +DOT_FONTNAME = Helvetica + +# The DOT_FONTSIZE tag can be used to set the size of the font of dot graphs. +# The default size is 10pt. + +DOT_FONTSIZE = 10 + +# By default doxygen will tell dot to use the Helvetica font. +# If you specify a different font using DOT_FONTNAME you can use DOT_FONTPATH to +# set the path where dot can find it. + +DOT_FONTPATH = + +# If the CLASS_GRAPH and HAVE_DOT tags are set to YES then doxygen +# will generate a graph for each documented class showing the direct and +# indirect inheritance relations. Setting this tag to YES will force the +# CLASS_DIAGRAMS tag to NO. + +CLASS_GRAPH = YES + +# If the COLLABORATION_GRAPH and HAVE_DOT tags are set to YES then doxygen +# will generate a graph for each documented class showing the direct and +# indirect implementation dependencies (inheritance, containment, and +# class references variables) of the class with other documented classes. + +COLLABORATION_GRAPH = YES + +# If the GROUP_GRAPHS and HAVE_DOT tags are set to YES then doxygen +# will generate a graph for groups, showing the direct groups dependencies + +GROUP_GRAPHS = YES + +# If the UML_LOOK tag is set to YES doxygen will generate inheritance and +# collaboration diagrams in a style similar to the OMG's Unified Modeling +# Language. + +UML_LOOK = NO + +# If set to YES, the inheritance and collaboration graphs will show the +# relations between templates and their instances. + +TEMPLATE_RELATIONS = NO + +# If the ENABLE_PREPROCESSING, SEARCH_INCLUDES, INCLUDE_GRAPH, and HAVE_DOT +# tags are set to YES then doxygen will generate a graph for each documented +# file showing the direct and indirect include dependencies of the file with +# other documented files. + +INCLUDE_GRAPH = YES + +# If the ENABLE_PREPROCESSING, SEARCH_INCLUDES, INCLUDED_BY_GRAPH, and +# HAVE_DOT tags are set to YES then doxygen will generate a graph for each +# documented header file showing the documented files that directly or +# indirectly include this file. + +INCLUDED_BY_GRAPH = YES + +# If the CALL_GRAPH and HAVE_DOT options are set to YES then +# doxygen will generate a call dependency graph for every global function +# or class method. Note that enabling this option will significantly increase +# the time of a run. So in most cases it will be better to enable call graphs +# for selected functions only using the \callgraph command. + +CALL_GRAPH = NO + +# If the CALLER_GRAPH and HAVE_DOT tags are set to YES then +# doxygen will generate a caller dependency graph for every global function +# or class method. Note that enabling this option will significantly increase +# the time of a run. So in most cases it will be better to enable caller +# graphs for selected functions only using the \callergraph command. + +CALLER_GRAPH = NO + +# If the GRAPHICAL_HIERARCHY and HAVE_DOT tags are set to YES then doxygen +# will generate a graphical hierarchy of all classes instead of a textual one. + +GRAPHICAL_HIERARCHY = YES + +# If the DIRECTORY_GRAPH, SHOW_DIRECTORIES and HAVE_DOT tags are set to YES +# then doxygen will show the dependencies a directory has on other directories +# in a graphical way. The dependency relations are determined by the #include +# relations between the files in the directories. + +DIRECTORY_GRAPH = YES + +# The DOT_IMAGE_FORMAT tag can be used to set the image format of the images +# generated by dot. Possible values are svg, png, jpg, or gif. +# If left blank png will be used. If you choose svg you need to set +# HTML_FILE_EXTENSION to xhtml in order to make the SVG files +# visible in IE 9+ (other browsers do not have this requirement). + +DOT_IMAGE_FORMAT = png + +# If DOT_IMAGE_FORMAT is set to svg, then this option can be set to YES to +# enable generation of interactive SVG images that allow zooming and panning. +# Note that this requires a modern browser other than Internet Explorer. +# Tested and working are Firefox, Chrome, Safari, and Opera. For IE 9+ you +# need to set HTML_FILE_EXTENSION to xhtml in order to make the SVG files +# visible. Older versions of IE do not have SVG support. + +INTERACTIVE_SVG = NO + +# The tag DOT_PATH can be used to specify the path where the dot tool can be +# found. If left blank, it is assumed the dot tool can be found in the path. + +DOT_PATH = + +# The DOTFILE_DIRS tag can be used to specify one or more directories that +# contain dot files that are included in the documentation (see the +# \dotfile command). + +DOTFILE_DIRS = + +# The MSCFILE_DIRS tag can be used to specify one or more directories that +# contain msc files that are included in the documentation (see the +# \mscfile command). + +MSCFILE_DIRS = + +# The DOT_GRAPH_MAX_NODES tag can be used to set the maximum number of +# nodes that will be shown in the graph. If the number of nodes in a graph +# becomes larger than this value, doxygen will truncate the graph, which is +# visualized by representing a node as a red box. Note that doxygen if the +# number of direct children of the root node in a graph is already larger than +# DOT_GRAPH_MAX_NODES then the graph will not be shown at all. Also note +# that the size of a graph can be further restricted by MAX_DOT_GRAPH_DEPTH. + +DOT_GRAPH_MAX_NODES = 50 + +# The MAX_DOT_GRAPH_DEPTH tag can be used to set the maximum depth of the +# graphs generated by dot. A depth value of 3 means that only nodes reachable +# from the root by following a path via at most 3 edges will be shown. Nodes +# that lay further from the root node will be omitted. Note that setting this +# option to 1 or 2 may greatly reduce the computation time needed for large +# code bases. Also note that the size of a graph can be further restricted by +# DOT_GRAPH_MAX_NODES. Using a depth of 0 means no depth restriction. + +MAX_DOT_GRAPH_DEPTH = 0 + +# Set the DOT_TRANSPARENT tag to YES to generate images with a transparent +# background. This is disabled by default, because dot on Windows does not +# seem to support this out of the box. Warning: Depending on the platform used, +# enabling this option may lead to badly anti-aliased labels on the edges of +# a graph (i.e. they become hard to read). + +DOT_TRANSPARENT = NO + +# Set the DOT_MULTI_TARGETS tag to YES allow dot to generate multiple output +# files in one run (i.e. multiple -o and -T options on the command line). This +# makes dot run faster, but since only newer versions of dot (>1.8.10) +# support this, this feature is disabled by default. + +DOT_MULTI_TARGETS = YES + +# If the GENERATE_LEGEND tag is set to YES (the default) Doxygen will +# generate a legend page explaining the meaning of the various boxes and +# arrows in the dot generated graphs. + +GENERATE_LEGEND = YES + +# If the DOT_CLEANUP tag is set to YES (the default) Doxygen will +# remove the intermediate dot files that are used to generate +# the various graphs. + +DOT_CLEANUP = YES diff --git a/ext/nomali/LICENSE b/ext/nomali/LICENSE new file mode 100644 index 000000000..d64569567 --- /dev/null +++ b/ext/nomali/LICENSE @@ -0,0 +1,202 @@ + + Apache License + Version 2.0, January 2004 + http://www.apache.org/licenses/ + + TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION + + 1. Definitions. + + "License" shall mean the terms and conditions for use, reproduction, + and distribution as defined by Sections 1 through 9 of this document. + + "Licensor" shall mean the copyright owner or entity authorized by + the copyright owner that is granting the License. + + "Legal Entity" shall mean the union of the acting entity and all + other entities that control, are controlled by, or are under common + control with that entity. For the purposes of this definition, + "control" means (i) the power, direct or indirect, to cause the + direction or management of such entity, whether by contract or + otherwise, or (ii) ownership of fifty percent (50%) or more of the + outstanding shares, or (iii) beneficial ownership of such entity. + + "You" (or "Your") shall mean an individual or Legal Entity + exercising permissions granted by this License. + + "Source" form shall mean the preferred form for making modifications, + including but not limited to software source code, documentation + source, and configuration files. + + "Object" form shall mean any form resulting from mechanical + transformation or translation of a Source form, including but + not limited to compiled object code, generated documentation, + and conversions to other media types. + + "Work" shall mean the work of authorship, whether in Source or + Object form, made available under the License, as indicated by a + copyright notice that is included in or attached to the work + (an example is provided in the Appendix below). + + "Derivative Works" shall mean any work, whether in Source or Object + form, that is based on (or derived from) the Work and for which the + editorial revisions, annotations, elaborations, or other modifications + represent, as a whole, an original work of authorship. For the purposes + of this License, Derivative Works shall not include works that remain + separable from, or merely link (or bind by name) to the interfaces of, + the Work and Derivative Works thereof. + + "Contribution" shall mean any work of authorship, including + the original version of the Work and any modifications or additions + to that Work or Derivative Works thereof, that is intentionally + submitted to Licensor for inclusion in the Work by the copyright owner + or by an individual or Legal Entity authorized to submit on behalf of + the copyright owner. For the purposes of this definition, "submitted" + means any form of electronic, verbal, or written communication sent + to the Licensor or its representatives, including but not limited to + communication on electronic mailing lists, source code control systems, + and issue tracking systems that are managed by, or on behalf of, the + Licensor for the purpose of discussing and improving the Work, but + excluding communication that is conspicuously marked or otherwise + designated in writing by the copyright owner as "Not a Contribution." + + "Contributor" shall mean Licensor and any individual or Legal Entity + on behalf of whom a Contribution has been received by Licensor and + subsequently incorporated within the Work. + + 2. Grant of Copyright License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + copyright license to reproduce, prepare Derivative Works of, + publicly display, publicly perform, sublicense, and distribute the + Work and such Derivative Works in Source or Object form. + + 3. Grant of Patent License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + (except as stated in this section) patent license to make, have made, + use, offer to sell, sell, import, and otherwise transfer the Work, + where such license applies only to those patent claims licensable + by such Contributor that are necessarily infringed by their + Contribution(s) alone or by combination of their Contribution(s) + with the Work to which such Contribution(s) was submitted. If You + institute patent litigation against any entity (including a + cross-claim or counterclaim in a lawsuit) alleging that the Work + or a Contribution incorporated within the Work constitutes direct + or contributory patent infringement, then any patent licenses + granted to You under this License for that Work shall terminate + as of the date such litigation is filed. + + 4. Redistribution. You may reproduce and distribute copies of the + Work or Derivative Works thereof in any medium, with or without + modifications, and in Source or Object form, provided that You + meet the following conditions: + + (a) You must give any other recipients of the Work or + Derivative Works a copy of this License; and + + (b) You must cause any modified files to carry prominent notices + stating that You changed the files; and + + (c) You must retain, in the Source form of any Derivative Works + that You distribute, all copyright, patent, trademark, and + attribution notices from the Source form of the Work, + excluding those notices that do not pertain to any part of + the Derivative Works; and + + (d) If the Work includes a "NOTICE" text file as part of its + distribution, then any Derivative Works that You distribute must + include a readable copy of the attribution notices contained + within such NOTICE file, excluding those notices that do not + pertain to any part of the Derivative Works, in at least one + of the following places: within a NOTICE text file distributed + as part of the Derivative Works; within the Source form or + documentation, if provided along with the Derivative Works; or, + within a display generated by the Derivative Works, if and + wherever such third-party notices normally appear. The contents + of the NOTICE file are for informational purposes only and + do not modify the License. You may add Your own attribution + notices within Derivative Works that You distribute, alongside + or as an addendum to the NOTICE text from the Work, provided + that such additional attribution notices cannot be construed + as modifying the License. + + You may add Your own copyright statement to Your modifications and + may provide additional or different license terms and conditions + for use, reproduction, or distribution of Your modifications, or + for any such Derivative Works as a whole, provided Your use, + reproduction, and distribution of the Work otherwise complies with + the conditions stated in this License. + + 5. Submission of Contributions. Unless You explicitly state otherwise, + any Contribution intentionally submitted for inclusion in the Work + by You to the Licensor shall be under the terms and conditions of + this License, without any additional terms or conditions. + Notwithstanding the above, nothing herein shall supersede or modify + the terms of any separate license agreement you may have executed + with Licensor regarding such Contributions. + + 6. Trademarks. This License does not grant permission to use the trade + names, trademarks, service marks, or product names of the Licensor, + except as required for reasonable and customary use in describing the + origin of the Work and reproducing the content of the NOTICE file. + + 7. Disclaimer of Warranty. Unless required by applicable law or + agreed to in writing, Licensor provides the Work (and each + Contributor provides its Contributions) on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or + implied, including, without limitation, any warranties or conditions + of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A + PARTICULAR PURPOSE. You are solely responsible for determining the + appropriateness of using or redistributing the Work and assume any + risks associated with Your exercise of permissions under this License. + + 8. Limitation of Liability. In no event and under no legal theory, + whether in tort (including negligence), contract, or otherwise, + unless required by applicable law (such as deliberate and grossly + negligent acts) or agreed to in writing, shall any Contributor be + liable to You for damages, including any direct, indirect, special, + incidental, or consequential damages of any character arising as a + result of this License or out of the use or inability to use the + Work (including but not limited to damages for loss of goodwill, + work stoppage, computer failure or malfunction, or any and all + other commercial damages or losses), even if such Contributor + has been advised of the possibility of such damages. + + 9. Accepting Warranty or Additional Liability. While redistributing + the Work or Derivative Works thereof, You may choose to offer, + and charge a fee for, acceptance of support, warranty, indemnity, + or other liability obligations and/or rights consistent with this + License. However, in accepting such obligations, You may act only + on Your own behalf and on Your sole responsibility, not on behalf + of any other Contributor, and only if You agree to indemnify, + defend, and hold each Contributor harmless for any liability + incurred by, or claims asserted against, such Contributor by reason + of your accepting any such warranty or additional liability. + + END OF TERMS AND CONDITIONS + + APPENDIX: How to apply the Apache License to your work. + + To apply the Apache License to your work, attach the following + boilerplate notice, with the fields enclosed by brackets "[]" + replaced with your own identifying information. (Don't include + the brackets!) The text should be enclosed in the appropriate + comment syntax for the file format. We also recommend that a + file or class name and description of purpose be included on the + same "printed page" as the copyright notice for easier + identification within third-party archives. + + Copyright [yyyy] [name of copyright owner] + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. diff --git a/ext/nomali/Makefile b/ext/nomali/Makefile new file mode 100644 index 000000000..171ce2668 --- /dev/null +++ b/ext/nomali/Makefile @@ -0,0 +1,81 @@ +# +# Copyright (c) 2014-2015 ARM Limited +# All rights reserved +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +# Authors: Andreas Sandberg + +DOXYGEN = doxygen + +GCC_VERSION := $(shell $(CC) -dumpversion | sed -e 's/\.//g') +ifeq "$(shell expr $(GCC_VERSION) \< 47)" "1" +$(error Default GCC version is too old. Please use gcc 4.7 or newer.) +endif + +CPPFLAGS = -Iinclude/ +CFLAGS = -fvisibility=hidden -O1 -g -Wall +CXXFLAGS = -std=c++0x $(CFLAGS) +LDFLAGS= + +LIB_CPPFLAGS = $(CPPFLAGS) +LIB_CFLAGS = $(CFLAGS) -fPIC +LIB_CXXFLAGS = $(CXXFLAGS) -fPIC +LIB_LDFLAGS= $(LDFLAGS) -shared + +# Default targets +ALL := + +# Test targets +ALL_TESTS := + +# Dependency includes +DEPS := + +# Files/directories to remove in the clean target +CLEAN := + +all: _all + +dir:=lib +include $(dir)/Rules.mk + +dir:=tests +include $(dir)/Rules.mk + +_all: $(ALL) + +test: $(ALL_TESTS) + @set -e; \ + for T in $^ ; do \ + echo "Running $${T}"; \ + ./$${T}; \ + done + +docs: + $(DOXYGEN) Doxyfile + +depclean: + $(RM) $(DEPS) + +clean: + $(RM) -r $(CLEAN) + $(RM) -r docs/html + + +.PHONY: all _all test depclean clean docs + +# Include dependencies +-include $(MODEL_OBJS:.o=.d) +-include $(LIBMIDGARDMODEL_OBJS:.o=.d) +-include $(LIBNOMALI_OBJS:.o=.d) diff --git a/ext/nomali/Rules.app.mk b/ext/nomali/Rules.app.mk new file mode 100644 index 000000000..a99fcca36 --- /dev/null +++ b/ext/nomali/Rules.app.mk @@ -0,0 +1,31 @@ +# +# Copyright (c) 2014-2015 ARM Limited +# All rights reserved +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +# Authors: Andreas Sandberg + +# Makefile fragment for executables + +$(d)/%.o: $(d)/%.c + $(CC) -c $(CPPFLAGS) $(CFLAGS) -o $@ $< + +$(d)/%.o: $(d)/%.cc + $(CXX) -c $(CPPFLAGS) $(CXXFLAGS) -o $@ $< + +$(d)/%.d: $(d)/%.c + $(CC) -MM -MT $(<:.c=.o) $(CPPFLAGS) $(CFLAGS) -o $@ $< + +$(d)/%.d: $(d)/%.c + $(CXX) -MM -MT $(<:.cc=.o) $(CPPFLAGS) $(CXXFLAGS) -o $@ $< diff --git a/ext/nomali/Rules.lib.mk b/ext/nomali/Rules.lib.mk new file mode 100644 index 000000000..2b2444b88 --- /dev/null +++ b/ext/nomali/Rules.lib.mk @@ -0,0 +1,31 @@ +# +# Copyright (c) 2014-2015 ARM Limited +# All rights reserved +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +# Authors: Andreas Sandberg + +# Makefile fragment for libraries + +$(d)/%.o: $(d)/%.c + $(CC) -c $(LIB_CPPFLAGS) $(LIB_CFLAGS) -o $@ $< + +$(d)/%.o: $(d)/%.cc + $(CXX) -c $(LIB_CPPFLAGS) $(LIB_CXXFLAGS) -o $@ $< + +$(d)/%.d: $(d)/%.c + $(CC) -MM -MT $(<:.c=.o) $(LIB_CPPFLAGS) $(LIB_CFLAGS) -o $@ $< + +$(d)/%.d: $(d)/%.c + $(CXX) -MM -MT $(<:.cc=.o) $(LIB_CPPFLAGS) $(LIB_CXXFLAGS) -o $@ $< diff --git a/ext/nomali/SConscript b/ext/nomali/SConscript new file mode 100644 index 000000000..669908148 --- /dev/null +++ b/ext/nomali/SConscript @@ -0,0 +1,63 @@ +# -*- mode:python -*- + +# Copyright (c) 2015 ARM Limited +# All rights reserved. +# +# The license below extends only to copyright in the software and shall +# not be construed as granting a license to any other intellectual +# property including but not limited to intellectual property relating +# to a hardware implementation of the functionality of the software +# licensed hereunder. You may use the software subject to the license +# terms below provided that you ensure that this notice is replicated +# unmodified and in its entirety in all distributions of the software, +# modified or unmodified, in source code or in binary form. +# +# Redistribution and use in source and binary forms, with or without +# modification, are permitted provided that the following conditions are +# met: redistributions of source code must retain the above copyright +# notice, this list of conditions and the following disclaimer; +# redistributions in binary form must reproduce the above copyright +# notice, this list of conditions and the following disclaimer in the +# documentation and/or other materials provided with the distribution; +# neither the name of the copyright holders nor the names of its +# contributors may be used to endorse or promote products derived from +# this software without specific prior written permission. +# +# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +# A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +# OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +# +# Authors: Andreas Sandberg + +Import('main') + +main.Prepend(CPPPATH=Dir('./include')) + +nomali = main.Clone() + +nomali_sources = [ + "lib/gpu.cc", + "lib/gpublock.cc", + "lib/gpucontrol.cc", + "lib/jobcontrol.cc", + "lib/jobslot.cc", + "lib/mali_midgard.cc", + "lib/mali_t6xx.cc", + "lib/mali_t7xx.cc", + "lib/mmu.cc", + "lib/nomali_api.cc", +] + +nomali.Library('nomali', [ nomali.SharedObject(f) for f in nomali_sources ]) + +main.Append(LIBS=['nomali']) +main.Prepend(LIBPATH=[Dir('.')]) + diff --git a/ext/nomali/doxygen.sed b/ext/nomali/doxygen.sed new file mode 100755 index 000000000..5d460bdcd --- /dev/null +++ b/ext/nomali/doxygen.sed @@ -0,0 +1,46 @@ +#!/bin/sed -f +# +# Copyright (c) 2014-2015 ARM Limited +# All rights reserved +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +# Authors: Andreas Sandberg + +# READ BEFORE EDITING: +# +# * Avoid adding or removing newlines (e.g., deleting matched lines). It's +# much easier to understand the Doxygen logs if they point to the right +# line in the source files. +# +# * SED can be hard to read, so please document what your replacement rules +# are supposed to do and why. +# + +# Handle TODO/FIXME/BUG comments +/\/\/ \(TODO\|FIXME\|BUG\):/ { + # Transform the first line of the comment block into a Doxygen C++ comment. + s/\([^\]\)\/\/ /\1\/\/\/ /; + + : todo_comment_cont + # Replace any TODO/FIXME/BUG commands with Doxygen equivalents + s/\(TODO\|FIXME\):/@todo /; + s/\(BUG\):/@bug /; + # Get the next line + n; + # If this line is only contains whitespace and a comment, it is a + # conntinuation of the previous line. If so, make it a Doxygen comment. + s/\([:space:]*\)\/\/\([^\/]\)/\1\/\/\/\2/ ; + # Try to match another line if the previous s command matched a line. + t todo_comment_cont; +} diff --git a/ext/nomali/include/libnomali/nomali.h b/ext/nomali/include/libnomali/nomali.h new file mode 100644 index 000000000..9af2a417a --- /dev/null +++ b/ext/nomali/include/libnomali/nomali.h @@ -0,0 +1,333 @@ +/* + * Copyright (c) 2014-2015 ARM Limited + * All rights reserved + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + * Authors: Andreas Sandberg + */ + +#ifndef _LIBNOMALI_NOMALI_HH +#define _LIBNOMALI_NOMALI_HH + +#include + +#ifdef __cplusplus +extern "C" { +#endif + +/** + * @file libnomali/nomali.h + * @short This header defines the NoMali stub GPU model interface. + * + */ + +/** Opaque NoMali model handle. */ +typedef void* nomali_handle_t; + +/** + * NoMali error codes. + */ +enum { + /** No error */ + NOMALI_E_OK = 0, + /** Unknown error */ + NOMALI_E_UNKNOWN, + /** Memory allocation failed */ + NOMALI_E_MEMORY, + /** Invalid model handle */ + NOMALI_E_HANDLE, + /** Invalid parameter */ + NOMALI_E_INVALID, + + /** + * Number of errors defined + * + * @note This error, and higher error numbers, can be issued if + * the library is newer than the header file. Software should + * tread this condition as an unknown error. + */ + NOMALI_E_NUM_ERRORS +}; +typedef int nomali_error_t; + +enum { + NOMALI_GPU_T60X = 0, + NOMALI_GPU_T62X, + NOMALI_GPU_T76X, + + NOMALI_GPU_T760 = NOMALI_GPU_T76X, +}; +typedef int nomali_gpu_type_t; + +typedef struct { + nomali_gpu_type_t type; + + unsigned ver_maj; + unsigned ver_min; + unsigned ver_status; +} nomali_config_t; + +enum { + /** Model is signalling an interrupt */ + NOMALI_CALLBACK_INT = 0, + /** Model read physical memory callback */ + NOMALI_CALLBACK_MEMREAD, + /** Model write physical memory callback */ + NOMALI_CALLBACK_MEMWRITE, + + /** Number of defined callbacks */ + NOMALI_CALLBACK_NUM_CALLBACKS +}; +typedef int nomali_callback_type_t; + +enum { + NOMALI_INT_GPU = 0, + NOMALI_INT_JOB, + NOMALI_INT_MMU, +}; +typedef int nomali_int_t; + +typedef uint64_t nomali_addr_t; +typedef uint64_t nomali_size_t; + +/** + * Callback information structure. + */ +typedef struct { + /** Callback type */ + nomali_callback_type_t type; + /** Pointer to user-defined data associated with callback */ + void *usr; + /** Pointer to callback function */ + union { + /** + * Interrupt state change + * + * @param h Model instance handle. + * @param usr User-defined data associated with callback. + * @param intno Interrupt number. + * @param set Non-zero if raising an interrupt, zero if clearing. + */ + void (*interrupt)(nomali_handle_t h, void *usr, + nomali_int_t intno, int set); + void (*memwrite)(nomali_handle_t h, void *usr, + nomali_addr_t addr, uint32_t value); + uint32_t (*memread)(nomali_handle_t h, void *usr, + nomali_addr_t addr); + } func; +} nomali_callback_t; + +/** + * GPU information struct. See nomali_get_info(). + */ +typedef struct { + /** Size (in bytes) of the register window used by the GPU */ + nomali_size_t reg_size; +} nomali_info_t; + +typedef uint32_t nomali_api_version_t; + +/** + * Current version of the NoMali API + * + * This version number will increase whenever the API changes. + * + * @see nomali_api_version() + */ +#define NOMALI_API_VERSION 0 + +/** + * Get the version of the API implemented by the library. + * + * Before instantiating a NoMali model, the driving application need + * to ensure that the library implements a compatible version of the + * NoMali API. This is done by calling this function and matching the + * return value with the NOMALI_API_VERSION define. The result of any + * call to the NoMali library is undefined if there is a miss-match + * between the two. + */ +nomali_api_version_t nomali_api_version(); + +/** + * Create an instance of the NoMali model. + * + * @param[out] h Handle of the new NoMali model instance, undefined on + * error. + * + * @param[in] cfg NoMali GPU configuration. + * + * @errors + * @error NOMALI_E_OK on success. + * @error NOMALI_E_MEMORY if a memory allocation failed. + * @error NOMALI_E_INVALID if a pointer to an output parameter is + * invalid. + */ +nomali_error_t nomali_create(nomali_handle_t *h, const nomali_config_t *cfg); +/** + * Destroy and free resources used by an existing NoMali instance. + * + * @param[in] h Model instance handle. + * + * @errors + * @error NOMALI_E_OK on success. + * @error NOMALI_E_HANDLE if the handle was invalid. + */ +nomali_error_t nomali_destroy(nomali_handle_t h); + + +/** + * Get a textual description of an error number. + * + * @param[in] error Error number to resolve. + * + * @return Pointer to a constant, null-terminated, string describing + * an error number. + */ +const char *nomali_errstr(nomali_error_t error); + +/** + * Setup callbacks from the model. + * + * @param[in] h Model instance handle. + * @param[in] callback Structure describing the new callback to be + * installed. + * + * @errors + * @error NOMALI_E_OK on success. + * @error NOMALI_E_HANDLE if the handle was invalid. + * @error NOMALI_E_INVALID if the callback type was invalid. + * + * @see nomali_callback_t + */ +nomali_error_t nomali_set_callback(nomali_handle_t h, + const nomali_callback_t *callback); + +/** + * Get information about the hardware simulated by the model. + * + * @param[in] h Model instance handle. + * @param[out] info Structure describing the model. + * + * @errors + * @error NOMALI_E_OK on success. + * @error NOMALI_E_HANDLE if the handle was invalid. + * @error NOMALI_E_INVALID if info is not pointing to a valid + * location. + * + * @see nomali_info_t + */ +nomali_error_t nomali_get_info(nomali_handle_t h, + nomali_info_t *info); + +/** + * Perform a reset of the device. + * + * @param[in] h Model instance handle. + * + * @errors + * @error NOMALI_E_OK on success. + * @error NOMALI_E_HANDLE if the handle was invalid. + */ +nomali_error_t nomali_reset(nomali_handle_t h); + +/** + * Read a register within the device. + * + * @param[in] h Model instance handle. + * @param[out] value Pointer to output. + * @param[in] addr Address to read. + * + * @errors + * @error NOMALI_E_OK on success. + * @error NOMALI_E_HANDLE if the handle was invalid. + * @error NOMALI_E_INVALID if an invalid register was specified or if the + * pointer to the output location was invalid. + */ +nomali_error_t nomali_reg_read(nomali_handle_t h, uint32_t *value, + nomali_addr_t addr); + +/** + * Write to a register within the device. + * + * @param[in] h Model instance handle. + * @param[in] addr Address to read. + * @param[in] value Value to write to the register. + * + * @errors + * @error NOMALI_E_OK on success. + * @error NOMALI_E_HANDLE if the handle was invalid. + * @error NOMALI_E_INVALID if an invalid register was specified. + */ +nomali_error_t nomali_reg_write(nomali_handle_t h, + nomali_addr_t addr, uint32_t value); + +/** + * Read a register without side effects. + * + * @param[in] h Model instance handle. + * @param[out] value Pointer to output. + * @param[in] addr Address to read. + * + * @errors + * @error NOMALI_E_OK on success. + * @error NOMALI_E_HANDLE if the handle was invalid. + * @error NOMALI_E_INVALID if an invalid register was specified or if the + * pointer to the output location was invalid. + */ +nomali_error_t nomali_reg_read_raw(nomali_handle_t h, uint32_t *value, + nomali_addr_t addr); + +/** + * Write to a register without side effects. + * + * @param[in] h Model instance handle. + * @param[in] addr Address to read. + * @param[in] value Value to write to the register. + * + * @errors + * @error NOMALI_E_OK on success. + * @error NOMALI_E_HANDLE if the handle was invalid. + * @error NOMALI_E_INVALID if an invalid register was specified. + */ +nomali_error_t nomali_reg_write_raw(nomali_handle_t h, + nomali_addr_t addr, uint32_t value); + +/** + * Get the state of an interrupt line + * + * This function queries the state of one of the GPU's interrupt + * lines. The state of the interrupt line is returned in 'state', + * which is 1 if the interrupt is being asserted and 0 otherwise. The + * value of the state variable is undefined if the function call + * fails. + * + * @param[in] h Model instance handle. + * @param[out] state Pointer to output, 1 if the interrupt is + * asserted, 0 otherwise. + * @param[in] intno Interrupt to query. + * + * @errors + * @error NOMALI_E_OK on success. + * @error NOMALI_E_HANDLE if the handle was invalid. + * @error NOMALI_E_INVALID if an invalid interrupt was specified or if + * pointer to the output location was invalid. + */ +nomali_error_t nomali_int_state(nomali_handle_t h, int *state, + nomali_int_t intno); + +#ifdef __cplusplus +}; +#endif + +#endif /* _LIBNOMALI_NOMALI_HH */ diff --git a/ext/nomali/lib/Rules.mk b/ext/nomali/lib/Rules.mk new file mode 100644 index 000000000..34fb6e32e --- /dev/null +++ b/ext/nomali/lib/Rules.mk @@ -0,0 +1,55 @@ +# +# Copyright (c) 2014-2015 ARM Limited +# All rights reserved +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +# Authors: Andreas Sandberg + +sp := $(sp).x +dirstack_$(sp) := $(d) +d := $(dir) + +NOMALI_OBJS := $(addprefix $(d)/, \ + gpu.o \ + gpublock.o \ + gpucontrol.o \ + jobcontrol.o \ + jobslot.o \ + mmu.o \ + \ + mali_midgard.o \ + mali_t6xx.o \ + mali_t7xx.o \ + ) + +LIBNOMALI_OBJS := $(addprefix $(d)/, \ + nomali_api.o \ + ) + +OBJS := $(NOMALI_OBJS) \ + $(LIBMIDGARDMODEL_OBJS) + +LIBS := libnomali.so + +ALL := $(ALL) $(LIBS) +DEPS := $(DEPS) $(OBJS:.o=.d) +CLEAN := $(CLEAN) $(OBJS) $(LIBS) + +include Rules.lib.mk + +libnomali.so: $(NOMALI_OBJS) $(LIBNOMALI_OBJS) + $(CXX) $(LIB_LDFLAGS) -o $@ $^ + +d := $(dirstack_$(sp)) +sp := $(basename $(sp)) diff --git a/ext/nomali/lib/gpu.cc b/ext/nomali/lib/gpu.cc new file mode 100644 index 000000000..88646ab36 --- /dev/null +++ b/ext/nomali/lib/gpu.cc @@ -0,0 +1,112 @@ +/* + * Copyright (c) 2014-2015 ARM Limited + * All rights reserved + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include "gpu.hh" + +#include "gpucontrol.hh" +#include "jobcontrol.hh" +#include "mmu.hh" +#include "regutils.hh" + +namespace NoMali { + +GPU::GPU(GPUControl &gc, JobControl &jc, MMU &_mmu) + : gpuControl(gc), jobControl(jc), mmu(_mmu), + blocks({&gpuControl, // REG_BLOCK_GPU + &jobControl, // REG_BLOCK_JOB + &mmu}) // REG_BLOCK_MMU +{ +} + +GPU::~GPU() +{ +} + +void +GPU::reset() +{ + for (auto *block : blocks) + block->reset(); +} + +uint32_t +GPU::readReg(RegAddr addr) +{ + GPUBlock * const block(getGPUBlock(addr)); + + return block ? block->readReg(getBlockReg(addr)) : 0; +} + +void +GPU::writeReg(RegAddr addr, uint32_t value) +{ + GPUBlock * const block(getGPUBlock(addr)); + + if (block) + block->writeReg(getBlockReg(addr), value); +} + +uint32_t +GPU::readRegRaw(RegAddr addr) +{ + GPUBlock * const block(getGPUBlock(addr)); + + return block ? block->readRegRaw(getBlockReg(addr)) : 0; +} + +void +GPU::writeRegRaw(RegAddr addr, uint32_t value) +{ + GPUBlock * const block(getGPUBlock(addr)); + + if (block) + block->writeRegRaw(getBlockReg(addr), value); +} + + +bool +GPU::intGPUAsserted() const +{ + return gpuControl.intAsserted(); +} + +bool +GPU::intJobAsserted() const +{ + return jobControl.intAsserted(); +} + +bool +GPU::intMMUAsserted() const +{ + return mmu.intAsserted(); +} + + +GPUBlock * +GPU::getGPUBlock(RegAddr addr) +{ + const RegBlock block(getRegBlock(addr)); + const uint16_t block_no(static_cast(block)); + + if (block_no < blocks.size()) + return blocks[block_no]; + else + return nullptr; +} + +} diff --git a/ext/nomali/lib/gpu.hh b/ext/nomali/lib/gpu.hh new file mode 100644 index 000000000..f167f1012 --- /dev/null +++ b/ext/nomali/lib/gpu.hh @@ -0,0 +1,205 @@ +/* + * Copyright (c) 2014-2015 ARM Limited + * All rights reserved + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + * Authors: Andreas Sandberg + */ + +#ifndef _LIBNOMALIMODEL_GPU_HH +#define _LIBNOMALIMODEL_GPU_HH + +#include + +#include "types.hh" + +namespace NoMali { + +class GPUBlock; +class GPUControl; +class JobControl; +class MMU; + +/** + * Top-level GPU component (abstract). + */ +class GPU +{ + public: + /** + * Instantiate a GPU from a set of functional blocks. + * + * @param gpuControl GPU control implementation. + * @param jobControl Job control implementation. + * @param mmu MMU implementation. + */ + GPU(GPUControl &gpuControl, JobControl &jobControl, MMU &mmu); + virtual ~GPU() = 0; + + /** + * Reset the whole GPU + * + * The default implementation of this method calls the reset() on + * all the function blocks. Function blocks in turn typically sets + * all registers to zero. + */ + virtual void reset(); + + + /** + * @{ + * @name Register Interface + */ + + /** + * Read a register value from the GPU. + * + * This method decodes the address to find the function block an + * access is intended for and forward the register access to that + * block. The access that reaches the block does not include the + * block base address. + * + * @param addr Register address to read. + * @return Value of the register. + */ + virtual uint32_t readReg(RegAddr addr); + + /** + * Write a register value to the GPU. + * + * This method decodes the address to find the function block an + * access is intended for and forward the register access to that + * block. The access that reaches the block does not include the + * block base address. + * + * @param addr Target address for the write operation. + * @param value Value to write. + */ + virtual void writeReg(RegAddr addr, uint32_t value); + + /** + * Read a register value from the GPU without side effects. + * + * This method decodes the address to find the function block an + * access is intended for and forward the register access to that + * block. The access that reaches the block does not include the + * block base address. + * + * Unlike a normal read (readReg()), this method does not include + * any side effects and reads straight from the register file. It + * is primarily intended for things checkpointing. + * + * @param addr Register address to read. + * @return Value of the register. + */ + virtual uint32_t readRegRaw(RegAddr addr); + + /** + * Write a register value to the GPU without side effects. + * + * This method decodes the address to find the function block an + * access is intended for and forward the register access to that + * block. The access that reaches the block does not include the + * block base address. + * + * Unlike a normal write (writeReg()), this method does not + * include any side effects and writes straight into the register + * file. It is primarily intended for things checkpointing. + * + * @param addr Target address for the write operation. + * @param value Value to write. + */ + virtual void writeRegRaw(RegAddr addr, uint32_t value); + + /** @} */ + + /** + * @{ + * @name Callbacks + */ + + /** + * Job interrupt state change + * + * @param set Non-zero if raising interrupt, zero if clearing. + */ + virtual void intJob(int set) {}; + /** + * MMU interrupt state change + * + * @param set Non-zero if raising interrupt, zero if clearing. + */ + virtual void intMMU(int set) {}; + /** + * GPU interrupt state change + * + * @param set Non-zero if raising interrupt, zero if clearing. + */ + virtual void intGPU(int set) {}; + + /** @} */ + + + /** + * Check if the GPU interrupt has been asserted. + * + * @see GPUControl::intAsserted() + * + * @return true if the GPU control block reports that an interrupt + * has been asserted. + */ + bool intGPUAsserted() const; + /** + * Check if the job interrupt has been asserted. + * + * @see JobControl::intAsserted() + * + * @return true if the job control block reports that an interrupt + * has been asserted. + */ + bool intJobAsserted() const; + /** + * Check if the MMU interrupt has been asserted. + * + * @see JobControl::intAsserted() + * + * @return true if the GPU control block reports that an interrupt + * has been asserted. + */ + bool intMMUAsserted() const; + + private: + /** + * Resolve an address into a functional block within the GPU. + * + * @return Valid pointer or NULL if address is out of range. + */ + GPUBlock *getGPUBlock(RegAddr addr); + + GPUControl &gpuControl; + JobControl &jobControl; + MMU &mmu; + + /** + * Vector of control blocks. + * + * @note The order MUST have the same correspond to the + * values in the RegBlock enum. + */ + const std::vector blocks; +}; + +} + +#endif // _LIBNOMALIMODEL_GPU_HH diff --git a/ext/nomali/lib/gpublock.cc b/ext/nomali/lib/gpublock.cc new file mode 100644 index 000000000..7bc88de7e --- /dev/null +++ b/ext/nomali/lib/gpublock.cc @@ -0,0 +1,156 @@ +/* + * Copyright (c) 2014-2015 ARM Limited + * All rights reserved + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + * Authors: Andreas Sandberg + */ + +#include "gpublock.hh" + +#include "gpu.hh" +#include "regutils.hh" + +namespace NoMali { + +GPUBlock::GPUBlock(GPU &_gpu) + : gpu(_gpu), regs(BLOCK_NUM_REGS) +{ +} + +GPUBlock::GPUBlock(GPU &_gpu, RegVector::size_type no_regs) + : gpu(_gpu), regs(no_regs) +{ +} + +GPUBlock::GPUBlock(GPUBlock &&rhs) + : gpu(rhs.gpu), + regs(std::move(rhs.regs)) +{ +} + +GPUBlock::~GPUBlock() +{ +} + +void +GPUBlock::reset() +{ + for (auto &r : regs) + r = 0; +} + +uint32_t +GPUBlock::readReg(RegAddr addr) +{ + return readRegRaw(addr); +} + +void +GPUBlock::writeReg(RegAddr addr, uint32_t value) +{ + writeRegRaw(addr, value); +} + +uint32_t +GPUBlock::readRegRaw(RegAddr addr) +{ + return regs[addr]; +} + +void +GPUBlock::writeRegRaw(RegAddr addr, uint32_t value) +{ + regs[addr] = value; +} + + + +GPUBlockInt::GPUBlockInt(GPU &_gpu, + const RegAddr &irq_raw_stat, + const RegAddr &irq_clear, + const RegAddr &irq_mask, + const RegAddr &irq_stat) + : GPUBlock(_gpu), + addrIrqRawStat(irq_raw_stat), addrIrqClear(irq_clear), + addrIrqMask(irq_mask), addrIrqStat(irq_stat) +{ +} + +GPUBlockInt::~GPUBlockInt() +{ +} + +uint32_t +GPUBlockInt::readReg(RegAddr addr) +{ + if (addr == addrIrqStat) { + return irqStatus(); + } else { + return GPUBlock::readReg(addr); + } +} + +void +GPUBlockInt::writeReg(RegAddr addr, uint32_t value) +{ + if (addr == addrIrqRawStat) { + raiseInterrupt(value); + } else if (addr == addrIrqClear) { + clearInterrupt(value); + } else if (addr == addrIrqMask ) { + const bool old_int(intAsserted()); + GPUBlock::writeReg(addr, value); + if (old_int != intAsserted()) + onInterrupt(intAsserted()); + } else if (addr == addrIrqStat ) { + // Ignore writes to the IRQ status register + } else { + // Handle addrIrqMask & defaults + GPUBlock::writeReg(addr, value); + } +} + + + +void +GPUBlockInt::raiseInterrupt(uint32_t ints) +{ + const bool old_int(intAsserted()); + + regs[addrIrqRawStat] |= ints; + // Is the interrupt line going high? + if (!old_int && intAsserted()) + onInterrupt(1); +} + +void +GPUBlockInt::clearInterrupt(uint32_t ints) +{ + const bool old_int(intAsserted()); + + regs[addrIrqRawStat] &= ~ints; + // Is the interrupt line going low? + if (old_int && !intAsserted()) + onInterrupt(0); +} + +uint32_t +GPUBlockInt::irqStatus() const +{ + return regs[addrIrqRawStat] & regs[addrIrqMask]; +} + + +} diff --git a/ext/nomali/lib/gpublock.hh b/ext/nomali/lib/gpublock.hh new file mode 100644 index 000000000..330ffcb7c --- /dev/null +++ b/ext/nomali/lib/gpublock.hh @@ -0,0 +1,221 @@ +/* + * Copyright (c) 2014-2015 ARM Limited + * All rights reserved + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + * Authors: Andreas Sandberg + */ + +#ifndef _LIBNOMALIMODEL_GPUBLOCK_HH +#define _LIBNOMALIMODEL_GPUBLOCK_HH + +#include "types.hh" + +namespace NoMali { + +class GPU; + +/** + * Base class for GPU function blocks providing common access + * functions. + */ +class GPUBlock +{ + public: + GPUBlock(GPU &_gpu); + GPUBlock(GPU &_gpu, RegVector::size_type no_regs); + GPUBlock(GPUBlock &&rhs); + virtual ~GPUBlock() = 0; + + /** + * Reset the function block. + * + * This method is called to simulated a hard reset of the GPU. It + * resets all registers to their default state and resets any + * block-specific state. The default implementation resets all + * registers to 0. + */ + virtual void reset(); + + + /** + * @{ + * @name Register Interface + */ + + /** + * Read a register within a function block. + * + * @param addr Function-block relative address. + * @return Register value (32-bits) + */ + virtual uint32_t readReg(RegAddr addr); + + /** + * Write to a register within a function block. + * + * @param addr Function-block relative address. + * @param value New value (32-bits) + */ + virtual void writeReg(RegAddr addr, uint32_t value); + + + /** + * Read a register within a function block without side effects. + * + * Unlike a normal read (readReg()), this method does not include + * any side effects and reads straight from the register file. It + * is primarily intended for things checkpointing. + * + * @param addr Function-block relative address. + * @return Register value (32-bits) + */ + virtual uint32_t readRegRaw(RegAddr addr); + + /** + * Write to a register within a function block without side + * effects. + * + * Unlike a normal write (writeReg()), this method does not + * include any side effects and writes straight into the register + * file. It is primarily intended for things checkpointing. + * + * @param addr Function-block relative address. + * @param value New value (32-bits) + */ + virtual void writeRegRaw(RegAddr addr, uint32_t value); + + /** @} */ + + protected: + /** Reference to the top-level GPU component */ + GPU &gpu; + + /** GPU block register file */ + RegVector regs; + + + private: + /** Disable the default constructor */ + GPUBlock(); + + /** Disable the copy constructor */ + GPUBlock(GPUBlock &_rhs); + + /** Disable the assignment operator */ + GPUBlock &operator=(GPUBlock &_rhs); +}; + +/** + * Base class for interrupt enabled GPU function blocks. + * + * Function blocks with interrupt functionality implement four + * different registers controlling interrupts: + *
    + *
  • XX_IRQ_RAWSTAT -- Raw interrupt state bit mask. (RW) + *
  • XX_IRQ_CLEAR -- Interrupt clear register. (WO) + *
  • XX_IRQ_MASK -- Bitmaks of enabled interrupts. (RW) + *
  • XX_IRQ_STATUS -- Currently pending unmasked interrupts. (RO) + *
+ * + * This class provides implements the handling of the registers above + * and utility functions to raise interrupts from the function block + * models. + */ +class GPUBlockInt + : public GPUBlock +{ + public: + GPUBlockInt(GPU &_gpu, + const RegAddr &irq_raw_stat, + const RegAddr &irq_clear, + const RegAddr &irq_mask, + const RegAddr &irq_stat); + virtual ~GPUBlockInt() = 0; + + uint32_t readReg(RegAddr addr) override; + void writeReg(RegAddr addr, uint32_t value) override; + + /** + * Raise an interrupt from this function block. + * + * Calling this method flags the interrupts in ints as pending in + * the raw interrupt status register. If this operation asserts a + * new unmasked interrupt (i.e., the state of the interrupt status + * register changes), the onInterrupt() callback is called to + * signal an interrupt state change. + * + * @param ints Bitfield representing interrupts to raise. + */ + void raiseInterrupt(uint32_t ints); + + /** + * Clear an interrupt from this function block. + * + * Calling this method clears the interrupts in ints in the raw + * interrupt status register. If this operation clears a an + * existing interrupt (i.e., the state of the interrupt status + * register changes), the onInterrupt() callback is called to + * signal an interrupt state change. + * + * @param ints Bitfield representing interrupts to raise. + */ + void clearInterrupt(uint32_t ints); + + /** + * Current interrupt status + * + * @return The value of the raw interrupt status register + * logically anded with the interrupt mask register. + */ + uint32_t irqStatus() const; + + /** + * Are there unmasked interrupts pending? + * + * @return true if the interrupt status register is non-zero, + * false otherwise. + */ + bool intAsserted() const { return !!irqStatus(); } + + protected: + /** + * Callback method for interrupt status change. + * + * This method is called whenever the interrupt signal going out + * of this GPU block changes. The new state of the signal can be + * determined from the 'set' parameter which is non-zero if the + * inerrupt is raised and zero if it is cleared. The state of the + * interrupt signal can also be queried using the irqStatus() + * method. + * + * @see raiseInterrupt() + * @see clearInterrupt() + * @see irqStatus() + * + * @param set Non-zero to raise interrupt, zero to clear + * interrupt. + */ + virtual void onInterrupt(int set) = 0; + + private: + const RegAddr addrIrqRawStat; + const RegAddr addrIrqClear; + const RegAddr addrIrqMask; + const RegAddr addrIrqStat; +}; + +} + +#endif // _LIBNOMALIMODEL_GPUBLOCK_HH diff --git a/ext/nomali/lib/gpucontrol.cc b/ext/nomali/lib/gpucontrol.cc new file mode 100644 index 000000000..688f5867e --- /dev/null +++ b/ext/nomali/lib/gpucontrol.cc @@ -0,0 +1,177 @@ +/* + * Copyright (c) 2014-2015 ARM Limited + * All rights reserved + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + * Authors: Andreas Sandberg + */ + +#include "gpucontrol.hh" +#include "gpu.hh" +#include "regutils.hh" + +namespace NoMali { + +typedef void (GPUControl::*GpuCmdHandler)(uint32_t); + +const std::vector GPUControl::cmds { + &GPUControl::cmdNop, // GPU_COMMAND_NOP + &GPUControl::cmdSoftReset, // GPU_COMMAND_SOFT_RESET + &GPUControl::cmdHardReset, // GPU_COMMAND_HARD_RESET + &GPUControl::cmdPerfCntClear, // GPU_COMMAND_PRFCNT_CLEAR + &GPUControl::cmdPerfCntSample, // GPU_COMMAND_PRFCNT_SAMPLE + &GPUControl::cmdCycleCountStart, // GPU_COMMAND_CYCLE_COUNT_START + &GPUControl::cmdCycleCountStop, // GPU_COMMAND_COUNT_STOP + &GPUControl::cmdCleanCaches, // GPU_COMMAND_CLEAN_CACHES + &GPUControl::cmdCleanInvCaches, // GPU_COMMAND_CLEAN_INV_CACHES +}; + +GPUControl::GPUControl(GPU &_gpu) + : GPUBlockInt(_gpu, + RegAddr(GPU_IRQ_RAWSTAT), + RegAddr(GPU_IRQ_CLEAR), + RegAddr(GPU_IRQ_MASK), + RegAddr(GPU_IRQ_STATUS)) +{ +} + +GPUControl::~GPUControl() +{ +} + +void +GPUControl::reset() +{ + GPUBlock::reset(); +} + +void +GPUControl::writeReg(RegAddr addr, uint32_t value) +{ + switch (addr.value) { + case GPU_IRQ_RAWSTAT: + case GPU_IRQ_CLEAR: + case GPU_IRQ_MASK: + case GPU_IRQ_STATUS: + GPUBlockInt::writeReg(addr, value); + break; + + case GPU_COMMAND: + gpuCommand(value); + break; + + case SHADER_PWRON_LO: + case SHADER_PWRON_HI: + case TILER_PWRON_LO: + case TILER_PWRON_HI: + case L2_PWRON_LO: + case L2_PWRON_HI: + case L3_PWRON_LO: + case L3_PWRON_HI: { + const RegAddr ready_reg(SHADER_READY_LO + + (addr.value - SHADER_PWRON_LO)); + const RegAddr present_reg(SHADER_PRESENT_LO + + (addr.value - SHADER_PWRON_LO)); + + regs[ready_reg] |= value & regs[present_reg]; + raiseInterrupt(POWER_CHANGED_SINGLE | POWER_CHANGED_ALL); + } break; + + case SHADER_PWROFF_LO: + case SHADER_PWROFF_HI: + case TILER_PWROFF_LO: + case TILER_PWROFF_HI: + case L2_PWROFF_LO: + case L2_PWROFF_HI: + case L3_PWROFF_LO: + case L3_PWROFF_HI: { + const RegAddr ready_reg(SHADER_READY_LO + + (addr.value - SHADER_PWROFF_LO)); + + regs[ready_reg] &= ~value; + raiseInterrupt(POWER_CHANGED_SINGLE | POWER_CHANGED_ALL); + } break; + + default: + // Ignore writes by default + break; + }; +} + +void +GPUControl::onInterrupt(int set) +{ + gpu.intGPU(set); +} + +void +GPUControl::gpuCommand(uint32_t cmd) +{ + if (cmd < cmds.size()) + (this->*cmds[cmd])(cmd); +} + +void +GPUControl::cmdNop(uint32_t cmd) +{ +} + +void +GPUControl::cmdHardReset(uint32_t cmd) +{ + gpu.reset(); + raiseInterrupt(RESET_COMPLETED); +} + +void +GPUControl::cmdSoftReset(uint32_t cmd) +{ + gpu.reset(); + raiseInterrupt(RESET_COMPLETED); +} + +void +GPUControl::cmdPerfCntClear(uint32_t cmd) +{ +} + +void +GPUControl::cmdPerfCntSample(uint32_t cmd) +{ + raiseInterrupt(PRFCNT_SAMPLE_COMPLETED); +} + +void +GPUControl::cmdCycleCountStart(uint32_t cmd) +{ +} + +void +GPUControl::cmdCycleCountStop(uint32_t cmd) +{ +} + +void +GPUControl::cmdCleanCaches(uint32_t cmd) +{ + raiseInterrupt(CLEAN_CACHES_COMPLETED); +} + +void +GPUControl::cmdCleanInvCaches(uint32_t cmd) +{ + raiseInterrupt(CLEAN_CACHES_COMPLETED); +} + +} diff --git a/ext/nomali/lib/gpucontrol.hh b/ext/nomali/lib/gpucontrol.hh new file mode 100644 index 000000000..b5bac4eb6 --- /dev/null +++ b/ext/nomali/lib/gpucontrol.hh @@ -0,0 +1,159 @@ +/* + * Copyright (c) 2014-2015 ARM Limited + * All rights reserved + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + * Authors: Andreas Sandberg + */ + +#ifndef _LIBNOMALIMODEL_GPUCONTROL_HH +#define _LIBNOMALIMODEL_GPUCONTROL_HH + +#include + +#include "types.hh" +#include "gpublock.hh" + +namespace NoMali { + +class GPU; + +/** + * Limited GPU control block implementation. + * + * This is a minimal implementation of the Midgard GPU control + * block. It contains the stuff necessary to do command decoding and + * dispatch, interrupt handling, and GPU block ready handling. + * + * An actual GPU implementation should specialize this class to setup + * the following registers from the reset() method: + *
    + *
  • GPU_ID + *
  • Feature registers (XX_FEATURES) + *
  • Present registers (XX_PRESENT) + *
  • Thread discovery (THREAD_XX) + *
  • Present registers (XX_PRESENT) + *
+ */ +class GPUControl + : public GPUBlockInt +{ + public: + GPUControl(GPU &_gpu); + virtual ~GPUControl(); + + virtual void reset() override = 0; + + void writeReg(RegAddr idx, uint32_t value) override; + + protected: + void onInterrupt(int set) override; + + /** + * @{ + * @name GPU control block commands + */ + + /** + * Control command dispatcher. + * + * This method is called whenever there is a write to the + * GPU_COMMAND register. The method uses a lookup table to call + * the right command handling method. + * + * @param cmd Command number (see the Midgard architecture + * specification) + */ + virtual void gpuCommand(uint32_t cmd); + /** + * Command handler for No-ops. + * + * @param cmd Command number (see the Midgard architecture + * specification) + */ + virtual void cmdNop(uint32_t cmd); + /** + * Command handler for GPU-wide hard resets + * + * @param cmd Command number (see the Midgard architecture + * specification) + */ + virtual void cmdHardReset(uint32_t cmd); + /** + * Command handler for GPU-wide soft resets + * + * @param cmd Command number (see the Midgard architecture + * specification) + */ + virtual void cmdSoftReset(uint32_t cmd); + /** + * Command handler for performance counter clear operations. + * + * @param cmd Command number (see the Midgard architecture + * specification) + */ + virtual void cmdPerfCntClear(uint32_t cmd); + /** + * Command handler for performance counter sample operations. + * + * @param cmd Command number (see the Midgard architecture + * specification) + */ + virtual void cmdPerfCntSample(uint32_t cmd); + /** + * Command handler for cycle counter start operations. + * + * @param cmd Command number (see the Midgard architecture + * specification) + */ + virtual void cmdCycleCountStart(uint32_t cmd); + /** + * Command handler for cycle counter stop operations. + * + * @param cmd Command number (see the Midgard architecture + * specification) + */ + virtual void cmdCycleCountStop(uint32_t cmd); + /** + * Command handler for cache cleaning operations. + * + * @param cmd Command number (see the Midgard architecture + * specification) + */ + virtual void cmdCleanCaches(uint32_t cmd); + /** + * Command handler for cache clean and invalidate operations. + * + * @param cmd Command number (see the Midgard architecture + * specification) + */ + virtual void cmdCleanInvCaches(uint32_t cmd); + + /** @} */ + + protected: + typedef void (GPUControl::*cmd_t)(uint32_t); + /** + * Mapping between command IDs and command handling methods. + * + * @note The order of this vector MUST correspond to the + * GPU control command IDs in the Midgard architecture + * specification. + */ + static const std::vector cmds; +}; + +} + +#endif // _LIBNOMALIMODEL_GPUCONTROL_HH diff --git a/ext/nomali/lib/jobcontrol.cc b/ext/nomali/lib/jobcontrol.cc new file mode 100644 index 000000000..ca4518c09 --- /dev/null +++ b/ext/nomali/lib/jobcontrol.cc @@ -0,0 +1,139 @@ +/* + * Copyright (c) 2014-2015 ARM Limited + * All rights reserved + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + * Authors: Andreas Sandberg + */ + +#include "jobcontrol.hh" + +#include "gpu.hh" +#include "regutils.hh" + +namespace NoMali { + +JobControl::JobControl(GPU &_gpu) + : GPUBlockInt(_gpu, + RegAddr(JOB_IRQ_RAWSTAT), + RegAddr(JOB_IRQ_CLEAR), + RegAddr(JOB_IRQ_MASK), + RegAddr(JOB_IRQ_STATUS)) +{ + slots.reserve(16); + for (int i = 0; i < 16; ++i) + slots.emplace_back(_gpu, *this, i); + +} + +JobControl::~JobControl() +{ +} + +uint32_t +JobControl::readReg(RegAddr addr) +{ + if (addr >= RegAddr(JOB_SLOT0)) { + return slots[getJobSlotNo(addr)].readReg(getJobSlotAddr(addr)); + } else { + return GPUBlockInt::readReg(addr); + } +} + +void +JobControl::writeReg(RegAddr addr, uint32_t value) +{ + switch(addr.value) { + case JOB_IRQ_CLEAR: + // Update JS state for all jobs that were affected by the IRQ + // clear + updateJsState((value & 0xFFFF) | ((value & 0xFFFF0000) >> 16)); + + // FALLTHROUGH - IRQ handling in base class + case JOB_IRQ_RAWSTAT: + case JOB_IRQ_MASK: + case JOB_IRQ_STATUS: + GPUBlockInt::writeReg(addr, value); + break; + + default: + if (addr >= RegAddr(JOB_SLOT0)) + slots[getJobSlotNo(addr)].writeReg(getJobSlotAddr(addr), value); + break; + } +} + +uint32_t +JobControl::readRegRaw(RegAddr addr) +{ + if (addr >= RegAddr(JOB_SLOT0)) { + return slots[getJobSlotNo(addr)].readRegRaw(getJobSlotAddr(addr)); + } else { + return GPUBlockInt::readRegRaw(addr); + } +} + + +void +JobControl::writeRegRaw(RegAddr addr, uint32_t value) +{ + if (addr >= RegAddr(JOB_SLOT0)) { + slots[getJobSlotNo(addr)].writeRegRaw(getJobSlotAddr(addr), value); + } else { + GPUBlockInt::writeRegRaw(addr, value); + } +} + +void +JobControl::jobDone(uint8_t slot) +{ + assert(slot <= 15); + raiseInterrupt(1 << slot); +} + +void +JobControl::jobFailed(uint8_t slot) +{ + assert(slot <= 15); + raiseInterrupt(0x10000 << slot); +} + +void +JobControl::updateJsState(uint16_t jobs) +{ + // The JS_STATE register contains two bits per job slot; one bit + // representing an active job and one bit representing the queued + // job. We need to mask out bits of the jobs affected by this update. + const uint32_t job_mask(jobs | (jobs << 16)); + uint16_t js_state(regs[RegAddr(JOB_IRQ_JS_STATE)] & ~job_mask); + + // Find if there is an active or active next job for all jobs in + // the job mask. + for (int i = 0; i < 16; ++i) { + const JobSlot &slot(slots[i]); + if (jobs & (1 << i)) { + js_state |= slot.active() ? (1 << i) : 0 | + slot.activeNext() ? (0x10000 << i) : 0; + } + } + regs[RegAddr(JOB_IRQ_JS_STATE)] = js_state; +} + +void +JobControl::onInterrupt(int set) +{ + gpu.intJob(set); +} + +} diff --git a/ext/nomali/lib/jobcontrol.hh b/ext/nomali/lib/jobcontrol.hh new file mode 100644 index 000000000..e0efc04c9 --- /dev/null +++ b/ext/nomali/lib/jobcontrol.hh @@ -0,0 +1,93 @@ +/* + * Copyright (c) 2014-2015 ARM Limited + * All rights reserved + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + * Authors: Andreas Sandberg + */ + +#ifndef _LIBNOMALIMODEL_JOBCONTROL_HH +#define _LIBNOMALIMODEL_JOBCONTROL_HH + +#include + +#include "gpublock.hh" +#include "jobslot.hh" +#include "types.hh" + +namespace NoMali { + +class GPU; + +/** + * Minimal GPU job control implementation. + * + * This class implements the job control block of a Midgard style + * GPU. The job control block mainly coordinates interrupt delivery + * and register mappings for the different job slots within the + * block. The actual job slots are implemented by the JobSlot class. + * + * @see JobSlot + */ +class JobControl + : public GPUBlockInt +{ + public: + JobControl(GPU &_gpu); + virtual ~JobControl(); + + uint32_t readReg(RegAddr idx) override; + void writeReg(RegAddr idx, uint32_t value) override; + + uint32_t readRegRaw(RegAddr idx) override; + void writeRegRaw(RegAddr idx, uint32_t value) override; + + /** + * Signal job done. + * + * Calling this method raises the job done interrupt for a + * specific job slot. This is typically called from the job slot + * running the job chain. + * + * @param slot Job slot number. + */ + void jobDone(uint8_t slot); + /** + * Signal job failed. + * + * Calling this method raises the job failed interrupt for a + * specific job slot. This is typically called from the job slot + * running the job chain. + * + * @param slot Job slot number. + */ + void jobFailed(uint8_t slot); + + protected: + /** + * Update the state of the job slot state snapshot register. + * + * @param jobs Bit mask representing which job slots to update. + */ + void updateJsState(uint16_t jobs); + + void onInterrupt(int set) override; + + /** Job slots belonging to this job control block */ + std::vector slots; +}; + +} + +#endif // _LIBNOMALIMODEL_JOBCONTROL_HH diff --git a/ext/nomali/lib/jobslot.cc b/ext/nomali/lib/jobslot.cc new file mode 100644 index 000000000..8ad4fa1ec --- /dev/null +++ b/ext/nomali/lib/jobslot.cc @@ -0,0 +1,216 @@ +/* + * Copyright (c) 2014-2015 ARM Limited + * All rights reserved + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + * Authors: Andreas Sandberg + */ + +#include "jobslot.hh" + +#include +#include + +#include "jobcontrol.hh" +#include "gpu.hh" +#include "regutils.hh" + +namespace NoMali { + +const std::vector JobSlot::cmds { + &JobSlot::cmdNop, // JSn_COMMAND_NOP + &JobSlot::cmdStart, // JSn_COMMAND_START + &JobSlot::cmdSoftStop, // JSn_COMMAND_SOFT_STOP + &JobSlot::cmdHardStop, // JSn_COMMAND_HARD_STOP + &JobSlot::cmdSoftStop0, // JSn_COMMAND_SOFT_STOP_0 + &JobSlot::cmdHardStop0, // JSn_COMMAND_HARD_STOP_0 + &JobSlot::cmdSoftStop1, // JSn_COMMAND_SOFT_STOP_1 + &JobSlot::cmdHardStop1, // JSn_COMMAND_HARD_STOP_1 +}; + +JobSlot::JobSlot(GPU &_gpu, JobControl &_jc, uint8_t _id) + : GPUBlock(_gpu, JSn_NO_REGS), + id(_id), + jc(_jc) +{ +} + +JobSlot::JobSlot(JobSlot &&rhs) + : GPUBlock(std::move(rhs)), + id(std::move(rhs.id)), + jc(rhs.jc) +{ +} + +JobSlot::~JobSlot() +{ +} + +void +JobSlot::writeReg(RegAddr addr, uint32_t value) +{ + switch (addr.value) { + case JSn_COMMAND: + jobCommand(value); + break; + + case JSn_COMMAND_NEXT: + regs[addr] = value; + tryStart(); + break; + + case JSn_HEAD_NEXT_LO: + case JSn_HEAD_NEXT_HI: + case JSn_AFFINITY_NEXT_LO: + case JSn_AFFINITY_NEXT_HI: + case JSn_CONFIG_NEXT: + GPUBlock::writeReg(addr, value); + break; + + default: + // Ignore writes by default + break; + }; +} + +bool +JobSlot::active() const +{ + return false; +} + +bool +JobSlot::activeNext() const +{ + return regs[RegAddr(JSn_COMMAND_NEXT)] == JSn_COMMAND_START; +} + +void +JobSlot::tryStart() +{ + // Only actually start something if the next command is start + if (regs[RegAddr(JSn_COMMAND_NEXT)] != JSn_COMMAND_START ) + return; + + // Reset the status register + regs[RegAddr(JSn_STATUS)] = 0; + + // Transfer the next job configuration to the active job + // configuration + regs.set64(RegAddr(JSn_HEAD_LO), regs.get64(RegAddr(JSn_HEAD_NEXT_LO))); + regs.set64(RegAddr(JSn_TAIL_LO), regs.get64(RegAddr(JSn_HEAD_NEXT_LO))); + regs.set64(RegAddr(JSn_AFFINITY_LO), + regs.get64(RegAddr(JSn_AFFINITY_NEXT_LO))); + regs[RegAddr(JSn_CONFIG)] = regs[RegAddr(JSn_CONFIG_NEXT)]; + regs[RegAddr(JSn_COMMAND)] = regs[RegAddr(JSn_COMMAND_NEXT)]; + + // Reset the next job configuration + regs.set64(RegAddr(JSn_HEAD_NEXT_LO), 0); + regs.set64(RegAddr(JSn_AFFINITY_NEXT_LO), 0); + regs[RegAddr(JSn_CONFIG_NEXT)] = 0; + regs[RegAddr(JSn_COMMAND_NEXT)] = 0; + + runJob(); +} + +void +JobSlot::runJob() +{ + exitJob(Status(Status::CLASS_NOFAULT, 0, 1), // JSn_STATUS_DONE + 0); // Time stamp counter value +} + +void +JobSlot::exitJob(Status status, uint64_t fault_address) +{ + assert(status.statusClass() == Status::CLASS_NOFAULT || + status.statusClass() == Status::CLASS_JOB); + + regs[RegAddr(JSn_STATUS)] = status.value; + + if (status.statusClass() == Status::CLASS_NOFAULT) { + jc.jobDone(id); + } else { + jc.jobFailed(id); + } +} + +void +JobSlot::jobCommand(uint32_t cmd) +{ + if (cmd < cmds.size()) + (this->*cmds[cmd])(cmd); +} + +void +JobSlot::cmdNop(uint32_t cmd) +{ + assert(cmd == JSn_COMMAND_NOP); +} + +void +JobSlot::cmdStart(uint32_t cmd) +{ + assert(cmd == JSn_COMMAND_START); + // The JSn_COMMAND_START should never be issued through the + // JSn_COMMAND register. It should use the JSn_COMMAND_NEXT + // register instead. + abort(); +} + +void +JobSlot::cmdSoftStop(uint32_t cmd) +{ + assert(cmd == JSn_COMMAND_SOFT_STOP || + cmd == JSn_COMMAND_SOFT_STOP_0 || + cmd == JSn_COMMAND_SOFT_STOP_1); +} + +void +JobSlot::cmdHardStop(uint32_t cmd) +{ + assert(cmd == JSn_COMMAND_HARD_STOP || + cmd == JSn_COMMAND_HARD_STOP_0 || + cmd == JSn_COMMAND_HARD_STOP_1); +} + +void +JobSlot::cmdSoftStop0(uint32_t cmd) +{ + if (!(regs[RegAddr(JSn_CONFIG)] & JSn_CONFIG_JOB_CHAIN_FLAG)) + cmdSoftStop(cmd); +} + +void +JobSlot::cmdHardStop0(uint32_t cmd) +{ + if (!(regs[RegAddr(JSn_CONFIG)] & JSn_CONFIG_JOB_CHAIN_FLAG)) + cmdHardStop(cmd); +} + +void +JobSlot::cmdSoftStop1(uint32_t cmd) +{ + if (regs[RegAddr(JSn_CONFIG)] & JSn_CONFIG_JOB_CHAIN_FLAG) + cmdSoftStop(cmd); +} + +void +JobSlot::cmdHardStop1(uint32_t cmd) +{ + if (regs[RegAddr(JSn_CONFIG)] & JSn_CONFIG_JOB_CHAIN_FLAG) + cmdHardStop(cmd); +} + +} diff --git a/ext/nomali/lib/jobslot.hh b/ext/nomali/lib/jobslot.hh new file mode 100644 index 000000000..31b178db2 --- /dev/null +++ b/ext/nomali/lib/jobslot.hh @@ -0,0 +1,208 @@ +/* + * Copyright (c) 2014-2015 ARM Limited + * All rights reserved + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + * Authors: Andreas Sandberg + */ + +#ifndef _LIBNOMALIMODEL_JOBSLOT_HH +#define _LIBNOMALIMODEL_JOBSLOT_HH + +#include + +#include "gpublock.hh" +#include "types.hh" + +namespace NoMali { + +class GPU; + +class JobControl; + +/** + * Midgard job slot implementation. + * + * A job slot is a part of a JobControl block that controls the state + * of one out of 16 active jobs. Each slot can contain one running job + * and a pending job. + */ +class JobSlot + : public GPUBlock +{ + public: + JobSlot(GPU &_gpu, JobControl &_jc, uint8_t slot_id); + JobSlot(JobSlot &&rhs); + virtual ~JobSlot(); + + void writeReg(RegAddr idx, uint32_t value) override; + + /** Is there an active job in this job slot? */ + bool active() const; + /** Is there a pending next job in this job slot? */ + bool activeNext() const; + + protected: + /** + * @{ + * @name Job Control + */ + + /** + * Try to start the next job in the slot. + * + * Start the next job if the following conditions are true: + *
    + *
  • There is no currently running job. + *
  • The pending command in the JSn_COMMAND_NEXT register is + * JSn_COMMAND_START. + *
+ * + * When the job is started, the registers describing the next job + * chain are moved (resetting them to zero) into the register + * block describing the currently running job. The job is then run + * by a call to runJob(). + */ + void tryStart(); + + /** + * Execute the job in described by the current job registers. + */ + void runJob(); + + /** + * Report the exit status of an exiting job. + * + * @note The exit status must be of the class + * Status::CLASS_NOFAULT or Status::CLASS_JOB. + * + * @note The fault address isn't always a fault address, it is + * sometimes used to represent a TSC value. See the Midgard + * architecture specification for details. + * + * @param status Job exit status. + * @param fault_address Fault address to write into descriptor. + */ + void exitJob(Status status, uint64_t fault_address); + + /** @} */ + + /** + * @{ + * @name Job slot commands + */ + + /** + * Control command dispatcher. + * + * This method is called whenever there is a write to the + * JSn_COMMAND register. The method uses a lookup table to call + * the right command handling method. + * + * @param cmd Command number (see the Midgard architecture + * specification) + */ + void jobCommand(uint32_t cmd); + + /** + * Command handler for No-ops. + * + * @param cmd Command number (see the Midgard architecture + * specification) + */ + void cmdNop(uint32_t cmd); + /** + * Command handler for job start commands. + * + * @note This should NEVER be called as the start command + * should never be written to the JSn_COMMAND register. Jobs are + * normally started by tryStart() whenever the state of the + * currently running job changes or JSn_COMMAND_START is written + * to the JSn_COMMAND_NEXT register. + * + * @param cmd Command number (see the Midgard architecture + * specification) + */ + void cmdStart(uint32_t cmd); + /** + * Gently stop the currently running job chain. + * + * @param cmd Command number (see the Midgard architecture + * specification) + */ + void cmdSoftStop(uint32_t cmd); + /** + * Force a stop of the currently running job chain. + * + * @param cmd Command number (see the Midgard architecture + * specification) + */ + void cmdHardStop(uint32_t cmd); + /** + * Soft stop the current job chain if the JOB_CHAIN_FLAG IS + * NOT set. + * + * @param cmd Command number (see the Midgard architecture + * specification) + */ + void cmdSoftStop0(uint32_t cmd); + /** + * Hard stop the current job chain if the JOB_CHAIN_FLAG IS + * NOT set. + * + * @param cmd Command number (see the Midgard architecture + * specification) + */ + void cmdHardStop0(uint32_t cmd); + /** + * Soft stop the current job chain if the JOB_CHAIN_FLAG IS + * set. + * + * @param cmd Command number (see the Midgard architecture + * specification) + */ + void cmdSoftStop1(uint32_t cmd); + /** + * Hard stop the current job chain if the JOB_CHAIN_FLAG IS + * set. + * + * @param cmd Command number (see the Midgard architecture + * specification) + */ + void cmdHardStop1(uint32_t cmd); + + /** @} */ + + /** Job slot ID */ + const uint8_t id; + + /** Parent JobControl block */ + JobControl &jc; + + private: + typedef void (JobSlot::*cmd_t)(uint32_t); + + /** + * Mapping between command IDs and command handling methods. + * + * @note The order of this vector MUST correspond to the + * job control command IDs in the Midgard architecture + * specification. + */ + static const std::vector cmds; +}; + +} + +#endif // _LIBNOMALIMODEL_JOBSLOT_HH diff --git a/ext/nomali/lib/mali_midg_regmap.h b/ext/nomali/lib/mali_midg_regmap.h new file mode 100644 index 000000000..90eca9c18 --- /dev/null +++ b/ext/nomali/lib/mali_midg_regmap.h @@ -0,0 +1,510 @@ +/* + * Copyright (c) 2014-2015 ARM Limited + * All rights reserved + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef _MIDGARD_REGMAP_H_ +#define _MIDGARD_REGMAP_H_ + +/* + * Begin Register Offsets + */ + +#define GPU_CONTROL_BASE 0x0000 +#define GPU_CONTROL_REG(r) (GPU_CONTROL_BASE + (r)) +#define GPU_ID 0x000 /* (RO) GPU and revision identifier */ +#define L2_FEATURES 0x004 /* (RO) Level 2 cache features */ +#define L3_FEATURES 0x008 /* (RO) Level 3 cache features */ +#define TILER_FEATURES 0x00C /* (RO) Tiler Features */ +#define MEM_FEATURES 0x010 /* (RO) Memory system features */ +#define MMU_FEATURES 0x014 /* (RO) MMU features */ +#define AS_PRESENT 0x018 /* (RO) Address space slots present */ +#define JS_PRESENT 0x01C /* (RO) Job slots present */ +#define GPU_IRQ_RAWSTAT 0x020 /* (RW) */ +#define GPU_IRQ_CLEAR 0x024 /* (WO) */ +#define GPU_IRQ_MASK 0x028 /* (RW) */ +#define GPU_IRQ_STATUS 0x02C /* (RO) */ + +/* IRQ flags */ +#define GPU_FAULT (1 << 0) /* A GPU Fault has occurred */ +#define MULTIPLE_GPU_FAULTS (1 << 7) /* More than one GPU Fault occurred. */ +#define RESET_COMPLETED (1 << 8) /* Set when a reset has completed. Intended to use with SOFT_RESET + commands which may take time. */ +#define POWER_CHANGED_SINGLE (1 << 9) /* Set when a single core has finished powering up or down. */ +#define POWER_CHANGED_ALL (1 << 10) /* Set when all cores have finished powering up or down + and the power manager is idle. */ + +#define PRFCNT_SAMPLE_COMPLETED (1 << 16) /* Set when a performance count sample has completed. */ +#define CLEAN_CACHES_COMPLETED (1 << 17) /* Set when a cache clean operation has completed. */ + +#define GPU_IRQ_REG_ALL (GPU_FAULT | MULTIPLE_GPU_FAULTS | RESET_COMPLETED \ + | POWER_CHANGED_ALL | PRFCNT_SAMPLE_COMPLETED) + +#define GPU_COMMAND 0x030 /* (WO) */ +#define GPU_STATUS 0x034 /* (RO) */ + +#define GROUPS_L2_COHERENT (1 << 0) /* Cores groups are l2 coherent */ +#define GROUPS_L3_COHERENT (1 << 1) /* Cores groups are l3 coherent */ + +#define GPU_FAULTSTATUS 0x03C /* (RO) GPU exception type and fault status */ +#define GPU_FAULTADDRESS_LO 0x040 /* (RO) GPU exception fault address, low word */ +#define GPU_FAULTADDRESS_HI 0x044 /* (RO) GPU exception fault address, high word */ + +#define PWR_KEY 0x050 /* (WO) Power manager key register */ +#define PWR_OVERRIDE0 0x054 /* (RW) Power manager override settings */ +#define PWR_OVERRIDE1 0x058 /* (RW) Power manager override settings */ + +#define PRFCNT_BASE_LO 0x060 /* (RW) Performance counter memory region base address, low word */ +#define PRFCNT_BASE_HI 0x064 /* (RW) Performance counter memory region base address, high word */ +#define PRFCNT_CONFIG 0x068 /* (RW) Performance counter configuration */ +#define PRFCNT_JM_EN 0x06C /* (RW) Performance counter enable flags for Job Manager */ +#define PRFCNT_SHADER_EN 0x070 /* (RW) Performance counter enable flags for shader cores */ +#define PRFCNT_TILER_EN 0x074 /* (RW) Performance counter enable flags for tiler */ +#define PRFCNT_L3_CACHE_EN 0x078 /* (RW) Performance counter enable flags for L3 cache */ +#define PRFCNT_MMU_L2_EN 0x07C /* (RW) Performance counter enable flags for MMU/L2 cache */ + +#define CYCLE_COUNT_LO 0x090 /* (RO) Cycle counter, low word */ +#define CYCLE_COUNT_HI 0x094 /* (RO) Cycle counter, high word */ +#define TIMESTAMP_LO 0x098 /* (RO) Global time stamp counter, low word */ +#define TIMESTAMP_HI 0x09C /* (RO) Global time stamp counter, high word */ + +#define THREAD_MAX_THREADS 0x0A0 /* (RO) Maximum number of threads per core */ +#define THREAD_MAX_WORKGROUP_SIZE 0x0A4 /* (RO) Maximum workgroup size */ +#define THREAD_MAX_BARRIER_SIZE 0x0A8 /* (RO) Maximum threads waiting at a barrier */ +#define THREAD_FEATURES 0x0AC /* (RO) Thread features */ + +#define TEXTURE_FEATURES_0 0x0B0 /* (RO) Support flags for indexed texture formats 0..31 */ +#define TEXTURE_FEATURES_1 0x0B4 /* (RO) Support flags for indexed texture formats 32..63 */ +#define TEXTURE_FEATURES_2 0x0B8 /* (RO) Support flags for indexed texture formats 64..95 */ + +#define TEXTURE_FEATURES_REG(n) GPU_CONTROL_REG(TEXTURE_FEATURES_0 + ((n) << 2)) + +#define JS0_FEATURES 0x0C0 /* (RO) Features of job slot 0 */ +#define JS1_FEATURES 0x0C4 /* (RO) Features of job slot 1 */ +#define JS2_FEATURES 0x0C8 /* (RO) Features of job slot 2 */ +#define JS3_FEATURES 0x0CC /* (RO) Features of job slot 3 */ +#define JS4_FEATURES 0x0D0 /* (RO) Features of job slot 4 */ +#define JS5_FEATURES 0x0D4 /* (RO) Features of job slot 5 */ +#define JS6_FEATURES 0x0D8 /* (RO) Features of job slot 6 */ +#define JS7_FEATURES 0x0DC /* (RO) Features of job slot 7 */ +#define JS8_FEATURES 0x0E0 /* (RO) Features of job slot 8 */ +#define JS9_FEATURES 0x0E4 /* (RO) Features of job slot 9 */ +#define JS10_FEATURES 0x0E8 /* (RO) Features of job slot 10 */ +#define JS11_FEATURES 0x0EC /* (RO) Features of job slot 11 */ +#define JS12_FEATURES 0x0F0 /* (RO) Features of job slot 12 */ +#define JS13_FEATURES 0x0F4 /* (RO) Features of job slot 13 */ +#define JS14_FEATURES 0x0F8 /* (RO) Features of job slot 14 */ +#define JS15_FEATURES 0x0FC /* (RO) Features of job slot 15 */ + +#define JS_FEATURES_REG(n) GPU_CONTROL_REG(JS0_FEATURES + ((n) << 2)) + +#define SHADER_PRESENT_LO 0x100 /* (RO) Shader core present bitmap, low word */ +#define SHADER_PRESENT_HI 0x104 /* (RO) Shader core present bitmap, high word */ + +#define TILER_PRESENT_LO 0x110 /* (RO) Tiler core present bitmap, low word */ +#define TILER_PRESENT_HI 0x114 /* (RO) Tiler core present bitmap, high word */ + +#define L2_PRESENT_LO 0x120 /* (RO) Level 2 cache present bitmap, low word */ +#define L2_PRESENT_HI 0x124 /* (RO) Level 2 cache present bitmap, high word */ + +#define L3_PRESENT_LO 0x130 /* (RO) Level 3 cache present bitmap, low word */ +#define L3_PRESENT_HI 0x134 /* (RO) Level 3 cache present bitmap, high word */ + +#define SHADER_READY_LO 0x140 /* (RO) Shader core ready bitmap, low word */ +#define SHADER_READY_HI 0x144 /* (RO) Shader core ready bitmap, high word */ + +#define TILER_READY_LO 0x150 /* (RO) Tiler core ready bitmap, low word */ +#define TILER_READY_HI 0x154 /* (RO) Tiler core ready bitmap, high word */ + +#define L2_READY_LO 0x160 /* (RO) Level 2 cache ready bitmap, low word */ +#define L2_READY_HI 0x164 /* (RO) Level 2 cache ready bitmap, high word */ + +#define L3_READY_LO 0x170 /* (RO) Level 3 cache ready bitmap, low word */ +#define L3_READY_HI 0x174 /* (RO) Level 3 cache ready bitmap, high word */ + +#define SHADER_PWRON_LO 0x180 /* (WO) Shader core power on bitmap, low word */ +#define SHADER_PWRON_HI 0x184 /* (WO) Shader core power on bitmap, high word */ + +#define TILER_PWRON_LO 0x190 /* (WO) Tiler core power on bitmap, low word */ +#define TILER_PWRON_HI 0x194 /* (WO) Tiler core power on bitmap, high word */ + +#define L2_PWRON_LO 0x1A0 /* (WO) Level 2 cache power on bitmap, low word */ +#define L2_PWRON_HI 0x1A4 /* (WO) Level 2 cache power on bitmap, high word */ + +#define L3_PWRON_LO 0x1B0 /* (WO) Level 3 cache power on bitmap, low word */ +#define L3_PWRON_HI 0x1B4 /* (WO) Level 3 cache power on bitmap, high word */ + +#define SHADER_PWROFF_LO 0x1C0 /* (WO) Shader core power off bitmap, low word */ +#define SHADER_PWROFF_HI 0x1C4 /* (WO) Shader core power off bitmap, high word */ + +#define TILER_PWROFF_LO 0x1D0 /* (WO) Tiler core power off bitmap, low word */ +#define TILER_PWROFF_HI 0x1D4 /* (WO) Tiler core power off bitmap, high word */ + +#define L2_PWROFF_LO 0x1E0 /* (WO) Level 2 cache power off bitmap, low word */ +#define L2_PWROFF_HI 0x1E4 /* (WO) Level 2 cache power off bitmap, high word */ + +#define L3_PWROFF_LO 0x1F0 /* (WO) Level 3 cache power off bitmap, low word */ +#define L3_PWROFF_HI 0x1F4 /* (WO) Level 3 cache power off bitmap, high word */ + +#define SHADER_PWRTRANS_LO 0x200 /* (RO) Shader core power transition bitmap, low word */ +#define SHADER_PWRTRANS_HI 0x204 /* (RO) Shader core power transition bitmap, high word */ + +#define TILER_PWRTRANS_LO 0x210 /* (RO) Tiler core power transition bitmap, low word */ +#define TILER_PWRTRANS_HI 0x214 /* (RO) Tiler core power transition bitmap, high word */ + +#define L2_PWRTRANS_LO 0x220 /* (RO) Level 2 cache power transition bitmap, low word */ +#define L2_PWRTRANS_HI 0x224 /* (RO) Level 2 cache power transition bitmap, high word */ + +#define L3_PWRTRANS_LO 0x230 /* (RO) Level 3 cache power transition bitmap, low word */ +#define L3_PWRTRANS_HI 0x234 /* (RO) Level 3 cache power transition bitmap, high word */ + +#define SHADER_PWRACTIVE_LO 0x240 /* (RO) Shader core active bitmap, low word */ +#define SHADER_PWRACTIVE_HI 0x244 /* (RO) Shader core active bitmap, high word */ + +#define TILER_PWRACTIVE_LO 0x250 /* (RO) Tiler core active bitmap, low word */ +#define TILER_PWRACTIVE_HI 0x254 /* (RO) Tiler core active bitmap, high word */ + +#define L2_PWRACTIVE_LO 0x260 /* (RO) Level 2 cache active bitmap, low word */ +#define L2_PWRACTIVE_HI 0x264 /* (RO) Level 2 cache active bitmap, high word */ + +#define L3_PWRACTIVE_LO 0x270 /* (RO) Level 3 cache active bitmap, low word */ +#define L3_PWRACTIVE_HI 0x274 /* (RO) Level 3 cache active bitmap, high word */ + +#define SHADER_CONFIG 0xF04 /* (RW) Shader core configuration settings (Mali-T60x additional register) */ +#define L2_MMU_CONFIG 0xF0C /* (RW) Configuration of the L2 cache and MMU (Mali-T60x additional register) */ + +#define JOB_CONTROL_BASE 0x1000 + +#define JOB_CONTROL_REG(r) (JOB_CONTROL_BASE + (r)) + +#define JOB_IRQ_RAWSTAT 0x000 /* Raw interrupt status register */ +#define JOB_IRQ_CLEAR 0x004 /* Interrupt clear register */ +#define JOB_IRQ_MASK 0x008 /* Interrupt mask register */ +#define JOB_IRQ_STATUS 0x00C /* Interrupt status register */ +#define JOB_IRQ_JS_STATE 0x010 /* status==active and _next == busy snapshot from last JOB_IRQ_CLEAR */ +#define JOB_IRQ_THROTTLE 0x014 /* cycles to delay delivering an interrupt externally. The JOB_IRQ_STATUS is NOT affected by this, just the delivery of the interrupt. */ + +#define JOB_SLOT0 0x800 /* Configuration registers for job slot 0 */ +#define JOB_SLOT1 0x880 /* Configuration registers for job slot 1 */ +#define JOB_SLOT2 0x900 /* Configuration registers for job slot 2 */ +#define JOB_SLOT3 0x980 /* Configuration registers for job slot 3 */ +#define JOB_SLOT4 0xA00 /* Configuration registers for job slot 4 */ +#define JOB_SLOT5 0xA80 /* Configuration registers for job slot 5 */ +#define JOB_SLOT6 0xB00 /* Configuration registers for job slot 6 */ +#define JOB_SLOT7 0xB80 /* Configuration registers for job slot 7 */ +#define JOB_SLOT8 0xC00 /* Configuration registers for job slot 8 */ +#define JOB_SLOT9 0xC80 /* Configuration registers for job slot 9 */ +#define JOB_SLOT10 0xD00 /* Configuration registers for job slot 10 */ +#define JOB_SLOT11 0xD80 /* Configuration registers for job slot 11 */ +#define JOB_SLOT12 0xE00 /* Configuration registers for job slot 12 */ +#define JOB_SLOT13 0xE80 /* Configuration registers for job slot 13 */ +#define JOB_SLOT14 0xF00 /* Configuration registers for job slot 14 */ +#define JOB_SLOT15 0xF80 /* Configuration registers for job slot 15 */ + +#define JOB_SLOT_REG(n, r) (JOB_CONTROL_REG(JOB_SLOT0 + ((n) << 7)) + (r)) + +#define JSn_HEAD_LO 0x00 /* (RO) Job queue head pointer for job slot n, low word */ +#define JSn_HEAD_HI 0x04 /* (RO) Job queue head pointer for job slot n, high word */ +#define JSn_TAIL_LO 0x08 /* (RO) Job queue tail pointer for job slot n, low word */ +#define JSn_TAIL_HI 0x0C /* (RO) Job queue tail pointer for job slot n, high word */ +#define JSn_AFFINITY_LO 0x10 /* (RO) Core affinity mask for job slot n, low word */ +#define JSn_AFFINITY_HI 0x14 /* (RO) Core affinity mask for job slot n, high word */ +#define JSn_CONFIG 0x18 /* (RO) Configuration settings for job slot n */ + +#define JSn_COMMAND 0x20 /* (WO) Command register for job slot n */ +#define JSn_STATUS 0x24 /* (RO) Status register for job slot n */ + +#define JSn_HEAD_NEXT_LO 0x40 /* (RW) Next job queue head pointer for job slot n, low word */ +#define JSn_HEAD_NEXT_HI 0x44 /* (RW) Next job queue head pointer for job slot n, high word */ + +#define JSn_AFFINITY_NEXT_LO 0x50 /* (RW) Next core affinity mask for job slot n, low word */ +#define JSn_AFFINITY_NEXT_HI 0x54 /* (RW) Next core affinity mask for job slot n, high word */ +#define JSn_CONFIG_NEXT 0x58 /* (RW) Next configuration settings for job slot n */ + +#define JSn_COMMAND_NEXT 0x60 /* (RW) Next command register for job slot n */ + +#define MEMORY_MANAGEMENT_BASE 0x2000 +#define MMU_REG(r) (MEMORY_MANAGEMENT_BASE + (r)) + +#define MMU_IRQ_RAWSTAT 0x000 /* (RW) Raw interrupt status register */ +#define MMU_IRQ_CLEAR 0x004 /* (WO) Interrupt clear register */ +#define MMU_IRQ_MASK 0x008 /* (RW) Interrupt mask register */ +#define MMU_IRQ_STATUS 0x00C /* (RO) Interrupt status register */ + +#define MMU_AS0 0x400 /* Configuration registers for address space 0 */ +#define MMU_AS1 0x440 /* Configuration registers for address space 1 */ +#define MMU_AS2 0x480 /* Configuration registers for address space 2 */ +#define MMU_AS3 0x4C0 /* Configuration registers for address space 3 */ +#define MMU_AS4 0x500 /* Configuration registers for address space 4 */ +#define MMU_AS5 0x540 /* Configuration registers for address space 5 */ +#define MMU_AS6 0x580 /* Configuration registers for address space 6 */ +#define MMU_AS7 0x5C0 /* Configuration registers for address space 7 */ +#define MMU_AS8 0x600 /* Configuration registers for address space 8 */ +#define MMU_AS9 0x640 /* Configuration registers for address space 9 */ +#define MMU_AS10 0x680 /* Configuration registers for address space 10 */ +#define MMU_AS11 0x6C0 /* Configuration registers for address space 11 */ +#define MMU_AS12 0x700 /* Configuration registers for address space 12 */ +#define MMU_AS13 0x740 /* Configuration registers for address space 13 */ +#define MMU_AS14 0x780 /* Configuration registers for address space 14 */ +#define MMU_AS15 0x7C0 /* Configuration registers for address space 15 */ + +#define MMU_AS_REG(n, r) (MMU_REG(MMU_AS0 + ((n) << 6)) + (r)) + +#define ASn_TRANSTAB_LO 0x00 /* (RW) Translation Table Base Address for address space n, low word */ +#define ASn_TRANSTAB_HI 0x04 /* (RW) Translation Table Base Address for address space n, high word */ +#define ASn_MEMATTR_LO 0x08 /* (RW) Memory attributes for address space n, low word. */ +#define ASn_MEMATTR_HI 0x0C /* (RW) Memory attributes for address space n, high word. */ +#define ASn_LOCKADDR_LO 0x10 /* (RW) Lock region address for address space n, low word */ +#define ASn_LOCKADDR_HI 0x14 /* (RW) Lock region address for address space n, high word */ +#define ASn_COMMAND 0x18 /* (WO) MMU command register for address space n */ +#define ASn_FAULTSTATUS 0x1C /* (RO) MMU fault status register for address space n */ +#define ASn_FAULTADDRESS_LO 0x20 /* (RO) Fault Address for address space n, low word */ +#define ASn_FAULTADDRESS_HI 0x24 /* (RO) Fault Address for address space n, high word */ +#define ASn_STATUS 0x28 /* (RO) Status flags for address space n */ + +/* End Register Offsets */ + +/* + * MMU_IRQ_RAWSTAT register values. Values are valid also for + MMU_IRQ_CLEAR, MMU_IRQ_MASK, MMU_IRQ_STATUS registers. + */ + +#define MMU_REGS_PAGE_FAULT_FLAGS 16 + +/* Macros return bit number to retrvie page fault or bus eror flag from MMU registers */ +#define MMU_REGS_PAGE_FAULT_FLAG(n) (n) +#define MMU_REGS_BUS_ERROR_FLAG(n) (n + MMU_REGS_PAGE_FAULT_FLAGS) + +/* + * Begin MMU TRANSTAB register values + */ +#define ASn_TRANSTAB_ADDR_SPACE_MASK 0xfffff000 +#define ASn_TRANSTAB_ADRMODE_UNMAPPED (0u << 0) +#define ASn_TRANSTAB_ADRMODE_IDENTITY (1u << 1) +#define ASn_TRANSTAB_ADRMODE_TABLE (3u << 0) +#define ASn_TRANSTAB_READ_INNER (1u << 2) +#define ASn_TRANSTAB_SHARE_OUTER (1u << 4) + +#define MMU_TRANSTAB_ADRMODE_MASK 0x00000003 + +/* + * Begin MMU STATUS register values + */ +#define ASn_STATUS_FLUSH_ACTIVE 0x01 + +#define ASn_FAULTSTATUS_ACCESS_TYPE_MASK (0x3<<8) +#define ASn_FAULTSTATUS_ACCESS_TYPE_EX (0x1<<8) +#define ASn_FAULTSTATUS_ACCESS_TYPE_READ (0x2<<8) +#define ASn_FAULTSTATUS_ACCESS_TYPE_WRITE (0x3<<8) + +/* + * Begin Command Values + */ + +/* JSn_COMMAND register commands */ +#define JSn_COMMAND_NOP 0x00 /* NOP Operation. Writing this value is ignored */ +#define JSn_COMMAND_START 0x01 /* Start processing a job chain. Writing this value is ignored */ +#define JSn_COMMAND_SOFT_STOP 0x02 /* Gently stop processing a job chain */ +#define JSn_COMMAND_HARD_STOP 0x03 /* Rudely stop processing a job chain */ +#define JSn_COMMAND_SOFT_STOP_0 0x04 /* Execute SOFT_STOP if JOB_CHAIN_FLAG is 0 */ +#define JSn_COMMAND_HARD_STOP_0 0x05 /* Execute HARD_STOP if JOB_CHAIN_FLAG is 0 */ +#define JSn_COMMAND_SOFT_STOP_1 0x06 /* Execute SOFT_STOP if JOB_CHAIN_FLAG is 1 */ +#define JSn_COMMAND_HARD_STOP_1 0x07 /* Execute HARD_STOP if JOB_CHAIN_FLAG is 1 */ + +/* ASn_COMMAND register commands */ +#define ASn_COMMAND_NOP 0x00 /* NOP Operation */ +#define ASn_COMMAND_UPDATE 0x01 /* Broadcasts the values in ASn_TRANSTAB and ASn_MEMATTR to all MMUs */ +#define ASn_COMMAND_LOCK 0x02 /* Issue a lock region command to all MMUs */ +#define ASn_COMMAND_UNLOCK 0x03 /* Issue a flush region command to all MMUs */ +#define ASn_COMMAND_FLUSH 0x04 /* Flush all L2 caches then issue a flush region command to all MMUs + (deprecated - only for use with T60x) */ +#define ASn_COMMAND_FLUSH_PT 0x04 /* Flush all L2 caches then issue a flush region command to all MMUs */ +#define ASn_COMMAND_FLUSH_MEM 0x05 /* Wait for memory accesses to complete, flush all the L1s cache then + flush all L2 caches then issue a flush region command to all MMUs */ + +/* Possible values of JSn_CONFIG and JSn_CONFIG_NEXT registers */ +#define JSn_CONFIG_START_FLUSH_NO_ACTION (0u << 0) +#define JSn_CONFIG_START_FLUSH_CLEAN (1u << 8) +#define JSn_CONFIG_START_FLUSH_CLEAN_INVALIDATE (3u << 8) +#define JSn_CONFIG_START_MMU (1u << 10) +#define JSn_CONFIG_JOB_CHAIN_FLAG (1u << 11) +#define JSn_CONFIG_END_FLUSH_NO_ACTION JSn_CONFIG_START_FLUSH_NO_ACTION +#define JSn_CONFIG_END_FLUSH_CLEAN (1u << 12) +#define JSn_CONFIG_END_FLUSH_CLEAN_INVALIDATE (3u << 12) +#define JSn_CONFIG_THREAD_PRI(n) ((n) << 16) + +/* JSn_STATUS register values */ + +/* NOTE: Please keep this values in sync with enum base_jd_event_code in mali_base_kernel.h. + * The values are separated to avoid dependency of userspace and kernel code. + */ + +/* Group of values representing the job status insead a particular fault */ +#define JSn_STATUS_NO_EXCEPTION_BASE 0x00 +#define JSn_STATUS_INTERRUPTED (JSn_STATUS_NO_EXCEPTION_BASE + 0x02) /* 0x02 means INTERRUPTED */ +#define JSn_STATUS_STOPPED (JSn_STATUS_NO_EXCEPTION_BASE + 0x03) /* 0x03 means STOPPED */ +#define JSn_STATUS_TERMINATED (JSn_STATUS_NO_EXCEPTION_BASE + 0x04) /* 0x04 means TERMINATED */ + +/* General fault values */ +#define JSn_STATUS_FAULT_BASE 0x40 +#define JSn_STATUS_CONFIG_FAULT (JSn_STATUS_FAULT_BASE) /* 0x40 means CONFIG FAULT */ +#define JSn_STATUS_POWER_FAULT (JSn_STATUS_FAULT_BASE + 0x01) /* 0x41 means POWER FAULT */ +#define JSn_STATUS_READ_FAULT (JSn_STATUS_FAULT_BASE + 0x02) /* 0x42 means READ FAULT */ +#define JSn_STATUS_WRITE_FAULT (JSn_STATUS_FAULT_BASE + 0x03) /* 0x43 means WRITE FAULT */ +#define JSn_STATUS_AFFINITY_FAULT (JSn_STATUS_FAULT_BASE + 0x04) /* 0x44 means AFFINITY FAULT */ +#define JSn_STATUS_BUS_FAULT (JSn_STATUS_FAULT_BASE + 0x08) /* 0x48 means BUS FAULT */ + +/* Instruction or data faults */ +#define JSn_STATUS_INSTRUCTION_FAULT_BASE 0x50 +#define JSn_STATUS_INSTR_INVALID_PC (JSn_STATUS_INSTRUCTION_FAULT_BASE) /* 0x50 means INSTR INVALID PC */ +#define JSn_STATUS_INSTR_INVALID_ENC (JSn_STATUS_INSTRUCTION_FAULT_BASE + 0x01) /* 0x51 means INSTR INVALID ENC */ +#define JSn_STATUS_INSTR_TYPE_MISMATCH (JSn_STATUS_INSTRUCTION_FAULT_BASE + 0x02) /* 0x52 means INSTR TYPE MISMATCH */ +#define JSn_STATUS_INSTR_OPERAND_FAULT (JSn_STATUS_INSTRUCTION_FAULT_BASE + 0x03) /* 0x53 means INSTR OPERAND FAULT */ +#define JSn_STATUS_INSTR_TLS_FAULT (JSn_STATUS_INSTRUCTION_FAULT_BASE + 0x04) /* 0x54 means INSTR TLS FAULT */ +#define JSn_STATUS_INSTR_BARRIER_FAULT (JSn_STATUS_INSTRUCTION_FAULT_BASE + 0x05) /* 0x55 means INSTR BARRIER FAULT */ +#define JSn_STATUS_INSTR_ALIGN_FAULT (JSn_STATUS_INSTRUCTION_FAULT_BASE + 0x06) /* 0x56 means INSTR ALIGN FAULT */ +/* NOTE: No fault with 0x57 code defined in spec. */ +#define JSn_STATUS_DATA_INVALID_FAULT (JSn_STATUS_INSTRUCTION_FAULT_BASE + 0x08) /* 0x58 means DATA INVALID FAULT */ +#define JSn_STATUS_TILE_RANGE_FAULT (JSn_STATUS_INSTRUCTION_FAULT_BASE + 0x09) /* 0x59 means TILE RANGE FAULT */ +#define JSn_STATUS_ADDRESS_RANGE_FAULT (JSn_STATUS_INSTRUCTION_FAULT_BASE + 0x0A) /* 0x5A means ADDRESS RANGE FAULT */ + +/* Other faults */ +#define JSn_STATUS_MEMORY_FAULT_BASE 0x60 +#define JSn_STATUS_OUT_OF_MEMORY (JSn_STATUS_MEMORY_FAULT_BASE) /* 0x60 means OUT OF MEMORY */ +#define JSn_STATUS_UNKNOWN 0x7F /* 0x7F means UNKNOWN */ + +/* GPU_COMMAND values */ +#define GPU_COMMAND_NOP 0x00 /* No operation, nothing happens */ +#define GPU_COMMAND_SOFT_RESET 0x01 /* Stop all external bus interfaces, and then reset the entire GPU. */ +#define GPU_COMMAND_HARD_RESET 0x02 /* Immediately reset the entire GPU. */ +#define GPU_COMMAND_PRFCNT_CLEAR 0x03 /* Clear all performance counters, setting them all to zero. */ +#define GPU_COMMAND_PRFCNT_SAMPLE 0x04 /* Sample all performance counters, writing them out to memory */ +#define GPU_COMMAND_CYCLE_COUNT_START 0x05 /* Starts the cycle counter, and system timestamp propagation */ +#define GPU_COMMAND_CYCLE_COUNT_STOP 0x06 /* Stops the cycle counter, and system timestamp propagation */ +#define GPU_COMMAND_CLEAN_CACHES 0x07 /* Clean all caches */ +#define GPU_COMMAND_CLEAN_INV_CACHES 0x08 /* Clean and invalidate all caches */ + +/* End Command Values */ + +/* GPU_STATUS values */ +#define GPU_STATUS_PRFCNT_ACTIVE (1 << 2) /* Set if the performance counters are active. */ + +/* PRFCNT_CONFIG register values */ +#define PRFCNT_CONFIG_AS_SHIFT 4 /* address space bitmap starts from bit 4 of the register */ +#define PRFCNT_CONFIG_MODE_OFF 0 /* The performance counters are disabled. */ +#define PRFCNT_CONFIG_MODE_MANUAL 1 /* The performance counters are enabled, but are only written out when a PRFCNT_SAMPLE command is issued using the GPU_COMMAND register. */ +#define PRFCNT_CONFIG_MODE_TILE 2 /* The performance counters are enabled, and are written out each time a tile finishes rendering. */ + +/* AS_MEMATTR values: */ +/* Use GPU implementation-defined caching policy. */ +#define ASn_MEMATTR_IMPL_DEF_CACHE_POLICY 0x48 +/* The attribute set to force all resources to be cached. */ +#define ASn_MEMATTR_FORCE_TO_CACHE_ALL 0x4F +/* Inner write-alloc cache setup, no outer caching */ +#define ASn_MEMATTR_WRITE_ALLOC 0x4D +/* symbol for default MEMATTR to use */ +#define ASn_MEMATTR_INDEX_DEFAULT 0 +/* HW implementation defined caching */ +#define ASn_MEMATTR_INDEX_IMPL_DEF_CACHE_POLICY 0 +/* Force cache on */ +#define ASn_MEMATTR_INDEX_FORCE_TO_CACHE_ALL 1 +/* Write-alloc inner */ +#define ASn_MEMATTR_INDEX_WRITE_ALLOC 2 + +/* GPU_ID register */ +#define GPU_ID_VERSION_STATUS_SHIFT 0 +#define GPU_ID_VERSION_MINOR_SHIFT 4 +#define GPU_ID_VERSION_MAJOR_SHIFT 12 +#define GPU_ID_VERSION_PRODUCT_ID_SHIFT 16 +#define GPU_ID_VERSION_STATUS (0xF << GPU_ID_VERSION_STATUS_SHIFT) +#define GPU_ID_VERSION_MINOR (0xFF << GPU_ID_VERSION_MINOR_SHIFT) +#define GPU_ID_VERSION_MAJOR (0xF << GPU_ID_VERSION_MAJOR_SHIFT) +#define GPU_ID_VERSION_PRODUCT_ID (0xFFFF << GPU_ID_VERSION_PRODUCT_ID_SHIFT) + +/* Values for GPU_ID_VERSION_PRODUCT_ID bitfield */ +#define GPU_ID_PI_T60X 0x6956 +#define GPU_ID_PI_T62X 0x0620 +#define GPU_ID_PI_T76X 0x0750 +#define GPU_ID_PI_T72X 0x0720 + +/* Values for GPU_ID_VERSION_STATUS field for PRODUCT_ID GPU_ID_PI_T60X */ +#define GPU_ID_S_15DEV0 0x1 +#define GPU_ID_S_EAC 0x2 + +/* Helper macro to create a GPU_ID assuming valid values for id, major, minor, status */ +#define GPU_ID_MAKE(id, major, minor, status) \ + (((id) << GPU_ID_VERSION_PRODUCT_ID_SHIFT) | \ + ((major) << GPU_ID_VERSION_MAJOR_SHIFT) | \ + ((minor) << GPU_ID_VERSION_MINOR_SHIFT) | \ + ((status) << GPU_ID_VERSION_STATUS_SHIFT)) + +/* End GPU_ID register */ + +/* JS_FEATURES register */ + +#define JSn_FEATURE_NULL_JOB (1u << 1) +#define JSn_FEATURE_SET_VALUE_JOB (1u << 2) +#define JSn_FEATURE_CACHE_FLUSH_JOB (1u << 3) +#define JSn_FEATURE_COMPUTE_JOB (1u << 4) +#define JSn_FEATURE_VERTEX_JOB (1u << 5) +#define JSn_FEATURE_GEOMETRY_JOB (1u << 6) +#define JSn_FEATURE_TILER_JOB (1u << 7) +#define JSn_FEATURE_FUSED_JOB (1u << 8) +#define JSn_FEATURE_FRAGMENT_JOB (1u << 9) + +/* End JS_FEATURES register */ + +/* L2_MMU_CONFIG register */ +#define L2_MMU_CONFIG_LIMIT_EXTERNAL_READS_SHIFT (24) +#define L2_MMU_CONFIG_LIMIT_EXTERNAL_READS (0x3 << L2_MMU_CONFIG_LIMIT_EXTERNAL_READS_SHIFT) +#define L2_MMU_CONFIG_LIMIT_EXTERNAL_READS_OCTANT (0x1 << L2_MMU_CONFIG_LIMIT_EXTERNAL_READS_SHIFT) +#define L2_MMU_CONFIG_LIMIT_EXTERNAL_READS_QUARTER (0x2 << L2_MMU_CONFIG_LIMIT_EXTERNAL_READS_SHIFT) +#define L2_MMU_CONFIG_LIMIT_EXTERNAL_READS_HALF (0x3 << L2_MMU_CONFIG_LIMIT_EXTERNAL_READS_SHIFT) + +#define L2_MMU_CONFIG_LIMIT_EXTERNAL_WRITES_SHIFT (26) +#define L2_MMU_CONFIG_LIMIT_EXTERNAL_WRITES (0x3 << L2_MMU_CONFIG_LIMIT_EXTERNAL_WRITES_SHIFT) +#define L2_MMU_CONFIG_LIMIT_EXTERNAL_WRITES_OCTANT (0x1 << L2_MMU_CONFIG_LIMIT_EXTERNAL_WRITES_SHIFT) +#define L2_MMU_CONFIG_LIMIT_EXTERNAL_WRITES_QUARTER (0x2 << L2_MMU_CONFIG_LIMIT_EXTERNAL_WRITES_SHIFT) +#define L2_MMU_CONFIG_LIMIT_EXTERNAL_WRITES_HALF (0x3 << L2_MMU_CONFIG_LIMIT_EXTERNAL_WRITES_SHIFT) +/* End L2_MMU_CONFIG register */ + +/* THREAD_* registers */ + +/* THREAD_FEATURES IMPLEMENTATION_TECHNOLOGY values */ +#define IMPLEMENTATION_UNSPECIFIED 0 +#define IMPLEMENTATION_SILICON 1 +#define IMPLEMENTATION_FPGA 2 +#define IMPLEMENTATION_MODEL 3 + +/* Default values when registers are not supported by the implemented hardware */ +#define THREAD_MT_DEFAULT 256 +#define THREAD_MWS_DEFAULT 256 +#define THREAD_MBS_DEFAULT 256 +#define THREAD_MR_DEFAULT 1024 +#define THREAD_MTQ_DEFAULT 4 +#define THREAD_MTGS_DEFAULT 10 + +/* End THREAD_* registers */ + +/* SHADER_CONFIG register */ + +#define SC_ALT_COUNTERS (1ul << 3) +#define SC_OVERRIDE_FWD_PIXEL_KILL (1ul << 4) +#define SC_SDC_DISABLE_OQ_DISCARD (1ul << 6) +#define SC_LS_PAUSEBUFFER_DISABLE (1ul << 16) +#define SC_ENABLE_TEXGRD_FLAGS (1ul << 25) +/* End SHADER_CONFIG register */ + +#endif /* _MIDGARD_REGMAP_H_ */ diff --git a/ext/nomali/lib/mali_midgard.cc b/ext/nomali/lib/mali_midgard.cc new file mode 100644 index 000000000..fe35f1259 --- /dev/null +++ b/ext/nomali/lib/mali_midgard.cc @@ -0,0 +1,92 @@ +/* + * Copyright (c) 2014-2015 ARM Limited + * All rights reserved + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + * Authors: Andreas Sandberg + */ + +#include "mali_midgard.hh" + +#include "regutils.hh" + +namespace NoMali { + +MaliMidgard::MaliMidgard(unsigned gpuType, + unsigned major, unsigned minor, unsigned status) + : MaliMidgard(GPU_ID_MAKE(gpuType, major, minor, status)) +{ +} + +MaliMidgard::MaliMidgard(uint32_t _gpuId) + : GPU(gpuControl, jobControl, mmu), + gpuControl(*this), + jobControl(*this), + mmu(*this), + gpuId(_gpuId) +{ +} + +MaliMidgard::~MaliMidgard() +{ +} + +void +MaliMidgard::setupControlIdRegisters(RegVector ®s) +{ + regs[RegAddr(L2_FEATURES)] = + (0x07 << 24) | // lg2 ext bus width + (0x13 << 16) | // lg2 cache size + (0x02 << 8) | // lg2 associativity + (0x06); // lg2 line size + + regs[RegAddr(TILER_FEATURES)] = + (0x8 << 8) | // Maximum no active hierarchy levels + 0x09; // lg2 bin size + + /* Coherent core group, but incoherent supergroup. 1 L2 slice. */ + regs[RegAddr(MEM_FEATURES)] = 0x1; + + regs[RegAddr(MMU_FEATURES)] = 0x2830; + regs[RegAddr(AS_PRESENT)] = 0xff; + regs[RegAddr(JS_PRESENT)] = 0x7; + regs[RegAddr(JS0_FEATURES)] = 0x20e; + regs[RegAddr(JS1_FEATURES)] = 0x1fe; + regs[RegAddr(JS2_FEATURES)] = 0x7e; + + regs[RegAddr(TEXTURE_FEATURES_0)] = 0x00fe001e; + regs[RegAddr(TEXTURE_FEATURES_1)] = 0xffff; + regs[RegAddr(TEXTURE_FEATURES_2)] = 0x9f81ffff; + + regs[RegAddr(THREAD_MAX_THREADS)] = 0x100; + regs[RegAddr(THREAD_MAX_WORKGROUP_SIZE)] = 0x100; + regs[RegAddr(THREAD_MAX_BARRIER_SIZE)] = 0x100; + regs[RegAddr(THREAD_FEATURES)] = 0x0a040400; + + regs.set64(RegAddr(SHADER_PRESENT_LO), 0xf); + regs.set64(RegAddr(TILER_PRESENT_LO), 0x1); + regs.set64(RegAddr(L2_PRESENT_LO), 0x1); +} + +void +MaliMidgard::GPUControlSpec::reset() +{ + GPUControl::reset(); + + regs[RegAddr(GPU_ID)] = midgard.gpuId; + + midgard.setupControlIdRegisters(regs); +} + +}; diff --git a/ext/nomali/lib/mali_midgard.hh b/ext/nomali/lib/mali_midgard.hh new file mode 100644 index 000000000..1030b3f49 --- /dev/null +++ b/ext/nomali/lib/mali_midgard.hh @@ -0,0 +1,70 @@ +/* + * Copyright (c) 2014-2015 ARM Limited + * All rights reserved + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + * Authors: Andreas Sandberg + */ + +#ifndef _LIBNOMALIMODEL_MALI_MIDGARD_HH +#define _LIBNOMALIMODEL_MALI_MIDGARD_HH + +#include "gpu.hh" + +#include "gpucontrol.hh" +#include "jobcontrol.hh" +#include "mmu.hh" + +namespace NoMali { + +/** + * Base class for Midgard based GPUs + */ +class MaliMidgard + : public GPU +{ + public: + MaliMidgard(unsigned gpuType, + unsigned major, unsigned minor, unsigned status); + MaliMidgard(uint32_t gpuId); + virtual ~MaliMidgard(); + + + protected: + class GPUControlSpec + : public GPUControl + { + public: + GPUControlSpec(MaliMidgard &_gpu) + : GPUControl(_gpu), midgard(_gpu) {} + + void reset() override; + + private: + MaliMidgard &midgard; + }; + + virtual void setupControlIdRegisters(RegVector ®s); + + GPUControlSpec gpuControl; + JobControl jobControl; + MMU mmu; + + private: + const uint32_t gpuId; +}; + +} + +#endif // _LIBNOMALIMODEL_MALI_MIDGARD_HH diff --git a/ext/nomali/lib/mali_t6xx.cc b/ext/nomali/lib/mali_t6xx.cc new file mode 100644 index 000000000..4d8221346 --- /dev/null +++ b/ext/nomali/lib/mali_t6xx.cc @@ -0,0 +1,55 @@ +/* + * Copyright (c) 2014-2015 ARM Limited + * All rights reserved + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + * Authors: Andreas Sandberg + */ + +#include "mali_t6xx.hh" + +#include "regutils.hh" + +namespace NoMali { + +MaliT6xxBase::MaliT6xxBase(unsigned gpuType, + unsigned major, unsigned minor, unsigned status) + : MaliMidgard(gpuType, major, minor, status) +{ +} + +void +MaliT6xxBase::setupControlIdRegisters(RegVector ®s) +{ + MaliMidgard::setupControlIdRegisters(regs); + + regs[RegAddr(L2_FEATURES)] = + (0x06 << 24) | // lg2 ext bus width + (0x10 << 16) | // lg2 cache size + (0x02 << 8) | // lg2 associativity + (0x06); // lg2 line size +} + + +MaliT60x::MaliT60x(unsigned major, unsigned minor, unsigned status) + : MaliT6xxBase(GPU_ID_PI_T60X, major, minor, status) +{ +} + +MaliT62x::MaliT62x(unsigned major, unsigned minor, unsigned status) + : MaliT6xxBase(GPU_ID_PI_T62X, major, minor, status) +{ +} + +}; diff --git a/ext/nomali/lib/mali_t6xx.hh b/ext/nomali/lib/mali_t6xx.hh new file mode 100644 index 000000000..b8e997659 --- /dev/null +++ b/ext/nomali/lib/mali_t6xx.hh @@ -0,0 +1,61 @@ +/* + * Copyright (c) 2014-2015 ARM Limited + * All rights reserved + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + * Authors: Andreas Sandberg + */ + +#ifndef _LIBNOMALIMODEL_MALI_T7XX_HH +#define _LIBNOMALIMODEL_MALI_T7XX_HH + +#include "mali_midgard.hh" + +namespace NoMali { + +class MaliT6xxBase + : public MaliMidgard +{ + public: + MaliT6xxBase(unsigned gpuType, + unsigned major, unsigned minor, unsigned status); + + protected: + void setupControlIdRegisters(RegVector ®s) override; +}; + + +/** + * Simple NoMali implementation of the Mali T60x + */ +class MaliT60x + : public MaliT6xxBase +{ + public: + MaliT60x(unsigned major, unsigned minor, unsigned status); +}; + +/** + * Simple NoMali implementation of the Mali T62x + */ +class MaliT62x + : public MaliT6xxBase +{ + public: + MaliT62x(unsigned major, unsigned minor, unsigned status); +}; + +} + +#endif // _LIBNOMALIMODEL_MALI_T7XX_HH diff --git a/ext/nomali/lib/mali_t7xx.cc b/ext/nomali/lib/mali_t7xx.cc new file mode 100644 index 000000000..33f3b6b24 --- /dev/null +++ b/ext/nomali/lib/mali_t7xx.cc @@ -0,0 +1,50 @@ +/* + * Copyright (c) 2014-2015 ARM Limited + * All rights reserved + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + * Authors: Andreas Sandberg + */ + +#include "mali_t7xx.hh" + +#include "regutils.hh" + +namespace NoMali { + +MaliT7xxBase::MaliT7xxBase(unsigned gpuType, + unsigned major, unsigned minor, unsigned status) + : MaliMidgard(gpuType, major, minor, status) +{ +} + +void +MaliT7xxBase::setupControlIdRegisters(RegVector ®s) +{ + MaliMidgard::setupControlIdRegisters(regs); + + regs[RegAddr(L2_FEATURES)] = + (0x07 << 24) | // lg2 ext bus width + (0x13 << 16) | // lg2 cache size + (0x02 << 8) | // lg2 associativity + (0x06); // lg2 line size +} + + +MaliT76x::MaliT76x(unsigned major, unsigned minor, unsigned status) + : MaliT7xxBase(GPU_ID_PI_T76X, major, minor, status) +{ +} + +}; diff --git a/ext/nomali/lib/mali_t7xx.hh b/ext/nomali/lib/mali_t7xx.hh new file mode 100644 index 000000000..3ea5d7074 --- /dev/null +++ b/ext/nomali/lib/mali_t7xx.hh @@ -0,0 +1,50 @@ +/* + * Copyright (c) 2014-2015 ARM Limited + * All rights reserved + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + * Authors: Andreas Sandberg + */ + +#ifndef _LIBNOMALIMODEL_MALIT_T7XX_HH +#define _LIBNOMALIMODEL_MALIT_T7XX_HH + +#include "mali_midgard.hh" + +namespace NoMali { + +class MaliT7xxBase + : public MaliMidgard +{ + public: + MaliT7xxBase(unsigned gpuType, + unsigned major, unsigned minor, unsigned status); + + protected: + void setupControlIdRegisters(RegVector ®s) override; +}; + +/** + * Simple NoMali implementation of the Mali T76x + */ +class MaliT76x + : public MaliT7xxBase +{ + public: + MaliT76x(unsigned major, unsigned minor, unsigned status); +}; + +} + +#endif // _LIBNOMALIMODEL_MALI_T7XX_HH diff --git a/ext/nomali/lib/mmu.cc b/ext/nomali/lib/mmu.cc new file mode 100644 index 000000000..2d166b5af --- /dev/null +++ b/ext/nomali/lib/mmu.cc @@ -0,0 +1,64 @@ +/* + * Copyright (c) 2014-2015 ARM Limited + * All rights reserved + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + * Authors: Andreas Sandberg + */ + +#include "mmu.hh" + +#include "gpu.hh" +#include "regutils.hh" + +namespace NoMali { + +MMU::MMU(GPU &_gpu) + : GPUBlockInt(_gpu, + RegAddr(MMU_IRQ_RAWSTAT), + RegAddr(MMU_IRQ_CLEAR), + RegAddr(MMU_IRQ_MASK), + RegAddr(MMU_IRQ_STATUS)), + regs(BLOCK_NUM_REGS) +{ +} + +MMU::~MMU() +{ +} + +void +MMU::writeReg(RegAddr addr, uint32_t value) +{ + switch (addr.value) { + case MMU_IRQ_RAWSTAT: + case MMU_IRQ_CLEAR: + case MMU_IRQ_MASK: + case MMU_IRQ_STATUS: + GPUBlockInt::writeReg(addr, value); + break; + + default: + // Ignore writes by default + break; + }; +} + +void +MMU::onInterrupt(int set) +{ + gpu.intMMU(set); +} + +} diff --git a/ext/nomali/lib/mmu.hh b/ext/nomali/lib/mmu.hh new file mode 100644 index 000000000..82864a6ff --- /dev/null +++ b/ext/nomali/lib/mmu.hh @@ -0,0 +1,57 @@ +/* + * Copyright (c) 2014-2015 ARM Limited + * All rights reserved + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + * Authors: Andreas Sandberg + */ + +#ifndef _LIBNOMALIMODEL_MMU_HH +#define _LIBNOMALIMODEL_MMU_HH + +#include + +#include "gpublock.hh" +#include "types.hh" + +namespace NoMali { + +class GPU; + +/** + * MMU dummy implementation. + * + * This is a dummy implementation of a Midgard GPU MMU block. The only + * features supported by the block is interrupt delivery and registers + * related to interrupt delivery. Writes to unimplemented registers + * (most registers) are discarded and their values are read as zero. + */ +class MMU + : public GPUBlockInt +{ + public: + MMU(GPU &_gpu); + virtual ~MMU(); + + void writeReg(RegAddr idx, uint32_t value) override; + + protected: + void onInterrupt(int set) override; + + RegVector regs; +}; + +} + +#endif // _LIBNOMALIMODEL_MMU_HH diff --git a/ext/nomali/lib/nomali_api.cc b/ext/nomali/lib/nomali_api.cc new file mode 100644 index 000000000..46f0e7fce --- /dev/null +++ b/ext/nomali/lib/nomali_api.cc @@ -0,0 +1,355 @@ +/* + * Copyright (c) 2014-2015 ARM Limited + * All rights reserved + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + * Authors: Andreas Sandberg + */ + +#include "libnomali/nomali.h" + +#include + +#include "mali_t6xx.hh" +#include "mali_t7xx.hh" + +#define EXPORT __attribute__ ((visibility ("default"))) + +static const char *errstrs[] = { + "No error", + "Unknown error", + "Memory allocation failed", + "Invalid model handle", + "Invalid parameter", +}; + +static_assert(sizeof(errstrs) / sizeof(*errstrs) == NOMALI_E_NUM_ERRORS, + "NoMali API error descriptions out of sync!"); + +class NoMaliApi +{ + public: + NoMaliApi(); + ~NoMaliApi(); + + void setGpu(NoMali::GPU *gpu) { _gpu = gpu; } + + public: + nomali_error_t setCallback(const nomali_callback_t *callback); + + nomali_error_t getInfo(nomali_info_t *info); + + nomali_error_t reset(); + nomali_error_t regRead(uint32_t *value, nomali_addr_t addr); + nomali_error_t regWrite(nomali_addr_t addr, uint32_t value); + nomali_error_t regReadRaw(uint32_t *value, nomali_addr_t addr); + nomali_error_t regWriteRaw(nomali_addr_t addr, uint32_t value); + nomali_error_t intState(int *state, nomali_int_t intno) const; + + public: + void callbackInt(nomali_int_t intno, int set); + + private: + nomali_callback_t callbacks[NOMALI_CALLBACK_NUM_CALLBACKS]; + + NoMali::GPU *_gpu; +}; + +template +class NoMaliApiGpu + : public BaseGpu +{ + public: + template + NoMaliApiGpu(NoMaliApi &_api, Args &&... args) + : BaseGpu(std::forward(args)...), + api(_api) + { + BaseGpu::reset(); + } + + public: + void intJob(int set) override { api.callbackInt(NOMALI_INT_JOB, set); } + void intMMU(int set) override { api.callbackInt(NOMALI_INT_MMU, set); } + void intGPU(int set) override { api.callbackInt(NOMALI_INT_GPU, set); } + + private: + NoMaliApi &api; +}; + + +NoMaliApi::NoMaliApi() + : _gpu(nullptr) +{ + memset(callbacks, 0, sizeof(callbacks)); +} + + +NoMaliApi::~NoMaliApi() +{ +} + +nomali_error_t +NoMaliApi::setCallback(const nomali_callback_t *callback) +{ + if (!callback || + callback->type >= NOMALI_CALLBACK_NUM_CALLBACKS) + return NOMALI_E_INVALID; + + callbacks[callback->type] = *callback; + + return NOMALI_E_OK; +} + +nomali_error_t +NoMaliApi::getInfo(nomali_info_t *info) +{ + if (!info) + return NOMALI_E_INVALID; + + info->reg_size = 0x4000; + + return NOMALI_E_OK; +} + +nomali_error_t +NoMaliApi::reset() +{ + _gpu->reset(); + return NOMALI_E_OK; +} + +nomali_error_t +NoMaliApi::regRead(uint32_t *value, nomali_addr_t addr) +{ + if (!value) + return NOMALI_E_INVALID; + + *value = _gpu->readReg(NoMali::RegAddr(addr)); + + return NOMALI_E_OK; +} + +nomali_error_t +NoMaliApi::regWrite(nomali_addr_t addr, uint32_t value) +{ + _gpu->writeReg(NoMali::RegAddr(addr), value); + + return NOMALI_E_OK; +} + + +nomali_error_t +NoMaliApi::regReadRaw(uint32_t *value, nomali_addr_t addr) +{ + if (!value) + return NOMALI_E_INVALID; + + *value = _gpu->readRegRaw(NoMali::RegAddr(addr)); + + return NOMALI_E_OK; +} + +nomali_error_t +NoMaliApi::regWriteRaw(nomali_addr_t addr, uint32_t value) +{ + _gpu->writeRegRaw(NoMali::RegAddr(addr), value); + + return NOMALI_E_OK; +} + +nomali_error_t +NoMaliApi::intState(int *state, nomali_int_t intno) const +{ + if (!state) + return NOMALI_E_INVALID; + + switch (intno) { + case NOMALI_INT_GPU: + *state = _gpu->intGPUAsserted(); + break; + + case NOMALI_INT_JOB: + *state = _gpu->intJobAsserted(); + break; + + case NOMALI_INT_MMU: + *state = _gpu->intMMUAsserted(); + break; + + default: + return NOMALI_E_INVALID; + } + + return NOMALI_E_OK; +} + + +void +NoMaliApi::callbackInt(nomali_int_t intno, int set) +{ + const nomali_callback_t &c(callbacks[NOMALI_CALLBACK_INT]); + + if (c.func.interrupt) + c.func.interrupt(static_cast(this), c.usr, intno, set); +} + + + +static NoMaliApi * +get_gpu(nomali_handle_t h) +{ + return h ? static_cast(h) : nullptr; +} + + +extern "C" EXPORT nomali_api_version_t +nomali_api_version() +{ + return NOMALI_API_VERSION; +} + +extern "C" EXPORT nomali_error_t +nomali_create(nomali_handle_t *h, const nomali_config_t *cfg) +{ + if (h && cfg) { + NoMaliApi *api(new NoMaliApi()); + *h = api; + if (!h) + return NOMALI_E_MEMORY; + + NoMali::GPU *gpu; + switch (cfg->type) { + case NOMALI_GPU_T60X: + gpu = new NoMaliApiGpu( + *api, + cfg->ver_maj, cfg->ver_min, cfg->ver_status); + break; + + case NOMALI_GPU_T62X: + gpu = new NoMaliApiGpu( + *api, + cfg->ver_maj, cfg->ver_min, cfg->ver_status); + break; + + + case NOMALI_GPU_T76X: + gpu = new NoMaliApiGpu( + *api, + cfg->ver_maj, cfg->ver_min, cfg->ver_status); + break; + + default: + delete api; + return NOMALI_E_INVALID; + }; + + if (!gpu) { + delete api; + return NOMALI_E_MEMORY; + } + + api->setGpu(gpu); + + return NOMALI_E_OK; + } else { + return NOMALI_E_INVALID; + } +} + +extern "C" EXPORT nomali_error_t +nomali_destroy(nomali_handle_t h) +{ + NoMaliApi *gpu(get_gpu(h)); + + if (gpu) { + delete gpu; + return NOMALI_E_OK; + } else { + return NOMALI_E_HANDLE; + } +} + +extern "C" EXPORT const char * +nomali_errstr(nomali_error_t error) +{ + if (error < NOMALI_E_NUM_ERRORS) + return errstrs[error]; + else + return "Invalid error number"; +} + +extern "C" EXPORT nomali_error_t +nomali_set_callback(nomali_handle_t h, + const nomali_callback_t *callback) +{ + NoMaliApi *gpu(get_gpu(h)); + return gpu ? gpu->setCallback(callback) : NOMALI_E_HANDLE; +} + +extern "C" EXPORT nomali_error_t +nomali_get_info(nomali_handle_t h, nomali_info_t *info) +{ + NoMaliApi *gpu(get_gpu(h)); + return gpu ? gpu->getInfo(info) : NOMALI_E_HANDLE; +} + +extern "C" EXPORT nomali_error_t +nomali_reset(nomali_handle_t h) +{ + NoMaliApi *gpu(get_gpu(h)); + return gpu ? gpu->reset() : NOMALI_E_HANDLE; +} + +extern "C" EXPORT nomali_error_t +nomali_reg_read(nomali_handle_t h, uint32_t *value, + nomali_addr_t addr) +{ + NoMaliApi *gpu(get_gpu(h)); + return gpu ? gpu->regRead(value, addr) : NOMALI_E_HANDLE; +} + +extern "C" EXPORT nomali_error_t +nomali_reg_write(nomali_handle_t h, + nomali_addr_t addr, uint32_t value) +{ + NoMaliApi *gpu(get_gpu(h)); + return gpu ? gpu->regWrite(addr, value) : NOMALI_E_HANDLE; +} + + +extern "C" EXPORT nomali_error_t +nomali_reg_read_raw(nomali_handle_t h, uint32_t *value, + nomali_addr_t addr) +{ + NoMaliApi *gpu(get_gpu(h)); + return gpu ? gpu->regReadRaw(value, addr) : NOMALI_E_HANDLE; +} + +extern "C" EXPORT nomali_error_t +nomali_reg_write_raw(nomali_handle_t h, + nomali_addr_t addr, uint32_t value) +{ + NoMaliApi *gpu(get_gpu(h)); + return gpu ? gpu->regWriteRaw(addr, value) : NOMALI_E_HANDLE; +} + +extern "C" EXPORT nomali_error_t +nomali_int_state(nomali_handle_t h, int *state, + nomali_int_t intno) +{ + NoMaliApi *gpu(get_gpu(h)); + return gpu ? gpu->intState(state, intno) : NOMALI_E_HANDLE; +} + diff --git a/ext/nomali/lib/regutils.hh b/ext/nomali/lib/regutils.hh new file mode 100644 index 000000000..7957df2b7 --- /dev/null +++ b/ext/nomali/lib/regutils.hh @@ -0,0 +1,103 @@ +/* + * Copyright (c) 2014-2015 ARM Limited + * All rights reserved + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + * Authors: Andreas Sandberg + */ + +#ifndef _LIBNOMALIMODEL_REGUTILS_HH +#define _LIBNOMALIMODEL_REGUTILS_HH + +#include + +#include "types.hh" +#include "mali_midg_regmap.h" + +namespace NoMali { + +/** Size of a function block in bytes */ +static const uint32_t BLOCK_REGS_SIZE(0x1000); +/** Number of registers in a function block */ +static const uint32_t BLOCK_NUM_REGS = BLOCK_REGS_SIZE >> 2; + +/** + * Register blocks within the GPU. + * + * The GPU splits its register space into chunks belonging to specific + * blocks. This enum lists those blocks. + */ +enum class RegBlock : uint16_t { + GPU = 0x0, + JOB = 0x1, + MMU = 0x2, + + UNKNOWN = 0xFFFF, +}; + +/** Get the register block from a GPU register address */ +static inline RegBlock +getRegBlock(RegAddr addr) +{ + return RegBlock(addr.value >> 12); +} + +/** + * Get the register address within a GPU block. + * + * This method masks away the block offset from a GPU register + * address. The resulting address is the address within a + * function block. + */ +static inline RegAddr +getBlockReg(RegAddr addr) +{ + static_assert((BLOCK_REGS_SIZE & (BLOCK_REGS_SIZE - 1)) == 0, + "BLOCK_REGS_SIZE is not a power of 2"); + return RegAddr(addr.value & (BLOCK_REGS_SIZE - 1)); +} + +/** + * Get the slot number owning an address within the JobControl block. + * + * @param Address relative to the JobControl block. + */ +static inline unsigned +getJobSlotNo(const RegAddr &addr) +{ + assert(addr.value >= JOB_SLOT0); + assert(addr.value <= 0xFFF); + return (addr.value - JOB_SLOT0) >> 7; +} + +/** + * Get a JobSlot-relative address from a JobControl-relative address. + * + * @param Address relative to the JobControl block. + * @return Address relative the start of the JobSlot. + */ +static inline RegAddr +getJobSlotAddr(const RegAddr &addr) +{ + const unsigned slot_no(getJobSlotNo(addr)); + const RegAddr slot_base(RegAddr(JOB_SLOT0 + slot_no * 0x80)); + return addr - slot_base; +} + +/** Number of registers per job slot */ +static const unsigned JSn_NO_REGS = 0x20; + +} + +#endif //_LIBNOMALIMODEL_REGUTILS_HH diff --git a/ext/nomali/lib/types.hh b/ext/nomali/lib/types.hh new file mode 100644 index 000000000..7d2d6e1f6 --- /dev/null +++ b/ext/nomali/lib/types.hh @@ -0,0 +1,218 @@ +/* + * Copyright (c) 2014-2015 ARM Limited + * All rights reserved + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + * Authors: Andreas Sandberg + */ + +#ifndef _LIBNOMALIMODEL_TYPES_HH +#define _LIBNOMALIMODEL_TYPES_HH + +#include +#include + +#include +#include + +namespace NoMali{ + +/** + * @{ + * @name Register handling utilities + */ + +/** + * Register address wrapper + * + * This class wraps a register address. Unlike a simple typedef, this + * provides safety from automatic type conversions from other integer + * types since the constructor must be called explicitly. + */ +struct RegAddr { + explicit RegAddr(uint32_t v) + : value(v) {} + + const uint32_t value; +}; + +inline bool +operator<(const RegAddr &lhs, const RegAddr &rhs) { + return lhs.value < rhs.value; +} + +inline bool +operator>(const RegAddr &lhs, const RegAddr &rhs) { + return lhs.value > rhs.value; +} + +inline bool +operator<=(const RegAddr &lhs, const RegAddr &rhs) { + return lhs.value <= rhs.value; +} + +inline bool +operator>=(const RegAddr &lhs, const RegAddr &rhs) { + return lhs.value >= rhs.value; +} + +inline bool +operator==(const RegAddr &lhs, const RegAddr &rhs) { + return lhs.value == rhs.value; +} + +inline bool +operator!=(const RegAddr &lhs, const RegAddr &rhs) { + return lhs.value != rhs.value; +} + +inline RegAddr +operator+(const RegAddr &lhs, const RegAddr &rhs) { + return RegAddr(lhs.value + rhs.value); +} + +inline RegAddr +operator-(const RegAddr &lhs, const RegAddr &rhs) { + assert(lhs >= rhs); + return RegAddr(lhs.value - rhs.value); +} + +/** + * Class for register storage + * + * This class wraps a std::vector and implements a subset of its + * functionality. Specifically, it is constant size and prevents + * indexing with anything other than RegAddr instances. + */ +class RegVector +{ + private: + typedef std::vector vector_t; + + public: + typedef vector_t::iterator iterator; + typedef vector_t::const_iterator const_iterator; + typedef vector_t::size_type size_type; + + public: + RegVector(size_type size) + : vector(size, 0) {} + + /** @{ */ + /** + * Helper function to get a 64-bit register. + * + * @param addr Address to the low part of the register. + * @return 64-bit value representing the concatenation of the HI + * and LO parts of the register. + */ + const uint32_t get64(const RegAddr &addr) const { + const unsigned idx_lo = index(addr); + const unsigned idx_hi = idx_lo + 1; + return (((uint64_t)vector[idx_hi]) << 32) | vector[idx_lo]; + } + + /** + * Helper function to set a 64-bit register. + * + * @param addr Address to the low part of the register. + * @param value Value to write into the 64-bit register. + */ + void set64(const RegAddr &addr, uint64_t value) { + const unsigned idx_lo = index(addr); + const unsigned idx_hi = idx_lo + 1; + vector[idx_lo] = value & 0xFFFFFFFF; + vector[idx_hi] = (value >> 32) & 0xFFFFFFFF; + } + + const uint32_t &operator[](const RegAddr &addr) const { + return vector[index(addr)]; + } + + uint32_t &operator[](const RegAddr &addr) { + return vector[index(addr)]; + } + + + iterator begin() noexcept { return vector.begin(); } + const_iterator begin() const noexcept { return vector.begin(); } + const_iterator cbegin() const noexcept { return vector.cbegin(); } + + iterator end() noexcept { return vector.end(); } + const_iterator end() const noexcept { return vector.end(); } + const_iterator cend() const noexcept { return vector.cend(); } + + const size_type size() const noexcept { return vector.size(); } + + private: + // Disable default constructor + RegVector(); + + static uint32_t index(const RegAddr &addr) { + assert((addr.value & 0x3) == 0); + return addr.value >> 2; + } + + + vector_t vector; +}; +/** @} */ + +/** + * Class representing the status codes in the Midgard architecture. + */ +struct Status { + /** + * Class representing the subsystem a status code originates from. + */ + enum StatusClass { + CLASS_NOFAULT = 0, + CLASS_JOB = 1, + CLASS_GPU = 2, + CLASS_MMU = 3, + }; + + typedef uint8_t Code; + typedef uint8_t SubCode; + + Status(StatusClass cls, Code code, SubCode subcode) + : value((cls << 6) | (code << 3) | subcode) { + assert((cls & ~0x3) == 0); + assert((code & ~0x7) == 0); + assert((subcode & ~0x7) == 0); + } + + explicit Status(uint8_t v) + : value(v) {} + + StatusClass statusClass() const { + return (StatusClass)((value >> 6) & 0x3); + } + + Code code() const { + return (value >> 3) & 0x7; + } + + SubCode subCode() const { + return value & 0x7; + } + + const uint8_t value; +}; + + +} + +#endif + diff --git a/ext/nomali/tests/Rules.mk b/ext/nomali/tests/Rules.mk new file mode 100644 index 000000000..492a326f2 --- /dev/null +++ b/ext/nomali/tests/Rules.mk @@ -0,0 +1,44 @@ +# +# Copyright (c) 2014-2015 ARM Limited +# All rights reserved +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +# Authors: Andreas Sandberg + +sp := $(sp).x +dirstack_$(sp) := $(d) +d := $(dir) + +HELPER_OBJS := $(addprefix $(d)/, \ + test_helpers.o \ + ) + +TESTS := $(addprefix $(d)/nomali_, \ + test0 \ + test_ints \ + ) + +OBJS := $(HELPER_OBJS) $(addsuffix .o, $(TESTS)) + +ALL_TESTS := $(ALL_TESTS) $(TESTS) +DEPS := $(DEPS) $(OBJS:.o=.d) +CLEAN := $(CLEAN) $(OBJS) $(TESTS) + +include Rules.app.mk + +$(d)/nomali_%: $(d)/nomali_%.o $(d)/test_helpers.o libnomali.so + $(CXX) $(LDFLAGS) -Wl,-rpath -Wl,"$(CURDIR)" -o $@ $^ + +d := $(dirstack_$(sp)) +sp := $(basename $(sp)) diff --git a/ext/nomali/tests/nomali_test0.c b/ext/nomali/tests/nomali_test0.c new file mode 100644 index 000000000..7ae82252c --- /dev/null +++ b/ext/nomali/tests/nomali_test0.c @@ -0,0 +1,53 @@ +/* + * Copyright (c) 2014-2015 ARM Limited + * All rights reserved + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + * Authors: Andreas Sandberg + */ + +#include +#include + +#include "nomali_test_helpers.h" +#include "../lib/mali_midg_regmap.h" + +int +main(int argc, char **argv) +{ + const nomali_config_t cfg = { + .type = NOMALI_GPU_T60X, + .ver_maj = 0, + .ver_min = 1, + .ver_status = 0, + }; + nomali_handle_t h; + nomali_error_t error = NOMALI_E_OK; + uint32_t value; + + E_NOMALI_TEST("nomali_create", nomali_create(&h, &cfg)); + if (error != NOMALI_E_OK) + test_bail("Failed to create NoMail instance!"); + + E_NOMALI_TEST("reg_read(GPU_ID)", + nomali_reg_read(h, &value, GPU_CONTROL_REG(GPU_ID))); + if (value != ((GPU_ID_PI_T60X << 16) | 0x10)) { + test_fail("GPU_ID"); + } else + test_ok("GPU_ID"); + + E_NOMALI_TEST("nomali_destroy", nomali_destroy(h)); + + return 0; +} diff --git a/ext/nomali/tests/nomali_test_helpers.h b/ext/nomali/tests/nomali_test_helpers.h new file mode 100644 index 000000000..9de491a2a --- /dev/null +++ b/ext/nomali/tests/nomali_test_helpers.h @@ -0,0 +1,46 @@ +/* + * Copyright (c) 2014-2015 ARM Limited + * All rights reserved + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + * Authors: Andreas Sandberg + */ + +#ifndef _TESTS_NOMALI_TEST_HELPERS_H +#define _TESTS_NOMALI_TEST_HELPERS_H + +#include +#include "test_helpers.h" + +#define E_NOMALI_BAIL(c) \ + do { \ + if ((error = (c)) != NOMALI_E_OK) { \ + test_bail(# c " failed: %s (%i)", \ + nomali_errstr(error), error); \ + } \ + } while (0) + +#define E_NOMALI_TEST(t, c) \ + do { \ + if ((error = (c)) != NOMALI_E_OK) { \ + test_diag(# c " failed: %s (%i)", \ + nomali_errstr(error), error); \ + test_fail(t); \ + } else { \ + test_ok(t); \ + } \ + } while (0) + + +#endif /* _TESTS_NOMALI_TEST_HELPERS_H */ diff --git a/ext/nomali/tests/nomali_test_ints.c b/ext/nomali/tests/nomali_test_ints.c new file mode 100644 index 000000000..54a7083ab --- /dev/null +++ b/ext/nomali/tests/nomali_test_ints.c @@ -0,0 +1,127 @@ +/* + * Copyright (c) 2014-2015 ARM Limited + * All rights reserved + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + * Authors: Andreas Sandberg + */ + +#include +#include + +#include "nomali_test_helpers.h" +#include "../lib/mali_midg_regmap.h" + +static void +on_int(nomali_handle_t h, void *usr, nomali_int_t intno, int set) +{ + test_diag("on_int: intno: %i, set: %i", intno, set); + *(int*)usr = !!set; +} + +static void +test_gpu_int(nomali_handle_t h) +{ + nomali_error_t error = NOMALI_E_OK; + int int_triggered = 0; + nomali_callback_t int_callback = { + .type = NOMALI_CALLBACK_INT, + .usr = &int_triggered, + .func.interrupt = on_int, + }; + + nomali_callback_t int_null_callback = { + .type = NOMALI_CALLBACK_INT, + .usr = NULL, + .func.interrupt = NULL, + }; + + /* + * Raise an interrupt without callbacks + */ + E_NOMALI_BAIL(nomali_reg_write(h, + GPU_CONTROL_REG(GPU_IRQ_CLEAR), + GPU_IRQ_REG_ALL)); + + E_NOMALI_BAIL(nomali_reg_write(h, GPU_CONTROL_REG(GPU_IRQ_MASK), + GPU_FAULT)); + + E_NOMALI_BAIL(nomali_reg_write(h, GPU_CONTROL_REG(GPU_IRQ_RAWSTAT), + GPU_FAULT)); + + E_NOMALI_BAIL(nomali_reg_write(h, + GPU_CONTROL_REG(GPU_IRQ_CLEAR), + GPU_IRQ_REG_ALL)); + + /* + * Register callbacks and raise interrupt again. + */ + E_NOMALI_BAIL(nomali_set_callback(h, &int_callback)); + if (int_triggered != 0) { + test_diag("Got spurious interrupt\n"); + test_fail("gpu_int"); + } + + E_NOMALI_BAIL(nomali_reg_write(h, GPU_CONTROL_REG(GPU_IRQ_RAWSTAT), + GPU_FAULT)); + if (int_triggered == 1) { + test_ok("gpu_int"); + } else { + test_fail("gpu_int"); + } + int_triggered = 0; + + + /* + * Register mask interrupts and raise interrupt again. + */ + E_NOMALI_BAIL(nomali_reg_write(h, + GPU_CONTROL_REG(GPU_IRQ_CLEAR), + GPU_IRQ_REG_ALL)); + E_NOMALI_BAIL(nomali_reg_write(h, GPU_CONTROL_REG(GPU_IRQ_MASK), + 0)); + E_NOMALI_BAIL(nomali_reg_write(h, GPU_CONTROL_REG(GPU_IRQ_RAWSTAT), + GPU_FAULT)); + if (int_triggered == 0) { + test_ok("gpu_int_masked"); + } else { + test_fail("gpu_int_maked"); + } + E_NOMALI_BAIL(nomali_reg_write(h, + GPU_CONTROL_REG(GPU_IRQ_CLEAR), + GPU_IRQ_REG_ALL)); + E_NOMALI_BAIL(nomali_set_callback(h, &int_null_callback)); +} + +int +main(int argc, char **argv) +{ + const nomali_config_t cfg = { + .type = NOMALI_GPU_T60X, + .ver_maj = 0, + .ver_min = 1, + .ver_status = 0, + }; + + nomali_handle_t h; + nomali_error_t error = NOMALI_E_OK; + + E_NOMALI_BAIL(nomali_create(&h, &cfg)); + + test_gpu_int(h); + + E_NOMALI_BAIL(nomali_destroy(h)); + + return 0; +} diff --git a/ext/nomali/tests/test_helpers.c b/ext/nomali/tests/test_helpers.c new file mode 100644 index 000000000..dad6d4ad1 --- /dev/null +++ b/ext/nomali/tests/test_helpers.c @@ -0,0 +1,147 @@ +/* + * Copyright (c) 2013 Andreas Sandberg + * All rights reserved + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + * Authors: Andreas Sandberg + */ + +#include "test_helpers.h" + +#include +#include +#include + +unsigned test_current = 0; +unsigned test_count = 0; +unsigned test_fail_count = 0; + +void +test_init(unsigned no_tests) +{ + assert(test_count == 0 && test_current == 0); + + test_count = no_tests; + test_current = 1; + test_fail_count = 0; + + printf("1..%u\n", no_tests); +} + +void +test_exit() +{ + if (test_fail_count) + exit(EXIT_FAILURE); + else + exit(EXIT_SUCCESS); +} + +void +test_bail(const char *fmt, ...) +{ + va_list ap; + va_start(ap, fmt); + + printf("Bail out! "); + vprintf(fmt, ap); + printf("\n"); + + va_end(ap); + + exit(EXIT_FAILURE); +} + +void +test_diag(const char *fmt, ...) +{ + va_list ap; + va_start(ap, fmt); + + printf("# "); + vprintf(fmt, ap); + printf("\n"); + + va_end(ap); +} + +static void +test_vstatus(const char *status, const char *test, + const char *directive, + const char *fmt_why, va_list ap) +{ + printf("%s %i", status, test_current); + + if (test && test[0] != '\0') + printf(" - %s", test); + + if (directive && directive[0] != '\0') { + printf(" # %s ", directive); + if (fmt_why && fmt_why[0] != '\0') + vprintf(fmt_why, ap); + } + printf("\n"); + + ++test_current; +} + +static void __attribute__((format (printf, 4, 5))) +test_status(const char *status, const char *test, + const char *directive, + const char *fmt_why, ...) +{ + va_list ap; + va_start(ap, fmt_why); + + test_vstatus(status, test, directive, fmt_why, ap); + + va_end(ap); +} + +void +test_ok(const char *test) +{ + test_status("ok", test, NULL, NULL); +} + +void +test_fail(const char *test) +{ + test_status("not ok", test, NULL, NULL); + ++test_fail_count; +} + +void +test_skip(const char *test, const char *fmt_why, ...) +{ + va_list ap; + va_start(ap, fmt_why); + + test_vstatus("ok", test, "SKIP", fmt_why, ap); + + va_end(ap); +} + +void +test_todo(const char *test, const char *fmt_why, ...) +{ + va_list ap; + va_start(ap, fmt_why); + + test_vstatus("not ok", test, "TODO", fmt_why, ap); + + va_end(ap); + + ++test_fail_count; +} diff --git a/ext/nomali/tests/test_helpers.h b/ext/nomali/tests/test_helpers.h new file mode 100644 index 000000000..68bea288b --- /dev/null +++ b/ext/nomali/tests/test_helpers.h @@ -0,0 +1,57 @@ +/* + * Copyright (c) 2013 Andreas Sandberg + * All rights reserved + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + * Authors: Andreas Sandberg + */ + +#ifndef _TEST_HELPERS +#define _TEST_HELPERS 1 + +#include + +#ifdef __cplusplus +#extern "C" { +#endif + +extern unsigned test_current; +extern unsigned test_count; +extern unsigned test_fail_count; + +void test_init(unsigned no_tests); +void test_exit() + __attribute__((noreturn)); + +void test_bail(const char *fmt, ...) + __attribute__((format (printf, 1, 2), noreturn)); + +void test_diag(const char *fmt, ...) + __attribute__((format (printf, 1, 2))); + +void test_ok(const char *test); + +void test_fail(const char *test); + +void test_skip(const char *test, const char *fmt_why, ...) + __attribute__((format (printf, 2, 3))); + +void test_todo(const char *test, const char *fmt_why, ...) + __attribute__((format (printf, 2, 3))); + +#ifdef __cplusplus +} +#endif + +#endif -- cgit v1.2.3