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.
This commit is contained in:
parent
a0cbf55411
commit
c274057840
39 changed files with 6484 additions and 0 deletions
|
@ -1202,6 +1202,10 @@ main.SConscript('ext/dramsim2/SConscript',
|
|||
main.SConscript('ext/drampower/SConscript',
|
||||
variant_dir = joinpath(build_root, 'drampower'))
|
||||
|
||||
# nomali build is shared across all configs in the build root.
|
||||
main.SConscript('ext/nomali/SConscript',
|
||||
variant_dir = joinpath(build_root, 'nomali'))
|
||||
|
||||
###################################################
|
||||
#
|
||||
# This function is used to set up a directory with switching headers
|
||||
|
|
8
ext/nomali/.gitignore
vendored
Normal file
8
ext/nomali/.gitignore
vendored
Normal file
|
@ -0,0 +1,8 @@
|
|||
/docs
|
||||
/tests/nomali_test0
|
||||
/tests/nomali_test_ints
|
||||
*~
|
||||
*.o
|
||||
*.d
|
||||
*.so
|
||||
*.a
|
1785
ext/nomali/Doxyfile
Normal file
1785
ext/nomali/Doxyfile
Normal file
File diff suppressed because it is too large
Load diff
202
ext/nomali/LICENSE
Normal file
202
ext/nomali/LICENSE
Normal file
|
@ -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.
|
81
ext/nomali/Makefile
Normal file
81
ext/nomali/Makefile
Normal file
|
@ -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)
|
31
ext/nomali/Rules.app.mk
Normal file
31
ext/nomali/Rules.app.mk
Normal file
|
@ -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 $@ $<
|
31
ext/nomali/Rules.lib.mk
Normal file
31
ext/nomali/Rules.lib.mk
Normal file
|
@ -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 $@ $<
|
63
ext/nomali/SConscript
Normal file
63
ext/nomali/SConscript
Normal file
|
@ -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('.')])
|
||||
|
46
ext/nomali/doxygen.sed
Executable file
46
ext/nomali/doxygen.sed
Executable file
|
@ -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;
|
||||
}
|
333
ext/nomali/include/libnomali/nomali.h
Normal file
333
ext/nomali/include/libnomali/nomali.h
Normal file
|
@ -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 <stdint.h>
|
||||
|
||||
#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 */
|
55
ext/nomali/lib/Rules.mk
Normal file
55
ext/nomali/lib/Rules.mk
Normal file
|
@ -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))
|
112
ext/nomali/lib/gpu.cc
Normal file
112
ext/nomali/lib/gpu.cc
Normal file
|
@ -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<uint16_t>(block));
|
||||
|
||||
if (block_no < blocks.size())
|
||||
return blocks[block_no];
|
||||
else
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
}
|
205
ext/nomali/lib/gpu.hh
Normal file
205
ext/nomali/lib/gpu.hh
Normal file
|
@ -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 <vector>
|
||||
|
||||
#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 <i>MUST</i> have the same correspond to the
|
||||
* values in the RegBlock enum.
|
||||
*/
|
||||
const std::vector<GPUBlock *> blocks;
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
#endif // _LIBNOMALIMODEL_GPU_HH
|
156
ext/nomali/lib/gpublock.cc
Normal file
156
ext/nomali/lib/gpublock.cc
Normal file
|
@ -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];
|
||||
}
|
||||
|
||||
|
||||
}
|
221
ext/nomali/lib/gpublock.hh
Normal file
221
ext/nomali/lib/gpublock.hh
Normal file
|
@ -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:
|
||||
* <ul>
|
||||
* <li>XX_IRQ_RAWSTAT -- Raw interrupt state bit mask. (RW)
|
||||
* <li>XX_IRQ_CLEAR -- Interrupt clear register. (WO)
|
||||
* <li>XX_IRQ_MASK -- Bitmaks of enabled interrupts. (RW)
|
||||
* <li>XX_IRQ_STATUS -- Currently pending unmasked interrupts. (RO)
|
||||
* </ul>
|
||||
*
|
||||
* 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
|
177
ext/nomali/lib/gpucontrol.cc
Normal file
177
ext/nomali/lib/gpucontrol.cc
Normal file
|
@ -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<GpuCmdHandler> 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);
|
||||
}
|
||||
|
||||
}
|
159
ext/nomali/lib/gpucontrol.hh
Normal file
159
ext/nomali/lib/gpucontrol.hh
Normal file
|
@ -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 <vector>
|
||||
|
||||
#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:
|
||||
* <ul>
|
||||
* <li>GPU_ID
|
||||
* <li>Feature registers (XX_FEATURES)
|
||||
* <li>Present registers (XX_PRESENT)
|
||||
* <li>Thread discovery (THREAD_XX)
|
||||
* <li>Present registers (XX_PRESENT)
|
||||
* </ul>
|
||||
*/
|
||||
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 <i>MUST</i> correspond to the
|
||||
* GPU control command IDs in the Midgard architecture
|
||||
* specification.
|
||||
*/
|
||||
static const std::vector<cmd_t> cmds;
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
#endif // _LIBNOMALIMODEL_GPUCONTROL_HH
|
139
ext/nomali/lib/jobcontrol.cc
Normal file
139
ext/nomali/lib/jobcontrol.cc
Normal file
|
@ -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);
|
||||
}
|
||||
|
||||
}
|
93
ext/nomali/lib/jobcontrol.hh
Normal file
93
ext/nomali/lib/jobcontrol.hh
Normal file
|
@ -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 <vector>
|
||||
|
||||
#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<JobSlot> slots;
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
#endif // _LIBNOMALIMODEL_JOBCONTROL_HH
|
216
ext/nomali/lib/jobslot.cc
Normal file
216
ext/nomali/lib/jobslot.cc
Normal file
|
@ -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 <cassert>
|
||||
#include <cstdlib>
|
||||
|
||||
#include "jobcontrol.hh"
|
||||
#include "gpu.hh"
|
||||
#include "regutils.hh"
|
||||
|
||||
namespace NoMali {
|
||||
|
||||
const std::vector<JobSlot::cmd_t> 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);
|
||||
}
|
||||
|
||||
}
|
208
ext/nomali/lib/jobslot.hh
Normal file
208
ext/nomali/lib/jobslot.hh
Normal file
|
@ -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 <vector>
|
||||
|
||||
#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:
|
||||
* <ul>
|
||||
* <li>There is no currently running job.
|
||||
* <li>The pending command in the JSn_COMMAND_NEXT register is
|
||||
* JSn_COMMAND_START.
|
||||
* </ul>
|
||||
*
|
||||
* 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 <i>NEVER</i> 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 <i>IS
|
||||
* NOT</i> 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 <i>IS
|
||||
* NOT</i> 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 <i>IS</i>
|
||||
* 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 <i>IS</i>
|
||||
* 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 <i>MUST</i> correspond to the
|
||||
* job control command IDs in the Midgard architecture
|
||||
* specification.
|
||||
*/
|
||||
static const std::vector<cmd_t> cmds;
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
#endif // _LIBNOMALIMODEL_JOBSLOT_HH
|
510
ext/nomali/lib/mali_midg_regmap.h
Normal file
510
ext/nomali/lib/mali_midg_regmap.h
Normal file
|
@ -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<n>_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<n>_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<n>_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_ */
|
92
ext/nomali/lib/mali_midgard.cc
Normal file
92
ext/nomali/lib/mali_midgard.cc
Normal file
|
@ -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);
|
||||
}
|
||||
|
||||
};
|
70
ext/nomali/lib/mali_midgard.hh
Normal file
70
ext/nomali/lib/mali_midgard.hh
Normal file
|
@ -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
|
55
ext/nomali/lib/mali_t6xx.cc
Normal file
55
ext/nomali/lib/mali_t6xx.cc
Normal file
|
@ -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)
|
||||
{
|
||||
}
|
||||
|
||||
};
|
61
ext/nomali/lib/mali_t6xx.hh
Normal file
61
ext/nomali/lib/mali_t6xx.hh
Normal file
|
@ -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
|
50
ext/nomali/lib/mali_t7xx.cc
Normal file
50
ext/nomali/lib/mali_t7xx.cc
Normal file
|
@ -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)
|
||||
{
|
||||
}
|
||||
|
||||
};
|
50
ext/nomali/lib/mali_t7xx.hh
Normal file
50
ext/nomali/lib/mali_t7xx.hh
Normal file
|
@ -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
|
64
ext/nomali/lib/mmu.cc
Normal file
64
ext/nomali/lib/mmu.cc
Normal file
|
@ -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);
|
||||
}
|
||||
|
||||
}
|
57
ext/nomali/lib/mmu.hh
Normal file
57
ext/nomali/lib/mmu.hh
Normal file
|
@ -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 <vector>
|
||||
|
||||
#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
|
355
ext/nomali/lib/nomali_api.cc
Normal file
355
ext/nomali/lib/nomali_api.cc
Normal file
|
@ -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 <cstring>
|
||||
|
||||
#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 BaseGpu>
|
||||
class NoMaliApiGpu
|
||||
: public BaseGpu
|
||||
{
|
||||
public:
|
||||
template<typename... Args>
|
||||
NoMaliApiGpu(NoMaliApi &_api, Args &&... args)
|
||||
: BaseGpu(std::forward<Args>(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<nomali_handle_t>(this), c.usr, intno, set);
|
||||
}
|
||||
|
||||
|
||||
|
||||
static NoMaliApi *
|
||||
get_gpu(nomali_handle_t h)
|
||||
{
|
||||
return h ? static_cast<NoMaliApi *>(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<NoMali::MaliT60x>(
|
||||
*api,
|
||||
cfg->ver_maj, cfg->ver_min, cfg->ver_status);
|
||||
break;
|
||||
|
||||
case NOMALI_GPU_T62X:
|
||||
gpu = new NoMaliApiGpu<NoMali::MaliT62x>(
|
||||
*api,
|
||||
cfg->ver_maj, cfg->ver_min, cfg->ver_status);
|
||||
break;
|
||||
|
||||
|
||||
case NOMALI_GPU_T76X:
|
||||
gpu = new NoMaliApiGpu<NoMali::MaliT76x>(
|
||||
*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;
|
||||
}
|
||||
|
103
ext/nomali/lib/regutils.hh
Normal file
103
ext/nomali/lib/regutils.hh
Normal file
|
@ -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 <cassert>
|
||||
|
||||
#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 <i>within</i> 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
|
218
ext/nomali/lib/types.hh
Normal file
218
ext/nomali/lib/types.hh
Normal file
|
@ -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 <cassert>
|
||||
#include <cstdint>
|
||||
|
||||
#include <utility>
|
||||
#include <vector>
|
||||
|
||||
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<uint32_t> 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
|
||||
|
44
ext/nomali/tests/Rules.mk
Normal file
44
ext/nomali/tests/Rules.mk
Normal file
|
@ -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))
|
53
ext/nomali/tests/nomali_test0.c
Normal file
53
ext/nomali/tests/nomali_test0.c
Normal file
|
@ -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 <libnomali/nomali.h>
|
||||
#include <inttypes.h>
|
||||
|
||||
#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;
|
||||
}
|
46
ext/nomali/tests/nomali_test_helpers.h
Normal file
46
ext/nomali/tests/nomali_test_helpers.h
Normal file
|
@ -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 <libnomali/nomali.h>
|
||||
#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 */
|
127
ext/nomali/tests/nomali_test_ints.c
Normal file
127
ext/nomali/tests/nomali_test_ints.c
Normal file
|
@ -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 <libnomali/nomali.h>
|
||||
#include <inttypes.h>
|
||||
|
||||
#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;
|
||||
}
|
147
ext/nomali/tests/test_helpers.c
Normal file
147
ext/nomali/tests/test_helpers.c
Normal file
|
@ -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 <assert.h>
|
||||
#include <stdarg.h>
|
||||
#include <stdlib.h>
|
||||
|
||||
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;
|
||||
}
|
57
ext/nomali/tests/test_helpers.h
Normal file
57
ext/nomali/tests/test_helpers.h
Normal file
|
@ -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 <stdio.h>
|
||||
|
||||
#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
|
Loading…
Reference in a new issue