From: Imagination Technologies/TI Date: Sat, 24 Mar 2012 23:36:31 +0000 (+0200) Subject: 4_00_00_01/1.4.14.2616 release X-Git-Url: http://git.openpandora.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=ae4d93ba3ecf489869ec14e452194871232b177c;p=sgx.git 4_00_00_01/1.4.14.2616 release --- ae4d93ba3ecf489869ec14e452194871232b177c diff --git a/COPYING b/COPYING new file mode 100644 index 0000000..84ac8ec --- /dev/null +++ b/COPYING @@ -0,0 +1,351 @@ + +This software is Copyright (C) 2008 Imagination Technologies Ltd. + All rights reserved. + +You may use, distribute and copy this software under the terms of +GNU General Public License version 2, which is displayed below. + +------------------------------------------------------------------------- + + GNU GENERAL PUBLIC LICENSE + Version 2, June 1991 + + Copyright (C) 1989, 1991 Free Software Foundation, Inc. + 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + Everyone is permitted to copy and distribute verbatim copies + of this license document, but changing it is not allowed. + + Preamble + + The licenses for most software are designed to take away your +freedom to share and change it. By contrast, the GNU General Public +License is intended to guarantee your freedom to share and change free +software--to make sure the software is free for all its users. This +General Public License applies to most of the Free Software +Foundation's software and to any other program whose authors commit to +using it. (Some other Free Software Foundation software is covered by +the GNU Library General Public License instead.) You can apply it to +your programs, too. + + When we speak of free software, we are referring to freedom, not +price. Our General Public Licenses are designed to make sure that you +have the freedom to distribute copies of free software (and charge for +this service if you wish), that you receive source code or can get it +if you want it, that you can change the software or use pieces of it +in new free programs; and that you know you can do these things. + + To protect your rights, we need to make restrictions that forbid +anyone to deny you these rights or to ask you to surrender the rights. +These restrictions translate to certain responsibilities for you if you +distribute copies of the software, or if you modify it. + + For example, if you distribute copies of such a program, whether +gratis or for a fee, you must give the recipients all the rights that +you have. You must make sure that they, too, receive or can get the +source code. And you must show them these terms so they know their +rights. + + We protect your rights with two steps: (1) copyright the software, and +(2) offer you this license which gives you legal permission to copy, +distribute and/or modify the software. + + Also, for each author's protection and ours, we want to make certain +that everyone understands that there is no warranty for this free +software. If the software is modified by someone else and passed on, we +want its recipients to know that what they have is not the original, so +that any problems introduced by others will not reflect on the original +authors' reputations. + + Finally, any free program is threatened constantly by software +patents. We wish to avoid the danger that redistributors of a free +program will individually obtain patent licenses, in effect making the +program proprietary. To prevent this, we have made it clear that any +patent must be licensed for everyone's free use or not licensed at all. + + The precise terms and conditions for copying, distribution and +modification follow. + + GNU GENERAL PUBLIC LICENSE + TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION + + 0. This License applies to any program or other work which contains +a notice placed by the copyright holder saying it may be distributed +under the terms of this General Public License. The "Program", below, +refers to any such program or work, and a "work based on the Program" +means either the Program or any derivative work under copyright law: +that is to say, a work containing the Program or a portion of it, +either verbatim or with modifications and/or translated into another +language. (Hereinafter, translation is included without limitation in +the term "modification".) Each licensee is addressed as "you". + +Activities other than copying, distribution and modification are not +covered by this License; they are outside its scope. The act of +running the Program is not restricted, and the output from the Program +is covered only if its contents constitute a work based on the +Program (independent of having been made by running the Program). +Whether that is true depends on what the Program does. + + 1. You may copy and distribute verbatim copies of the Program's +source code as you receive it, in any medium, provided that you +conspicuously and appropriately publish on each copy an appropriate +copyright notice and disclaimer of warranty; keep intact all the +notices that refer to this License and to the absence of any warranty; +and give any other recipients of the Program a copy of this License +along with the Program. + +You may charge a fee for the physical act of transferring a copy, and +you may at your option offer warranty protection in exchange for a fee. + + 2. You may modify your copy or copies of the Program or any portion +of it, thus forming a work based on the Program, and copy and +distribute such modifications or work under the terms of Section 1 +above, provided that you also meet all of these conditions: + + a) You must cause the modified files to carry prominent notices + stating that you changed the files and the date of any change. + + b) You must cause any work that you distribute or publish, that in + whole or in part contains or is derived from the Program or any + part thereof, to be licensed as a whole at no charge to all third + parties under the terms of this License. + + c) If the modified program normally reads commands interactively + when run, you must cause it, when started running for such + interactive use in the most ordinary way, to print or display an + announcement including an appropriate copyright notice and a + notice that there is no warranty (or else, saying that you provide + a warranty) and that users may redistribute the program under + these conditions, and telling the user how to view a copy of this + License. (Exception: if the Program itself is interactive but + does not normally print such an announcement, your work based on + the Program is not required to print an announcement.) + +These requirements apply to the modified work as a whole. If +identifiable sections of that work are not derived from the Program, +and can be reasonably considered independent and separate works in +themselves, then this License, and its terms, do not apply to those +sections when you distribute them as separate works. But when you +distribute the same sections as part of a whole which is a work based +on the Program, the distribution of the whole must be on the terms of +this License, whose permissions for other licensees extend to the +entire whole, and thus to each and every part regardless of who wrote it. + +Thus, it is not the intent of this section to claim rights or contest +your rights to work written entirely by you; rather, the intent is to +exercise the right to control the distribution of derivative or +collective works based on the Program. + +In addition, mere aggregation of another work not based on the Program +with the Program (or with a work based on the Program) on a volume of +a storage or distribution medium does not bring the other work under +the scope of this License. + + 3. You may copy and distribute the Program (or a work based on it, +under Section 2) in object code or executable form under the terms of +Sections 1 and 2 above provided that you also do one of the following: + + a) Accompany it with the complete corresponding machine-readable + source code, which must be distributed under the terms of Sections + 1 and 2 above on a medium customarily used for software interchange; or, + + b) Accompany it with a written offer, valid for at least three + years, to give any third party, for a charge no more than your + cost of physically performing source distribution, a complete + machine-readable copy of the corresponding source code, to be + distributed under the terms of Sections 1 and 2 above on a medium + customarily used for software interchange; or, + + c) Accompany it with the information you received as to the offer + to distribute corresponding source code. (This alternative is + allowed only for noncommercial distribution and only if you + received the program in object code or executable form with such + an offer, in accord with Subsection b above.) + +The source code for a work means the preferred form of the work for +making modifications to it. For an executable work, complete source +code means all the source code for all modules it contains, plus any +associated interface definition files, plus the scripts used to +control compilation and installation of the executable. However, as a +special exception, the source code distributed need not include +anything that is normally distributed (in either source or binary +form) with the major components (compiler, kernel, and so on) of the +operating system on which the executable runs, unless that component +itself accompanies the executable. + +If distribution of executable or object code is made by offering +access to copy from a designated place, then offering equivalent +access to copy the source code from the same place counts as +distribution of the source code, even though third parties are not +compelled to copy the source along with the object code. + + 4. You may not copy, modify, sublicense, or distribute the Program +except as expressly provided under this License. Any attempt +otherwise to copy, modify, sublicense or distribute the Program is +void, and will automatically terminate your rights under this License. +However, parties who have received copies, or rights, from you under +this License will not have their licenses terminated so long as such +parties remain in full compliance. + + 5. You are not required to accept this License, since you have not +signed it. However, nothing else grants you permission to modify or +distribute the Program or its derivative works. These actions are +prohibited by law if you do not accept this License. Therefore, by +modifying or distributing the Program (or any work based on the +Program), you indicate your acceptance of this License to do so, and +all its terms and conditions for copying, distributing or modifying +the Program or works based on it. + + 6. Each time you redistribute the Program (or any work based on the +Program), the recipient automatically receives a license from the +original licensor to copy, distribute or modify the Program subject to +these terms and conditions. You may not impose any further +restrictions on the recipients' exercise of the rights granted herein. +You are not responsible for enforcing compliance by third parties to +this License. + + 7. If, as a consequence of a court judgment or allegation of patent +infringement or for any other reason (not limited to patent issues), +conditions are imposed on you (whether by court order, agreement or +otherwise) that contradict the conditions of this License, they do not +excuse you from the conditions of this License. If you cannot +distribute so as to satisfy simultaneously your obligations under this +License and any other pertinent obligations, then as a consequence you +may not distribute the Program at all. For example, if a patent +license would not permit royalty-free redistribution of the Program by +all those who receive copies directly or indirectly through you, then +the only way you could satisfy both it and this License would be to +refrain entirely from distribution of the Program. + +If any portion of this section is held invalid or unenforceable under +any particular circumstance, the balance of the section is intended to +apply and the section as a whole is intended to apply in other +circumstances. + +It is not the purpose of this section to induce you to infringe any +patents or other property right claims or to contest validity of any +such claims; this section has the sole purpose of protecting the +integrity of the free software distribution system, which is +implemented by public license practices. Many people have made +generous contributions to the wide range of software distributed +through that system in reliance on consistent application of that +system; it is up to the author/donor to decide if he or she is willing +to distribute software through any other system and a licensee cannot +impose that choice. + +This section is intended to make thoroughly clear what is believed to +be a consequence of the rest of this License. + + 8. If the distribution and/or use of the Program is restricted in +certain countries either by patents or by copyrighted interfaces, the +original copyright holder who places the Program under this License +may add an explicit geographical distribution limitation excluding +those countries, so that distribution is permitted only in or among +countries not thus excluded. In such case, this License incorporates +the limitation as if written in the body of this License. + + 9. The Free Software Foundation may publish revised and/or new versions +of the General Public License from time to time. Such new versions will +be similar in spirit to the present version, but may differ in detail to +address new problems or concerns. + +Each version is given a distinguishing version number. If the Program +specifies a version number of this License which applies to it and "any +later version", you have the option of following the terms and conditions +either of that version or of any later version published by the Free +Software Foundation. If the Program does not specify a version number of +this License, you may choose any version ever published by the Free Software +Foundation. + + 10. If you wish to incorporate parts of the Program into other free +programs whose distribution conditions are different, write to the author +to ask for permission. For software which is copyrighted by the Free +Software Foundation, write to the Free Software Foundation; we sometimes +make exceptions for this. Our decision will be guided by the two goals +of preserving the free status of all derivatives of our free software and +of promoting the sharing and reuse of software generally. + + NO WARRANTY + + 11. BECAUSE THE PROGRAM IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY +FOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW. EXCEPT WHEN +OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES +PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED +OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF +MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE ENTIRE RISK AS +TO THE QUALITY AND PERFORMANCE OF THE PROGRAM IS WITH YOU. SHOULD THE +PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING, +REPAIR OR CORRECTION. + + 12. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING +WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY AND/OR +REDISTRIBUTE THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, +INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING +OUT OF THE USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED +TO LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY +YOU OR THIRD PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER +PROGRAMS), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE +POSSIBILITY OF SUCH DAMAGES. + + END OF TERMS AND CONDITIONS + + Appendix: How to Apply These Terms to Your New Programs + + If you develop a new program, and you want it to be of the greatest +possible use to the public, the best way to achieve this is to make it +free software which everyone can redistribute and change under these terms. + + To do so, attach the following notices to the program. It is safest +to attach them to the start of each source file to most effectively +convey the exclusion of warranty; and each file should have at least +the "copyright" line and a pointer to where the full notice is found. + + + Copyright (C) 19yy + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + +Also add information on how to contact you by electronic and paper mail. + +If the program is interactive, make it output a short notice like this +when it starts in an interactive mode: + + Gnomovision version 69, Copyright (C) 19yy name of author + Gnomovision comes with ABSOLUTELY NO WARRANTY; for details type `show w'. + This is free software, and you are welcome to redistribute it + under certain conditions; type `show c' for details. + +The hypothetical commands `show w' and `show c' should show the appropriate +parts of the General Public License. Of course, the commands you use may +be called something other than `show w' and `show c'; they could even be +mouse-clicks or menu items--whatever suits your program. + +You should also get your employer (if you work as a programmer) or your +school, if any, to sign a "copyright disclaimer" for the program, if +necessary. Here is a sample; alter the names: + + Yoyodyne, Inc., hereby disclaims all copyright interest in the program + `Gnomovision' (which makes passes at compilers) written by James Hacker. + + , 1 April 1989 + Ty Coon, President of Vice + +This General Public License does not permit incorporating your program into +proprietary programs. If your program is a subroutine library, you may +consider it more useful to permit linking proprietary applications with the +library. If this is what you want to do, use the GNU Library General +Public License instead of this License. + +------------------------------------------------------------------------- + diff --git a/INSTALL b/INSTALL new file mode 100644 index 0000000..bd08a56 --- /dev/null +++ b/INSTALL @@ -0,0 +1,76 @@ + +SGX Embedded Systems DDK for the Linux kernel. +Copyright (C) 2008 Imagination Technologies Ltd. All rights reserved. +====================================================================== + +This file covers how to build and install the Imagination Technologies +SGX DDK for the Linux kernel. + + +Build System Environment Variables +------------------------------------------- + +The SGX DDK Build scripts depend on a number of environment variables +being setup before compilation or installation of DDK software can +commence: + +$DISCIMAGE +The DDK Build scripts install files to the location specified by the +DISCIMAGE environment variable, when the make install target is used. +This should point to the target filesystem. +$ export DISCIMAGE=/path/to/filesystem + +$KERNELDIR +When building the SGX DDK kernel module, the build needs access +to the headers of the Linux kernel +$ export KERNELDIR=/path/to/kernel + +$PATH +If a cross compiler is being used make sure the PATH environment variable +includes the path to the toolchain +$ export PATH=$PATH:/path/to/toolchain + +$CROSS_COMPILE +Since the SGX DDK Build scripts are geared toward a cross-compilation +workflow, the CROSS_COMPILE environment variable needs to be set +$ export CROSS_COMPILE=toolchain-prefix- + + +Build and Install Instructions +------------------------------------------- + +The SGX DDK configures different target builds within directories under +eurasiacon/build/linux/. + +The supported build targets are: + + all Makes everything + clean Removes all intermediate files created by a build. + clobber Removes all binaries for all builds as well. + install Runs the install script generated by the build. + +The following variables may be set on the command line to influence a build. + + BUILD The type of build being performed. + Alternatives are release, timing or debug. + CFLAGS Build dependent optimisations and debug information flags. + SILENT Determines whether text of commands is produced during build. + +To build for, change to the appropriate target directory, e.g.: +$ cd eurasiacon/build/linux/platform/kbuild + +Issue the make command: +$ make BUILD=debug all + +The DDK software must be installed by the root user. Become the root user: +$ su + +Install the DDK software: +$ make install + +Become an ordinary user again: +$ exit + + + + diff --git a/Kbuild b/Kbuild new file mode 100644 index 0000000..3ca2fc8 --- /dev/null +++ b/Kbuild @@ -0,0 +1,64 @@ +obj-m := pvrsrvkm.o + +FILES := \ +services4/srvkm/common/queue.c \ +services4/srvkm/common/hash.c \ +services4/srvkm/common/perproc.c \ +services4/srvkm/common/mem.c \ +services4/srvkm/common/power.c \ +services4/srvkm/common/deviceclass.c \ +services4/srvkm/common/metrics.c \ +services4/srvkm/common/resman.c \ +services4/srvkm/common/buffer_manager.c \ +services4/srvkm/common/pvrsrv.c \ +services4/srvkm/common/handle.c \ +services4/srvkm/common/ra.c \ +services4/srvkm/common/devicemem.c \ +services4/srvkm/env/linux/pvr_debug.c \ +services4/srvkm/env/linux/mm.c \ +services4/srvkm/env/linux/mutex.c \ +services4/srvkm/env/linux/mmap.c \ +services4/srvkm/env/linux/module.c \ +services4/srvkm/env/linux/proc.c \ +services4/srvkm/env/linux/event.c \ +services4/srvkm/env/linux/osfunc.c \ +services4/srvkm/env/linux/pvr_bridge_k.c \ +services4/srvkm/env/linux/pdump.c \ +services4/srvkm/env/linux/mutils.c \ +services4/srvkm/env/linux/osperproc.c \ +services4/srvkm/devices/sgx/sgxtransfer.c \ +services4/srvkm/devices/sgx/sgxinit.c \ +services4/srvkm/devices/sgx/sgxutils.c \ +services4/srvkm/devices/sgx/pb.c \ +services4/srvkm/devices/sgx/sgxkick.c \ +services4/srvkm/devices/sgx/mmu.c \ +services4/srvkm/devices/sgx/sgxreset.c \ +services4/srvkm/devices/sgx/sgxpower.c \ +services4/srvkm/bridged/bridged_pvr_bridge.c \ +services4/srvkm/bridged/bridged_support.c \ +services4/srvkm/bridged/sgx/bridged_sgx_bridge.c \ +services4/system/$(TI_PLATFORM)/sysutils_linux.c \ +services4/system/$(TI_PLATFORM)/sysconfig.c \ + +EXTRA_CFLAGS += -I$(src)/include4 +EXTRA_CFLAGS += -I$(src)/services4/include +EXTRA_CFLAGS += -I$(src)/services4/srvkm/include +EXTRA_CFLAGS += -I$(src)/services4/srvkm/hwdefs +EXTRA_CFLAGS += -I$(src)/services4/srvkm/bridged +EXTRA_CFLAGS += -I$(src)/services4/srvkm/devices/sgx +EXTRA_CFLAGS += -I$(src)/services4/srvkm/env/linux +EXTRA_CFLAGS += -I$(src)/services4/system/include +EXTRA_CFLAGS += -I$(src)/services4/system/$(TI_PLATFORM) +EXTRA_CFLAGS += -I$(src)/services4/srvkm/bridged/sgx + +EXTRA_CFLAGS += $(ALL_CFLAGS) + +pvrsrvkm-y := $(FILES:.c=.o) +ifeq ($(TI_PLATFORM),ti8168) +obj-y := services4/3rdparty/dc_ti8168_linux/ +else +obj-y := services4/3rdparty/dc_omap3430_linux/ +endif +obj-y += services4/3rdparty/bufferclass_ti/ + + diff --git a/Makefile b/Makefile new file mode 100644 index 0000000..0e33ae0 --- /dev/null +++ b/Makefile @@ -0,0 +1,175 @@ +export KERNELDIR = /opt/oe/stuff/build/tmp/work/beagleboard-angstrom-linux-gnueabi/linux-omap-2.6.29-r44/git/ + +export KERNEL_PATH=$(KERNELDIR) +export KERNEL_SRC=$(KERNELDIR) +export KDIR=$(KERNELDIR) + +export BUILD = release + +export KBUILD_EXTRA_SYMBOLS = `pwd`/services4/srvkm/env/linux/kbuild/Module.symvers + +SGXCORE = 530 +ifeq ($(TI_PLATFORM),ti8168) +CORE = -DPLAT_TI8168 -DSGX530 -DSUPPORT_SGX530 -DSGX_CORE_REV=125 +else +ifeq ($(TI_PLATFORM),omap3630) +CORE = -DSGX530 -DSUPPORT_SGX530 -DSGX_CORE_REV=125 +else +CORE = -DSGX530 -DSUPPORT_SGX530 -DSGX_CORE_REV=121 +endif +endif +SUPPORT_SGX = 1 +SUPPORT_HW_RECOVERY = 1 +SUPPORT_SGX_HWPERF = 1 +SYS_USING_INTERRUPTS = 1 +SUPPORT_TI_PM = 0 + +PVR2D_ALT_2DHW = 1 + +LDM_PLATFORM ?= 1 + +# Only enable active power management if passive power management is +# enabled, as indicated by LDM_PLATFORM being set to 1. On OMAP, +# the system can suspend in the case where active power management is +# enabled in the SGX driver, but passive power management isn't. As +# passive power management isn't enabled, the driver won't see the +# system suspend/resume events, and so won't take appropriate action. +ifeq ($(LDM_PLATFORM),1) +SUPPORT_ACTIVE_POWER_MANAGEMENT ?= 1 +else +SUPPORT_ACTIVE_POWER_MANAGEMENT = 0 +endif + +export PVR_BUILD_DIR := $(shell pwd) + +DATE := $(shell date "+%a %B %d %Z %Y" ) + +CBUILD = -DPVR_BUILD_DIR="\"$(PVR_BUILD_DIR)\"" \ + -DPVR_BUILD_DATE="\"$(DATE)\"" \ + -DPVR_BUILD_TYPE="\"$(BUILD)\"" + +# Don't support HW recovery on debug builds +CBUILD.debug = -DDEBUG +CBUILD.timing = -DTIMING +CBUILD.release = -DRELEASE +CFLAGS.debug = -g -O0 -DDLL_METRIC=1 +CFLAGS.timing = $(OPTIM) -g -DDLL_METRIC=1 -DTIMING +CFLAGS.release = $(OPTIM) -g +CFLAGS = $(CFLAGS.$(BUILD)) + + +ifeq ("$(BUILD)", "debug") +DEBUG_LINUX_MEMORY_ALLOCATIONS ?= 1 +DEBUG_LINUX_MEM_AREAS ?= 1 +DEBUG_LINUX_MMAP_AREAS ?= 1 +DEBUG_LINUX_XML_PROC_FILES ?= 0 +DEBUG_LINUX_SLAB_ALLOCATIONS ?= 0 +DEBUG_BRIDGE_KM ?= 1 +DEBUG_TRACE_BRIDGE_KM ?= 0 +endif + +TRANSFER_QUEUE ?= 1 +SUPPORT_SGX_EVENT_OBJECT ?= 1 +SUPPORT_SECURE_HANDLES = 1 +SUPPORT_SECURE_FD_EXPORT = 1 +SUPPORT_SRVINIT = 1 +SUPPORT_PERCONTEXT_PB = 1 +SUPPORT_LINUX_X86_PAT ?=1 +SUPPORT_LINUX_X86_WRITECOMBINE ?=1 +SUPPORT_SGX_LOW_LATENCY_SCHEDULING ?=1 + + +SYS_CFLAGS += -DSERVICES4 -D_XOPEN_SOURCE=600 -DPVR2D_VALIDATE_INPUT_PARAMS + +# Thread support +USE_PTHREADS ?= 1 +USE_GCC__thread_KEYWORD ?= 0 +OPTIMISE_NON_NPTL_SINGLE_THREAD_TLS_LOOKUP ?= 0 +DISABLE_THREADS ?= 0 + +# Automatically define C compiler macros for features possible (or not) in use. + +SYS_CFLAGS.$(SUPPORT_SRVINIT) += -DSUPPORT_SRVINIT + +SYS_CFLAGS.$(SUPPORT_SGX) += -DSUPPORT_SGX +SYS_CFLAGS.$(SUPPORT_XWS) += -DSUPPORT_XWS +SYS_CFLAGS.$(PDUMP) += -DPDUMP +SYS_CFLAGS.$(SUPPORT_POWER_MANAGEMENT) += -DSUPPORT_POWER_MANAGEMENT +SYS_CFLAGS.$(SUPPORT_BUFFER_CLASS) += -DSUPPORT_BUFFER_CLASS + +SYS_CFLAGS.$(SUPPORT_PERCONTEXT_PB) += -DSUPPORT_PERCONTEXT_PB +SYS_CFLAGS.$(SUPPORT_DYNAMIC_PBRESIZE) += -DSUPPORT_DYNAMIC_PBRESIZE + +SYS_CFLAGS.$(USE_FBDEV) += -DUSE_FBDEV +SYS_CFLAGS.$(USE_FBDEV) += -DFBDEV_NAME="\"$(FBDEV_NAME)\"" +SYS_CFLAGS.$(SUPPORT_DYNAMIC_3DCLOCKGATING) += -DSUPPORT_DYNAMIC_3DCLOCKGATING +SYS_CFLAGS.$(REENTRANCY_PROTECTION) += -DREENTRANCY_PROTECTION +SYS_CFLAGS.$(SCHEDULER_CONTROL_SUPPORT) += -DSCHEDULER_CONTROL_SUPPORT +SYS_CFLAGS.$(USE_IMG_POWER_DOMAIN_FUNCTION) += -DUSE_IMG_POWER_DOMAIN_FUNCTION + +SYS_CFLAGS.$(USE_DMALLOC) += -DDMALLOC + +SYS_CFLAGS.$(DEBUG_LINUX_MEMORY_ALLOCATIONS) += -DDEBUG_LINUX_MEMORY_ALLOCATIONS +SYS_CFLAGS.$(DEBUG_LINUX_MEM_AREAS) += -DDEBUG_LINUX_MEM_AREAS +SYS_CFLAGS.$(DEBUG_LINUX_MMAP_AREAS) += -DDEBUG_LINUX_MMAP_AREAS +SYS_CFLAGS.$(DEBUG_LINUX_XML_PROC_FILES) += -DDEBUG_LINUX_XML_PROC_FILES +SYS_CFLAGS.$(DEBUG_LINUX_SLAB_ALLOCATIONS) += -DDEBUG_LINUX_SLAB_ALLOCATIONS +SYS_CFLAGS.$(DEBUG_BRIDGE_KM) += -DDEBUG_BRIDGE_KM +SYS_CFLAGS.$(DEBUG_TRACE_BRIDGE_KM) += -DDEBUG_TRACE_BRIDGE_KM +SYS_CFLAGS.$(DEBUG_BRIDGE_KM_DISPATCH_TABLE) += -DDEBUG_BRIDGE_KM_DISPATCH_TABLE + +SYS_CFLAGS.$(SUPPORT_LINUX_X86_WRITECOMBINE) += -DSUPPORT_LINUX_X86_WRITECOMBINE + +SYS_CFLAGS.$(SGX_PDS_EVENTS_DISABLED) += -DSGX_PDS_EVENTS_DISABLED +SYS_CFLAGS.$(USE_SUPPORT_NO_TA3D_OVERLAP) += -DUSE_SUPPORT_NO_TA3D_OVERLAP +SYS_CFLAGS.$(SUPPORT_SGX_TILING) += -DSUPPORT_SGX_TILING +SYS_CFLAGS.$(TRANSFER_QUEUE) += -DTRANSFER_QUEUE + +SYS_CFLAGS.$(SUPPORT_SGX_MMU_DUMMY_PAGE) += -DSUPPORT_SGX_MMU_DUMMY_PAGE + +SYS_CFLAGS.$(PVRSRV_USSE_EDM_STATUS_DEBUG) += -DPVRSRV_USSE_EDM_STATUS_DEBUG + +SYS_CFLAGS.$(SUPPORT_DRI_DRM) += -DSUPPORT_DRI_DRM + +SYS_CFLAGS.$(SYS_USING_INTERRUPTS) += -DSYS_USING_INTERRUPTS +SYS_CFLAGS.$(SUPPORT_HW_RECOVERY) += -DSUPPORT_HW_RECOVERY +SYS_CFLAGS.$(SUPPORT_ACTIVE_POWER_MANAGEMENT) += -DSUPPORT_ACTIVE_POWER_MANAGEMENT + +SYS_CFLAGS.$(SUPPORT_SECURE_HANDLES) += -DPVR_SECURE_HANDLES +SYS_CFLAGS.$(SUPPORT_SECURE_FD_EXPORT) += -DPVR_SECURE_FD_EXPORT + + +SYS_CFLAGS.$(USE_PTHREADS) += -DUSE_PTHREADS +SYS_CFLAGS.$(USE_GCC__thread_KEYWORD) += -DUSE_GCC__thread_KEYWORD +SYS_CFLAGS.$(OPTIMISE_NON_NPTL_SINGLE_THREAD_TLS_LOOKUP) += -DOPTIMISE_NON_NPTL_SINGLE_THREAD_TLS_LOOKUP +SYS_CFLAGS.$(DISABLE_THREADS) += -DDISABLE_THREADS +SYS_CFLAGS.$(SUPPORT_SGX_EVENT_OBJECT) += -DSUPPORT_SGX_EVENT_OBJECT +SYS_CFLAGS.$(LDM_PLATFORM) += -DLDM_PLATFORM +SYS_CFLAGS.$(LDM_PCI) += -DLDM_PCI +SYS_CFLAGS.$(PVR_MANUAL_POWER_CONTROL) += -DPVR_MANUAL_POWER_CONTROL + +SYS_CFLAGS.$(PVR2D_ALT_2DHW) += -DPVR2D_ALT_2DHW + +SYS_CFLAGS.$(SUPPORT_SGX_HWPERF) += -DSUPPORT_SGX_HWPERF + +SYS_CFLAGS.$(SUPPORT_SGX_LOW_LATENCY_SCHEDULING) += -DSUPPORT_SGX_LOW_LATENCY_SCHEDULING + + +SYS_CFLAGS.$(SUPPORT_LINUX_X86_PAT) += -DSUPPORT_LINUX_X86_PAT + + +SYS_CFLAGS.$(SUPPORT_TI_PM) += -DSUPPORT_TI_PM + +export ALL_CFLAGS = -DLINUX \ + $(CBUILD) $(CBUILD.$(BUILD)) \ + $(SYS_CFLAGS) $(SYS_CFLAGS.1) \ + $(MODULE_CFLAGS) $(MODULE_CFLAGS.$(BUILD)) \ + $(CORE) \ + $(CFLAGS) + +all: + $(MAKE) -C $(KERNELDIR) M=`pwd` $* + +clean: + $(MAKE) -C $(KERNELDIR) M=`pwd` clean + diff --git a/README b/README new file mode 100644 index 0000000..788a703 --- /dev/null +++ b/README @@ -0,0 +1,48 @@ + +SGX Embedded Systems DDK for Linux kernel. +Copyright (C) 2008 Imagination Technologies Ltd. All rights reserved. +====================================================================== + + +About +------------------------------------------- + +This is the Imagination Technologies SGX DDK for the Linux kernel. + + +License +------------------------------------------- + +You may use, distribute and copy this software under the terms of +GNU General Public License version 2. + +The full GNU General Public License version 2 is included in this +distribution in the file called "COPYING". + + +Build and Install Instructions +------------------------------------------- + +For details see the "INSTALL" file. + +To build for, change to the appropriate target directory, e.g.: +$ cd eurasiacon/build/linux/platform/kbuild + +Issue the make command: +$ make BUILD=debug all + +The DDK software must be installed by the root user. Become the root user: +$ su + +Install the DDK software: +$ make install + +Become an ordinary user again: +$ exit + + +Contact information: +------------------------------------------- + +Imagination Technologies Ltd. +Home Park Estate, Kings Langley, Herts, WD4 8LZ, UK diff --git a/eurasiacon/build/linux/kbuild/Makefile.kbuild b/eurasiacon/build/linux/kbuild/Makefile.kbuild new file mode 100644 index 0000000..dd92077 --- /dev/null +++ b/eurasiacon/build/linux/kbuild/Makefile.kbuild @@ -0,0 +1,84 @@ +# +# Copyright(c) 2008 Imagination Technologies Ltd. All rights reserved. +# +# This program is free software; you can redistribute it and/or modify it +# under the terms and conditions of the GNU General Public License, +# version 2, as published by the Free Software Foundation. +# +# This program is distributed in the hope it will be useful but, except +# as otherwise stated in writing, without any warranty; without even the +# implied warranty of merchantability or fitness for a particular purpose. +# See the GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License along with +# this program; if not, write to the Free Software Foundation, Inc., +# 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA. +# +# The full GNU General Public License is included in this distribution in +# the file called "COPYING". +# +# Contact Information: +# Imagination Technologies Ltd. +# Home Park Estate, Kings Langley, Herts, WD4 8LZ, UK +# +# +# + +export EURASIAROOT ?= $(shell cd ../../../../../;echo $$PWD) + +# Determine PVR_BUILD_DIR automatically from the directory from which we're +# invoked. The use of $(notdir ..) here actually strips away the leading +# components of the current directory here. We export this so it's passed to +# sub-makes automatically. +# +export PVR_BUILD_DIR = $(notdir $(shell cd ../; echo $$PWD)) + + +# Include target specific variables. +# +include $(EURASIAROOT)/eurasiacon/build/linux/$(PVR_BUILD_DIR)/makefile.shared_conf + +# Include target core specific variables here - this expands on the above settings. +# +include $(EURASIAROOT)/eurasiacon/build/linux/$(PVR_BUILD_DIR)/makefile.core + +# Include and setup generic build variables. +# +include $(EURASIAROOT)/eurasiacon/build/linux/makefile.shared_conf + + +ifeq ($(PDUMP),1) +PDUMP_SUBDIRS += $(EURASIAROOT)/tools/intern/debug/dbgdriv/linux +endif + +KBUILD_SUBDIRS = \ + $(PDUMP_SUBDIRS) \ + $(EURASIAROOT)/services4/srvkm/env/linux \ + $(EXTRA_SUBDIRS) + +ifeq ($(SILENT),) +all %: + set -x; \ + for dir in $(KBUILD_SUBDIRS); \ + do \ + if test -e $$dir;\ + then \ + $(MAKE) $(MAKE_OPT) -C $$dir/kbuild \ + -f $(EURASIAROOT)/eurasiacon/build/linux/kbuild/Makefile.kbuild_subdir $@ || \ + exit 1; \ + fi \ + done +else +all %: + $(SILENT)for dir in $(KBUILD_SUBDIRS); \ + do \ + if test -e $$dir;\ + then \ + echo +$$dir; \ + $(MAKE) $(MAKE_OPT) -C $$dir/kbuild \ + -f $(EURASIAROOT)/eurasiacon/build/linux/kbuild/Makefile.kbuild_subdir $@ || \ + exit 1; \ + fi \ + done +endif + diff --git a/eurasiacon/build/linux/kbuild/Makefile.kbuild_subdir b/eurasiacon/build/linux/kbuild/Makefile.kbuild_subdir new file mode 100644 index 0000000..c18bbe3 --- /dev/null +++ b/eurasiacon/build/linux/kbuild/Makefile.kbuild_subdir @@ -0,0 +1,47 @@ +# +# Copyright(c) 2008 Imagination Technologies Ltd. All rights reserved. +# +# This program is free software; you can redistribute it and/or modify it +# under the terms and conditions of the GNU General Public License, +# version 2, as published by the Free Software Foundation. +# +# This program is distributed in the hope it will be useful but, except +# as otherwise stated in writing, without any warranty; without even the +# implied warranty of merchantability or fitness for a particular purpose. +# See the GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License along with +# this program; if not, write to the Free Software Foundation, Inc., +# 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA. +# +# The full GNU General Public License is included in this distribution in +# the file called "COPYING". +# +# Contact Information: +# Imagination Technologies Ltd. +# Home Park Estate, Kings Langley, Herts, WD4 8LZ, UK +# +# +# + +# Include target specific variables. +# +include $(EURASIAROOT)/eurasiacon/build/linux/$(PVR_BUILD_DIR)/makefile.shared_conf + +# Include target core specific variables here - this expands on the above settings. +# +include $(EURASIAROOT)/eurasiacon/build/linux/$(PVR_BUILD_DIR)/makefile.core + +# Include and setup generic build variables. +# +include $(EURASIAROOT)/eurasiacon/build/linux/makefile.shared_conf + +# Include the local module settings. +# +include Makefile + +# Include the build rules for kbuild modules +# +include $(EURASIAROOT)/eurasiacon/build/linux/kbuild/Makefile.kbuild_subdir_rules + + diff --git a/eurasiacon/build/linux/kbuild/Makefile.kbuild_subdir_common b/eurasiacon/build/linux/kbuild/Makefile.kbuild_subdir_common new file mode 100644 index 0000000..92d3034 --- /dev/null +++ b/eurasiacon/build/linux/kbuild/Makefile.kbuild_subdir_common @@ -0,0 +1,40 @@ +# +# Copyright(c) 2008 Imagination Technologies Ltd. All rights reserved. +# +# This program is free software; you can redistribute it and/or modify it +# under the terms and conditions of the GNU General Public License, +# version 2, as published by the Free Software Foundation. +# +# This program is distributed in the hope it will be useful but, except +# as otherwise stated in writing, without any warranty; without even the +# implied warranty of merchantability or fitness for a particular purpose. +# See the GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License along with +# this program; if not, write to the Free Software Foundation, Inc., +# 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA. +# +# The full GNU General Public License is included in this distribution in +# the file called "COPYING". +# +# Contact Information: +# Imagination Technologies Ltd. +# Home Park Estate, Kings Langley, Herts, WD4 8LZ, UK +# +# + +obj-m = $(MODULE).o + + +$(MODULE)-objs = $(SOURCES:.c=.o) + +EXTRA_CFLAGS = $(INCLUDES) \ + $(ALL_CFLAGS_kbuild) \ + -Wall -fno-strict-aliasing -Werror + +ifeq ($(SILENT),@) + KBUILD_VERBOSE ?= 0 +else + KBUILD_VERBOSE ?= 1 +endif + diff --git a/eurasiacon/build/linux/kbuild/Makefile.kbuild_subdir_rules b/eurasiacon/build/linux/kbuild/Makefile.kbuild_subdir_rules new file mode 100644 index 0000000..a2af203 --- /dev/null +++ b/eurasiacon/build/linux/kbuild/Makefile.kbuild_subdir_rules @@ -0,0 +1,117 @@ +# +# Copyright(c) 2008 Imagination Technologies Ltd. All rights reserved. +# +# This program is free software; you can redistribute it and/or modify it +# under the terms and conditions of the GNU General Public License, +# version 2, as published by the Free Software Foundation. +# +# This program is distributed in the hope it will be useful but, except +# as otherwise stated in writing, without any warranty; without even the +# implied warranty of merchantability or fitness for a particular purpose. +# See the GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License along with +# this program; if not, write to the Free Software Foundation, Inc., +# 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA. +# +# The full GNU General Public License is included in this distribution in +# the file called "COPYING". +# +# Contact Information: +# Imagination Technologies Ltd. +# Home Park Estate, Kings Langley, Herts, WD4 8LZ, UK +# +# +# + +PWD := $(shell pwd) + +export + +KBUILD_MODULE := $(MODULE).$(KM_SUFFIX) +KBUILD_SYSBIN := $(SYSBIN) + +KBUILD_DIRS := $(dir $(SOURCES)) + +ifneq ("$(SYM_VERS_DEPS)", "") +KBUILD_SYM_VERS := $(SYM_VERS_DEPS)/kbuild/Module.symvers +KBUILD_COPY_SYM_VERS := symvers +endif + +# The version file is useful. It should only be created when it doesn't +# exist. We use the .INTERMEDIATE rule here to signify we want to rebuild +# PVRVERSION_H if EURASIACON_PJ changes but not to worry about EURASIACON_PJ +# if it's not there. +# +# DON'T CHANGE THIS unless you REALLY do know what you're doing! +# +.INTERMEDIATE: $(EURASIACON_PJ) + +$(PVRVERSION_H): $(EURASIACON_PJ) + @if [ ! -f "$(EURASIACON_PJ)" ]; then \ + echo; \ + echo "** Both $$EURASIAROOT/include/pvrversion.h and eurasiacon.pj missing."; \ + echo "** Your tree is not intact. Cannot continue."; \ + echo; \ + exit 1; \ + fi + $(SILENT)$(RM) $@ + $(SILENT)$(PERL) $(EURASIAROOT)/eurasiacon/build/scripts/create_pvrversion.pl \ + -i $(EURASIACON_PJ) $@ + $(ECHO) " Updated pvrversion.h" + +.PHONY: symvers +symvers: + @if [ -f "$(KBUILD_SYM_VERS)" ]; then \ + cp -f $(KBUILD_SYM_VERS) $(PWD) ;\ + fi + +.PHONY: modules +modules: $(PVRVERSION_H) $(KBUILD_COPY_SYM_VERS) + $(SILENT)$(MAKE) -C $(KERNELDIR) M=$(PWD) modules + +.PHONY: install +install: + $(SILENT)$(MAKE) INSTALL_MOD_PATH=$(DISCIMAGE) INSTALL_MOD_DIR=kernel/drivers/char -C $(KERNELDIR) M=$(PWD) modules_install + +.PHONY: clean +clean: + $(SILENT)$(MAKE) -C $(KERNELDIR) M=$(PWD) clean + $(SILENT)$(RM) $(KBUILD_SYSBIN)/$(KBUILD_MODULE) + $(SILENT)$(RM) $(SOURCES:.c=.o) + $(SILENT)$(RM) $(addsuffix .*.o.cmd, $(dir $(SOURCES))) + $(SILENT)$(RM) $(PWD)/Module.symvers + +.PHONY: clobber +clobber: clean + $(SILENT)$(RM) -r $(KBUILD_SYSBIN) + +.PHONY: help +help: + $(SILENT)$(MAKE) -C $(KERNELDIR) M=$(PWD) help + +.PHONY: all +all: $(KBUILD_SYSBIN)/$(KBUILD_MODULE) + +$(KBUILD_SYSBIN)/$(KBUILD_MODULE): modules $(KBUILD_SYSBIN) + $(ECHO) " Copying $(KBUILD_MODULE) to $(KBUILD_SYSBIN)" + $(SILENT)$(CP) $(KBUILD_MODULE) $(KBUILD_SYSBIN) + +$(KBUILD_SYSBIN): + $(SILENT)$(MKDIR) $(KBUILD_SYSBIN) + +.PHONY: package +package: all +ifeq ("$(BUILD)", "release") + $(ECHO) " DDK-packaging $(MODULE) " + $(SILENT)$(STRIP) --strip-unneeded $(KBUILD_MODULE) + $(SILENT)$(STRIP) --strip-unneeded $(KBUILD_SYSBIN)/$(KBUILD_MODULE) +endif #ifeq ("$(BUILD)", "release") + +.PHONY: symbolpackage +symbolpackage: package + + + + + diff --git a/eurasiacon/build/linux/makefile.shared_conf b/eurasiacon/build/linux/makefile.shared_conf new file mode 100755 index 0000000..14dcac0 --- /dev/null +++ b/eurasiacon/build/linux/makefile.shared_conf @@ -0,0 +1,330 @@ +# +# Copyright(c) 2008 Imagination Technologies Ltd. All rights reserved. +# +# This program is free software; you can redistribute it and/or modify it +# under the terms and conditions of the GNU General Public License, +# version 2, as published by the Free Software Foundation. +# +# This program is distributed in the hope it will be useful but, except +# as otherwise stated in writing, without any warranty; without even the +# implied warranty of merchantability or fitness for a particular purpose. +# See the GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License along with +# this program; if not, write to the Free Software Foundation, Inc., +# 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA. +# +# The full GNU General Public License is included in this distribution in +# the file called "COPYING". +# +# Contact Information: +# Imagination Technologies Ltd. +# Home Park Estate, Kings Langley, Herts, WD4 8LZ, UK +# +# +# +################################################################################## + +# ENV is used in a few other makefiles instead of the literal 'linux', for +# reasons of portability, presumably. It's common to all of the linux makeconf +# files (usually build/*/makeconf.build) so now lives. +# +ENV ?= linux + +# Compilers and other such tools +# +AR = $(CROSS_COMPILE)ar +AS = $(CROSS_COMPILE)as +#CC = $(CROSS_COMPILE)gcc +CPP = $(CROSS_COMPILE)g++ +LD = $(CROSS_COMPILE)ld +OBJCOPY = $(CROSS_COMPILE)objcopy +OBJDUMP = $(CROSS_COMPILE)objdump +RANLIB = $(CROSS_COMPILE)ranlib +STRIP = $(CROSS_COMPILE)strip +SIZE = $(CROSS_COMPILE)size + +ifdef QAC_ANALYSE +CC=perl $(ANALROOT)/wrapper.pl -wcf $(ANALROOT)/eurasia_linux.cfg $(CROSS_COMPILE)gcc +else +CC= $(CROSS_COMPILE)gcc +endif + +CAT ?= cat +CP ?= cp +CHMOD ?= chmod +DOS2UNIX ?= dos2unix +ECHO ?= -@echo +FIND ?= find +GREP ?= grep +LN ?= ln -s +MKDIR ?= mkdir -p +MV ?= mv +RM ?= rm -f +SED ?= sed +M4 ?= m4 +TOUCH ?= touch +PERL ?= perl +SORT ?= sort +UNIQ ?= uniq +FLEX ?= flex +BISON ?= bison +MD5SUM ?= md5sum +ENV ?= env +CUT ?= cut + +# SILENT=@ causes command text to be omitted during the process. If you want +# to see what's really happening then use "make SILENT= ..." +# +SILENT = @ + +# V=1 is equivalent to SILENT= +# (Noteably it is the same variable used by the Linux kbuild scripts, so hopfully +# intuative to those familiar with kbuild) +ifeq ($(V),1) +SILENT = +endif + +# BUILD=release sets the default release. +# +BUILD ?= release + +# Services version. +# +SERVICES ?= 4 +export SERVICES + +# Minor convenience variables +# +DO_MKDIR = $(SILENT)$(MKDIR) $@ +DO_LN_S = $(SILENT)$(LN) -s $< $@ + +# MAKE_OPT defaults to --no-print-directory to declutter the build output. +# +MAKE_OPT ?= --no-print-directory + +# Useful (important) directories for the build. +# +BIN = bin_$(PVR_BUILD_DIR)_$(BUILD)_$(MODULE) +TMP = tmp_$(PVR_BUILD_DIR)_$(BUILD)_$(MODULE) +_SYSBIN = $(EURASIAROOT)/eurasiacon/binary +SYSBIN = $(_SYSBIN)_$(PVR_BUILD_DIR)_$(BUILD) + +# Work out our origins. eurasiacon.pj is not supplied to end-users +# so instead we supply pvrversion.h. We produce pvrversion.h if +# if doesn't exist. +# +DATE := $(shell date "+%a %B %d %Z %Y" ) +EURASIACON_PJ = $(EURASIAROOT)/eurasiacon.pj +PVRVERSION_H = $(EURASIAROOT)/include$(SERVICES)/pvrversion.h +PVRVERSION = $(shell if [ -f $(EURASIACON_PJ) ]; then \ + $(GREP) "\$Revision" $(EURASIACON_PJ) |\ + $(SED) "s,.* \([0-9.]*\) .*,\1,"; \ + else \ + $(GREP) "PVRVERSION_STRING" < $(PVRVERSION_H) | $(SED) "s,.*\"\([0-9.]*\)\".*,\1,"; \ + fi) +PVRVERSION_MAJ = $(shell echo $(PVRVERSION) | $(CUT) -d '.' -f1) +PVRVERSION_MIN = $(shell echo $(PVRVERSION) | $(CUT) -d '.' -f2) +PVRVERSION_BRANCH = $(shell echo $(PVRVERSION) | $(CUT) -d '.' -f3) +PVRVERSION_BUILD = $(shell echo $(PVRVERSION) | $(CUT) -d '.' -f4,5,6) + +# Linux kernel defines +# +KERNEL_VER = $(shell grep "^VERSION = " \ + $(KERNELDIR)/Makefile | $(CUT) -f3 -d' ') +KERNEL_REL = $(shell grep "^PATCHLEVEL = " \ + $(KERNELDIR)/Makefile | $(CUT) -f3 -d' ') +KERNEL_SUBREL = $(shell grep "^SUBLEVEL = " \ + $(KERNELDIR)/Makefile | $(CUT) -f3 -d' ') +KERNEL_ID ?= $(shell grep -h '\#define UTS_RELEASE' $(KERNELDIR)/include/linux/* | \ + $(CUT) -f3 -d' ' | \ + $(SED) s/\"//g) + +KERNELVERSION = $(KERNEL_VER).$(KERNEL_REL).$(KERNEL_SUBREL) + +# Get checksum from env variables +# +ENV_CHECKSUM = $(shell echo $(ALL_CFLAGS_$(MODSUFFIX)) | $(MD5SUM) - | $(CUT) -d' ' -f 1) + +# Linux kernel defines +# +ifeq ("$(KERNEL_VER)", "2") +ifeq ("$(KERNEL_REL)", "6") +KM_SUFFIX = ko +else +KM_SUFFIX = o +CFLAGS_.o += -DEXPORT_SYMTAB $(CFLAGS_.ko) +endif +else +KM_SUFFIX = o +endif + +# The standard CFLAGS macro can be overridden on the 'make' command line. We +# put CBUILD in a separate macro so its setting doesn't get lost when a user +# *does* override CFLAGS. +# + +CBUILD = -DPVR_BUILD_DIR="\"$(PVR_BUILD_DIR)\"" \ + -DPVR_BUILD_DATE="\"$(DATE)\"" \ + -DPVR_BUILD_TYPE="\"$(BUILD)\"" + +# Don't support HW recovery on debug builds +CBUILD.debug = -DDEBUG +CBUILD.timing = -DTIMING +CBUILD.release = -DRELEASE +CFLAGS.debug = -g -O0 -DDLL_METRIC=1 +CFLAGS.timing = $(OPTIM) -g -DDLL_METRIC=1 -DTIMING +CFLAGS.release = $(OPTIM) -g +CFLAGS = $(CFLAGS.$(BUILD)) + +# Defaults for useful things. +# + +ifeq ("$(BUILD)", "debug") +DEBUG_LINUX_MEMORY_ALLOCATIONS ?= 1 +DEBUG_LINUX_MEM_AREAS ?= 1 +DEBUG_LINUX_MMAP_AREAS ?= 1 +DEBUG_LINUX_XML_PROC_FILES ?= 0 +DEBUG_LINUX_SLAB_ALLOCATIONS ?= 0 +DEBUG_BRIDGE_KM ?= 1 +DEBUG_TRACE_BRIDGE_KM ?= 0 +DEBUG_BRIDGE_KM_DISPATCH_TABLE ?= 0 +endif + +TRANSFER_QUEUE ?= 1 +SUPPORT_SGX_EVENT_OBJECT ?=1 +SUPPORT_SECURE_HANDLES = 1 +SUPPORT_SECURE_FD_EXPORT = 1 +SUPPORT_SRVINIT = 1 +SUPPORT_PERCONTEXT_PB = 1 +SUPPORT_LINUX_X86_PAT ?=1 +SUPPORT_LINUX_X86_WRITECOMBINE ?=1 +SUPPORT_SGX_LOW_LATENCY_SCHEDULING ?=1 + +DC_NOHW_WIDTH ?= 640 +DC_NOHW_HEIGHT ?= 480 + +SYS_CFLAGS += -DSERVICES4 -D_XOPEN_SOURCE=600 -DPVR2D_VALIDATE_INPUT_PARAMS + +# Thread support +USE_PTHREADS ?= 1 +USE_GCC__thread_KEYWORD ?= 0 +OPTIMISE_NON_NPTL_SINGLE_THREAD_TLS_LOOKUP ?= 0 +DISABLE_THREADS ?= 0 + +# Automatically define C compiler macros for features possible (or not) in use. + +SYS_CFLAGS.$(SUPPORT_SRVINIT) += -DSUPPORT_SRVINIT + +SYS_CFLAGS.$(SUPPORT_SGX) += -DSUPPORT_SGX +SYS_CFLAGS.$(SUPPORT_VGX) += -DSUPPORT_VGX +SYS_CFLAGS.$(SUPPORT_XWS) += -DSUPPORT_XWS +SYS_CFLAGS.$(SUPPORT_EWS) += -DSUPPORT_EWS +SYS_CFLAGS.$(PDUMP) += -DPDUMP +SYS_CFLAGS.$(VGX_PDUMP_FROM_FIRMWARE) += -DVGX_PDUMP_FROM_FIRMWARE +SYS_CFLAGS.$(SUPPORT_POWER_MANAGEMENT) += -DSUPPORT_POWER_MANAGEMENT +SYS_CFLAGS.$(SUPPORT_BUFFER_CLASS) += -DSUPPORT_BUFFER_CLASS + +SYS_CFLAGS.$(SUPPORT_PERCONTEXT_PB) += -DSUPPORT_PERCONTEXT_PB +SYS_CFLAGS.$(SUPPORT_DYNAMIC_PBRESIZE) += -DSUPPORT_DYNAMIC_PBRESIZE + +SYS_CFLAGS.$(USE_FBDEV) += -DUSE_FBDEV +SYS_CFLAGS.$(USE_FBDEV) += -DFBDEV_NAME="\"$(FBDEV_NAME)\"" +SYS_CFLAGS.$(SUPPORT_DYNAMIC_3DCLOCKGATING) += -DSUPPORT_DYNAMIC_3DCLOCKGATING +SYS_CFLAGS.$(REENTRANCY_PROTECTION) += -DREENTRANCY_PROTECTION +SYS_CFLAGS.$(SCHEDULER_CONTROL_SUPPORT) += -DSCHEDULER_CONTROL_SUPPORT +SYS_CFLAGS.$(USE_IMG_POWER_DOMAIN_FUNCTION) += -DUSE_IMG_POWER_DOMAIN_FUNCTION + +SYS_CFLAGS.$(USE_DMALLOC) += -DDMALLOC + +SYS_CFLAGS.$(DEBUG_LINUX_MEMORY_ALLOCATIONS) += -DDEBUG_LINUX_MEMORY_ALLOCATIONS +SYS_CFLAGS.$(DEBUG_LINUX_MEM_AREAS) += -DDEBUG_LINUX_MEM_AREAS +SYS_CFLAGS.$(DEBUG_LINUX_MMAP_AREAS) += -DDEBUG_LINUX_MMAP_AREAS +SYS_CFLAGS.$(DEBUG_LINUX_XML_PROC_FILES) += -DDEBUG_LINUX_XML_PROC_FILES +SYS_CFLAGS.$(DEBUG_LINUX_SLAB_ALLOCATIONS) += -DDEBUG_LINUX_SLAB_ALLOCATIONS +SYS_CFLAGS.$(DEBUG_BRIDGE_KM) += -DDEBUG_BRIDGE_KM +SYS_CFLAGS.$(DEBUG_TRACE_BRIDGE_KM) += -DDEBUG_TRACE_BRIDGE_KM +SYS_CFLAGS.$(DEBUG_BRIDGE_KM_DISPATCH_TABLE) += -DDEBUG_BRIDGE_KM_DISPATCH_TABLE + +SYS_CFLAGS.$(SUPPORT_LINUX_X86_WRITECOMBINE) += -DSUPPORT_LINUX_X86_WRITECOMBINE + +SYS_CFLAGS.$(SGX_PDS_EVENTS_DISABLED) += -DSGX_PDS_EVENTS_DISABLED +SYS_CFLAGS.$(USE_SUPPORT_NO_TA3D_OVERLAP) += -DUSE_SUPPORT_NO_TA3D_OVERLAP +SYS_CFLAGS.$(SUPPORT_SGX_TILING) += -DSUPPORT_SGX_TILING +SYS_CFLAGS.$(TRANSFER_QUEUE) += -DTRANSFER_QUEUE + +SYS_CFLAGS.$(SUPPORT_SGX_MMU_DUMMY_PAGE) += -DSUPPORT_SGX_MMU_DUMMY_PAGE + +SYS_CFLAGS.$(PVRSRV_USSE_EDM_STATUS_DEBUG) += -DPVRSRV_USSE_EDM_STATUS_DEBUG +SYS_CFLAGS.$(SGX_FEATURE_MP) += -DSGX_FEATURE_MP +SYS_CFLAGS.$(SGX_FAST_DPM_INIT) += -DSGX_FAST_DPM_INIT + +SYS_CFLAGS.$(NO_HARDWARE) += -DNO_HARDWARE + +SYS_CFLAGS.$(SUPPORT_DRI_DRM) += -DSUPPORT_DRI_DRM +SYS_CFLAGS.$(USE_PRIMARY_SURFACE_IN_FLIP_CHAIN) += -DUSE_PRIMARY_SURFACE_IN_FLIP_CHAIN + +ifneq ("$(NO_HARDWARE)", "1") +SYS_CFLAGS.$(SYS_USING_INTERRUPTS) += -DSYS_USING_INTERRUPTS +SYS_CFLAGS.$(SUPPORT_HW_RECOVERY) += -DSUPPORT_HW_RECOVERY +SYS_CFLAGS.$(SUPPORT_ACTIVE_POWER_MANAGEMENT) += -DSUPPORT_ACTIVE_POWER_MANAGEMENT +endif + +ifeq ("$(PDUMP)", "1") +SUPPORT_DBGDRV_EVENT_OBJECTS ?=1 +SYS_CFLAGS.$(SUPPORT_DBGDRV_EVENT_OBJECTS) += -DSUPPORT_DBGDRV_EVENT_OBJECTS +endif + +SYS_CFLAGS.$(SUPPORT_SECURE_HANDLES) += -DPVR_SECURE_HANDLES +SYS_CFLAGS.$(SUPPORT_SECURE_FD_EXPORT) += -DPVR_SECURE_FD_EXPORT + +SYS_CFLAGS.$(USE_PTHREADS) += -DUSE_PTHREADS +SYS_CFLAGS.$(USE_GCC__thread_KEYWORD) += -DUSE_GCC__thread_KEYWORD +SYS_CFLAGS.$(OPTIMISE_NON_NPTL_SINGLE_THREAD_TLS_LOOKUP) += -DOPTIMISE_NON_NPTL_SINGLE_THREAD_TLS_LOOKUP +SYS_CFLAGS.$(DISABLE_THREADS) += -DDISABLE_THREADS +SYS_CFLAGS.$(SUPPORT_SGX_EVENT_OBJECT) += -DSUPPORT_SGX_EVENT_OBJECT +SYS_CFLAGS.$(LDM_PLATFORM) += -DLDM_PLATFORM +SYS_CFLAGS.$(LDM_PCI) += -DLDM_PCI +SYS_CFLAGS.$(PVR_MANUAL_POWER_CONTROL) += -DPVR_MANUAL_POWER_CONTROL + +SYS_CFLAGS.$(PVR2D_ALT_2DHW) += -DPVR2D_ALT_2DHW + +SYS_CFLAGS.$(SUPPORT_SGX_HWPERF) += -DSUPPORT_SGX_HWPERF + +SYS_CFLAGS.$(SUPPORT_SLC) += -DSGX_FEATURE_SYSTEM_CACHE +SYS_CFLAGS.$(BYPASS_SLC) += -DSGX_BYPASS_SYSTEM_CACHE +SYS_CFLAGS.$(SUPPORT_SGX_LOW_LATENCY_SCHEDULING) += -DSUPPORT_SGX_LOW_LATENCY_SCHEDULING + + +SYS_CFLAGS.$(SUPPORT_LINUX_X86_PAT) += -DSUPPORT_LINUX_X86_PAT + +ifeq ("$(PVR_SYSTEM)", "sgx_nohw") +ifndef RTSIM +SYS_CFLAGS += -DNO_HARDWARE +endif +SYS_CFLAGS += -DDC_NOHW_BUFFER_WIDTH=$(DC_NOHW_WIDTH) -DDC_NOHW_BUFFER_HEIGHT=$(DC_NOHW_HEIGHT) +endif + +ifeq ("$(PVR_SYSTEM)", "vgx_nohw") +SYS_CFLAGS += -DNO_HARDWARE -DDC_NOHW_BUFFER_WIDTH=$(DC_NOHW_WIDTH) -DDC_NOHW_BUFFER_HEIGHT=$(DC_NOHW_HEIGHT) +endif + +ifdef SGX_FEATURE_MP_CORE_COUNT +SYS_CFLAGS += -DSGX_FEATURE_MP_CORE_COUNT=$(SGX_FEATURE_MP_CORE_COUNT) +endif + +SYS_INCLUDES = -I$(EURASIAROOT)/include4 \ + -I$(EURASIAROOT)/eurasiacon/includeext \ + -I$(SYSBIN) \ + -isystem $(KERNELDIR)/include + + +ALL_CFLAGS_kbuild = -DLINUX \ + $(CBUILD) $(CBUILD.$(BUILD)) \ + $(SYS_CFLAGS) $(SYS_CFLAGS.1) \ + $(MODULE_CFLAGS) $(MODULE_CFLAGS.$(BUILD)) \ + $(CORE) \ + -Wall -fno-strict-aliasing \ + $(CFLAGS) + + diff --git a/eurasiacon/build/linux/omap3430_linux/kbuild/Makefile b/eurasiacon/build/linux/omap3430_linux/kbuild/Makefile new file mode 100644 index 0000000..5747505 --- /dev/null +++ b/eurasiacon/build/linux/omap3430_linux/kbuild/Makefile @@ -0,0 +1,31 @@ +# +# Copyright(c) 2008 Imagination Technologies Ltd. All rights reserved. +# +# This program is free software; you can redistribute it and/or modify it +# under the terms and conditions of the GNU General Public License, +# version 2, as published by the Free Software Foundation. +# +# This program is distributed in the hope it will be useful but, except +# as otherwise stated in writing, without any warranty; without even the +# implied warranty of merchantability or fitness for a particular purpose. +# See the GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License along with +# this program; if not, write to the Free Software Foundation, Inc., +# 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA. +# +# The full GNU General Public License is included in this distribution in +# the file called "COPYING". +# +# Contact Information: +# Imagination Technologies Ltd. +# Home Park Estate, Kings Langley, Herts, WD4 8LZ, UK +# +# +# + +include ../../kbuild/Makefile.kbuild + +EXTRA_SUBDIRS = $(EURASIAROOT)/services4/3rdparty/dc_omap3430_linux \ + $(EURASIAROOT)/services4/3rdparty/bufferclass_example + diff --git a/eurasiacon/build/linux/omap3430_linux/kbuild/build_gfx_kernelmodules b/eurasiacon/build/linux/omap3430_linux/kbuild/build_gfx_kernelmodules new file mode 100755 index 0000000..04f32f1 --- /dev/null +++ b/eurasiacon/build/linux/omap3430_linux/kbuild/build_gfx_kernelmodules @@ -0,0 +1,23 @@ +#!/bin/sh + +#set home path +#HOME=/home/ + +#set environment variables +export DISCIMAGE=/home/prabu/gfx10/ +#export KERNELDIR=/home/prabu/AM35x-OMAP35x-PSP-SDK-03.00.00.04/src/kernel/linux-03.00.00.04 + +export KERNELDIR=/home/prabu/linux-omap3 + +export PATH=$PATH:/opt/cslite/arm-2009q1/bin +export CROSS_COMPILE=arm-none-linux-gnueabi- + +#clean the build +make clean + +#uncomment this to perform debug build +#make BUILD=debug + +#Perform Release Build +make + diff --git a/eurasiacon/build/linux/omap3430_linux/makefile.core b/eurasiacon/build/linux/omap3430_linux/makefile.core new file mode 100755 index 0000000..b16d3ef --- /dev/null +++ b/eurasiacon/build/linux/omap3430_linux/makefile.core @@ -0,0 +1,37 @@ +# +# Copyright(c) 2008 Imagination Technologies Ltd. All rights reserved. +# +# This program is free software; you can redistribute it and/or modify it +# under the terms and conditions of the GNU General Public License, +# version 2, as published by the Free Software Foundation. +# +# This program is distributed in the hope it will be useful but, except +# as otherwise stated in writing, without any warranty; without even the +# implied warranty of merchantability or fitness for a particular purpose. +# See the GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License along with +# this program; if not, write to the Free Software Foundation, Inc., +# 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA. +# +# The full GNU General Public License is included in this distribution in +# the file called "COPYING". +# +# Contact Information: +# Imagination Technologies Ltd. +# Home Park Estate, Kings Langley, Herts, WD4 8LZ, UK +# +# + +CORE = -DSGX$(SGXCORE) -DSUPPORT_SGX$(SGXCORE) + +ifeq ("$(SGXCOREREV)","") +ifeq ("$(SGXCORE)","530") +CORE += -DSGX_CORE_REV=125 +else +CORE += -DUSE_SGX_CORE_REV_HEAD +endif +else +CORE += -DSGX_CORE_REV=$(SGXCOREREV) +endif + diff --git a/eurasiacon/build/linux/omap3430_linux/makefile.shared_conf b/eurasiacon/build/linux/omap3430_linux/makefile.shared_conf new file mode 100755 index 0000000..9eb7f17 --- /dev/null +++ b/eurasiacon/build/linux/omap3430_linux/makefile.shared_conf @@ -0,0 +1,75 @@ +# +# Copyright(c) 2008 Imagination Technologies Ltd. All rights reserved. +# +# This program is free software; you can redistribute it and/or modify it +# under the terms and conditions of the GNU General Public License, +# version 2, as published by the Free Software Foundation. +# +# This program is distributed in the hope it will be useful but, except +# as otherwise stated in writing, without any warranty; without even the +# implied warranty of merchantability or fitness for a particular purpose. +# See the GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License along with +# this program; if not, write to the Free Software Foundation, Inc., +# 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA. +# +# The full GNU General Public License is included in this distribution in +# the file called "COPYING". +# +# Contact Information: +# Imagination Technologies Ltd. +# Home Park Estate, Kings Langley, Herts, WD4 8LZ, UK +# +# + +# Tool chain and cross-compile settings. gcc must be in the path. +# +CROSS_COMPILE ?= arm-none-linux-gnueabi- +TOOLCHAIN ?= $(shell dirname $(shell which $(CROSS_COMPILE)gcc))/../ +OBJCOPYFORMAT = elf32-littlearm + +CROSSPLATFORM_PATHS = +CROSSPLATFORM_LIBS =-ldl + +SYS_EXE_LDFLAGS = -Xlinker -rpath-link=$(TOOLCHAIN)/arm-none-linux-gnueabi/lib + +# Cross-compile extra settings. +# +PVR_SYSTEM = omap3430 +DISPLAY_CONTROLLER = omaplfb + +ARCH_CFLAGS = -march=armv7-a + +# SYS_FLAGS contains any flags specific to this system +SYS_CFLAGS = -DSGX_DYNAMIC_TIMING_INFO \ + -DSYS_CUSTOM_POWERLOCK_WRAP + +# The version of the kernel that is required for compilation +REQUIREDKERNELVERSION = 2.6.24 + +# +# OPTIM contains the optimisation level in timing and release builds +OPTIM = -Os + +SGXCORE = 530 +SUPPORT_SGX = 1 + +SUPPORT_HW_RECOVERY = 1 +SUPPORT_SGX_HWPERF = 1 +SYS_USING_INTERRUPTS = 1 + +PVR2D_ALT_2DHW = 1 +LDM_PLATFORM ?= 1 + +# Only enable active power management if passive power management is +# enabled, as indicated by LDM_PLATFORM being set to 1. On OMAP, +# the system can suspend in the case where active power management is +# enabled in the SGX driver, but passive power management isn't. As +# passive power management isn't enabled, the driver won't see the +# system suspend/resume events, and so won't take appropriate action. +ifeq ($(LDM_PLATFORM),1) +SUPPORT_ACTIVE_POWER_MANAGEMENT ?= 1 +else +SUPPORT_ACTIVE_POWER_MANAGEMENT = 0 +endif diff --git a/eurasiacon/build/linux/omap3630_linux/kbuild/Makefile b/eurasiacon/build/linux/omap3630_linux/kbuild/Makefile new file mode 100644 index 0000000..5747505 --- /dev/null +++ b/eurasiacon/build/linux/omap3630_linux/kbuild/Makefile @@ -0,0 +1,31 @@ +# +# Copyright(c) 2008 Imagination Technologies Ltd. All rights reserved. +# +# This program is free software; you can redistribute it and/or modify it +# under the terms and conditions of the GNU General Public License, +# version 2, as published by the Free Software Foundation. +# +# This program is distributed in the hope it will be useful but, except +# as otherwise stated in writing, without any warranty; without even the +# implied warranty of merchantability or fitness for a particular purpose. +# See the GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License along with +# this program; if not, write to the Free Software Foundation, Inc., +# 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA. +# +# The full GNU General Public License is included in this distribution in +# the file called "COPYING". +# +# Contact Information: +# Imagination Technologies Ltd. +# Home Park Estate, Kings Langley, Herts, WD4 8LZ, UK +# +# +# + +include ../../kbuild/Makefile.kbuild + +EXTRA_SUBDIRS = $(EURASIAROOT)/services4/3rdparty/dc_omap3430_linux \ + $(EURASIAROOT)/services4/3rdparty/bufferclass_example + diff --git a/eurasiacon/build/linux/omap3630_linux/kbuild/build_gfx_kernelmodules b/eurasiacon/build/linux/omap3630_linux/kbuild/build_gfx_kernelmodules new file mode 100755 index 0000000..04f32f1 --- /dev/null +++ b/eurasiacon/build/linux/omap3630_linux/kbuild/build_gfx_kernelmodules @@ -0,0 +1,23 @@ +#!/bin/sh + +#set home path +#HOME=/home/ + +#set environment variables +export DISCIMAGE=/home/prabu/gfx10/ +#export KERNELDIR=/home/prabu/AM35x-OMAP35x-PSP-SDK-03.00.00.04/src/kernel/linux-03.00.00.04 + +export KERNELDIR=/home/prabu/linux-omap3 + +export PATH=$PATH:/opt/cslite/arm-2009q1/bin +export CROSS_COMPILE=arm-none-linux-gnueabi- + +#clean the build +make clean + +#uncomment this to perform debug build +#make BUILD=debug + +#Perform Release Build +make + diff --git a/eurasiacon/build/linux/omap3630_linux/makefile.core b/eurasiacon/build/linux/omap3630_linux/makefile.core new file mode 100755 index 0000000..b16d3ef --- /dev/null +++ b/eurasiacon/build/linux/omap3630_linux/makefile.core @@ -0,0 +1,37 @@ +# +# Copyright(c) 2008 Imagination Technologies Ltd. All rights reserved. +# +# This program is free software; you can redistribute it and/or modify it +# under the terms and conditions of the GNU General Public License, +# version 2, as published by the Free Software Foundation. +# +# This program is distributed in the hope it will be useful but, except +# as otherwise stated in writing, without any warranty; without even the +# implied warranty of merchantability or fitness for a particular purpose. +# See the GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License along with +# this program; if not, write to the Free Software Foundation, Inc., +# 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA. +# +# The full GNU General Public License is included in this distribution in +# the file called "COPYING". +# +# Contact Information: +# Imagination Technologies Ltd. +# Home Park Estate, Kings Langley, Herts, WD4 8LZ, UK +# +# + +CORE = -DSGX$(SGXCORE) -DSUPPORT_SGX$(SGXCORE) + +ifeq ("$(SGXCOREREV)","") +ifeq ("$(SGXCORE)","530") +CORE += -DSGX_CORE_REV=125 +else +CORE += -DUSE_SGX_CORE_REV_HEAD +endif +else +CORE += -DSGX_CORE_REV=$(SGXCOREREV) +endif + diff --git a/eurasiacon/build/linux/omap3630_linux/makefile.shared_conf b/eurasiacon/build/linux/omap3630_linux/makefile.shared_conf new file mode 100755 index 0000000..fed61f1 --- /dev/null +++ b/eurasiacon/build/linux/omap3630_linux/makefile.shared_conf @@ -0,0 +1,75 @@ +# +# Copyright(c) 2008 Imagination Technologies Ltd. All rights reserved. +# +# This program is free software; you can redistribute it and/or modify it +# under the terms and conditions of the GNU General Public License, +# version 2, as published by the Free Software Foundation. +# +# This program is distributed in the hope it will be useful but, except +# as otherwise stated in writing, without any warranty; without even the +# implied warranty of merchantability or fitness for a particular purpose. +# See the GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License along with +# this program; if not, write to the Free Software Foundation, Inc., +# 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA. +# +# The full GNU General Public License is included in this distribution in +# the file called "COPYING". +# +# Contact Information: +# Imagination Technologies Ltd. +# Home Park Estate, Kings Langley, Herts, WD4 8LZ, UK +# +# + +# Tool chain and cross-compile settings. gcc must be in the path. +# +CROSS_COMPILE ?= arm-none-linux-gnueabi- +TOOLCHAIN ?= $(shell dirname $(shell which $(CROSS_COMPILE)gcc))/../ +OBJCOPYFORMAT = elf32-littlearm + +CROSSPLATFORM_PATHS = +CROSSPLATFORM_LIBS =-ldl + +SYS_EXE_LDFLAGS = -Xlinker -rpath-link=$(TOOLCHAIN)/arm-none-linux-gnueabi/lib + +# Cross-compile extra settings. +# +PVR_SYSTEM = omap3630 +DISPLAY_CONTROLLER = omaplfb + +ARCH_CFLAGS = -march=armv7-a + +# SYS_FLAGS contains any flags specific to this system +SYS_CFLAGS = -DSGX_DYNAMIC_TIMING_INFO \ + -DSYS_CUSTOM_POWERLOCK_WRAP + +# The version of the kernel that is required for compilation +REQUIREDKERNELVERSION = 2.6.32 + +# +# OPTIM contains the optimisation level in timing and release builds +OPTIM = -Os + +SGXCORE = 530 +SUPPORT_SGX = 1 + +SUPPORT_HW_RECOVERY = 1 +SUPPORT_SGX_HWPERF = 1 +SYS_USING_INTERRUPTS = 1 + +PVR2D_ALT_2DHW = 1 +LDM_PLATFORM ?= 1 + +# Only enable active power management if passive power management is +# enabled, as indicated by LDM_PLATFORM being set to 1. On OMAP, +# the system can suspend in the case where active power management is +# enabled in the SGX driver, but passive power management isn't. As +# passive power management isn't enabled, the driver won't see the +# system suspend/resume events, and so won't take appropriate action. +ifeq ($(LDM_PLATFORM),1) +SUPPORT_ACTIVE_POWER_MANAGEMENT ?= 1 +else +SUPPORT_ACTIVE_POWER_MANAGEMENT = 0 +endif diff --git a/include4/dbgdrvif.h b/include4/dbgdrvif.h new file mode 100644 index 0000000..e10db38 --- /dev/null +++ b/include4/dbgdrvif.h @@ -0,0 +1,267 @@ +/********************************************************************** + * + * Copyright(c) 2008 Imagination Technologies Ltd. All rights reserved. + * + * This program is free software; you can redistribute it and/or modify it + * under the terms and conditions of the GNU General Public License, + * version 2, as published by the Free Software Foundation. + * + * This program is distributed in the hope it will be useful but, except + * as otherwise stated in writing, without any warranty; without even the + * implied warranty of merchantability or fitness for a particular purpose. + * See the GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License along with + * this program; if not, write to the Free Software Foundation, Inc., + * 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA. + * + * The full GNU General Public License is included in this distribution in + * the file called "COPYING". + * + * Contact Information: + * Imagination Technologies Ltd. + * Home Park Estate, Kings Langley, Herts, WD4 8LZ, UK + * + ******************************************************************************/ + +#ifndef _DBGDRVIF_ +#define _DBGDRVIF_ + + +#include "ioctldef.h" + +#define DEBUG_CAPMODE_FRAMED 0x00000001 +#define DEBUG_CAPMODE_CONTINUOUS 0x00000002 +#define DEBUG_CAPMODE_HOTKEY 0x00000004 + +#define DEBUG_OUTMODE_STANDARDDBG 0x00000001 +#define DEBUG_OUTMODE_MONO 0x00000002 +#define DEBUG_OUTMODE_STREAMENABLE 0x00000004 +#define DEBUG_OUTMODE_ASYNC 0x00000008 +#define DEBUG_OUTMODE_SGXVGA 0x00000010 + +#define DEBUG_FLAGS_USE_NONPAGED_MEM 0x00000001 +#define DEBUG_FLAGS_NO_BUF_EXPANDSION 0x00000002 +#define DEBUG_FLAGS_ENABLESAMPLE 0x00000004 + +#define DEBUG_FLAGS_TEXTSTREAM 0x80000000 + +#define DEBUG_LEVEL_0 0x00000001 +#define DEBUG_LEVEL_1 0x00000003 +#define DEBUG_LEVEL_2 0x00000007 +#define DEBUG_LEVEL_3 0x0000000F +#define DEBUG_LEVEL_4 0x0000001F +#define DEBUG_LEVEL_5 0x0000003F +#define DEBUG_LEVEL_6 0x0000007F +#define DEBUG_LEVEL_7 0x000000FF +#define DEBUG_LEVEL_8 0x000001FF +#define DEBUG_LEVEL_9 0x000003FF +#define DEBUG_LEVEL_10 0x000007FF +#define DEBUG_LEVEL_11 0x00000FFF + +#define DEBUG_LEVEL_SEL0 0x00000001 +#define DEBUG_LEVEL_SEL1 0x00000002 +#define DEBUG_LEVEL_SEL2 0x00000004 +#define DEBUG_LEVEL_SEL3 0x00000008 +#define DEBUG_LEVEL_SEL4 0x00000010 +#define DEBUG_LEVEL_SEL5 0x00000020 +#define DEBUG_LEVEL_SEL6 0x00000040 +#define DEBUG_LEVEL_SEL7 0x00000080 +#define DEBUG_LEVEL_SEL8 0x00000100 +#define DEBUG_LEVEL_SEL9 0x00000200 +#define DEBUG_LEVEL_SEL10 0x00000400 +#define DEBUG_LEVEL_SEL11 0x00000800 + +#define DEBUG_SERVICE_IOCTL_BASE 0x800 +#define DEBUG_SERVICE_CREATESTREAM CTL_CODE(FILE_DEVICE_UNKNOWN, DEBUG_SERVICE_IOCTL_BASE + 0x01, METHOD_BUFFERED, FILE_ANY_ACCESS) +#define DEBUG_SERVICE_DESTROYSTREAM CTL_CODE(FILE_DEVICE_UNKNOWN, DEBUG_SERVICE_IOCTL_BASE + 0x02, METHOD_BUFFERED, FILE_ANY_ACCESS) +#define DEBUG_SERVICE_GETSTREAM CTL_CODE(FILE_DEVICE_UNKNOWN, DEBUG_SERVICE_IOCTL_BASE + 0x03, METHOD_BUFFERED, FILE_ANY_ACCESS) +#define DEBUG_SERVICE_WRITESTRING CTL_CODE(FILE_DEVICE_UNKNOWN, DEBUG_SERVICE_IOCTL_BASE + 0x04, METHOD_BUFFERED, FILE_ANY_ACCESS) +#define DEBUG_SERVICE_READSTRING CTL_CODE(FILE_DEVICE_UNKNOWN, DEBUG_SERVICE_IOCTL_BASE + 0x05, METHOD_BUFFERED, FILE_ANY_ACCESS) +#define DEBUG_SERVICE_WRITE CTL_CODE(FILE_DEVICE_UNKNOWN, DEBUG_SERVICE_IOCTL_BASE + 0x06, METHOD_BUFFERED, FILE_ANY_ACCESS) +#define DEBUG_SERVICE_READ CTL_CODE(FILE_DEVICE_UNKNOWN, DEBUG_SERVICE_IOCTL_BASE + 0x07, METHOD_BUFFERED, FILE_ANY_ACCESS) +#define DEBUG_SERVICE_SETDEBUGMODE CTL_CODE(FILE_DEVICE_UNKNOWN, DEBUG_SERVICE_IOCTL_BASE + 0x08, METHOD_BUFFERED, FILE_ANY_ACCESS) +#define DEBUG_SERVICE_SETDEBUGOUTMODE CTL_CODE(FILE_DEVICE_UNKNOWN, DEBUG_SERVICE_IOCTL_BASE + 0x09, METHOD_BUFFERED, FILE_ANY_ACCESS) +#define DEBUG_SERVICE_SETDEBUGLEVEL CTL_CODE(FILE_DEVICE_UNKNOWN, DEBUG_SERVICE_IOCTL_BASE + 0x0A, METHOD_BUFFERED, FILE_ANY_ACCESS) +#define DEBUG_SERVICE_SETFRAME CTL_CODE(FILE_DEVICE_UNKNOWN, DEBUG_SERVICE_IOCTL_BASE + 0x0B, METHOD_BUFFERED, FILE_ANY_ACCESS) +#define DEBUG_SERVICE_GETFRAME CTL_CODE(FILE_DEVICE_UNKNOWN, DEBUG_SERVICE_IOCTL_BASE + 0x0C, METHOD_BUFFERED, FILE_ANY_ACCESS) +#define DEBUG_SERVICE_OVERRIDEMODE CTL_CODE(FILE_DEVICE_UNKNOWN, DEBUG_SERVICE_IOCTL_BASE + 0x0D, METHOD_BUFFERED, FILE_ANY_ACCESS) +#define DEBUG_SERVICE_DEFAULTMODE CTL_CODE(FILE_DEVICE_UNKNOWN, DEBUG_SERVICE_IOCTL_BASE + 0x0E, METHOD_BUFFERED, FILE_ANY_ACCESS) +#define DEBUG_SERVICE_GETSERVICETABLE CTL_CODE(FILE_DEVICE_UNKNOWN, DEBUG_SERVICE_IOCTL_BASE + 0x0F, METHOD_BUFFERED, FILE_ANY_ACCESS) +#define DEBUG_SERVICE_WRITE2 CTL_CODE(FILE_DEVICE_UNKNOWN, DEBUG_SERVICE_IOCTL_BASE + 0x10, METHOD_BUFFERED, FILE_ANY_ACCESS) +#define DEBUG_SERVICE_WRITESTRINGCM CTL_CODE(FILE_DEVICE_UNKNOWN, DEBUG_SERVICE_IOCTL_BASE + 0x11, METHOD_BUFFERED, FILE_ANY_ACCESS) +#define DEBUG_SERVICE_WRITECM CTL_CODE(FILE_DEVICE_UNKNOWN, DEBUG_SERVICE_IOCTL_BASE + 0x12, METHOD_BUFFERED, FILE_ANY_ACCESS) +#define DEBUG_SERVICE_SETMARKER CTL_CODE(FILE_DEVICE_UNKNOWN, DEBUG_SERVICE_IOCTL_BASE + 0x13, METHOD_BUFFERED, FILE_ANY_ACCESS) +#define DEBUG_SERVICE_GETMARKER CTL_CODE(FILE_DEVICE_UNKNOWN, DEBUG_SERVICE_IOCTL_BASE + 0x14, METHOD_BUFFERED, FILE_ANY_ACCESS) +#define DEBUG_SERVICE_ISCAPTUREFRAME CTL_CODE(FILE_DEVICE_UNKNOWN, DEBUG_SERVICE_IOCTL_BASE + 0x15, METHOD_BUFFERED, FILE_ANY_ACCESS) +#define DEBUG_SERVICE_WRITELF CTL_CODE(FILE_DEVICE_UNKNOWN, DEBUG_SERVICE_IOCTL_BASE + 0x16, METHOD_BUFFERED, FILE_ANY_ACCESS) +#define DEBUG_SERVICE_READLF CTL_CODE(FILE_DEVICE_UNKNOWN, DEBUG_SERVICE_IOCTL_BASE + 0x17, METHOD_BUFFERED, FILE_ANY_ACCESS) +#define DEBUG_SERVICE_WAITFOREVENT CTL_CODE(FILE_DEVICE_UNKNOWN, DEBUG_SERVICE_IOCTL_BASE + 0x18, METHOD_BUFFERED, FILE_ANY_ACCESS) + + +typedef enum _DBG_EVENT_ +{ + DBG_EVENT_STREAM_DATA = 1 +} DBG_EVENT; + +typedef struct _DBG_IN_CREATESTREAM_ +{ + IMG_UINT32 ui32Pages; + IMG_UINT32 ui32CapMode; + IMG_UINT32 ui32OutMode; + IMG_CHAR *pszName; +}DBG_IN_CREATESTREAM, *PDBG_IN_CREATESTREAM; + +typedef struct _DBG_IN_FINDSTREAM_ +{ + IMG_BOOL bResetStream; + IMG_CHAR *pszName; +}DBG_IN_FINDSTREAM, *PDBG_IN_FINDSTREAM; + +typedef struct _DBG_IN_WRITESTRING_ +{ + IMG_VOID *pvStream; + IMG_UINT32 ui32Level; + IMG_CHAR *pszString; +}DBG_IN_WRITESTRING, *PDBG_IN_WRITESTRING; + +typedef struct _DBG_IN_READSTRING_ +{ + IMG_VOID *pvStream; + IMG_UINT32 ui32StringLen; + IMG_CHAR *pszString; +} DBG_IN_READSTRING, *PDBG_IN_READSTRING; + +typedef struct _DBG_IN_SETDEBUGMODE_ +{ + IMG_VOID *pvStream; + IMG_UINT32 ui32Mode; + IMG_UINT32 ui32Start; + IMG_UINT32 ui32End; + IMG_UINT32 ui32SampleRate; +} DBG_IN_SETDEBUGMODE, *PDBG_IN_SETDEBUGMODE; + +typedef struct _DBG_IN_SETDEBUGOUTMODE_ +{ + IMG_VOID *pvStream; + IMG_UINT32 ui32Mode; +} DBG_IN_SETDEBUGOUTMODE, *PDBG_IN_SETDEBUGOUTMODE; + +typedef struct _DBG_IN_SETDEBUGLEVEL_ +{ + IMG_VOID *pvStream; + IMG_UINT32 ui32Level; +} DBG_IN_SETDEBUGLEVEL, *PDBG_IN_SETDEBUGLEVEL; + +typedef struct _DBG_IN_SETFRAME_ +{ + IMG_VOID *pvStream; + IMG_UINT32 ui32Frame; +} DBG_IN_SETFRAME, *PDBG_IN_SETFRAME; + +typedef struct _DBG_IN_WRITE_ +{ + IMG_VOID *pvStream; + IMG_UINT32 ui32Level; + IMG_UINT32 ui32TransferSize; + IMG_UINT8 *pui8InBuffer; +} DBG_IN_WRITE, *PDBG_IN_WRITE; + +typedef struct _DBG_IN_READ_ +{ + IMG_VOID *pvStream; + IMG_BOOL bReadInitBuffer; + IMG_UINT32 ui32OutBufferSize; + IMG_UINT8 *pui8OutBuffer; +} DBG_IN_READ, *PDBG_IN_READ; + +typedef struct _DBG_IN_OVERRIDEMODE_ +{ + IMG_VOID *pvStream; + IMG_UINT32 ui32Mode; +} DBG_IN_OVERRIDEMODE, *PDBG_IN_OVERRIDEMODE; + +typedef struct _DBG_IN_ISCAPTUREFRAME_ +{ + IMG_VOID *pvStream; + IMG_BOOL bCheckPreviousFrame; +} DBG_IN_ISCAPTUREFRAME, *PDBG_IN_ISCAPTUREFRAME; + +typedef struct _DBG_IN_SETMARKER_ +{ + IMG_VOID *pvStream; + IMG_UINT32 ui32Marker; +} DBG_IN_SETMARKER, *PDBG_IN_SETMARKER; + +typedef struct _DBG_IN_WRITE_LF_ +{ + IMG_UINT32 ui32Flags; + IMG_VOID *pvStream; + IMG_UINT32 ui32Level; + IMG_UINT32 ui32BufferSize; + IMG_UINT8 *pui8InBuffer; +} DBG_IN_WRITE_LF, *PDBG_IN_WRITE_LF; + +#define WRITELF_FLAGS_RESETBUF 0x00000001 + +typedef struct _DBG_STREAM_ +{ + struct _DBG_STREAM_ *psNext; + struct _DBG_STREAM_ *psInitStream; + IMG_BOOL bInitPhaseComplete; + IMG_UINT32 ui32Flags; + IMG_UINT32 ui32Base; + IMG_UINT32 ui32Size; + IMG_UINT32 ui32RPtr; + IMG_UINT32 ui32WPtr; + IMG_UINT32 ui32DataWritten; + IMG_UINT32 ui32CapMode; + IMG_UINT32 ui32OutMode; + IMG_UINT32 ui32DebugLevel; + IMG_UINT32 ui32DefaultMode; + IMG_UINT32 ui32Start; + IMG_UINT32 ui32End; + IMG_UINT32 ui32Current; + IMG_UINT32 ui32Access; + IMG_UINT32 ui32SampleRate; + IMG_UINT32 ui32Reserved; + IMG_UINT32 ui32Timeout; + IMG_UINT32 ui32Marker; + IMG_CHAR szName[30]; +} DBG_STREAM,*PDBG_STREAM; + +typedef struct _DBGKM_SERVICE_TABLE_ +{ + IMG_UINT32 ui32Size; + IMG_VOID * (IMG_CALLCONV *pfnCreateStream) (IMG_CHAR * pszName,IMG_UINT32 ui32CapMode,IMG_UINT32 ui32OutMode,IMG_UINT32 ui32Flags,IMG_UINT32 ui32Pages); + IMG_VOID (IMG_CALLCONV *pfnDestroyStream) (PDBG_STREAM psStream); + IMG_VOID * (IMG_CALLCONV *pfnFindStream) (IMG_CHAR * pszName, IMG_BOOL bResetInitBuffer); + IMG_UINT32 (IMG_CALLCONV *pfnWriteString) (PDBG_STREAM psStream,IMG_CHAR * pszString,IMG_UINT32 ui32Level); + IMG_UINT32 (IMG_CALLCONV *pfnReadString) (PDBG_STREAM psStream,IMG_CHAR * pszString,IMG_UINT32 ui32Limit); + IMG_UINT32 (IMG_CALLCONV *pfnWriteBIN) (PDBG_STREAM psStream,IMG_UINT8 *pui8InBuf,IMG_UINT32 ui32InBuffSize,IMG_UINT32 ui32Level); + IMG_UINT32 (IMG_CALLCONV *pfnReadBIN) (PDBG_STREAM psStream,IMG_BOOL bReadInitBuffer, IMG_UINT32 ui32OutBufferSize,IMG_UINT8 *pui8OutBuf); + IMG_VOID (IMG_CALLCONV *pfnSetCaptureMode) (PDBG_STREAM psStream,IMG_UINT32 ui32CapMode,IMG_UINT32 ui32Start,IMG_UINT32 ui32Stop,IMG_UINT32 ui32SampleRate); + IMG_VOID (IMG_CALLCONV *pfnSetOutputMode) (PDBG_STREAM psStream,IMG_UINT32 ui32OutMode); + IMG_VOID (IMG_CALLCONV *pfnSetDebugLevel) (PDBG_STREAM psStream,IMG_UINT32 ui32DebugLevel); + IMG_VOID (IMG_CALLCONV *pfnSetFrame) (PDBG_STREAM psStream,IMG_UINT32 ui32Frame); + IMG_UINT32 (IMG_CALLCONV *pfnGetFrame) (PDBG_STREAM psStream); + IMG_VOID (IMG_CALLCONV *pfnOverrideMode) (PDBG_STREAM psStream,IMG_UINT32 ui32Mode); + IMG_VOID (IMG_CALLCONV *pfnDefaultMode) (PDBG_STREAM psStream); + IMG_UINT32 (IMG_CALLCONV *pfnDBGDrivWrite2) (PDBG_STREAM psStream,IMG_UINT8 *pui8InBuf,IMG_UINT32 ui32InBuffSize,IMG_UINT32 ui32Level); + IMG_UINT32 (IMG_CALLCONV *pfnWriteStringCM) (PDBG_STREAM psStream,IMG_CHAR * pszString,IMG_UINT32 ui32Level); + IMG_UINT32 (IMG_CALLCONV *pfnWriteBINCM) (PDBG_STREAM psStream,IMG_UINT8 *pui8InBuf,IMG_UINT32 ui32InBuffSize,IMG_UINT32 ui32Level); + IMG_VOID (IMG_CALLCONV *pfnSetMarker) (PDBG_STREAM psStream,IMG_UINT32 ui32Marker); + IMG_UINT32 (IMG_CALLCONV *pfnGetMarker) (PDBG_STREAM psStream); + IMG_VOID (IMG_CALLCONV *pfnStartInitPhase) (PDBG_STREAM psStream); + IMG_VOID (IMG_CALLCONV *pfnStopInitPhase) (PDBG_STREAM psStream); + IMG_UINT32 (IMG_CALLCONV *pfnIsCaptureFrame) (PDBG_STREAM psStream, IMG_BOOL bCheckPreviousFrame); + IMG_UINT32 (IMG_CALLCONV *pfnWriteLF) (PDBG_STREAM psStream, IMG_UINT8 *pui8InBuf, IMG_UINT32 ui32InBuffSize, IMG_UINT32 ui32Level, IMG_UINT32 ui32Flags); + IMG_UINT32 (IMG_CALLCONV *pfnReadLF) (PDBG_STREAM psStream, IMG_UINT32 ui32OutBuffSize, IMG_UINT8 *pui8OutBuf); + IMG_UINT32 (IMG_CALLCONV *pfnGetStreamOffset) (PDBG_STREAM psStream); + IMG_VOID (IMG_CALLCONV *pfnSetStreamOffset) (PDBG_STREAM psStream, IMG_UINT32 ui32StreamOffset); + IMG_UINT32 (IMG_CALLCONV *pfnIsLastCaptureFrame) (PDBG_STREAM psStream); + IMG_VOID (IMG_CALLCONV *pfnWaitForEvent) (DBG_EVENT eEvent); +} DBGKM_SERVICE_TABLE, *PDBGKM_SERVICE_TABLE; + + +#endif diff --git a/include4/img_defs.h b/include4/img_defs.h new file mode 100644 index 0000000..bf3f16e --- /dev/null +++ b/include4/img_defs.h @@ -0,0 +1,104 @@ +/********************************************************************** + * + * Copyright(c) 2008 Imagination Technologies Ltd. All rights reserved. + * + * This program is free software; you can redistribute it and/or modify it + * under the terms and conditions of the GNU General Public License, + * version 2, as published by the Free Software Foundation. + * + * This program is distributed in the hope it will be useful but, except + * as otherwise stated in writing, without any warranty; without even the + * implied warranty of merchantability or fitness for a particular purpose. + * See the GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License along with + * this program; if not, write to the Free Software Foundation, Inc., + * 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA. + * + * The full GNU General Public License is included in this distribution in + * the file called "COPYING". + * + * Contact Information: + * Imagination Technologies Ltd. + * Home Park Estate, Kings Langley, Herts, WD4 8LZ, UK + * + ******************************************************************************/ + +#if !defined (__IMG_DEFS_H__) +#define __IMG_DEFS_H__ + +#include "img_types.h" + +typedef enum img_tag_TriStateSwitch +{ + IMG_ON = 0x00, + IMG_OFF, + IMG_IGNORE + +} img_TriStateSwitch, * img_pTriStateSwitch; + +#define IMG_SUCCESS 0 + +#define IMG_NO_REG 1 + +#if defined (NO_INLINE_FUNCS) + #define INLINE + #define FORCE_INLINE +#else +#if defined (__cplusplus) + #define INLINE inline + #define FORCE_INLINE inline +#else + #define INLINE __inline + #define FORCE_INLINE static __inline +#endif +#endif + + +#ifndef PVR_UNREFERENCED_PARAMETER +#define PVR_UNREFERENCED_PARAMETER(param) (param) = (param) +#endif + +#ifdef __GNUC__ +#define unref__ __attribute__ ((unused)) +#else +#define unref__ +#endif + +#ifndef _TCHAR_DEFINED +#if defined(UNICODE) +typedef unsigned short TCHAR, *PTCHAR, *PTSTR; +#else +typedef char TCHAR, *PTCHAR, *PTSTR; +#endif +#define _TCHAR_DEFINED +#endif + + + #if defined(__linux__) || defined(__METAG) + + #define IMG_CALLCONV + #define IMG_INTERNAL __attribute__ ((visibility ("hidden"))) + #define IMG_EXPORT + #define IMG_IMPORT + #define IMG_RESTRICT __restrict__ + + #else + #error("define an OS") + #endif + +#ifndef IMG_ABORT + #define IMG_ABORT() abort() +#endif + +#ifndef IMG_MALLOC + #define IMG_MALLOC(A) malloc (A) +#endif + +#ifndef IMG_FREE + #define IMG_FREE(A) free (A) +#endif + +#define IMG_CONST const + +#endif diff --git a/include4/img_types.h b/include4/img_types.h new file mode 100644 index 0000000..b1e0af4 --- /dev/null +++ b/include4/img_types.h @@ -0,0 +1,118 @@ +/********************************************************************** + * + * Copyright(c) 2008 Imagination Technologies Ltd. All rights reserved. + * + * This program is free software; you can redistribute it and/or modify it + * under the terms and conditions of the GNU General Public License, + * version 2, as published by the Free Software Foundation. + * + * This program is distributed in the hope it will be useful but, except + * as otherwise stated in writing, without any warranty; without even the + * implied warranty of merchantability or fitness for a particular purpose. + * See the GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License along with + * this program; if not, write to the Free Software Foundation, Inc., + * 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA. + * + * The full GNU General Public License is included in this distribution in + * the file called "COPYING". + * + * Contact Information: + * Imagination Technologies Ltd. + * Home Park Estate, Kings Langley, Herts, WD4 8LZ, UK + * + ******************************************************************************/ + +#ifndef __IMG_TYPES_H__ +#define __IMG_TYPES_H__ + +typedef unsigned int IMG_UINT, *IMG_PUINT; +typedef signed int IMG_INT, *IMG_PINT; + +typedef unsigned char IMG_UINT8, *IMG_PUINT8; +typedef unsigned char IMG_BYTE, *IMG_PBYTE; +typedef signed char IMG_INT8, *IMG_PINT8; +typedef char IMG_CHAR, *IMG_PCHAR; + +typedef unsigned short IMG_UINT16, *IMG_PUINT16; +typedef signed short IMG_INT16, *IMG_PINT16; +typedef unsigned long IMG_UINT32, *IMG_PUINT32; +typedef signed long IMG_INT32, *IMG_PINT32; + +#if !defined(IMG_UINT32_MAX) + #define IMG_UINT32_MAX 0xFFFFFFFFUL +#endif + + #if (defined(LINUX) || defined(__METAG)) +#if !defined(USE_CODE) + typedef unsigned long long IMG_UINT64, *IMG_PUINT64; + typedef long long IMG_INT64, *IMG_PINT64; +#endif + #else + + #error("define an OS") + + #endif + +#if !(defined(LINUX) && defined (__KERNEL__)) +typedef float IMG_FLOAT, *IMG_PFLOAT; +typedef double IMG_DOUBLE, *IMG_PDOUBLE; +#endif + +typedef enum tag_img_bool +{ + IMG_FALSE = 0, + IMG_TRUE = 1, + IMG_FORCE_ALIGN = 0x7FFFFFFF +} IMG_BOOL, *IMG_PBOOL; + +typedef void IMG_VOID, *IMG_PVOID; + +typedef IMG_INT32 IMG_RESULT; + +typedef IMG_UINT32 IMG_UINTPTR_T; + +typedef IMG_PVOID IMG_HANDLE; + +typedef void** IMG_HVOID, * IMG_PHVOID; + +typedef IMG_UINT32 IMG_SIZE_T; + +#define IMG_NULL 0 + + +typedef IMG_PVOID IMG_CPU_VIRTADDR; + +typedef struct {IMG_UINT32 uiAddr;} IMG_CPU_PHYADDR; + +typedef struct {IMG_UINT32 uiAddr;} IMG_DEV_VIRTADDR; + +typedef struct {IMG_UINT32 uiAddr;} IMG_DEV_PHYADDR; + +typedef struct {IMG_UINT32 uiAddr;} IMG_SYS_PHYADDR; + +typedef struct _SYSTEM_ADDR_ +{ + + IMG_UINT32 ui32PageCount; + union + { + + + + IMG_SYS_PHYADDR sContig; + + + + + + + + IMG_SYS_PHYADDR asNonContig[1]; + } u; +} SYSTEM_ADDR; + +#include "img_defs.h" + +#endif diff --git a/include4/ioctldef.h b/include4/ioctldef.h new file mode 100644 index 0000000..4b23ad4 --- /dev/null +++ b/include4/ioctldef.h @@ -0,0 +1,98 @@ +/********************************************************************** + * + * Copyright(c) 2008 Imagination Technologies Ltd. All rights reserved. + * + * This program is free software; you can redistribute it and/or modify it + * under the terms and conditions of the GNU General Public License, + * version 2, as published by the Free Software Foundation. + * + * This program is distributed in the hope it will be useful but, except + * as otherwise stated in writing, without any warranty; without even the + * implied warranty of merchantability or fitness for a particular purpose. + * See the GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License along with + * this program; if not, write to the Free Software Foundation, Inc., + * 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA. + * + * The full GNU General Public License is included in this distribution in + * the file called "COPYING". + * + * Contact Information: + * Imagination Technologies Ltd. + * Home Park Estate, Kings Langley, Herts, WD4 8LZ, UK + * + ******************************************************************************/ + +#ifndef __IOCTLDEF_H__ +#define __IOCTLDEF_H__ + +#define MAKEIOCTLINDEX(i) (((i) >> 2) & 0xFFF) + +#ifndef CTL_CODE + +#define DEVICE_TYPE ULONG + +#define FILE_DEVICE_BEEP 0x00000001 +#define FILE_DEVICE_CD_ROM 0x00000002 +#define FILE_DEVICE_CD_ROM_FILE_SYSTEM 0x00000003 +#define FILE_DEVICE_CONTROLLER 0x00000004 +#define FILE_DEVICE_DATALINK 0x00000005 +#define FILE_DEVICE_DFS 0x00000006 +#define FILE_DEVICE_DISK 0x00000007 +#define FILE_DEVICE_DISK_FILE_SYSTEM 0x00000008 +#define FILE_DEVICE_FILE_SYSTEM 0x00000009 +#define FILE_DEVICE_INPORT_PORT 0x0000000a +#define FILE_DEVICE_KEYBOARD 0x0000000b +#define FILE_DEVICE_MAILSLOT 0x0000000c +#define FILE_DEVICE_MIDI_IN 0x0000000d +#define FILE_DEVICE_MIDI_OUT 0x0000000e +#define FILE_DEVICE_MOUSE 0x0000000f +#define FILE_DEVICE_MULTI_UNC_PROVIDER 0x00000010 +#define FILE_DEVICE_NAMED_PIPE 0x00000011 +#define FILE_DEVICE_NETWORK 0x00000012 +#define FILE_DEVICE_NETWORK_BROWSER 0x00000013 +#define FILE_DEVICE_NETWORK_FILE_SYSTEM 0x00000014 +#define FILE_DEVICE_NULL 0x00000015 +#define FILE_DEVICE_PARALLEL_PORT 0x00000016 +#define FILE_DEVICE_PHYSICAL_NETCARD 0x00000017 +#define FILE_DEVICE_PRINTER 0x00000018 +#define FILE_DEVICE_SCANNER 0x00000019 +#define FILE_DEVICE_SERIAL_MOUSE_PORT 0x0000001a +#define FILE_DEVICE_SERIAL_PORT 0x0000001b +#define FILE_DEVICE_SCREEN 0x0000001c +#define FILE_DEVICE_SOUND 0x0000001d +#define FILE_DEVICE_STREAMS 0x0000001e +#define FILE_DEVICE_TAPE 0x0000001f +#define FILE_DEVICE_TAPE_FILE_SYSTEM 0x00000020 +#define FILE_DEVICE_TRANSPORT 0x00000021 +#define FILE_DEVICE_UNKNOWN 0x00000022 +#define FILE_DEVICE_VIDEO 0x00000023 +#define FILE_DEVICE_VIRTUAL_DISK 0x00000024 +#define FILE_DEVICE_WAVE_IN 0x00000025 +#define FILE_DEVICE_WAVE_OUT 0x00000026 +#define FILE_DEVICE_8042_PORT 0x00000027 +#define FILE_DEVICE_NETWORK_REDIRECTOR 0x00000028 +#define FILE_DEVICE_BATTERY 0x00000029 +#define FILE_DEVICE_BUS_EXTENDER 0x0000002a +#define FILE_DEVICE_MODEM 0x0000002b +#define FILE_DEVICE_VDM 0x0000002c +#define FILE_DEVICE_MASS_STORAGE 0x0000002d + +#define CTL_CODE( DeviceType, Function, Method, Access ) ( \ + ((DeviceType) << 16) | ((Access) << 14) | ((Function) << 2) | (Method) \ +) + +#define METHOD_BUFFERED 0 +#define METHOD_IN_DIRECT 1 +#define METHOD_OUT_DIRECT 2 +#define METHOD_NEITHER 3 + +#define FILE_ANY_ACCESS 0 +#define FILE_READ_ACCESS ( 0x0001 ) +#define FILE_WRITE_ACCESS ( 0x0002 ) + +#endif + +#endif + diff --git a/include4/pdumpdefs.h b/include4/pdumpdefs.h new file mode 100644 index 0000000..ca599ce --- /dev/null +++ b/include4/pdumpdefs.h @@ -0,0 +1,98 @@ +/********************************************************************** + * + * Copyright(c) 2008 Imagination Technologies Ltd. All rights reserved. + * + * This program is free software; you can redistribute it and/or modify it + * under the terms and conditions of the GNU General Public License, + * version 2, as published by the Free Software Foundation. + * + * This program is distributed in the hope it will be useful but, except + * as otherwise stated in writing, without any warranty; without even the + * implied warranty of merchantability or fitness for a particular purpose. + * See the GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License along with + * this program; if not, write to the Free Software Foundation, Inc., + * 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA. + * + * The full GNU General Public License is included in this distribution in + * the file called "COPYING". + * + * Contact Information: + * Imagination Technologies Ltd. + * Home Park Estate, Kings Langley, Herts, WD4 8LZ, UK + * + ******************************************************************************/ + +#if !defined (__PDUMPDEFS_H__) +#define __PDUMPDEFS_H__ + +typedef enum _PDUMP_PIXEL_FORMAT_ +{ + PVRSRV_PDUMP_PIXEL_FORMAT_RGB8 = 1, + PVRSRV_PDUMP_PIXEL_FORMAT_RGB332 = 2, + PVRSRV_PDUMP_PIXEL_FORMAT_KRGB555 = 3, + PVRSRV_PDUMP_PIXEL_FORMAT_RGB565 = 4, + PVRSRV_PDUMP_PIXEL_FORMAT_ARGB4444 = 5, + PVRSRV_PDUMP_PIXEL_FORMAT_ARGB1555 = 6, + PVRSRV_PDUMP_PIXEL_FORMAT_RGB888 = 7, + PVRSRV_PDUMP_PIXEL_FORMAT_ARGB8888 = 8, + PVRSRV_PDUMP_PIXEL_FORMAT_YUV8 = 9, + PVRSRV_PDUMP_PIXEL_FORMAT_AYUV4444 = 10, + PVRSRV_PDUMP_PIXEL_FORMAT_VY0UY1_8888 = 11, + PVRSRV_PDUMP_PIXEL_FORMAT_UY0VY1_8888 = 12, + PVRSRV_PDUMP_PIXEL_FORMAT_Y0UY1V_8888 = 13, + PVRSRV_PDUMP_PIXEL_FORMAT_Y0VY1U_8888 = 14, + PVRSRV_PDUMP_PIXEL_FORMAT_YUV888 = 15, + PVRSRV_PDUMP_PIXEL_FORMAT_UYVY10101010 = 16, + PVRSRV_PDUMP_PIXEL_FORMAT_VYAUYA8888 = 17, + PVRSRV_PDUMP_PIXEL_FORMAT_AYUV8888 = 18, + PVRSRV_PDUMP_PIXEL_FORMAT_AYUV2101010 = 19, + PVRSRV_PDUMP_PIXEL_FORMAT_YUV101010 = 20, + PVRSRV_PDUMP_PIXEL_FORMAT_PL12Y8 = 21, + PVRSRV_PDUMP_PIXEL_FORMAT_YUV_IMC2 = 22, + PVRSRV_PDUMP_PIXEL_FORMAT_YUV_YV12 = 23, + PVRSRV_PDUMP_PIXEL_FORMAT_YUV_PL8 = 24, + PVRSRV_PDUMP_PIXEL_FORMAT_YUV_PL12 = 25, + PVRSRV_PDUMP_PIXEL_FORMAT_422PL12YUV8 = 26, + PVRSRV_PDUMP_PIXEL_FORMAT_420PL12YUV8 = 27, + PVRSRV_PDUMP_PIXEL_FORMAT_PL12Y10 = 28, + PVRSRV_PDUMP_PIXEL_FORMAT_422PL12YUV10 = 29, + PVRSRV_PDUMP_PIXEL_FORMAT_420PL12YUV10 = 30, + PVRSRV_PDUMP_PIXEL_FORMAT_ABGR8888 = 31, + PVRSRV_PDUMP_PIXEL_FORMAT_BGRA8888 = 32, + PVRSRV_PDUMP_PIXEL_FORMAT_ARGB8332 = 33, + PVRSRV_PDUMP_PIXEL_FORMAT_RGB555 = 34, + PVRSRV_PDUMP_PIXEL_FORMAT_F16 = 35, + PVRSRV_PDUMP_PIXEL_FORMAT_F32 = 36, + PVRSRV_PDUMP_PIXEL_FORMAT_L16 = 37, + PVRSRV_PDUMP_PIXEL_FORMAT_L32 = 38, + + PVRSRV_PDUMP_PIXEL_FORMAT_FORCE_I32 = 0x7fffffff + +} PDUMP_PIXEL_FORMAT; + +typedef enum _PDUMP_MEM_FORMAT_ +{ + PVRSRV_PDUMP_MEM_FORMAT_STRIDE = 0, + PVRSRV_PDUMP_MEM_FORMAT_RESERVED = 1, + PVRSRV_PDUMP_MEM_FORMAT_TILED = 8, + PVRSRV_PDUMP_MEM_FORMAT_TWIDDLED = 9, + PVRSRV_PDUMP_MEM_FORMAT_HYBRID = 10, + + PVRSRV_PDUMP_MEM_FORMAT_FORCE_I32 = 0x7fffffff +} PDUMP_MEM_FORMAT; + +typedef enum _PDUMP_POLL_OPERATOR +{ + PDUMP_POLL_OPERATOR_EQUAL = 0, + PDUMP_POLL_OPERATOR_LESS = 1, + PDUMP_POLL_OPERATOR_LESSEQUAL = 2, + PDUMP_POLL_OPERATOR_GREATER = 3, + PDUMP_POLL_OPERATOR_GREATEREQUAL = 4, + PDUMP_POLL_OPERATOR_NOTEQUAL = 5, +} PDUMP_POLL_OPERATOR; + + +#endif + diff --git a/include4/pvr_debug.h b/include4/pvr_debug.h new file mode 100644 index 0000000..72379c7 --- /dev/null +++ b/include4/pvr_debug.h @@ -0,0 +1,105 @@ +/********************************************************************** + * + * Copyright(c) 2008 Imagination Technologies Ltd. All rights reserved. + * + * This program is free software; you can redistribute it and/or modify it + * under the terms and conditions of the GNU General Public License, + * version 2, as published by the Free Software Foundation. + * + * This program is distributed in the hope it will be useful but, except + * as otherwise stated in writing, without any warranty; without even the + * implied warranty of merchantability or fitness for a particular purpose. + * See the GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License along with + * this program; if not, write to the Free Software Foundation, Inc., + * 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA. + * + * The full GNU General Public License is included in this distribution in + * the file called "COPYING". + * + * Contact Information: + * Imagination Technologies Ltd. + * Home Park Estate, Kings Langley, Herts, WD4 8LZ, UK + * + ******************************************************************************/ + +#ifndef __PVR_DEBUG_H__ +#define __PVR_DEBUG_H__ + + +#include "img_types.h" + +#if defined (__cplusplus) +extern "C" { +#endif + +#define PVR_MAX_DEBUG_MESSAGE_LEN (512) + +#define DBGPRIV_FATAL 0x01UL +#define DBGPRIV_ERROR 0x02UL +#define DBGPRIV_WARNING 0x04UL +#define DBGPRIV_MESSAGE 0x08UL +#define DBGPRIV_VERBOSE 0x10UL +#define DBGPRIV_CALLTRACE 0x20UL +#define DBGPRIV_ALLOC 0x40UL +#define DBGPRIV_ALLLEVELS (DBGPRIV_FATAL | DBGPRIV_ERROR | DBGPRIV_WARNING | DBGPRIV_MESSAGE | DBGPRIV_VERBOSE) + + + +#define PVR_DBG_FATAL DBGPRIV_FATAL,__FILE__, __LINE__ +#define PVR_DBG_ERROR DBGPRIV_ERROR,__FILE__, __LINE__ +#define PVR_DBG_WARNING DBGPRIV_WARNING,__FILE__, __LINE__ +#define PVR_DBG_MESSAGE DBGPRIV_MESSAGE,__FILE__, __LINE__ +#define PVR_DBG_VERBOSE DBGPRIV_VERBOSE,__FILE__, __LINE__ +#define PVR_DBG_CALLTRACE DBGPRIV_CALLTRACE,__FILE__, __LINE__ +#define PVR_DBG_ALLOC DBGPRIV_ALLOC,__FILE__, __LINE__ + +#if defined(DEBUG) + #define PVR_ASSERT(EXPR) if (!(EXPR)) PVRSRVDebugAssertFail(__FILE__, __LINE__); + #define PVR_DPF(X) PVRSRVDebugPrintf X + #define PVR_TRACE(X) PVRSRVTrace X + +IMG_IMPORT IMG_VOID IMG_CALLCONV PVRSRVDebugAssertFail(const IMG_CHAR *pszFile, + IMG_UINT32 ui32Line); + +IMG_IMPORT IMG_VOID IMG_CALLCONV PVRSRVDebugPrintf(IMG_UINT32 ui32DebugLevel, + const IMG_CHAR *pszFileName, + IMG_UINT32 ui32Line, + const IMG_CHAR *pszFormat, + ...); + +IMG_IMPORT IMG_VOID IMG_CALLCONV PVRSRVTrace(const IMG_CHAR* pszFormat, ... ); + +IMG_VOID PVRSRVDebugSetLevel (IMG_UINT32 uDebugLevel); + + #define PVR_DBG_BREAK + +#else + +#if defined(TIMING) + + #define PVR_ASSERT(EXPR) + #define PVR_DPF(X) + #define PVR_TRACE(X) PVRSRVTrace X + #define PVR_DBG_BREAK + +IMG_IMPORT IMG_VOID IMG_CALLCONV PVRSRVTrace(const IMG_CHAR* pszFormat, ... ); + +#else + + #define PVR_ASSERT(EXPR) + #define PVR_DPF(X) + #define PVR_TRACE(X) + #define PVR_DBG_BREAK + +#endif +#endif + + +#if defined (__cplusplus) +} +#endif + +#endif + diff --git a/include4/pvrmodule.h b/include4/pvrmodule.h new file mode 100644 index 0000000..30cb2c3 --- /dev/null +++ b/include4/pvrmodule.h @@ -0,0 +1,31 @@ +/********************************************************************** + * + * Copyright(c) 2008 Imagination Technologies Ltd. All rights reserved. + * + * This program is free software; you can redistribute it and/or modify it + * under the terms and conditions of the GNU General Public License, + * version 2, as published by the Free Software Foundation. + * + * This program is distributed in the hope it will be useful but, except + * as otherwise stated in writing, without any warranty; without even the + * implied warranty of merchantability or fitness for a particular purpose. + * See the GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License along with + * this program; if not, write to the Free Software Foundation, Inc., + * 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA. + * + * The full GNU General Public License is included in this distribution in + * the file called "COPYING". + * + * Contact Information: + * Imagination Technologies Ltd. + * Home Park Estate, Kings Langley, Herts, WD4 8LZ, UK + * + ******************************************************************************/ + +#ifndef _PVRMODULE_H_ +#define _PVRMODULE_H_ +MODULE_AUTHOR("Imagination Technologies Ltd. "); +MODULE_LICENSE("GPL"); +#endif diff --git a/include4/pvrversion.h b/include4/pvrversion.h new file mode 100644 index 0000000..dce1ccd --- /dev/null +++ b/include4/pvrversion.h @@ -0,0 +1,38 @@ +/********************************************************************** + * + * Copyright(c) 2008 Imagination Technologies Ltd. All rights reserved. + * + * This program is free software; you can redistribute it and/or modify it + * under the terms and conditions of the GNU General Public License, + * version 2, as published by the Free Software Foundation. + * + * This program is distributed in the hope it will be useful but, except + * as otherwise stated in writing, without any warranty; without even the + * implied warranty of merchantability or fitness for a particular purpose. + * See the GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License along with + * this program; if not, write to the Free Software Foundation, Inc., + * 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA. + * + * The full GNU General Public License is included in this distribution in + * the file called "COPYING". + * + * Contact Information: + * Imagination Technologies Ltd. + * Home Park Estate, Kings Langley, Herts, WD4 8LZ, UK + * + ******************************************************************************/ + +#ifndef _PVRVERSION_H_ +#define _PVRVERSION_H_ + +#define PVRVERSION_MAJ 1 +#define PVRVERSION_MIN 4 +#define PVRVERSION_BRANCH 14 +#define PVRVERSION_BUILD 2616 +#define PVRVERSION_STRING "1.4.14.2616" +#define PVRVERSION_FILE "eurasiacon.pj" + +#endif + diff --git a/include4/regpaths.h b/include4/regpaths.h new file mode 100644 index 0000000..a551eff --- /dev/null +++ b/include4/regpaths.h @@ -0,0 +1,43 @@ +/********************************************************************** + * + * Copyright(c) 2008 Imagination Technologies Ltd. All rights reserved. + * + * This program is free software; you can redistribute it and/or modify it + * under the terms and conditions of the GNU General Public License, + * version 2, as published by the Free Software Foundation. + * + * This program is distributed in the hope it will be useful but, except + * as otherwise stated in writing, without any warranty; without even the + * implied warranty of merchantability or fitness for a particular purpose. + * See the GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License along with + * this program; if not, write to the Free Software Foundation, Inc., + * 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA. + * + * The full GNU General Public License is included in this distribution in + * the file called "COPYING". + * + * Contact Information: + * Imagination Technologies Ltd. + * Home Park Estate, Kings Langley, Herts, WD4 8LZ, UK + * + ******************************************************************************/ + +#ifndef __REGPATHS_H__ +#define __REGPATHS_H__ + +#define POWERVR_REG_ROOT "Drivers\\Display\\PowerVR" +#define POWERVR_CHIP_KEY "\\SGX1\\" + +#define POWERVR_EURASIA_KEY "PowerVREurasia\\" + +#define POWERVR_SERVICES_KEY "\\Registry\\Machine\\System\\CurrentControlSet\\Services\\PowerVR\\" + +#define PVRSRV_REGISTRY_ROOT POWERVR_EURASIA_KEY "HWSettings\\PVRSRVKM" + + +#define MAX_REG_STRING_SIZE 128 + + +#endif diff --git a/include4/services.h b/include4/services.h new file mode 100644 index 0000000..f81ef27 --- /dev/null +++ b/include4/services.h @@ -0,0 +1,817 @@ +/********************************************************************** + * + * Copyright(c) 2008 Imagination Technologies Ltd. All rights reserved. + * + * This program is free software; you can redistribute it and/or modify it + * under the terms and conditions of the GNU General Public License, + * version 2, as published by the Free Software Foundation. + * + * This program is distributed in the hope it will be useful but, except + * as otherwise stated in writing, without any warranty; without even the + * implied warranty of merchantability or fitness for a particular purpose. + * See the GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License along with + * this program; if not, write to the Free Software Foundation, Inc., + * 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA. + * + * The full GNU General Public License is included in this distribution in + * the file called "COPYING". + * + * Contact Information: + * Imagination Technologies Ltd. + * Home Park Estate, Kings Langley, Herts, WD4 8LZ, UK + * + ******************************************************************************/ + +#ifndef __SERVICES_H__ +#define __SERVICES_H__ + +#if defined (__cplusplus) +extern "C" { +#endif + +#include "img_defs.h" +#include "servicesext.h" +#include "pdumpdefs.h" + + +#define PVRSRV_4K_PAGE_SIZE 4096UL + +#define PVRSRV_MAX_CMD_SIZE 1024 + +#define PVRSRV_MAX_DEVICES 16 + +#define EVENTOBJNAME_MAXLENGTH (50) + +#define PVRSRV_MEM_READ (1UL<<0) +#define PVRSRV_MEM_WRITE (1UL<<1) +#define PVRSRV_MEM_CACHE_CONSISTENT (1UL<<2) +#define PVRSRV_MEM_NO_SYNCOBJ (1UL<<3) +#define PVRSRV_MEM_INTERLEAVED (1UL<<4) +#define PVRSRV_MEM_DUMMY (1UL<<5) +#define PVRSRV_MEM_EDM_PROTECT (1UL<<6) +#define PVRSRV_MEM_ZERO (1UL<<7) +#define PVRSRV_MEM_USER_SUPPLIED_DEVVADDR (1UL<<8) +#define PVRSRV_MEM_RAM_BACKED_ALLOCATION (1UL<<9) +#define PVRSRV_MEM_NO_RESMAN (1UL<<10) +#define PVRSRV_MEM_EXPORTED (1UL<<11) + + +#define PVRSRV_HAP_CACHED (1UL<<12) +#define PVRSRV_HAP_UNCACHED (1UL<<13) +#define PVRSRV_HAP_WRITECOMBINE (1UL<<14) +#define PVRSRV_HAP_CACHETYPE_MASK (PVRSRV_HAP_CACHED|PVRSRV_HAP_UNCACHED|PVRSRV_HAP_WRITECOMBINE) +#define PVRSRV_HAP_KERNEL_ONLY (1UL<<15) +#define PVRSRV_HAP_SINGLE_PROCESS (1UL<<16) +#define PVRSRV_HAP_MULTI_PROCESS (1UL<<17) +#define PVRSRV_HAP_FROM_EXISTING_PROCESS (1UL<<18) +#define PVRSRV_HAP_NO_CPU_VIRTUAL (1UL<<19) +#define PVRSRV_HAP_MAPTYPE_MASK (PVRSRV_HAP_KERNEL_ONLY \ + |PVRSRV_HAP_SINGLE_PROCESS \ + |PVRSRV_HAP_MULTI_PROCESS \ + |PVRSRV_HAP_FROM_EXISTING_PROCESS \ + |PVRSRV_HAP_NO_CPU_VIRTUAL) +#define PVRSRV_MEM_BACKINGSTORE_FIELD_SHIFT (24) + +#define PVRSRV_MAP_NOUSERVIRTUAL (1UL<<27) + +#define PVRSRV_NO_CONTEXT_LOSS 0 +#define PVRSRV_SEVERE_LOSS_OF_CONTEXT 1 +#define PVRSRV_PRE_STATE_CHANGE_MASK 0x80 + + +#define PVRSRV_DEFAULT_DEV_COOKIE (1) + + +#define PVRSRV_MISC_INFO_TIMER_PRESENT (1UL<<0) +#define PVRSRV_MISC_INFO_CLOCKGATE_PRESENT (1UL<<1) +#define PVRSRV_MISC_INFO_MEMSTATS_PRESENT (1UL<<2) +#define PVRSRV_MISC_INFO_GLOBALEVENTOBJECT_PRESENT (1UL<<3) +#define PVRSRV_MISC_INFO_DDKVERSION_PRESENT (1UL<<4) + +#define PVRSRV_PDUMP_MAX_FILENAME_SIZE 20 +#define PVRSRV_PDUMP_MAX_COMMENT_SIZE 200 + + +#define PVRSRV_CHANGEDEVMEM_ATTRIBS_CACHECOHERENT 0x00000001 + +#define PVRSRV_MAPEXTMEMORY_FLAGS_ALTERNATEVA 0x00000001 +#define PVRSRV_MAPEXTMEMORY_FLAGS_PHYSCONTIG 0x00000002 + +#define PVRSRV_MODIFYSYNCOPS_FLAGS_WOP_INC 0x00000001 +#define PVRSRV_MODIFYSYNCOPS_FLAGS_ROP_INC 0x00000002 +#define PVRSRV_MODIFYSYNCOPS_FLAGS_WOC_INC 0x00000004 +#define PVRSRV_MODIFYSYNCOPS_FLAGS_ROC_INC 0x00000008 + +typedef enum _PVRSRV_DEVICE_TYPE_ +{ + PVRSRV_DEVICE_TYPE_UNKNOWN = 0 , + PVRSRV_DEVICE_TYPE_MBX1 = 1 , + PVRSRV_DEVICE_TYPE_MBX1_LITE = 2 , + + PVRSRV_DEVICE_TYPE_M24VA = 3, + PVRSRV_DEVICE_TYPE_MVDA2 = 4, + PVRSRV_DEVICE_TYPE_MVED1 = 5, + PVRSRV_DEVICE_TYPE_MSVDX = 6, + + PVRSRV_DEVICE_TYPE_SGX = 7, + + PVRSRV_DEVICE_TYPE_VGX = 8, + + + PVRSRV_DEVICE_TYPE_EXT = 9, + + PVRSRV_DEVICE_TYPE_LAST = 9, + + PVRSRV_DEVICE_TYPE_FORCE_I32 = 0x7fffffff + +} PVRSRV_DEVICE_TYPE; + +#define HEAP_ID( _dev_ , _dev_heap_idx_ ) ( ((_dev_)<<24) | ((_dev_heap_idx_)&((1<<24)-1)) ) +#define HEAP_IDX( _heap_id_ ) ( (_heap_id_)&((1<<24) - 1 ) ) +#define HEAP_DEV( _heap_id_ ) ( (_heap_id_)>>24 ) + +#define PVRSRV_UNDEFINED_HEAP_ID (~0LU) + +typedef enum +{ + IMG_EGL = 0x00000001, + IMG_OPENGLES1 = 0x00000002, + IMG_OPENGLES2 = 0x00000003, + IMG_D3DM = 0x00000004, + IMG_SRV_UM = 0x00000005, + IMG_OPENVG = 0x00000006, + IMG_SRVCLIENT = 0x00000007, + IMG_VISTAKMD = 0x00000008, + IMG_VISTA3DNODE = 0x00000009, + IMG_VISTAMVIDEONODE = 0x0000000A, + IMG_VISTAVPBNODE = 0x0000000B, + IMG_OPENGL = 0x0000000C, + IMG_D3D = 0x0000000D + +} IMG_MODULE_ID; + + +#define APPHINT_MAX_STRING_SIZE 256 + +typedef enum +{ + IMG_STRING_TYPE = 1, + IMG_FLOAT_TYPE , + IMG_UINT_TYPE , + IMG_INT_TYPE , + IMG_FLAG_TYPE +}IMG_DATA_TYPE; + + +typedef struct _PVRSRV_CONNECTION_ +{ + IMG_HANDLE hServices; + IMG_UINT32 ui32ProcessID; +}PVRSRV_CONNECTION; + + +typedef struct _PVRSRV_DEV_DATA_ +{ + PVRSRV_CONNECTION sConnection; + IMG_HANDLE hDevCookie; + +} PVRSRV_DEV_DATA, *PPVRSRV_DEV_DATA; + +typedef struct _PVRSRV_MEMUPDATE_ +{ + IMG_UINT32 ui32UpdateAddr; + IMG_UINT32 ui32UpdateVal; +} PVRSRV_MEMUPDATE; + +typedef struct _PVRSRV_HWREG_ +{ + IMG_UINT32 ui32RegAddr; + IMG_UINT32 ui32RegVal; +} PVRSRV_HWREG; + +typedef struct _PVRSRV_MEMBLK_ +{ + IMG_DEV_VIRTADDR sDevVirtAddr; + IMG_HANDLE hOSMemHandle; + IMG_HANDLE hOSWrapMem; + IMG_HANDLE hBuffer; + IMG_HANDLE hResItem; + IMG_SYS_PHYADDR *psIntSysPAddr; + +} PVRSRV_MEMBLK; + +typedef struct _PVRSRV_KERNEL_MEM_INFO_ *PPVRSRV_KERNEL_MEM_INFO; + +typedef struct _PVRSRV_CLIENT_MEM_INFO_ +{ + + IMG_PVOID pvLinAddr; + + + IMG_PVOID pvLinAddrKM; + + + IMG_DEV_VIRTADDR sDevVAddr; + + + + + + + IMG_CPU_PHYADDR sCpuPAddr; + + + IMG_UINT32 ui32Flags; + + + + + IMG_UINT32 ui32ClientFlags; + + + IMG_UINT32 ui32AllocSize; + + + + struct _PVRSRV_CLIENT_SYNC_INFO_ *psClientSyncInfo; + + + IMG_HANDLE hMappingInfo; + + + IMG_HANDLE hKernelMemInfo; + + + IMG_HANDLE hResItem; + + + + + + struct _PVRSRV_CLIENT_MEM_INFO_ *psNext; + +} PVRSRV_CLIENT_MEM_INFO, *PPVRSRV_CLIENT_MEM_INFO; + + +#if 0 +typedef struct _PVRSRV_CLIENT_SYNC_INFO_ +{ + + PVRSRV_SYNC_DATA *psSyncData; + + + + + + IMG_DEV_VIRTADDR sWriteOpsCompleteDevVAddr; + + + IMG_DEV_VIRTADDR sReadOpsCompleteDevVAddr; + + + IMG_HANDLE hMappingInfo; + + + IMG_HANDLE hKernelSyncInfo; + +} PVRSRV_CLIENT_SYNC_INFO, *PPVRSRV_CLIENT_SYNC_INFO; +#endif + +#define PVRSRV_MAX_CLIENT_HEAPS (32) +typedef struct _PVRSRV_HEAP_INFO_ +{ + IMG_UINT32 ui32HeapID; + IMG_HANDLE hDevMemHeap; + IMG_DEV_VIRTADDR sDevVAddrBase; + IMG_UINT32 ui32HeapByteSize; + IMG_UINT32 ui32Attribs; +}PVRSRV_HEAP_INFO; + + + + +typedef struct _PVRSRV_DEVICE_IDENTIFIER_ +{ + PVRSRV_DEVICE_TYPE eDeviceType; + PVRSRV_DEVICE_CLASS eDeviceClass; + IMG_UINT32 ui32DeviceIndex; + +} PVRSRV_DEVICE_IDENTIFIER; + +typedef struct _PVRSRV_EVENTOBJECT_ +{ + + IMG_CHAR szName[EVENTOBJNAME_MAXLENGTH]; + + IMG_HANDLE hOSEventKM; + +} PVRSRV_EVENTOBJECT; + +typedef struct _PVRSRV_MISC_INFO_ +{ + IMG_UINT32 ui32StateRequest; + IMG_UINT32 ui32StatePresent; + + + IMG_VOID *pvSOCTimerRegisterKM; + IMG_VOID *pvSOCTimerRegisterUM; + IMG_HANDLE hSOCTimerRegisterOSMemHandle; + IMG_HANDLE hSOCTimerRegisterMappingInfo; + + + IMG_VOID *pvSOCClockGateRegs; + IMG_UINT32 ui32SOCClockGateRegsSize; + + + IMG_CHAR *pszMemoryStr; + IMG_UINT32 ui32MemoryStrLen; + + + PVRSRV_EVENTOBJECT sGlobalEventObject; + IMG_HANDLE hOSGlobalEvent; + + + IMG_UINT32 aui32DDKVersion[4]; +} PVRSRV_MISC_INFO; + + +IMG_IMPORT +PVRSRV_ERROR IMG_CALLCONV PVRSRVConnect(PVRSRV_CONNECTION *psConnection); + +IMG_IMPORT +PVRSRV_ERROR IMG_CALLCONV PVRSRVDisconnect(PVRSRV_CONNECTION *psConnection); + +IMG_IMPORT +PVRSRV_ERROR IMG_CALLCONV PVRSRVEnumerateDevices(IMG_CONST PVRSRV_CONNECTION *psConnection, + IMG_UINT32 *puiNumDevices, + PVRSRV_DEVICE_IDENTIFIER *puiDevIDs); +IMG_IMPORT +PVRSRV_ERROR IMG_CALLCONV PVRSRVAcquireDeviceData(IMG_CONST PVRSRV_CONNECTION *psConnection, + IMG_UINT32 uiDevIndex, + PVRSRV_DEV_DATA *psDevData, + PVRSRV_DEVICE_TYPE eDeviceType); +IMG_IMPORT +PVRSRV_ERROR IMG_CALLCONV PVRSRVGetMiscInfo (IMG_CONST PVRSRV_CONNECTION *psConnection, PVRSRV_MISC_INFO *psMiscInfo); + +IMG_IMPORT +PVRSRV_ERROR IMG_CALLCONV PVRSRVReleaseMiscInfo (IMG_CONST PVRSRV_CONNECTION *psConnection, PVRSRV_MISC_INFO *psMiscInfo); + +#if 1 +IMG_IMPORT +IMG_UINT32 ReadHWReg(IMG_PVOID pvLinRegBaseAddr, IMG_UINT32 ui32Offset); + +IMG_IMPORT +IMG_VOID WriteHWReg(IMG_PVOID pvLinRegBaseAddr, IMG_UINT32 ui32Offset, IMG_UINT32 ui32Value); + +IMG_IMPORT IMG_VOID WriteHWRegs(IMG_PVOID pvLinRegBaseAddr, IMG_UINT32 ui32Count, PVRSRV_HWREG *psHWRegs); +#endif + +IMG_IMPORT +PVRSRV_ERROR PVRSRVPollForValue ( const PVRSRV_CONNECTION *psConnection, + IMG_HANDLE hOSEvent, + volatile IMG_UINT32 *pui32LinMemAddr, + IMG_UINT32 ui32Value, + IMG_UINT32 ui32Mask, + IMG_UINT32 ui32Waitus, + IMG_UINT32 ui32Tries); + +IMG_IMPORT +PVRSRV_ERROR IMG_CALLCONV PVRSRVCreateDeviceMemContext(IMG_CONST PVRSRV_DEV_DATA *psDevData, + IMG_HANDLE *phDevMemContext, + IMG_UINT32 *pui32SharedHeapCount, + PVRSRV_HEAP_INFO *psHeapInfo); + +IMG_IMPORT +PVRSRV_ERROR IMG_CALLCONV PVRSRVDestroyDeviceMemContext(IMG_CONST PVRSRV_DEV_DATA *psDevData, + IMG_HANDLE hDevMemContext); + +IMG_IMPORT +PVRSRV_ERROR IMG_CALLCONV PVRSRVGetDeviceMemHeapInfo(IMG_CONST PVRSRV_DEV_DATA *psDevData, + IMG_HANDLE hDevMemContext, + IMG_UINT32 *pui32SharedHeapCount, + PVRSRV_HEAP_INFO *psHeapInfo); + +IMG_IMPORT +PVRSRV_ERROR IMG_CALLCONV PVRSRVAllocDeviceMem(IMG_CONST PVRSRV_DEV_DATA *psDevData, + IMG_HANDLE hDevMemHeap, + IMG_UINT32 ui32Attribs, + IMG_UINT32 ui32Size, + IMG_UINT32 ui32Alignment, + PVRSRV_CLIENT_MEM_INFO **ppsMemInfo); + +IMG_IMPORT +PVRSRV_ERROR IMG_CALLCONV PVRSRVFreeDeviceMem(IMG_CONST PVRSRV_DEV_DATA *psDevData, + PVRSRV_CLIENT_MEM_INFO *psMemInfo); + +IMG_IMPORT +PVRSRV_ERROR IMG_CALLCONV PVRSRVExportDeviceMem(IMG_CONST PVRSRV_DEV_DATA *psDevData, + PVRSRV_CLIENT_MEM_INFO *psMemInfo, + IMG_HANDLE *phMemInfo); + +IMG_IMPORT +PVRSRV_ERROR IMG_CALLCONV PVRSRVReserveDeviceVirtualMem(IMG_CONST PVRSRV_DEV_DATA *psDevData, + IMG_HANDLE hDevMemHeap, + IMG_DEV_VIRTADDR *psDevVAddr, + IMG_UINT32 ui32Size, + IMG_UINT32 ui32Alignment, + PVRSRV_CLIENT_MEM_INFO **ppsMemInfo); +IMG_IMPORT +PVRSRV_ERROR IMG_CALLCONV PVRSRVFreeDeviceVirtualMem(IMG_CONST PVRSRV_DEV_DATA *psDevData, + PVRSRV_CLIENT_MEM_INFO *psMemInfo); + +IMG_IMPORT +PVRSRV_ERROR IMG_CALLCONV PVRSRVMapDeviceMemory (IMG_CONST PVRSRV_DEV_DATA *psDevData, + IMG_HANDLE hKernelMemInfo, + IMG_HANDLE hDstDevMemHeap, + PVRSRV_CLIENT_MEM_INFO **ppsDstMemInfo); + +IMG_IMPORT +PVRSRV_ERROR IMG_CALLCONV PVRSRVUnmapDeviceMemory (IMG_CONST PVRSRV_DEV_DATA *psDevData, + PVRSRV_CLIENT_MEM_INFO *psMemInfo); + +IMG_IMPORT +PVRSRV_ERROR IMG_CALLCONV PVRSRVMapExtMemory (IMG_CONST PVRSRV_DEV_DATA *psDevData, + PVRSRV_CLIENT_MEM_INFO *psMemInfo, + IMG_SYS_PHYADDR *psSysPAddr, + IMG_UINT32 ui32Flags); +IMG_IMPORT +PVRSRV_ERROR IMG_CALLCONV PVRSRVUnmapExtMemory (IMG_CONST PVRSRV_DEV_DATA *psDevData, + PVRSRV_CLIENT_MEM_INFO *psMemInfo, + IMG_UINT32 ui32Flags); + +IMG_IMPORT +PVRSRV_ERROR IMG_CALLCONV PVRSRVWrapExtMemory(IMG_CONST PVRSRV_DEV_DATA *psDevData, + IMG_HANDLE hDevMemContext, + IMG_UINT32 ui32ByteSize, + IMG_UINT32 ui32PageOffset, + IMG_BOOL bPhysContig, + IMG_SYS_PHYADDR *psSysPAddr, + IMG_VOID *pvLinAddr, + PVRSRV_CLIENT_MEM_INFO **ppsMemInfo); +IMG_IMPORT +PVRSRV_ERROR IMG_CALLCONV PVRSRVUnwrapExtMemory (IMG_CONST PVRSRV_DEV_DATA *psDevData, + PVRSRV_CLIENT_MEM_INFO *psMemInfo); + +PVRSRV_ERROR PVRSRVChangeDeviceMemoryAttributes(IMG_CONST PVRSRV_DEV_DATA *psDevData, + PVRSRV_CLIENT_MEM_INFO *psClientMemInfo, + IMG_UINT32 ui32Attribs); + +IMG_IMPORT +PVRSRV_ERROR IMG_CALLCONV PVRSRVMapDeviceClassMemory (IMG_CONST PVRSRV_DEV_DATA *psDevData, + IMG_HANDLE hDevMemContext, + IMG_HANDLE hDeviceClassBuffer, + PVRSRV_CLIENT_MEM_INFO **ppsMemInfo); +IMG_IMPORT +PVRSRV_ERROR IMG_CALLCONV PVRSRVUnmapDeviceClassMemory (IMG_CONST PVRSRV_DEV_DATA *psDevData, + PVRSRV_CLIENT_MEM_INFO *psMemInfo); + +IMG_IMPORT +PVRSRV_ERROR IMG_CALLCONV PVRSRVMapPhysToUserSpace(IMG_CONST PVRSRV_DEV_DATA *psDevData, + IMG_SYS_PHYADDR sSysPhysAddr, + IMG_UINT32 uiSizeInBytes, + IMG_PVOID *ppvUserAddr, + IMG_UINT32 *puiActualSize, + IMG_PVOID *ppvProcess); + +IMG_IMPORT +PVRSRV_ERROR IMG_CALLCONV PVRSRVUnmapPhysToUserSpace(IMG_CONST PVRSRV_DEV_DATA *psDevData, + IMG_PVOID pvUserAddr, + IMG_PVOID pvProcess); + +typedef enum _PVRSRV_SYNCVAL_MODE_ +{ + PVRSRV_SYNCVAL_READ = IMG_TRUE, + PVRSRV_SYNCVAL_WRITE = IMG_FALSE, + +} PVRSRV_SYNCVAL_MODE, *PPVRSRV_SYNCVAL_MODE; + +typedef IMG_UINT32 PVRSRV_SYNCVAL; + +IMG_IMPORT PVRSRV_ERROR PVRSRVWaitForOpsComplete(PPVRSRV_CLIENT_MEM_INFO psMemInfo, + PVRSRV_SYNCVAL_MODE eMode, PVRSRV_SYNCVAL OpRequired); + +IMG_IMPORT PVRSRV_ERROR PVRSRVWaitForAllOpsComplete(PPVRSRV_CLIENT_MEM_INFO psMemInfo, + PVRSRV_SYNCVAL_MODE eMode); + +IMG_IMPORT IMG_BOOL PVRSRVTestOpsComplete(PPVRSRV_CLIENT_MEM_INFO psMemInfo, + PVRSRV_SYNCVAL_MODE eMode, PVRSRV_SYNCVAL OpRequired); + +IMG_IMPORT IMG_BOOL PVRSRVTestAllOpsComplete(PPVRSRV_CLIENT_MEM_INFO psMemInfo, + PVRSRV_SYNCVAL_MODE eMode); + +IMG_IMPORT IMG_BOOL PVRSRVTestOpsNotComplete(PPVRSRV_CLIENT_MEM_INFO psMemInfo, + PVRSRV_SYNCVAL_MODE eMode, PVRSRV_SYNCVAL OpRequired); + +IMG_IMPORT IMG_BOOL PVRSRVTestAllOpsNotComplete(PPVRSRV_CLIENT_MEM_INFO psMemInfo, + PVRSRV_SYNCVAL_MODE eMode); + +IMG_IMPORT PVRSRV_SYNCVAL PVRSRVGetPendingOpSyncVal(PPVRSRV_CLIENT_MEM_INFO psMemInfo, + PVRSRV_SYNCVAL_MODE eMode); + + +IMG_IMPORT +PVRSRV_ERROR IMG_CALLCONV PVRSRVEnumerateDeviceClass(IMG_CONST PVRSRV_CONNECTION *psConnection, + PVRSRV_DEVICE_CLASS DeviceClass, + IMG_UINT32 *pui32DevCount, + IMG_UINT32 *pui32DevID); + +IMG_IMPORT +IMG_HANDLE IMG_CALLCONV PVRSRVOpenDCDevice(IMG_CONST PVRSRV_DEV_DATA *psDevData, + IMG_UINT32 ui32DeviceID); + +IMG_IMPORT +PVRSRV_ERROR IMG_CALLCONV PVRSRVCloseDCDevice(IMG_CONST PVRSRV_CONNECTION *psConnection, IMG_HANDLE hDevice); + +IMG_IMPORT +PVRSRV_ERROR IMG_CALLCONV PVRSRVEnumDCFormats (IMG_HANDLE hDevice, + IMG_UINT32 *pui32Count, + DISPLAY_FORMAT *psFormat); + +IMG_IMPORT +PVRSRV_ERROR IMG_CALLCONV PVRSRVEnumDCDims (IMG_HANDLE hDevice, + IMG_UINT32 *pui32Count, + DISPLAY_FORMAT *psFormat, + DISPLAY_DIMS *psDims); + +IMG_IMPORT +PVRSRV_ERROR IMG_CALLCONV PVRSRVGetDCSystemBuffer(IMG_HANDLE hDevice, + IMG_HANDLE *phBuffer); + +IMG_IMPORT +PVRSRV_ERROR IMG_CALLCONV PVRSRVGetDCInfo(IMG_HANDLE hDevice, + DISPLAY_INFO* psDisplayInfo); + +IMG_IMPORT +PVRSRV_ERROR IMG_CALLCONV PVRSRVCreateDCSwapChain (IMG_HANDLE hDevice, + IMG_UINT32 ui32Flags, + DISPLAY_SURF_ATTRIBUTES *psDstSurfAttrib, + DISPLAY_SURF_ATTRIBUTES *psSrcSurfAttrib, + IMG_UINT32 ui32BufferCount, + IMG_UINT32 ui32OEMFlags, + IMG_UINT32 *pui32SwapChainID, + IMG_HANDLE *phSwapChain); + +IMG_IMPORT +PVRSRV_ERROR IMG_CALLCONV PVRSRVDestroyDCSwapChain (IMG_HANDLE hDevice, + IMG_HANDLE hSwapChain); + +IMG_IMPORT +PVRSRV_ERROR IMG_CALLCONV PVRSRVSetDCDstRect (IMG_HANDLE hDevice, + IMG_HANDLE hSwapChain, + IMG_RECT *psDstRect); + +IMG_IMPORT +PVRSRV_ERROR IMG_CALLCONV PVRSRVSetDCSrcRect (IMG_HANDLE hDevice, + IMG_HANDLE hSwapChain, + IMG_RECT *psSrcRect); + +IMG_IMPORT +PVRSRV_ERROR IMG_CALLCONV PVRSRVSetDCDstColourKey (IMG_HANDLE hDevice, + IMG_HANDLE hSwapChain, + IMG_UINT32 ui32CKColour); + +IMG_IMPORT +PVRSRV_ERROR IMG_CALLCONV PVRSRVSetDCSrcColourKey (IMG_HANDLE hDevice, + IMG_HANDLE hSwapChain, + IMG_UINT32 ui32CKColour); + +IMG_IMPORT +PVRSRV_ERROR IMG_CALLCONV PVRSRVGetDCBuffers(IMG_HANDLE hDevice, + IMG_HANDLE hSwapChain, + IMG_HANDLE *phBuffer); + +IMG_IMPORT +PVRSRV_ERROR IMG_CALLCONV PVRSRVSwapToDCBuffer (IMG_HANDLE hDevice, + IMG_HANDLE hBuffer, + IMG_UINT32 ui32ClipRectCount, + IMG_RECT *psClipRect, + IMG_UINT32 ui32SwapInterval, + IMG_HANDLE hPrivateTag); + +IMG_IMPORT +PVRSRV_ERROR IMG_CALLCONV PVRSRVSwapToDCSystem (IMG_HANDLE hDevice, + IMG_HANDLE hSwapChain); + +IMG_IMPORT +IMG_HANDLE IMG_CALLCONV PVRSRVOpenBCDevice(IMG_CONST PVRSRV_DEV_DATA *psDevData, + IMG_UINT32 ui32DeviceID); + +IMG_IMPORT +PVRSRV_ERROR IMG_CALLCONV PVRSRVCloseBCDevice(IMG_CONST PVRSRV_CONNECTION *psConnection, + IMG_HANDLE hDevice); + +IMG_IMPORT +PVRSRV_ERROR IMG_CALLCONV PVRSRVGetBCBufferInfo(IMG_HANDLE hDevice, + BUFFER_INFO *psBuffer); + +IMG_IMPORT +PVRSRV_ERROR IMG_CALLCONV PVRSRVGetBCBuffer(IMG_HANDLE hDevice, + IMG_UINT32 ui32BufferIndex, + IMG_HANDLE *phBuffer); + + +IMG_IMPORT +PVRSRV_ERROR IMG_CALLCONV PVRSRVPDumpInit(IMG_CONST PVRSRV_CONNECTION *psConnection); + +IMG_IMPORT +PVRSRV_ERROR IMG_CALLCONV PVRSRVPDumpStartInitPhase(IMG_CONST PVRSRV_CONNECTION *psConnection); + +IMG_IMPORT +PVRSRV_ERROR IMG_CALLCONV PVRSRVPDumpStopInitPhase(IMG_CONST PVRSRV_CONNECTION *psConnection); + +IMG_IMPORT +PVRSRV_ERROR IMG_CALLCONV PVRSRVPDumpMemPol(IMG_CONST PVRSRV_CONNECTION *psConnection, + PVRSRV_CLIENT_MEM_INFO *psMemInfo, + IMG_UINT32 ui32Offset, + IMG_UINT32 ui32Value, + IMG_UINT32 ui32Mask, + IMG_BOOL bLastFrame, + IMG_BOOL bOverwrite); + +IMG_IMPORT +PVRSRV_ERROR IMG_CALLCONV PVRSRVPDumpSyncPol(IMG_CONST PVRSRV_CONNECTION *psConnection, + PVRSRV_CLIENT_SYNC_INFO *psClientSyncInfo, + IMG_BOOL bIsRead, + IMG_UINT32 ui32Value, + IMG_UINT32 ui32Mask); + +IMG_IMPORT +PVRSRV_ERROR IMG_CALLCONV PVRSRVPDumpMem(IMG_CONST PVRSRV_CONNECTION *psConnection, + IMG_PVOID pvAltLinAddr, + PVRSRV_CLIENT_MEM_INFO *psMemInfo, + IMG_UINT32 ui32Offset, + IMG_UINT32 ui32Bytes, + IMG_UINT32 ui32Flags); + +IMG_IMPORT +PVRSRV_ERROR IMG_CALLCONV PVRSRVPDumpSync(IMG_CONST PVRSRV_CONNECTION *psConnection, + IMG_PVOID pvAltLinAddr, + PVRSRV_CLIENT_SYNC_INFO *psClientSyncInfo, + IMG_UINT32 ui32Offset, + IMG_UINT32 ui32Bytes); + +IMG_IMPORT +PVRSRV_ERROR IMG_CALLCONV PVRSRVPDumpReg(IMG_CONST PVRSRV_CONNECTION *psConnection, + IMG_UINT32 ui32RegAddr, + IMG_UINT32 ui32RegValue, + IMG_UINT32 ui32Flags); + +IMG_IMPORT +PVRSRV_ERROR IMG_CALLCONV PVRSRVPDumpRegPolWithFlags(IMG_CONST PVRSRV_CONNECTION *psConnection, + IMG_UINT32 ui32RegAddr, + IMG_UINT32 ui32RegValue, + IMG_UINT32 ui32Mask, + IMG_UINT32 ui32Flags); +IMG_IMPORT +PVRSRV_ERROR IMG_CALLCONV PVRSRVPDumpRegPol(IMG_CONST PVRSRV_CONNECTION *psConnection, + IMG_UINT32 ui32RegAddr, + IMG_UINT32 ui32RegValue, + IMG_UINT32 ui32Mask); + +IMG_IMPORT +PVRSRV_ERROR IMG_CALLCONV PVRSRVPDumpPDReg(IMG_CONST PVRSRV_CONNECTION *psConnection, + IMG_UINT32 ui32RegAddr, + IMG_UINT32 ui32RegValue); +IMG_IMPORT +PVRSRV_ERROR IMG_CALLCONV PVRSRVPDumpPDDevPAddr(IMG_CONST PVRSRV_CONNECTION *psConnection, + PVRSRV_CLIENT_MEM_INFO *psMemInfo, + IMG_UINT32 ui32Offset, + IMG_DEV_PHYADDR sPDDevPAddr); + +IMG_IMPORT +PVRSRV_ERROR IMG_CALLCONV PVRSRVPDumpMemPages(IMG_CONST PVRSRV_CONNECTION *psConnection, + IMG_HANDLE hKernelMemInfo, + IMG_DEV_PHYADDR *pPages, + IMG_UINT32 ui32NumPages, + IMG_DEV_VIRTADDR sDevAddr, + IMG_UINT32 ui32Start, + IMG_UINT32 ui32Length, + IMG_BOOL bContinuous); + +IMG_IMPORT +PVRSRV_ERROR IMG_CALLCONV PVRSRVPDumpSetFrame(IMG_CONST PVRSRV_CONNECTION *psConnection, + IMG_UINT32 ui32Frame); + +IMG_IMPORT +PVRSRV_ERROR IMG_CALLCONV PVRSRVPDumpComment(IMG_CONST PVRSRV_CONNECTION *psConnection, + IMG_CONST IMG_CHAR *pszComment, + IMG_BOOL bContinuous); + +IMG_IMPORT +PVRSRV_ERROR IMG_CALLCONV PVRSRVPDumpCommentf(IMG_CONST PVRSRV_CONNECTION *psConnection, + IMG_BOOL bContinuous, + IMG_CONST IMG_CHAR *pszFormat, ...); + +IMG_IMPORT +PVRSRV_ERROR IMG_CALLCONV PVRSRVPDumpCommentWithFlagsf(IMG_CONST PVRSRV_CONNECTION *psConnection, + IMG_UINT32 ui32Flags, + IMG_CONST IMG_CHAR *pszFormat, ...); + +IMG_IMPORT +PVRSRV_ERROR IMG_CALLCONV PVRSRVPDumpDriverInfo(IMG_CONST PVRSRV_CONNECTION *psConnection, + IMG_CHAR *pszString, + IMG_BOOL bContinuous); + +IMG_IMPORT +PVRSRV_ERROR IMG_CALLCONV PVRSRVPDumpIsCapturing(IMG_CONST PVRSRV_CONNECTION *psConnection, + IMG_BOOL *pbIsCapturing); + +IMG_IMPORT +PVRSRV_ERROR IMG_CALLCONV PVRSRVPDumpBitmap(IMG_CONST PVRSRV_CONNECTION *psConnection, + IMG_CHAR *pszFileName, + IMG_UINT32 ui32FileOffset, + IMG_UINT32 ui32Width, + IMG_UINT32 ui32Height, + IMG_UINT32 ui32StrideInBytes, + IMG_DEV_VIRTADDR sDevBaseAddr, + IMG_UINT32 ui32Size, + PDUMP_PIXEL_FORMAT ePixelFormat, + PDUMP_MEM_FORMAT eMemFormat, + IMG_UINT32 ui32PDumpFlags); + +IMG_IMPORT +PVRSRV_ERROR IMG_CALLCONV PVRSRVPDumpRegRead(IMG_CONST PVRSRV_CONNECTION *psConnection, + IMG_CONST IMG_CHAR *pszFileName, + IMG_UINT32 ui32FileOffset, + IMG_UINT32 ui32Address, + IMG_UINT32 ui32Size, + IMG_UINT32 ui32PDumpFlags); + + +IMG_IMPORT +IMG_BOOL IMG_CALLCONV PVRSRVPDumpIsCapturingTest(IMG_CONST PVRSRV_CONNECTION *psConnection); + +IMG_IMPORT +PVRSRV_ERROR IMG_CALLCONV PVRSRVPDumpCycleCountRegRead(IMG_CONST PVRSRV_CONNECTION *psConnection, + IMG_UINT32 ui32RegOffset, + IMG_BOOL bLastFrame); + +IMG_IMPORT IMG_HANDLE PVRSRVLoadLibrary(const IMG_CHAR *pszLibraryName); +IMG_IMPORT PVRSRV_ERROR PVRSRVUnloadLibrary(IMG_HANDLE hExtDrv); +IMG_IMPORT PVRSRV_ERROR PVRSRVGetLibFuncAddr(IMG_HANDLE hExtDrv, const IMG_CHAR *pszFunctionName, IMG_VOID **ppvFuncAddr); + +IMG_IMPORT IMG_UINT32 PVRSRVClockus (void); +IMG_IMPORT IMG_VOID PVRSRVWaitus (IMG_UINT32 ui32Timeus); +IMG_IMPORT IMG_VOID PVRSRVReleaseThreadQuanta (void); +IMG_IMPORT IMG_UINT32 IMG_CALLCONV PVRSRVGetCurrentProcessID(void); +IMG_IMPORT IMG_CHAR * IMG_CALLCONV PVRSRVSetLocale(const IMG_CHAR *pszLocale); + + + + + +IMG_IMPORT IMG_VOID IMG_CALLCONV PVRSRVCreateAppHintState(IMG_MODULE_ID eModuleID, + const IMG_CHAR *pszAppName, + IMG_VOID **ppvState); +IMG_IMPORT IMG_VOID IMG_CALLCONV PVRSRVFreeAppHintState(IMG_MODULE_ID eModuleID, + IMG_VOID *pvHintState); + +IMG_IMPORT IMG_BOOL IMG_CALLCONV PVRSRVGetAppHint(IMG_VOID *pvHintState, + const IMG_CHAR *pszHintName, + IMG_DATA_TYPE eDataType, + const IMG_VOID *pvDefault, + IMG_VOID *pvReturn); + +IMG_IMPORT IMG_PVOID IMG_CALLCONV PVRSRVAllocUserModeMem (IMG_UINT32 ui32Size); +IMG_IMPORT IMG_PVOID IMG_CALLCONV PVRSRVCallocUserModeMem (IMG_UINT32 ui32Size); +IMG_IMPORT IMG_PVOID IMG_CALLCONV PVRSRVReallocUserModeMem (IMG_PVOID pvBase, IMG_SIZE_T uNewSize); +IMG_IMPORT IMG_VOID IMG_CALLCONV PVRSRVFreeUserModeMem (IMG_PVOID pvMem); +IMG_IMPORT IMG_VOID PVRSRVMemCopy(IMG_VOID *pvDst, const IMG_VOID *pvSrc, IMG_UINT32 ui32Size); +IMG_IMPORT IMG_VOID PVRSRVMemSet(IMG_VOID *pvDest, IMG_UINT8 ui8Value, IMG_UINT32 ui32Size); + +struct _PVRSRV_MUTEX_OPAQUE_STRUCT_; +typedef struct _PVRSRV_MUTEX_OPAQUE_STRUCT_ *PVRSRV_MUTEX_HANDLE; + +IMG_IMPORT PVRSRV_ERROR IMG_CALLCONV PVRSRVCreateMutex(PVRSRV_MUTEX_HANDLE *phMutex); +IMG_IMPORT PVRSRV_ERROR IMG_CALLCONV PVRSRVDestroyMutex(PVRSRV_MUTEX_HANDLE hMutex); +IMG_IMPORT IMG_VOID IMG_CALLCONV PVRSRVLockMutex(PVRSRV_MUTEX_HANDLE hMutex); +IMG_IMPORT IMG_VOID IMG_CALLCONV PVRSRVUnlockMutex(PVRSRV_MUTEX_HANDLE hMutex); + +#if (defined(DEBUG) && defined(__linux__)) +IMG_PVOID PVRSRVAllocUserModeMemTracking(IMG_UINT32 ui32Size, IMG_CHAR *pszFileName, IMG_UINT32 ui32LineNumber); +IMG_PVOID PVRSRVCallocUserModeMemTracking(IMG_UINT32 ui32Size, IMG_CHAR *pszFileName, IMG_UINT32 ui32LineNumber); +IMG_VOID PVRSRVFreeUserModeMemTracking(IMG_VOID *pvMem); +IMG_PVOID PVRSRVReallocUserModeMemTracking(IMG_VOID *pvMem, IMG_UINT32 ui32NewSize, IMG_CHAR *pszFileName, IMG_UINT32 ui32LineNumber); +#endif + +IMG_IMPORT PVRSRV_ERROR PVRSRVEventObjectWait(const PVRSRV_CONNECTION *psConnection, + IMG_HANDLE hOSEvent); + +IMG_IMPORT +PVRSRV_ERROR IMG_CALLCONV PVRSRVModifySyncOps(PVRSRV_CONNECTION *psConnection, + IMG_HANDLE hKernelSyncInfo, + IMG_UINT32 ui32ModifyFlags, + IMG_UINT32 *pui32ReadOpsPending, + IMG_UINT32 *pui32WriteOpsPending, + IMG_UINT32 *pui32ReadOpsComplete, + IMG_UINT32 *pui32WriteOpsComplete); + +#define TIME_NOT_PASSED_UINT32(a,b,c) ((a - b) < c) + +#if defined (__cplusplus) +} +#endif +#endif + diff --git a/include4/servicesext.h b/include4/servicesext.h new file mode 100644 index 0000000..947f354 --- /dev/null +++ b/include4/servicesext.h @@ -0,0 +1,557 @@ +/********************************************************************** + * + * Copyright(c) 2008 Imagination Technologies Ltd. All rights reserved. + * + * This program is free software; you can redistribute it and/or modify it + * under the terms and conditions of the GNU General Public License, + * version 2, as published by the Free Software Foundation. + * + * This program is distributed in the hope it will be useful but, except + * as otherwise stated in writing, without any warranty; without even the + * implied warranty of merchantability or fitness for a particular purpose. + * See the GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License along with + * this program; if not, write to the Free Software Foundation, Inc., + * 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA. + * + * The full GNU General Public License is included in this distribution in + * the file called "COPYING". + * + * Contact Information: + * Imagination Technologies Ltd. + * Home Park Estate, Kings Langley, Herts, WD4 8LZ, UK + * + ******************************************************************************/ + +#if !defined (__SERVICESEXT_H__) +#define __SERVICESEXT_H__ + +#define PVRSRV_LOCKFLG_READONLY (1) + +typedef enum _PVRSRV_ERROR_ +{ + PVRSRV_OK = 0, + PVRSRV_ERROR_GENERIC = 1, + PVRSRV_ERROR_OUT_OF_MEMORY = 2, + PVRSRV_ERROR_TOO_FEW_BUFFERS = 3, + PVRSRV_ERROR_SYMBOL_NOT_FOUND = 4, + PVRSRV_ERROR_OUT_OF_HSPACE = 5, + PVRSRV_ERROR_INVALID_PARAMS = 6, + PVRSRV_ERROR_TILE_MAP_FAILED = 7, + PVRSRV_ERROR_INIT_FAILURE = 8, + PVRSRV_ERROR_CANT_REGISTER_CALLBACK = 9, + PVRSRV_ERROR_INVALID_DEVICE = 10, + PVRSRV_ERROR_NOT_OWNER = 11, + PVRSRV_ERROR_BAD_MAPPING = 12, + PVRSRV_ERROR_TIMEOUT = 13, + PVRSRV_ERROR_NO_PRIMARY = 14, + PVRSRV_ERROR_FLIP_CHAIN_EXISTS = 15, + PVRSRV_ERROR_CANNOT_ACQUIRE_SYSDATA = 16, + PVRSRV_ERROR_SCENE_INVALID = 17, + PVRSRV_ERROR_STREAM_ERROR = 18, + PVRSRV_ERROR_INVALID_INTERRUPT = 19, + PVRSRV_ERROR_FAILED_DEPENDENCIES = 20, + PVRSRV_ERROR_CMD_NOT_PROCESSED = 21, + PVRSRV_ERROR_CMD_TOO_BIG = 22, + PVRSRV_ERROR_DEVICE_REGISTER_FAILED = 23, + PVRSRV_ERROR_FIFO_SPACE = 24, + PVRSRV_ERROR_TA_RECOVERY = 25, + PVRSRV_ERROR_INDOSORLOWPOWER = 26, + PVRSRV_ERROR_TOOMANYBUFFERS = 27, + PVRSRV_ERROR_NOT_SUPPORTED = 28, + PVRSRV_ERROR_PROCESSING_BLOCKED = 29, + + + PVRSRV_ERROR_CANNOT_FLUSH_QUEUE = 31, + PVRSRV_ERROR_CANNOT_GET_QUEUE_SPACE = 32, + PVRSRV_ERROR_CANNOT_GET_RENDERDETAILS = 33, + PVRSRV_ERROR_RETRY = 34, + + PVRSRV_ERROR_DDK_VERSION_MISMATCH = 35, + PVRSRV_ERROR_BUILD_MISMATCH = 36, + + PVRSRV_ERROR_FORCE_I32 = 0x7fffffff + +} PVRSRV_ERROR; + + +typedef enum _PVRSRV_DEVICE_CLASS_ +{ + PVRSRV_DEVICE_CLASS_3D = 0 , + PVRSRV_DEVICE_CLASS_DISPLAY = 1 , + PVRSRV_DEVICE_CLASS_BUFFER = 2 , + PVRSRV_DEVICE_CLASS_VIDEO = 3 , + + PVRSRV_DEVICE_CLASS_FORCE_I32 = 0x7fffffff + +} PVRSRV_DEVICE_CLASS; + + + +typedef enum _PVRSRV_POWER_STATE_ +{ + PVRSRV_POWER_Unspecified = -1, + PVRSRV_POWER_STATE_D0 = 0, + PVRSRV_POWER_STATE_D1 = 1, + PVRSRV_POWER_STATE_D2 = 2, + PVRSRV_POWER_STATE_D3 = 3, + PVRSRV_POWER_STATE_D4 = 4, + + PVRSRV_POWER_STATE_FORCE_I32 = 0x7fffffff + +} PVR_POWER_STATE, *PPVR_POWER_STATE; + + +typedef PVRSRV_ERROR (*PFN_PRE_POWER) (IMG_HANDLE, PVR_POWER_STATE, PVR_POWER_STATE); +typedef PVRSRV_ERROR (*PFN_POST_POWER) (IMG_HANDLE, PVR_POWER_STATE, PVR_POWER_STATE); + +typedef PVRSRV_ERROR (*PFN_PRE_CLOCKSPEED_CHANGE) (IMG_HANDLE, IMG_BOOL, PVR_POWER_STATE); +typedef PVRSRV_ERROR (*PFN_POST_CLOCKSPEED_CHANGE) (IMG_HANDLE, IMG_BOOL, PVR_POWER_STATE); + + +typedef enum _PVRSRV_PIXEL_FORMAT_ { + + PVRSRV_PIXEL_FORMAT_UNKNOWN = 0, + PVRSRV_PIXEL_FORMAT_RGB565 = 1, + PVRSRV_PIXEL_FORMAT_RGB555 = 2, + PVRSRV_PIXEL_FORMAT_RGB888 = 3, + PVRSRV_PIXEL_FORMAT_BGR888 = 4, + PVRSRV_PIXEL_FORMAT_GREY_SCALE = 8, + PVRSRV_PIXEL_FORMAT_PAL12 = 13, + PVRSRV_PIXEL_FORMAT_PAL8 = 14, + PVRSRV_PIXEL_FORMAT_PAL4 = 15, + PVRSRV_PIXEL_FORMAT_PAL2 = 16, + PVRSRV_PIXEL_FORMAT_PAL1 = 17, + PVRSRV_PIXEL_FORMAT_ARGB1555 = 18, + PVRSRV_PIXEL_FORMAT_ARGB4444 = 19, + PVRSRV_PIXEL_FORMAT_ARGB8888 = 20, + PVRSRV_PIXEL_FORMAT_ABGR8888 = 21, + PVRSRV_PIXEL_FORMAT_YV12 = 22, + PVRSRV_PIXEL_FORMAT_I420 = 23, + PVRSRV_PIXEL_FORMAT_IMC2 = 25, + PVRSRV_PIXEL_FORMAT_XRGB8888, + PVRSRV_PIXEL_FORMAT_XBGR8888, + PVRSRV_PIXEL_FORMAT_XRGB4444, + PVRSRV_PIXEL_FORMAT_ARGB8332, + PVRSRV_PIXEL_FORMAT_A2RGB10, + PVRSRV_PIXEL_FORMAT_A2BGR10, + PVRSRV_PIXEL_FORMAT_P8, + PVRSRV_PIXEL_FORMAT_L8, + PVRSRV_PIXEL_FORMAT_A8L8, + PVRSRV_PIXEL_FORMAT_A4L4, + PVRSRV_PIXEL_FORMAT_L16, + PVRSRV_PIXEL_FORMAT_L6V5U5, + PVRSRV_PIXEL_FORMAT_V8U8, + PVRSRV_PIXEL_FORMAT_V16U16, + PVRSRV_PIXEL_FORMAT_QWVU8888, + PVRSRV_PIXEL_FORMAT_XLVU8888, + PVRSRV_PIXEL_FORMAT_QWVU16, + PVRSRV_PIXEL_FORMAT_D16, + PVRSRV_PIXEL_FORMAT_D24S8, + PVRSRV_PIXEL_FORMAT_D24X8, + + + PVRSRV_PIXEL_FORMAT_ABGR16, + PVRSRV_PIXEL_FORMAT_ABGR16F, + PVRSRV_PIXEL_FORMAT_ABGR32, + PVRSRV_PIXEL_FORMAT_ABGR32F, + PVRSRV_PIXEL_FORMAT_B10GR11, + PVRSRV_PIXEL_FORMAT_GR88, + PVRSRV_PIXEL_FORMAT_BGR32, + PVRSRV_PIXEL_FORMAT_GR32, + PVRSRV_PIXEL_FORMAT_E5BGR9, + + + PVRSRV_PIXEL_FORMAT_DXT1, + PVRSRV_PIXEL_FORMAT_DXT23, + PVRSRV_PIXEL_FORMAT_DXT45, + + + PVRSRV_PIXEL_FORMAT_R8G8_B8G8, + PVRSRV_PIXEL_FORMAT_G8R8_G8B8, + + + PVRSRV_PIXEL_FORMAT_NV11, + PVRSRV_PIXEL_FORMAT_NV12, + + + PVRSRV_PIXEL_FORMAT_YUY2, + PVRSRV_PIXEL_FORMAT_YUV420, + PVRSRV_PIXEL_FORMAT_YUV444, + PVRSRV_PIXEL_FORMAT_VUY444, + PVRSRV_PIXEL_FORMAT_YUYV, + PVRSRV_PIXEL_FORMAT_YVYU, + PVRSRV_PIXEL_FORMAT_UYVY, + PVRSRV_PIXEL_FORMAT_VYUY, + + PVRSRV_PIXEL_FORMAT_FOURCC_ORG_UYVY, + PVRSRV_PIXEL_FORMAT_FOURCC_ORG_YUYV, + PVRSRV_PIXEL_FORMAT_FOURCC_ORG_YVYU, + PVRSRV_PIXEL_FORMAT_FOURCC_ORG_VYUY, + + + PVRSRV_PIXEL_FORMAT_A32B32G32R32, + PVRSRV_PIXEL_FORMAT_A32B32G32R32F, + PVRSRV_PIXEL_FORMAT_A32B32G32R32_UINT, + PVRSRV_PIXEL_FORMAT_A32B32G32R32_SINT, + + + PVRSRV_PIXEL_FORMAT_B32G32R32, + PVRSRV_PIXEL_FORMAT_B32G32R32F, + PVRSRV_PIXEL_FORMAT_B32G32R32_UINT, + PVRSRV_PIXEL_FORMAT_B32G32R32_SINT, + + + PVRSRV_PIXEL_FORMAT_G32R32, + PVRSRV_PIXEL_FORMAT_G32R32F, + PVRSRV_PIXEL_FORMAT_G32R32_UINT, + PVRSRV_PIXEL_FORMAT_G32R32_SINT, + + + PVRSRV_PIXEL_FORMAT_D32F, + PVRSRV_PIXEL_FORMAT_R32, + PVRSRV_PIXEL_FORMAT_R32F, + PVRSRV_PIXEL_FORMAT_R32_UINT, + PVRSRV_PIXEL_FORMAT_R32_SINT, + + + PVRSRV_PIXEL_FORMAT_A16B16G16R16, + PVRSRV_PIXEL_FORMAT_A16B16G16R16F, + PVRSRV_PIXEL_FORMAT_A16B16G16R16_SINT, + PVRSRV_PIXEL_FORMAT_A16B16G16R16_SNORM, + PVRSRV_PIXEL_FORMAT_A16B16G16R16_UINT, + PVRSRV_PIXEL_FORMAT_A16B16G16R16_UNORM, + + + PVRSRV_PIXEL_FORMAT_G16R16, + PVRSRV_PIXEL_FORMAT_G16R16F, + PVRSRV_PIXEL_FORMAT_G16R16_UINT, + PVRSRV_PIXEL_FORMAT_G16R16_UNORM, + PVRSRV_PIXEL_FORMAT_G16R16_SINT, + PVRSRV_PIXEL_FORMAT_G16R16_SNORM, + + + PVRSRV_PIXEL_FORMAT_R16, + PVRSRV_PIXEL_FORMAT_R16F, + PVRSRV_PIXEL_FORMAT_R16_UINT, + PVRSRV_PIXEL_FORMAT_R16_UNORM, + PVRSRV_PIXEL_FORMAT_R16_SINT, + PVRSRV_PIXEL_FORMAT_R16_SNORM, + + + PVRSRV_PIXEL_FORMAT_A8B8G8R8, + PVRSRV_PIXEL_FORMAT_A8B8G8R8_UINT, + PVRSRV_PIXEL_FORMAT_A8B8G8R8_UNORM, + PVRSRV_PIXEL_FORMAT_A8B8G8R8_SINT, + PVRSRV_PIXEL_FORMAT_A8B8G8R8_SNORM, + + + PVRSRV_PIXEL_FORMAT_G8R8, + PVRSRV_PIXEL_FORMAT_G8R8_UINT, + PVRSRV_PIXEL_FORMAT_G8R8_UNORM, + PVRSRV_PIXEL_FORMAT_G8R8_SINT, + PVRSRV_PIXEL_FORMAT_G8R8_SNORM, + + + PVRSRV_PIXEL_FORMAT_A8, + PVRSRV_PIXEL_FORMAT_R8, + PVRSRV_PIXEL_FORMAT_R8_UINT, + PVRSRV_PIXEL_FORMAT_R8_UNORM, + PVRSRV_PIXEL_FORMAT_R8_SINT, + PVRSRV_PIXEL_FORMAT_R8_SNORM, + + + PVRSRV_PIXEL_FORMAT_A2B10G10R10, + PVRSRV_PIXEL_FORMAT_A2B10G10R10_UNORM, + PVRSRV_PIXEL_FORMAT_A2B10G10R10_UINT, + + + PVRSRV_PIXEL_FORMAT_B10G11R11, + PVRSRV_PIXEL_FORMAT_B10G11R11F, + + + PVRSRV_PIXEL_FORMAT_X24G8R32, + PVRSRV_PIXEL_FORMAT_G8R24, + PVRSRV_PIXEL_FORMAT_E5B9G9R9, + PVRSRV_PIXEL_FORMAT_R1, + + PVRSRV_PIXEL_FORMAT_BC1, + PVRSRV_PIXEL_FORMAT_BC1_UNORM, + PVRSRV_PIXEL_FORMAT_BC1_SRGB, + PVRSRV_PIXEL_FORMAT_BC2, + PVRSRV_PIXEL_FORMAT_BC2_UNORM, + PVRSRV_PIXEL_FORMAT_BC2_SRGB, + PVRSRV_PIXEL_FORMAT_BC3, + PVRSRV_PIXEL_FORMAT_BC3_UNORM, + PVRSRV_PIXEL_FORMAT_BC3_SRGB, + PVRSRV_PIXEL_FORMAT_BC4, + PVRSRV_PIXEL_FORMAT_BC4_UNORM, + PVRSRV_PIXEL_FORMAT_BC4_SNORM, + PVRSRV_PIXEL_FORMAT_BC5, + PVRSRV_PIXEL_FORMAT_BC5_UNORM, + PVRSRV_PIXEL_FORMAT_BC5_SNORM, + + PVRSRV_PIXEL_FORMAT_FORCE_I32 = 0x7fffffff, +} PVRSRV_PIXEL_FORMAT; + +typedef enum _PVRSRV_ALPHA_FORMAT_ { + PVRSRV_ALPHA_FORMAT_UNKNOWN = 0x00000000, + PVRSRV_ALPHA_FORMAT_PRE = 0x00000001, + PVRSRV_ALPHA_FORMAT_NONPRE = 0x00000002, + PVRSRV_ALPHA_FORMAT_MASK = 0x0000000F, +} PVRSRV_ALPHA_FORMAT; + +typedef enum _PVRSRV_COLOURSPACE_FORMAT_ { + PVRSRV_COLOURSPACE_FORMAT_UNKNOWN = 0x00000000, + PVRSRV_COLOURSPACE_FORMAT_LINEAR = 0x00010000, + PVRSRV_COLOURSPACE_FORMAT_NONLINEAR = 0x00020000, + PVRSRV_COLOURSPACE_FORMAT_MASK = 0x000F0000, +} PVRSRV_COLOURSPACE_FORMAT; + + +typedef enum _PVRSRV_ROTATION_ { + PVRSRV_ROTATE_0 = 0, + PVRSRV_ROTATE_90 = 1, + PVRSRV_ROTATE_180 = 2, + PVRSRV_ROTATE_270 = 3, + PVRSRV_FLIP_Y + +} PVRSRV_ROTATION; + +#define PVRSRV_CREATE_SWAPCHAIN_SHARED (1<<0) +#define PVRSRV_CREATE_SWAPCHAIN_QUERY (1<<1) +#define PVRSRV_CREATE_SWAPCHAIN_OEMOVERLAY (1<<2) + +typedef struct _PVRSRV_SYNC_DATA_ +{ + + IMG_UINT32 ui32WriteOpsPending; + volatile IMG_UINT32 ui32WriteOpsComplete; + + + IMG_UINT32 ui32ReadOpsPending; + volatile IMG_UINT32 ui32ReadOpsComplete; + + + IMG_UINT32 ui32LastOpDumpVal; + IMG_UINT32 ui32LastReadOpDumpVal; + +} PVRSRV_SYNC_DATA; + +typedef struct _PVRSRV_CLIENT_SYNC_INFO_ +{ + + PVRSRV_SYNC_DATA *psSyncData; + + + + + + IMG_DEV_VIRTADDR sWriteOpsCompleteDevVAddr; + + + IMG_DEV_VIRTADDR sReadOpsCompleteDevVAddr; + + + IMG_HANDLE hMappingInfo; + + + IMG_HANDLE hKernelSyncInfo; + +} PVRSRV_CLIENT_SYNC_INFO, *PPVRSRV_CLIENT_SYNC_INFO; + + +typedef struct PVRSRV_RESOURCE_TAG +{ + volatile IMG_UINT32 ui32Lock; + IMG_UINT32 ui32ID; +}PVRSRV_RESOURCE; +typedef PVRSRV_RESOURCE PVRSRV_RES_HANDLE; + + +typedef IMG_VOID (*PFN_CMD_COMPLETE) (IMG_HANDLE); +typedef IMG_VOID (**PPFN_CMD_COMPLETE) (IMG_HANDLE); + +typedef IMG_BOOL (*PFN_CMD_PROC) (IMG_HANDLE, IMG_UINT32, IMG_VOID*); +typedef IMG_BOOL (**PPFN_CMD_PROC) (IMG_HANDLE, IMG_UINT32, IMG_VOID*); + + +typedef struct _IMG_RECT_ +{ + IMG_INT32 x0; + IMG_INT32 y0; + IMG_INT32 x1; + IMG_INT32 y1; +}IMG_RECT; + +typedef struct _IMG_RECT_16_ +{ + IMG_INT16 x0; + IMG_INT16 y0; + IMG_INT16 x1; + IMG_INT16 y1; +}IMG_RECT_16; + + +typedef PVRSRV_ERROR (*PFN_GET_BUFFER_ADDR)(IMG_HANDLE, + IMG_HANDLE, + IMG_SYS_PHYADDR**, + IMG_UINT32*, + IMG_VOID**, + IMG_HANDLE*, + IMG_BOOL*); + + +typedef struct DISPLAY_DIMS_TAG +{ + IMG_UINT32 ui32ByteStride; + IMG_UINT32 ui32Width; + IMG_UINT32 ui32Height; +} DISPLAY_DIMS; + + +typedef struct DISPLAY_FORMAT_TAG +{ + + PVRSRV_PIXEL_FORMAT pixelformat; +} DISPLAY_FORMAT; + +typedef struct DISPLAY_SURF_ATTRIBUTES_TAG +{ + + PVRSRV_PIXEL_FORMAT pixelformat; + + DISPLAY_DIMS sDims; +} DISPLAY_SURF_ATTRIBUTES; + + +typedef struct DISPLAY_MODE_INFO_TAG +{ + + PVRSRV_PIXEL_FORMAT pixelformat; + + DISPLAY_DIMS sDims; + + IMG_UINT32 ui32RefreshHZ; + + IMG_UINT32 ui32OEMFlags; +} DISPLAY_MODE_INFO; + + + +#define MAX_DISPLAY_NAME_SIZE (50) + +typedef struct DISPLAY_INFO_TAG +{ + IMG_UINT32 ui32MaxSwapChains; + + IMG_UINT32 ui32MaxSwapChainBuffers; + + IMG_UINT32 ui32MinSwapInterval; + + IMG_UINT32 ui32MaxSwapInterval; + + IMG_CHAR szDisplayName[MAX_DISPLAY_NAME_SIZE]; + +#if defined(SUPPORT_HW_CURSOR) + IMG_UINT16 ui32CursorWidth; + IMG_UINT16 ui32CursorHeight; +#endif + +} DISPLAY_INFO; + +typedef struct ACCESS_INFO_TAG +{ + IMG_UINT32 ui32Size; + IMG_UINT32 ui32FBPhysBaseAddress; + IMG_UINT32 ui32FBMemAvailable; + IMG_UINT32 ui32SysPhysBaseAddress; + IMG_UINT32 ui32SysSize; + IMG_UINT32 ui32DevIRQ; +}ACCESS_INFO; + + +typedef struct PVRSRV_CURSOR_SHAPE_TAG +{ + IMG_UINT16 ui16Width; + IMG_UINT16 ui16Height; + IMG_INT16 i16XHot; + IMG_INT16 i16YHot; + + + IMG_VOID* pvMask; + IMG_INT16 i16MaskByteStride; + + + IMG_VOID* pvColour; + IMG_INT16 i16ColourByteStride; + PVRSRV_PIXEL_FORMAT eColourPixelFormat; +} PVRSRV_CURSOR_SHAPE; + +#define PVRSRV_SET_CURSOR_VISIBILITY (1<<0) +#define PVRSRV_SET_CURSOR_POSITION (1<<1) +#define PVRSRV_SET_CURSOR_SHAPE (1<<2) +#define PVRSRV_SET_CURSOR_ROTATION (1<<3) + +typedef struct PVRSRV_CURSOR_INFO_TAG +{ + + IMG_UINT32 ui32Flags; + + + IMG_BOOL bVisible; + + + IMG_INT16 i16XPos; + IMG_INT16 i16YPos; + + + PVRSRV_CURSOR_SHAPE sCursorShape; + + + IMG_UINT32 ui32Rotation; + +} PVRSRV_CURSOR_INFO; + + +typedef struct _PVRSRV_REGISTRY_INFO_ +{ + IMG_UINT32 ui32DevCookie; + IMG_PCHAR pszKey; + IMG_PCHAR pszValue; + IMG_PCHAR pszBuf; + IMG_UINT32 ui32BufSize; +} PVRSRV_REGISTRY_INFO, *PPVRSRV_REGISTRY_INFO; + + +PVRSRV_ERROR IMG_CALLCONV PVRSRVReadRegistryString (PPVRSRV_REGISTRY_INFO psRegInfo); +PVRSRV_ERROR IMG_CALLCONV PVRSRVWriteRegistryString (PPVRSRV_REGISTRY_INFO psRegInfo); + + +#define PVRSRV_BC_FLAGS_YUVCSC_CONFORMANT_RANGE (0 << 0) +#define PVRSRV_BC_FLAGS_YUVCSC_FULL_RANGE (1 << 0) + +#define PVRSRV_BC_FLAGS_YUVCSC_BT601 (0 << 1) +#define PVRSRV_BC_FLAGS_YUVCSC_BT709 (1 << 1) + +typedef struct BUFFER_INFO_TAG +{ + IMG_UINT32 ui32BufferCount; + IMG_UINT32 ui32BufferDeviceID; + PVRSRV_PIXEL_FORMAT pixelformat; + IMG_UINT32 ui32ByteStride; + IMG_UINT32 ui32Width; + IMG_UINT32 ui32Height; + IMG_UINT32 ui32Flags; +} BUFFER_INFO; + +typedef enum _OVERLAY_DEINTERLACE_MODE_ +{ + WEAVE=0x0, + BOB_ODD, + BOB_EVEN, + BOB_EVEN_NONINTERLEAVED +} OVERLAY_DEINTERLACE_MODE; + +#endif diff --git a/include4/sgx_options.h b/include4/sgx_options.h new file mode 100644 index 0000000..dfafbd7 --- /dev/null +++ b/include4/sgx_options.h @@ -0,0 +1,234 @@ +/********************************************************************** + * + * Copyright(c) 2008 Imagination Technologies Ltd. All rights reserved. + * + * This program is free software; you can redistribute it and/or modify it + * under the terms and conditions of the GNU General Public License, + * version 2, as published by the Free Software Foundation. + * + * This program is distributed in the hope it will be useful but, except + * as otherwise stated in writing, without any warranty; without even the + * implied warranty of merchantability or fitness for a particular purpose. + * See the GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License along with + * this program; if not, write to the Free Software Foundation, Inc., + * 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA. + * + * The full GNU General Public License is included in this distribution in + * the file called "COPYING". + * + * Contact Information: + * Imagination Technologies Ltd. + * Home Park Estate, Kings Langley, Herts, WD4 8LZ, UK + * + ******************************************************************************/ + +#if defined(DEBUG) || defined (INTERNAL_TEST) +#define DEBUG_SET_OFFSET OPTIONS_BIT0 +#define OPTIONS_BIT0 0x1 +#else +#define OPTIONS_BIT0 0x0 +#endif + +#if defined(PDUMP) || defined (INTERNAL_TEST) +#define PDUMP_SET_OFFSET OPTIONS_BIT1 +#define OPTIONS_BIT1 (0x1 << 1) +#else +#define OPTIONS_BIT1 0x0 +#endif + +#if defined(PVRSRV_USSE_EDM_STATUS_DEBUG) || defined (INTERNAL_TEST) +#define PVRSRV_USSE_EDM_STATUS_DEBUG_SET_OFFSET OPTIONS_BIT2 +#define OPTIONS_BIT2 (0x1 << 2) +#else +#define OPTIONS_BIT2 0x0 +#endif + +#if defined(SUPPORT_HW_RECOVERY) || defined (INTERNAL_TEST) +#define SUPPORT_HW_RECOVERY_SET_OFFSET OPTIONS_BIT3 +#define OPTIONS_BIT3 (0x1 << 3) +#else +#define OPTIONS_BIT3 0x0 +#endif + + + +#if defined(PVR_SECURE_HANDLES) || defined (INTERNAL_TEST) +#define PVR_SECURE_HANDLES_SET_OFFSET OPTIONS_BIT4 +#define OPTIONS_BIT4 (0x1 << 4) +#else +#define OPTIONS_BIT4 0x0 +#endif + +#if defined(SGX_BYPASS_SYSTEM_CACHE) || defined (INTERNAL_TEST) +#define SGX_BYPASS_SYSTEM_CACHE_SET_OFFSET OPTIONS_BIT5 +#define OPTIONS_BIT5 (0x1 << 5) +#else +#define OPTIONS_BIT5 0x0 +#endif + +#if defined(SGX_DMS_AGE_ENABLE) || defined (INTERNAL_TEST) +#define SGX_DMS_AGE_ENABLE_SET_OFFSET OPTIONS_BIT6 +#define OPTIONS_BIT6 (0x1 << 6) +#else +#define OPTIONS_BIT6 0x0 +#endif + +#if defined(SGX_DONT_SWITCH_OFF_FEATURES) || defined (INTERNAL_TEST) +#define SGX_DONT_SWITCH_OFF_FEATURES_SET_OFFSET OPTIONS_BIT7 +#define OPTIONS_BIT7 (0x1 << 7) +#else +#define OPTIONS_BIT7 0x0 +#endif + + + +#if defined(SGX_FAST_DPM_INIT) || defined (INTERNAL_TEST) +#define SGX_FAST_DPM_INIT_SET_OFFSET OPTIONS_BIT8 +#define OPTIONS_BIT8 (0x1 << 8) +#else +#define OPTIONS_BIT8 0x0 +#endif + +#if defined(SGX_FEATURE_DCU) || defined (INTERNAL_TEST) +#define SGX_FEATURE_DCU_SET_OFFSET OPTIONS_BIT9 +#define OPTIONS_BIT9 (0x1 << 9) +#else +#define OPTIONS_BIT9 0x0 +#endif + +#if defined(SGX_FEATURE_MP) || defined (INTERNAL_TEST) +#define SGX_FEATURE_MP_SET_OFFSET OPTIONS_BIT10 +#define OPTIONS_BIT10 (0x1 << 10) +#else +#define OPTIONS_BIT10 0x0 +#endif + +#if defined(SGX_FEATURE_MULTITHREADED_UKERNEL) || defined (INTERNAL_TEST) +#define SGX_FEATURE_MULTITHREADED_UKERNEL_SET_OFFSET OPTIONS_BIT11 +#define OPTIONS_BIT11 (0x1 << 11) +#else +#define OPTIONS_BIT11 0x0 +#endif + + + +#if defined(SGX_FEATURE_OVERLAPPED_SPM) || defined (INTERNAL_TEST) +#define SGX_FEATURE_OVERLAPPED_SPM_SET_OFFSET OPTIONS_BIT12 +#define OPTIONS_BIT12 (0x1 << 12) +#else +#define OPTIONS_BIT12 0x0 +#endif + +#if defined(SGX_FEATURE_RENDER_TARGET_ARRAYS) || defined (INTERNAL_TEST) +#define SGX_FEATURE_RENDER_TARGET_ARRAYS_SET_OFFSET OPTIONS_BIT13 +#define OPTIONS_BIT13 (0x1 << 13) +#else +#define OPTIONS_BIT13 0x0 +#endif + +#if defined(SGX_FEATURE_SYSTEM_CACHE) || defined (INTERNAL_TEST) +#define SGX_FEATURE_SYSTEM_CACHE_SET_OFFSET OPTIONS_BIT14 +#define OPTIONS_BIT14 (0x1 << 14) +#else +#define OPTIONS_BIT14 0x0 +#endif + +#if defined(SGX_SUPPORT_HWPROFILING) || defined (INTERNAL_TEST) +#define SGX_SUPPORT_HWPROFILING_SET_OFFSET OPTIONS_BIT15 +#define OPTIONS_BIT15 (0x1 << 15) +#else +#define OPTIONS_BIT15 0x0 +#endif + + + +#if defined(SUPPORT_ACTIVE_POWER_MANAGEMENT) || defined (INTERNAL_TEST) +#define SUPPORT_ACTIVE_POWER_MANAGEMENT_SET_OFFSET OPTIONS_BIT16 +#define OPTIONS_BIT16 (0x1 << 16) +#else +#define OPTIONS_BIT16 0x0 +#endif + +#if defined(SUPPORT_DISPLAYCONTROLLER_TILING) || defined (INTERNAL_TEST) +#define SUPPORT_DISPLAYCONTROLLER_TILING_SET_OFFSET OPTIONS_BIT17 +#define OPTIONS_BIT17 (0x1 << 17) +#else +#define OPTIONS_BIT17 0x0 +#endif + +#if defined(SUPPORT_PERCONTEXT_PB) || defined (INTERNAL_TEST) +#define SUPPORT_PERCONTEXT_PB_SET_OFFSET OPTIONS_BIT18 +#define OPTIONS_BIT18 (0x1 << 18) +#else +#define OPTIONS_BIT18 0x0 +#endif + +#if defined(SUPPORT_SGX_HWPERF) || defined (INTERNAL_TEST) +#define SUPPORT_SGX_HWPERF_SET_OFFSET OPTIONS_BIT19 +#define OPTIONS_BIT19 (0x1 << 19) +#else +#define OPTIONS_BIT19 0x0 +#endif + + + +#if defined(SUPPORT_SGX_MMU_DUMMY_PAGE) || defined (INTERNAL_TEST) +#define SUPPORT_SGX_MMU_DUMMY_PAGE_SET_OFFSET OPTIONS_BIT20 +#define OPTIONS_BIT20 (0x1 << 20) +#else +#define OPTIONS_BIT20 0x0 +#endif + +#if defined(SUPPORT_SGX_PRIORITY_SCHEDULING) || defined (INTERNAL_TEST) +#define SUPPORT_SGX_PRIORITY_SCHEDULING_SET_OFFSET OPTIONS_BIT21 +#define OPTIONS_BIT21 (0x1 << 21) +#else +#define OPTIONS_BIT21 0x0 +#endif + +#if defined(USE_SUPPORT_NO_TA3D_OVERLAP) || defined (INTERNAL_TEST) +#define USE_SUPPORT_NO_TA3D_OVERLAP_SET_OFFSET OPTIONS_BIT22 +#define OPTIONS_BIT22 (0x1 << 22) +#else +#define OPTIONS_BIT22 0x0 +#endif + + +#if defined(SGX_FEATURE_MP) || defined (INTERNAL_TEST) +#define OPTIONS_HIGHBYTE ((SGX_FEATURE_MP_CORE_COUNT-1) << SGX_FEATURE_MP_CORE_COUNT_SET_OFFSET) +#define SGX_FEATURE_MP_CORE_COUNT_SET_OFFSET 28UL +#define SGX_FEATURE_MP_CORE_COUNT_SET_MASK 0xFF +#else +#define OPTIONS_HIGHBYTE 0x0 +#endif + + + +#define SGX_BUILD_OPTIONS \ + OPTIONS_BIT0 |\ + OPTIONS_BIT1 |\ + OPTIONS_BIT2 |\ + OPTIONS_BIT3 |\ + OPTIONS_BIT4 |\ + OPTIONS_BIT5 |\ + OPTIONS_BIT6 |\ + OPTIONS_BIT7 |\ + OPTIONS_BIT8 |\ + OPTIONS_BIT9 |\ + OPTIONS_BIT10 |\ + OPTIONS_BIT11 |\ + OPTIONS_BIT12 |\ + OPTIONS_BIT13 |\ + OPTIONS_BIT14 |\ + OPTIONS_BIT15 |\ + OPTIONS_BIT16 |\ + OPTIONS_BIT17 |\ + OPTIONS_BIT18 |\ + OPTIONS_BIT19 |\ + OPTIONS_BIT20 |\ + OPTIONS_BIT21 |\ + OPTIONS_BIT22 |\ + OPTIONS_HIGHBYTE + diff --git a/include4/sgxapi_km.h b/include4/sgxapi_km.h new file mode 100644 index 0000000..ab0e411 --- /dev/null +++ b/include4/sgxapi_km.h @@ -0,0 +1,289 @@ +/********************************************************************** + * + * Copyright(c) 2008 Imagination Technologies Ltd. All rights reserved. + * + * This program is free software; you can redistribute it and/or modify it + * under the terms and conditions of the GNU General Public License, + * version 2, as published by the Free Software Foundation. + * + * This program is distributed in the hope it will be useful but, except + * as otherwise stated in writing, without any warranty; without even the + * implied warranty of merchantability or fitness for a particular purpose. + * See the GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License along with + * this program; if not, write to the Free Software Foundation, Inc., + * 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA. + * + * The full GNU General Public License is included in this distribution in + * the file called "COPYING". + * + * Contact Information: + * Imagination Technologies Ltd. + * Home Park Estate, Kings Langley, Herts, WD4 8LZ, UK + * + ******************************************************************************/ + +#ifndef __SGXAPI_KM_H__ +#define __SGXAPI_KM_H__ + +#if defined (__cplusplus) +extern "C" { +#endif + +#include "sgxdefs.h" + +#if defined(__linux__) && !defined(USE_CODE) + #if defined(__KERNEL__) + #include + #else + #include + #endif +#endif + +#define SGX_UNDEFINED_HEAP_ID (~0LU) +#define SGX_GENERAL_HEAP_ID 0 +#define SGX_TADATA_HEAP_ID 1 +#define SGX_KERNEL_CODE_HEAP_ID 2 +#define SGX_KERNEL_DATA_HEAP_ID 3 +#define SGX_PIXELSHADER_HEAP_ID 4 +#define SGX_VERTEXSHADER_HEAP_ID 5 +#define SGX_PDSPIXEL_CODEDATA_HEAP_ID 6 +#define SGX_PDSVERTEX_CODEDATA_HEAP_ID 7 +#define SGX_SYNCINFO_HEAP_ID 8 +#define SGX_3DPARAMETERS_HEAP_ID 9 +#if defined(SUPPORT_SGX_GENERAL_MAPPING_HEAP) + #define SGX_GENERAL_MAPPING_HEAP_ID 10 + #if defined(SGX_FEATURE_2D_HARDWARE) + #define SGX_2D_HEAP_ID 11 + #define SGX_MAX_HEAP_ID 12 + #else + #define SGX_MAX_HEAP_ID 11 + #endif +#else + #if defined(SGX_FEATURE_2D_HARDWARE) + #define SGX_2D_HEAP_ID 10 + #define SGX_MAX_HEAP_ID 11 + #else + #define SGX_MAX_HEAP_ID 10 + #endif +#endif + +#define SGX_MAX_TA_STATUS_VALS 32 +#define SGX_MAX_3D_STATUS_VALS 2 + +#define SGX_MAX_SRC_SYNCS 4 + +#ifdef SUPPORT_SGX_HWPERF + +#define PVRSRV_SGX_HWPERF_NUM_COUNTERS 9 + +#define PVRSRV_SGX_HWPERF_INVALID 0x1 + +#define PVRSRV_SGX_HWPERF_TRANSFER 0x2 +#define PVRSRV_SGX_HWPERF_TA 0x3 +#define PVRSRV_SGX_HWPERF_3D 0x4 +#define PVRSRV_SGX_HWPERF_2D 0x5 + +#define PVRSRV_SGX_HWPERF_MK_EVENT 0x101 +#define PVRSRV_SGX_HWPERF_MK_TA 0x102 +#define PVRSRV_SGX_HWPERF_MK_3D 0x103 +#define PVRSRV_SGX_HWPERF_MK_2D 0x104 + +#define PVRSRV_SGX_HWPERF_TYPE_STARTEND_BIT 28 +#define PVRSRV_SGX_HWPERF_TYPE_OP_MASK ((1 << PVRSRV_SGX_HWPERF_TYPE_STARTEND_BIT) - 1) +#define PVRSRV_SGX_HWPERF_TYPE_OP_START (0 << PVRSRV_SGX_HWPERF_TYPE_STARTEND_BIT) +#define PVRSRV_SGX_HWPERF_TYPE_OP_END (1 << PVRSRV_SGX_HWPERF_TYPE_STARTEND_BIT) + +#define PVRSRV_SGX_HWPERF_TYPE_TRANSFER_START (PVRSRV_SGX_HWPERF_TRANSFER | PVRSRV_SGX_HWPERF_TYPE_OP_START) +#define PVRSRV_SGX_HWPERF_TYPE_TRANSFER_END (PVRSRV_SGX_HWPERF_TRANSFER | PVRSRV_SGX_HWPERF_TYPE_OP_END) +#define PVRSRV_SGX_HWPERF_TYPE_TA_START (PVRSRV_SGX_HWPERF_TA | PVRSRV_SGX_HWPERF_TYPE_OP_START) +#define PVRSRV_SGX_HWPERF_TYPE_TA_END (PVRSRV_SGX_HWPERF_TA | PVRSRV_SGX_HWPERF_TYPE_OP_END) +#define PVRSRV_SGX_HWPERF_TYPE_3D_START (PVRSRV_SGX_HWPERF_3D | PVRSRV_SGX_HWPERF_TYPE_OP_START) +#define PVRSRV_SGX_HWPERF_TYPE_3D_END (PVRSRV_SGX_HWPERF_3D | PVRSRV_SGX_HWPERF_TYPE_OP_END) +#define PVRSRV_SGX_HWPERF_TYPE_2D_START (PVRSRV_SGX_HWPERF_2D | PVRSRV_SGX_HWPERF_TYPE_OP_START) +#define PVRSRV_SGX_HWPERF_TYPE_2D_END (PVRSRV_SGX_HWPERF_2D | PVRSRV_SGX_HWPERF_TYPE_OP_END) + +#define PVRSRV_SGX_HWPERF_TYPE_MK_EVENT_START (PVRSRV_SGX_HWPERF_MK_EVENT | PVRSRV_SGX_HWPERF_TYPE_OP_START) +#define PVRSRV_SGX_HWPERF_TYPE_MK_EVENT_END (PVRSRV_SGX_HWPERF_MK_EVENT | PVRSRV_SGX_HWPERF_TYPE_OP_END) +#define PVRSRV_SGX_HWPERF_TYPE_MK_TA_START (PVRSRV_SGX_HWPERF_MK_TA | PVRSRV_SGX_HWPERF_TYPE_OP_START) +#define PVRSRV_SGX_HWPERF_TYPE_MK_TA_END (PVRSRV_SGX_HWPERF_MK_TA | PVRSRV_SGX_HWPERF_TYPE_OP_END) +#define PVRSRV_SGX_HWPERF_TYPE_MK_3D_START (PVRSRV_SGX_HWPERF_MK_3D | PVRSRV_SGX_HWPERF_TYPE_OP_START) +#define PVRSRV_SGX_HWPERF_TYPE_MK_3D_END (PVRSRV_SGX_HWPERF_MK_3D | PVRSRV_SGX_HWPERF_TYPE_OP_END) +#define PVRSRV_SGX_HWPERF_TYPE_MK_2D_START (PVRSRV_SGX_HWPERF_MK_2D | PVRSRV_SGX_HWPERF_TYPE_OP_START) +#define PVRSRV_SGX_HWPERF_TYPE_MK_2D_END (PVRSRV_SGX_HWPERF_MK_2D | PVRSRV_SGX_HWPERF_TYPE_OP_END) + +#define PVRSRV_SGX_HWPERF_OFF (0x0) +#define PVRSRV_SGX_HWPERF_GRAPHICS_ON (1UL << 0) +#define PVRSRV_SGX_HWPERF_MK_EXECUTION_ON (1UL << 1) + + +typedef struct _PVRSRV_SGX_HWPERF_CB_ENTRY_ +{ + IMG_UINT32 ui32FrameNo; + IMG_UINT32 ui32Type; + IMG_UINT32 ui32Ordinal; + IMG_UINT32 ui32Clocksx16; + IMG_UINT32 ui32Counters[PVRSRV_SGX_HWPERF_NUM_COUNTERS]; +} PVRSRV_SGX_HWPERF_CB_ENTRY; + + +typedef struct _PVRSRV_SGX_HWPERF_CBDATA_ +{ + IMG_UINT32 ui32FrameNo; + IMG_UINT32 ui32Type; + IMG_UINT32 ui32StartTimeWraps; + IMG_UINT32 ui32StartTime; + IMG_UINT32 ui32EndTimeWraps; + IMG_UINT32 ui32EndTime; + IMG_UINT32 ui32ClockSpeed; + IMG_UINT32 ui32TimeMax; +} PVRSRV_SGX_HWPERF_CBDATA; + + +typedef struct _SGX_MISC_INFO_HWPERF_RETRIEVE_CB +{ + PVRSRV_SGX_HWPERF_CBDATA* psHWPerfData; + IMG_UINT32 ui32ArraySize; + IMG_UINT32 ui32DataCount; + IMG_UINT32 ui32Time; +} SGX_MISC_INFO_HWPERF_RETRIEVE_CB; +#endif + + +typedef struct _CTL_STATUS_ +{ + IMG_DEV_VIRTADDR sStatusDevAddr; + IMG_UINT32 ui32StatusValue; +} CTL_STATUS; + + +typedef enum _SGX_MISC_INFO_REQUEST_ +{ + SGX_MISC_INFO_REQUEST_CLOCKSPEED = 0, + SGX_MISC_INFO_REQUEST_SGXREV, + SGX_MISC_INFO_REQUEST_DRIVER_SGXREV, +#if defined(SUPPORT_SGX_HWPERF) + SGX_MISC_INFO_REQUEST_SET_HWPERF_STATUS, + SGX_MISC_INFO_REQUEST_HWPERF_CB_ON, + SGX_MISC_INFO_REQUEST_HWPERF_CB_OFF, + SGX_MISC_INFO_REQUEST_HWPERF_RETRIEVE_CB, +#endif + SGX_MISC_INFO_REQUEST_FORCE_I16 = 0x7fff +} SGX_MISC_INFO_REQUEST; + + +typedef struct _PVRSRV_SGX_MISCINFO_FEATURES +{ + IMG_UINT32 ui32CoreRev; + IMG_UINT32 ui32CoreID; + IMG_UINT32 ui32DDKVersion; + IMG_UINT32 ui32DDKBuild; + IMG_UINT32 ui32CoreIdSW; + IMG_UINT32 ui32CoreRevSW; + IMG_UINT32 ui32BuildOptions; +} PVRSRV_SGX_MISCINFO_FEATURES; + +typedef struct _SGX_MISC_INFO_ +{ + SGX_MISC_INFO_REQUEST eRequest; + + union + { + IMG_UINT32 reserved; + PVRSRV_SGX_MISCINFO_FEATURES sSGXFeatures; + IMG_UINT32 ui32SGXClockSpeed; +#ifdef SUPPORT_SGX_HWPERF + IMG_UINT32 ui32NewHWPerfStatus; + SGX_MISC_INFO_HWPERF_RETRIEVE_CB sRetrieveCB; +#endif + } uData; +} SGX_MISC_INFO; + +#if defined(SGX_FEATURE_2D_HARDWARE) +#define PVRSRV_MAX_BLT_SRC_SYNCS 3 +#endif + + +#define SGX_KICKTA_DUMPBITMAP_MAX_NAME_LENGTH 256 + +typedef struct _SGX_KICKTA_DUMPBITMAP_ +{ + IMG_DEV_VIRTADDR sDevBaseAddr; + IMG_UINT32 ui32Flags; + IMG_UINT32 ui32Width; + IMG_UINT32 ui32Height; + IMG_UINT32 ui32Stride; + IMG_UINT32 ui32PDUMPFormat; + IMG_UINT32 ui32BytesPP; + IMG_CHAR pszName[SGX_KICKTA_DUMPBITMAP_MAX_NAME_LENGTH]; +} SGX_KICKTA_DUMPBITMAP, *PSGX_KICKTA_DUMPBITMAP; + +#define PVRSRV_SGX_PDUMP_CONTEXT_MAX_BITMAP_ARRAY_SIZE (16) + +typedef struct _PVRSRV_SGX_PDUMP_CONTEXT_ +{ + + IMG_UINT32 ui32CacheControl; + +} PVRSRV_SGX_PDUMP_CONTEXT; + + +typedef struct _SGX_KICKTA_DUMP_ROFF_ +{ + IMG_HANDLE hKernelMemInfo; + IMG_UINT32 uiAllocIndex; + IMG_UINT32 ui32Offset; + IMG_UINT32 ui32Value; + IMG_PCHAR pszName; +} SGX_KICKTA_DUMP_ROFF, *PSGX_KICKTA_DUMP_ROFF; + +typedef struct _SGX_KICKTA_DUMP_BUFFER_ +{ + IMG_UINT32 ui32SpaceUsed; + IMG_UINT32 ui32Start; + IMG_UINT32 ui32End; + IMG_UINT32 ui32BufferSize; + IMG_UINT32 ui32BackEndLength; + IMG_UINT32 uiAllocIndex; + IMG_HANDLE hKernelMemInfo; + IMG_PVOID pvLinAddr; +#if defined(SUPPORT_SGX_NEW_STATUS_VALS) + IMG_HANDLE hCtrlKernelMemInfo; + IMG_DEV_VIRTADDR sCtrlDevVAddr; +#endif + IMG_PCHAR pszName; +} SGX_KICKTA_DUMP_BUFFER, *PSGX_KICKTA_DUMP_BUFFER; + +#ifdef PDUMP +typedef struct _SGX_KICKTA_PDUMP_ +{ + + PSGX_KICKTA_DUMPBITMAP psPDumpBitmapArray; + IMG_UINT32 ui32PDumpBitmapSize; + + + PSGX_KICKTA_DUMP_BUFFER psBufferArray; + IMG_UINT32 ui32BufferArraySize; + + + PSGX_KICKTA_DUMP_ROFF psROffArray; + IMG_UINT32 ui32ROffArraySize; +} SGX_KICKTA_PDUMP, *PSGX_KICKTA_PDUMP; +#endif + +#if defined(TRANSFER_QUEUE) +#if defined(SGX_FEATURE_2D_HARDWARE) +#define SGX_MAX_2D_BLIT_CMD_SIZE 26 +#define SGX_MAX_2D_SRC_SYNC_OPS 3 +#endif +#define SGX_MAX_TRANSFER_STATUS_VALS 2 +#define SGX_MAX_TRANSFER_SYNC_OPS 5 +#endif + +#if defined (__cplusplus) +} +#endif + +#endif + diff --git a/include4/sgxscript.h b/include4/sgxscript.h new file mode 100644 index 0000000..47c9e48 --- /dev/null +++ b/include4/sgxscript.h @@ -0,0 +1,81 @@ +/********************************************************************** + * + * Copyright(c) 2008 Imagination Technologies Ltd. All rights reserved. + * + * This program is free software; you can redistribute it and/or modify it + * under the terms and conditions of the GNU General Public License, + * version 2, as published by the Free Software Foundation. + * + * This program is distributed in the hope it will be useful but, except + * as otherwise stated in writing, without any warranty; without even the + * implied warranty of merchantability or fitness for a particular purpose. + * See the GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License along with + * this program; if not, write to the Free Software Foundation, Inc., + * 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA. + * + * The full GNU General Public License is included in this distribution in + * the file called "COPYING". + * + * Contact Information: + * Imagination Technologies Ltd. + * Home Park Estate, Kings Langley, Herts, WD4 8LZ, UK + * + ******************************************************************************/ + +#ifndef __SGXSCRIPT_H__ +#define __SGXSCRIPT_H__ + +#if defined (__cplusplus) +extern "C" { +#endif + +#define SGX_MAX_INIT_COMMANDS 64 +#define SGX_MAX_DEINIT_COMMANDS 16 + +typedef enum _SGX_INIT_OPERATION +{ + SGX_INIT_OP_ILLEGAL = 0, + SGX_INIT_OP_WRITE_HW_REG, +#if defined(PDUMP) + SGX_INIT_OP_PDUMP_HW_REG, +#endif + SGX_INIT_OP_HALT +} SGX_INIT_OPERATION; + +typedef union _SGX_INIT_COMMAND +{ + SGX_INIT_OPERATION eOp; + struct { + SGX_INIT_OPERATION eOp; + IMG_UINT32 ui32Offset; + IMG_UINT32 ui32Value; + } sWriteHWReg; +#if defined(PDUMP) + struct { + SGX_INIT_OPERATION eOp; + IMG_UINT32 ui32Offset; + IMG_UINT32 ui32Value; + } sPDumpHWReg; +#endif +#if defined(FIX_HW_BRN_22997) && defined(FIX_HW_BRN_23030) && defined(SGX_FEATURE_HOST_PORT) + struct { + SGX_INIT_OPERATION eOp; + } sWorkaroundBRN22997; +#endif +} SGX_INIT_COMMAND; + +typedef struct _SGX_INIT_SCRIPTS_ +{ + SGX_INIT_COMMAND asInitCommandsPart1[SGX_MAX_INIT_COMMANDS]; + SGX_INIT_COMMAND asInitCommandsPart2[SGX_MAX_INIT_COMMANDS]; + SGX_INIT_COMMAND asDeinitCommands[SGX_MAX_DEINIT_COMMANDS]; +} SGX_INIT_SCRIPTS; + +#if defined(__cplusplus) +} +#endif + +#endif + diff --git a/services4/3rdparty/bufferclass_example/bufferclass_example.c b/services4/3rdparty/bufferclass_example/bufferclass_example.c new file mode 100644 index 0000000..c32bf3c --- /dev/null +++ b/services4/3rdparty/bufferclass_example/bufferclass_example.c @@ -0,0 +1,428 @@ +/********************************************************************** + * + * Copyright(c) 2008 Imagination Technologies Ltd. All rights reserved. + * + * This program is free software; you can redistribute it and/or modify it + * under the terms and conditions of the GNU General Public License, + * version 2, as published by the Free Software Foundation. + * + * This program is distributed in the hope it will be useful but, except + * as otherwise stated in writing, without any warranty; without even the + * implied warranty of merchantability or fitness for a particular purpose. + * See the GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License along with + * this program; if not, write to the Free Software Foundation, Inc., + * 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA. + * + * The full GNU General Public License is included in this distribution in + * the file called "COPYING". + * + * Contact Information: + * Imagination Technologies Ltd. + * Home Park Estate, Kings Langley, Herts, WD4 8LZ, UK + * + ******************************************************************************/ + +#include "bufferclass_example.h" + + +static void *gpvAnchor = NULL; +static PFN_BC_GET_PVRJTABLE pfnGetPVRJTable = IMG_NULL; + +BC_EXAMPLE_DEVINFO * GetAnchorPtr(void) +{ + return (BC_EXAMPLE_DEVINFO *)gpvAnchor; +} + +static void SetAnchorPtr(BC_EXAMPLE_DEVINFO *psDevInfo) +{ + gpvAnchor = (void *)psDevInfo; +} + + +static PVRSRV_ERROR OpenBCDevice(IMG_HANDLE *phDevice) +{ + BC_EXAMPLE_DEVINFO *psDevInfo; + + psDevInfo = GetAnchorPtr(); + + + *phDevice = (IMG_HANDLE)psDevInfo; + + return (PVRSRV_OK); +} + + +static PVRSRV_ERROR CloseBCDevice(IMG_HANDLE hDevice) +{ + UNREFERENCED_PARAMETER(hDevice); + + return (PVRSRV_OK); +} + +static PVRSRV_ERROR GetBCBuffer(IMG_HANDLE hDevice, + IMG_UINT32 ui32BufferNumber, + PVRSRV_SYNC_DATA *psSyncData, + IMG_HANDLE *phBuffer) +{ + BC_EXAMPLE_DEVINFO *psDevInfo; + + if(!hDevice || !phBuffer) + { + return (PVRSRV_ERROR_INVALID_PARAMS); + } + + psDevInfo = (BC_EXAMPLE_DEVINFO*)hDevice; + + if( ui32BufferNumber < psDevInfo->sBufferInfo.ui32BufferCount ) + { + psDevInfo->psSystemBuffer[ui32BufferNumber].psSyncData = psSyncData; + *phBuffer = (IMG_HANDLE)&psDevInfo->psSystemBuffer[ui32BufferNumber]; + } + else + { + return (PVRSRV_ERROR_INVALID_PARAMS); + } + + return (PVRSRV_OK); +} + + +static PVRSRV_ERROR GetBCInfo(IMG_HANDLE hDevice, BUFFER_INFO *psBCInfo) +{ + BC_EXAMPLE_DEVINFO *psDevInfo; + + if(!hDevice || !psBCInfo) + { + return (PVRSRV_ERROR_INVALID_PARAMS); + } + + psDevInfo = (BC_EXAMPLE_DEVINFO*)hDevice; + + *psBCInfo = psDevInfo->sBufferInfo; + + return (PVRSRV_OK); +} + + +static PVRSRV_ERROR GetBCBufferAddr(IMG_HANDLE hDevice, + IMG_HANDLE hBuffer, + IMG_SYS_PHYADDR **ppsSysAddr, + IMG_UINT32 *pui32ByteSize, + IMG_VOID **ppvCpuVAddr, + IMG_HANDLE *phOSMapInfo, + IMG_BOOL *pbIsContiguous) +{ + BC_EXAMPLE_BUFFER *psBuffer; + + if(!hDevice || !hBuffer || !ppsSysAddr || !pui32ByteSize) + { + return (PVRSRV_ERROR_INVALID_PARAMS); + } + + psBuffer = (BC_EXAMPLE_BUFFER *) hBuffer; + + *ppsSysAddr = &psBuffer->sPageAlignSysAddr; + *ppvCpuVAddr = psBuffer->sCPUVAddr; + + *pui32ByteSize = (IMG_UINT32)psBuffer->ulSize; + + *phOSMapInfo = IMG_NULL; + *pbIsContiguous = IMG_TRUE; + + return (PVRSRV_OK); +} + + +BCE_ERROR BC_Example_Register(void) +{ + BC_EXAMPLE_DEVINFO *psDevInfo; + + + + + + + + + + + + psDevInfo = GetAnchorPtr(); + + if (psDevInfo == NULL) + { + + psDevInfo = (BC_EXAMPLE_DEVINFO *)BCAllocKernelMem(sizeof(BC_EXAMPLE_DEVINFO)); + + if(!psDevInfo) + { + return (BCE_ERROR_OUT_OF_MEMORY); + } + + + SetAnchorPtr((void*)psDevInfo); + + + psDevInfo->ulRefCount = 0; + + + if(BCOpenPVRServices(&psDevInfo->hPVRServices) != BCE_OK) + { + return (BCE_ERROR_INIT_FAILURE); + } + if(BCGetLibFuncAddr (psDevInfo->hPVRServices, "PVRGetBufferClassJTable", &pfnGetPVRJTable) != BCE_OK) + { + return (BCE_ERROR_INIT_FAILURE); + } + + + if(!(*pfnGetPVRJTable)(&psDevInfo->sPVRJTable)) + { + return (BCE_ERROR_INIT_FAILURE); + } + + + + psDevInfo->ulNumBuffers = 0; + + psDevInfo->psSystemBuffer = BCAllocKernelMem(sizeof(BC_EXAMPLE_BUFFER) * BC_EXAMPLE_NUM_BUFFERS); + + if(!psDevInfo->psSystemBuffer) + { + return (BCE_ERROR_OUT_OF_MEMORY); + } + + + psDevInfo->sBufferInfo.pixelformat = PVRSRV_PIXEL_FORMAT_UNKNOWN; + psDevInfo->sBufferInfo.ui32Width = 0; + psDevInfo->sBufferInfo.ui32Height = 0; + psDevInfo->sBufferInfo.ui32ByteStride = 0; + psDevInfo->sBufferInfo.ui32BufferDeviceID = BC_EXAMPLE_DEVICEID; + psDevInfo->sBufferInfo.ui32Flags = 0; + psDevInfo->sBufferInfo.ui32BufferCount = (IMG_UINT32)psDevInfo->ulNumBuffers; + + + + psDevInfo->sBCJTable.ui32TableSize = sizeof(PVRSRV_BC_SRV2BUFFER_KMJTABLE); + psDevInfo->sBCJTable.pfnOpenBCDevice = OpenBCDevice; + psDevInfo->sBCJTable.pfnCloseBCDevice = CloseBCDevice; + psDevInfo->sBCJTable.pfnGetBCBuffer = GetBCBuffer; + psDevInfo->sBCJTable.pfnGetBCInfo = GetBCInfo; + psDevInfo->sBCJTable.pfnGetBufferAddr = GetBCBufferAddr; + + + + + if(psDevInfo->sPVRJTable.pfnPVRSRVRegisterBCDevice (&psDevInfo->sBCJTable, + &psDevInfo->ulDeviceID ) != PVRSRV_OK) + { + return (BCE_ERROR_DEVICE_REGISTER_FAILED); + } + } + + + psDevInfo->ulRefCount++; + + + return (BCE_OK); +} + +BCE_ERROR BC_Example_Unregister(void) +{ + BC_EXAMPLE_DEVINFO *psDevInfo; + + psDevInfo = GetAnchorPtr(); + + + if (psDevInfo == NULL) + { + return (BCE_ERROR_GENERIC); + } + + psDevInfo->ulRefCount--; + + if (psDevInfo->ulRefCount == 0) + { + + PVRSRV_BC_BUFFER2SRV_KMJTABLE *psJTable = &psDevInfo->sPVRJTable; + + + + if (psJTable->pfnPVRSRVRemoveBCDevice(psDevInfo->ulDeviceID) != PVRSRV_OK) + { + return (BCE_ERROR_GENERIC); + } + + if (BCClosePVRServices(psDevInfo->hPVRServices) != BCE_OK) + { + psDevInfo->hPVRServices = NULL; + return (BCE_ERROR_GENERIC); + } + + if (psDevInfo->psSystemBuffer) + { + BCFreeKernelMem(psDevInfo->psSystemBuffer); + } + + + BCFreeKernelMem(psDevInfo); + + + SetAnchorPtr(NULL); + } + + + return (BCE_OK); +} + + +BCE_ERROR BC_Example_Buffers_Create(void) +{ + BC_EXAMPLE_DEVINFO *psDevInfo; + IMG_CPU_PHYADDR sSystemBufferCPUPAddr; + unsigned long i; + + + + psDevInfo = GetAnchorPtr(); + if (psDevInfo == NULL) + { + + return (BCE_ERROR_DEVICE_REGISTER_FAILED); + } + if (psDevInfo->ulNumBuffers) + { + + return (BCE_ERROR_GENERIC); + } + + + psDevInfo->sBufferInfo.pixelformat = BC_EXAMPLE_PIXELFORMAT; + psDevInfo->sBufferInfo.ui32Width = BC_EXAMPLE_WIDTH; + psDevInfo->sBufferInfo.ui32Height = BC_EXAMPLE_HEIGHT; + psDevInfo->sBufferInfo.ui32ByteStride = BC_EXAMPLE_STRIDE; + psDevInfo->sBufferInfo.ui32BufferDeviceID = BC_EXAMPLE_DEVICEID; + psDevInfo->sBufferInfo.ui32Flags = PVRSRV_BC_FLAGS_YUVCSC_FULL_RANGE | PVRSRV_BC_FLAGS_YUVCSC_BT601; + + for(i=psDevInfo->ulNumBuffers; i < BC_EXAMPLE_NUM_BUFFERS; i++) + { + unsigned long ulSize = BC_EXAMPLE_HEIGHT * BC_EXAMPLE_STRIDE; + + if(psDevInfo->sBufferInfo.pixelformat == PVRSRV_PIXEL_FORMAT_NV12) + { + + ulSize += ((BC_EXAMPLE_STRIDE >> 1) * (BC_EXAMPLE_HEIGHT >> 1) << 1); + } + + + if (BCAllocContigMemory(ulSize, + &psDevInfo->psSystemBuffer[i].hMemHandle, + &psDevInfo->psSystemBuffer[i].sCPUVAddr, + &sSystemBufferCPUPAddr) != BCE_OK) + { + break; + } + + psDevInfo->ulNumBuffers++; + + psDevInfo->psSystemBuffer[i].ulSize = ulSize; + psDevInfo->psSystemBuffer[i].sSysAddr = CpuPAddrToSysPAddrBC(sSystemBufferCPUPAddr); + psDevInfo->psSystemBuffer[i].sPageAlignSysAddr.uiAddr = (psDevInfo->psSystemBuffer[i].sSysAddr.uiAddr & 0xFFFFF000); + psDevInfo->psSystemBuffer[i].psSyncData = NULL; + } + + psDevInfo->sBufferInfo.ui32BufferCount = (IMG_UINT32)psDevInfo->ulNumBuffers; + + + + psDevInfo->sBCJTable.ui32TableSize = sizeof(PVRSRV_BC_SRV2BUFFER_KMJTABLE); + psDevInfo->sBCJTable.pfnOpenBCDevice = OpenBCDevice; + psDevInfo->sBCJTable.pfnCloseBCDevice = CloseBCDevice; + psDevInfo->sBCJTable.pfnGetBCBuffer = GetBCBuffer; + psDevInfo->sBCJTable.pfnGetBCInfo = GetBCInfo; + psDevInfo->sBCJTable.pfnGetBufferAddr = GetBCBufferAddr; + + + return (BCE_OK); +} + +BCE_ERROR BC_Example_Buffers_Destroy(void) +{ + BC_EXAMPLE_DEVINFO *psDevInfo; + unsigned long i; + + psDevInfo = GetAnchorPtr(); + + + if (psDevInfo == NULL) + { + + + return (BCE_ERROR_DEVICE_REGISTER_FAILED); + } + + + + for(i = 0; i < psDevInfo->ulNumBuffers; i++) + { + BCFreeContigMemory(psDevInfo->psSystemBuffer[i].ulSize, + psDevInfo->psSystemBuffer[i].hMemHandle, + psDevInfo->psSystemBuffer[i].sCPUVAddr, + SysPAddrToCpuPAddrBC(psDevInfo->psSystemBuffer[i].sSysAddr)); + } + psDevInfo->ulNumBuffers = 0; + + + psDevInfo->sBufferInfo.pixelformat = PVRSRV_PIXEL_FORMAT_UNKNOWN; + psDevInfo->sBufferInfo.ui32Width = 0; + psDevInfo->sBufferInfo.ui32Height = 0; + psDevInfo->sBufferInfo.ui32ByteStride = 0; + psDevInfo->sBufferInfo.ui32BufferDeviceID = BC_EXAMPLE_DEVICEID; + psDevInfo->sBufferInfo.ui32Flags = 0; + psDevInfo->sBufferInfo.ui32BufferCount = (IMG_UINT32)psDevInfo->ulNumBuffers; + + + return (BCE_OK); +} + + +BCE_ERROR BC_Example_Init(void) +{ + BCE_ERROR eError; + + eError = BC_Example_Register(); + if (eError != BCE_OK) + { + return eError; + } + + eError = BC_Example_Buffers_Create(); + if (eError != BCE_OK) + { + return eError; + } + + return (BCE_OK); +} + +BCE_ERROR BC_Example_Deinit(void) +{ + BCE_ERROR eError; + + eError = BC_Example_Buffers_Destroy(); + if (eError != BCE_OK) + { + return eError; + } + + eError = BC_Example_Unregister(); + if (eError != BCE_OK) + { + return eError; + } + + return (BCE_OK); +} + diff --git a/services4/3rdparty/bufferclass_example/bufferclass_example.h b/services4/3rdparty/bufferclass_example/bufferclass_example.h new file mode 100644 index 0000000..1791dd0 --- /dev/null +++ b/services4/3rdparty/bufferclass_example/bufferclass_example.h @@ -0,0 +1,184 @@ +/********************************************************************** + * + * Copyright(c) 2008 Imagination Technologies Ltd. All rights reserved. + * + * This program is free software; you can redistribute it and/or modify it + * under the terms and conditions of the GNU General Public License, + * version 2, as published by the Free Software Foundation. + * + * This program is distributed in the hope it will be useful but, except + * as otherwise stated in writing, without any warranty; without even the + * implied warranty of merchantability or fitness for a particular purpose. + * See the GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License along with + * this program; if not, write to the Free Software Foundation, Inc., + * 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA. + * + * The full GNU General Public License is included in this distribution in + * the file called "COPYING". + * + * Contact Information: + * Imagination Technologies Ltd. + * Home Park Estate, Kings Langley, Herts, WD4 8LZ, UK + * + ******************************************************************************/ + +#ifndef __BC_EXAMPLE_H__ +#define __BC_EXAMPLE_H__ + +#include "img_defs.h" +#include "servicesext.h" +#include "kernelbuffer.h" + +#if defined(__cplusplus) +extern "C" { +#endif + +extern IMG_IMPORT IMG_BOOL PVRGetBufferClassJTable(PVRSRV_BC_BUFFER2SRV_KMJTABLE *psJTable); + +#define BC_EXAMPLE_NUM_BUFFERS 3 + +#define YUV420 1 +#ifdef YUV420 + +#define BC_EXAMPLE_WIDTH (320) +#define BC_EXAMPLE_HEIGHT (160) +#define BC_EXAMPLE_STRIDE (320) +#define BC_EXAMPLE_PIXELFORMAT (PVRSRV_PIXEL_FORMAT_NV12) + +#else +#ifdef YUV422 + +#define BC_EXAMPLE_WIDTH (320) +#define BC_EXAMPLE_HEIGHT (160) +#define BC_EXAMPLE_STRIDE (320*2) +#define BC_EXAMPLE_PIXELFORMAT (PVRSRV_PIXEL_FORMAT_FOURCC_ORG_UYVY) + +#else + +#define BC_EXAMPLE_WIDTH (320) +#define BC_EXAMPLE_HEIGHT (160) +#define BC_EXAMPLE_STRIDE (320*2) +#define BC_EXAMPLE_PIXELFORMAT (PVRSRV_PIXEL_FORMAT_RGB565) + +#endif +#endif + +#define BC_EXAMPLE_DEVICEID 0 + +typedef void * BCE_HANDLE; + +typedef enum tag_bce_bool +{ + BCE_FALSE = 0, + BCE_TRUE = 1, +} BCE_BOOL, *BCE_PBOOL; + +typedef struct BC_EXAMPLE_BUFFER_TAG +{ + unsigned long ulSize; + BCE_HANDLE hMemHandle; + + + + IMG_SYS_PHYADDR sSysAddr; + IMG_SYS_PHYADDR sPageAlignSysAddr; + IMG_CPU_VIRTADDR sCPUVAddr; + PVRSRV_SYNC_DATA *psSyncData; + + struct BC_EXAMPLE_BUFFER_TAG *psNext; +} BC_EXAMPLE_BUFFER; + + +typedef struct BC_EXAMPLE_DEVINFO_TAG +{ + unsigned long ulDeviceID; + + BC_EXAMPLE_BUFFER *psSystemBuffer; + + + unsigned long ulNumBuffers; + + + PVRSRV_BC_BUFFER2SRV_KMJTABLE sPVRJTable; + + + PVRSRV_BC_SRV2BUFFER_KMJTABLE sBCJTable; + + + + + BCE_HANDLE hPVRServices; + + + unsigned long ulRefCount; + + + + BUFFER_INFO sBufferInfo; + +} BC_EXAMPLE_DEVINFO; + + +typedef enum _BCE_ERROR_ +{ + BCE_OK = 0, + BCE_ERROR_GENERIC = 1, + BCE_ERROR_OUT_OF_MEMORY = 2, + BCE_ERROR_TOO_FEW_BUFFERS = 3, + BCE_ERROR_INVALID_PARAMS = 4, + BCE_ERROR_INIT_FAILURE = 5, + BCE_ERROR_CANT_REGISTER_CALLBACK = 6, + BCE_ERROR_INVALID_DEVICE = 7, + BCE_ERROR_DEVICE_REGISTER_FAILED = 8, + BCE_ERROR_NO_PRIMARY = 9 +} BCE_ERROR; + + +#ifndef UNREFERENCED_PARAMETER +#define UNREFERENCED_PARAMETER(param) (param) = (param) +#endif + +#ifndef NULL +#define NULL 0 +#endif + +BCE_ERROR BC_Example_Register(void); +BCE_ERROR BC_Example_Unregister(void); +BCE_ERROR BC_Example_Buffers_Create(void); +BCE_ERROR BC_Example_Buffers_Destroy(void); +BCE_ERROR BC_Example_Init(void); +BCE_ERROR BC_Example_Deinit(void); + +BCE_ERROR BCOpenPVRServices(BCE_HANDLE *phPVRServices); +BCE_ERROR BCClosePVRServices(BCE_HANDLE hPVRServices); + +void *BCAllocKernelMem(unsigned long ulSize); +void BCFreeKernelMem(void *pvMem); + +BCE_ERROR BCAllocContigMemory(unsigned long ulSize, + BCE_HANDLE *phMemHandle, + IMG_CPU_VIRTADDR *pLinAddr, + IMG_CPU_PHYADDR *pPhysAddr); + +void BCFreeContigMemory(unsigned long ulSize, + BCE_HANDLE hMemHandle, + IMG_CPU_VIRTADDR LinAddr, + IMG_CPU_PHYADDR PhysAddr); + +IMG_SYS_PHYADDR CpuPAddrToSysPAddrBC(IMG_CPU_PHYADDR cpu_paddr); +IMG_CPU_PHYADDR SysPAddrToCpuPAddrBC(IMG_SYS_PHYADDR sys_paddr); + +void *MapPhysAddr(IMG_SYS_PHYADDR sSysAddr, unsigned long ulSize); +void UnMapPhysAddr(void *pvAddr, unsigned long ulSize); + +BCE_ERROR BCGetLibFuncAddr (BCE_HANDLE hExtDrv, char *szFunctionName, PFN_BC_GET_PVRJTABLE *ppfnFuncTable); +BC_EXAMPLE_DEVINFO * GetAnchorPtr(void); + +#if defined(__cplusplus) +} +#endif + +#endif + diff --git a/services4/3rdparty/bufferclass_example/bufferclass_example_linux.c b/services4/3rdparty/bufferclass_example/bufferclass_example_linux.c new file mode 100644 index 0000000..e88764d --- /dev/null +++ b/services4/3rdparty/bufferclass_example/bufferclass_example_linux.c @@ -0,0 +1,348 @@ +/********************************************************************** + * + * Copyright(c) 2008 Imagination Technologies Ltd. All rights reserved. + * + * This program is free software; you can redistribute it and/or modify it + * under the terms and conditions of the GNU General Public License, + * version 2, as published by the Free Software Foundation. + * + * This program is distributed in the hope it will be useful but, except + * as otherwise stated in writing, without any warranty; without even the + * implied warranty of merchantability or fitness for a particular purpose. + * See the GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License along with + * this program; if not, write to the Free Software Foundation, Inc., + * 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA. + * + * The full GNU General Public License is included in this distribution in + * the file called "COPYING". + * + * Contact Information: + * Imagination Technologies Ltd. + * Home Park Estate, Kings Langley, Herts, WD4 8LZ, UK + * + ******************************************************************************/ + +#include +#include +#include +#include +#include +#include + +#if defined(LMA) +#include +#else +#include +#endif + +#include "bufferclass_example.h" +#include "bufferclass_example_linux.h" +#include "pvrmodule.h" + +#define DEVNAME "bc_example" +#define DRVNAME DEVNAME + +#if defined(BCE_USE_SET_MEMORY) +#undef BCE_USE_SET_MEMORY +#endif + +#if defined(__i386__) && (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,26)) && defined(SUPPORT_LINUX_X86_PAT) && defined(SUPPORT_LINUX_X86_WRITECOMBINE) +#include +#define BCE_USE_SET_MEMORY +#endif + +MODULE_SUPPORTED_DEVICE(DEVNAME); + +int BC_Example_Bridge(struct inode *inode, struct file *file, unsigned int cmd, unsigned long arg); +int FillBuffer(unsigned int uiBufferIndex); +int GetBufferCount(unsigned int *puiBufferCount); + +static int AssignedMajorNumber; + +static struct file_operations bufferclass_example_fops = { + ioctl:BC_Example_Bridge, +}; + + +#define unref__ __attribute__ ((unused)) + +#if defined(LMA) +#define PVR_BUFFERCLASS_MEMOFFSET (220 * 1024 * 1024) +#define PVR_BUFFERCLASS_MEMSIZE (4 * 1024 * 1024) + +unsigned long g_ulMemBase = 0; +unsigned long g_ulMemCurrent = 0; + +#define VENDOR_ID_PVR 0x1010 +#define DEVICE_ID_PVR 0x1CF1 + + +#define PVR_MEM_PCI_BASENUM 2 +#endif + + +static int __init BC_Example_ModInit(void) +{ +#if defined(LMA) + struct pci_dev *psPCIDev; + int error; +#endif + +#if defined(LMA) + psPCIDev = pci_get_device(VENDOR_ID_PVR, DEVICE_ID_PVR, NULL); + if (psPCIDev == NULL) + { + printk(KERN_ERR DRVNAME ": BC_Example_ModInit: pci_get_device failed\n"); + + goto ExitError; + } + + if ((error = pci_enable_device(psPCIDev)) != 0) + { + printk(KERN_ERR DRVNAME ": BC_Example_ModInit: pci_enable_device failed (%d)\n", error); + goto ExitError; + } +#endif + + AssignedMajorNumber = register_chrdev(0, DEVNAME, &bufferclass_example_fops); + + if (AssignedMajorNumber <= 0) + { + printk(KERN_ERR DRVNAME ": BC_Example_ModInit: unable to get major number\n"); + + goto ExitDisable; + } + +#if defined(DEBUG) + printk(KERN_ERR DRVNAME ": BC_Example_ModInit: major device %d\n", AssignedMajorNumber); +#endif + +#if defined(LMA) + + g_ulMemBase = pci_resource_start(psPCIDev, PVR_MEM_PCI_BASENUM) + PVR_BUFFERCLASS_MEMOFFSET; +#endif + + if(BC_Example_Init() != BCE_OK) + { + printk (KERN_ERR DRVNAME ": BC_Example_ModInit: can't init device\n"); + goto ExitUnregister; + } + +#if defined(LMA) + + pci_disable_device(psPCIDev); +#endif + + return 0; + +ExitUnregister: + unregister_chrdev(AssignedMajorNumber, DEVNAME); +ExitDisable: +#if defined(LMA) + pci_disable_device(psPCIDev); +ExitError: +#endif + return -EBUSY; +} + +static void __exit BC_Example_ModCleanup(void) +{ + unregister_chrdev(AssignedMajorNumber, DEVNAME); + + if(BC_Example_Deinit() != BCE_OK) + { + printk (KERN_ERR DRVNAME ": BC_Example_ModCleanup: can't deinit device\n"); + } + +} + + +void *BCAllocKernelMem(unsigned long ulSize) +{ + return kmalloc(ulSize, GFP_KERNEL); +} + +void BCFreeKernelMem(void *pvMem) +{ + kfree(pvMem); +} + +BCE_ERROR BCAllocContigMemory(unsigned long ulSize, + BCE_HANDLE unref__ *phMemHandle, + IMG_CPU_VIRTADDR *pLinAddr, + IMG_CPU_PHYADDR *pPhysAddr) +{ +#if defined(LMA) + void *pvLinAddr; + + + if(g_ulMemCurrent + ulSize >= PVR_BUFFERCLASS_MEMSIZE) + { + return (BCE_ERROR_OUT_OF_MEMORY); + } + + pvLinAddr = ioremap(g_ulMemBase + g_ulMemCurrent, ulSize); + + if(pvLinAddr) + { + pPhysAddr->uiAddr = g_ulMemBase + g_ulMemCurrent; + *pLinAddr = pvLinAddr; + + + g_ulMemCurrent += ulSize; + return (BCE_OK); + } + return (BCE_ERROR_OUT_OF_MEMORY); +#else +#if defined(BCE_USE_SET_MEMORY) + void *pvLinAddr; + unsigned long ulAlignedSize = PAGE_ALIGN(ulSize); + int iPages = (int)(ulAlignedSize >> PAGE_SHIFT); + int iError; + + pvLinAddr = kmalloc(ulAlignedSize, GFP_KERNEL); + BUG_ON(((unsigned long)pvLinAddr) & ~PAGE_MASK); + + iError = set_memory_wc((unsigned long)pvLinAddr, iPages); + if (iError != 0) + { + printk(KERN_ERR DRVNAME ": BCAllocContigMemory: set_memory_wc failed (%d)\n", iError); + return (BCE_ERROR_OUT_OF_MEMORY); + } + + pPhysAddr->uiAddr = virt_to_phys(pvLinAddr); + *pLinAddr = pvLinAddr; + + return (BCE_OK); +#else + dma_addr_t dma; + void *pvLinAddr; + + pvLinAddr = dma_alloc_coherent(NULL, ulSize, &dma, GFP_KERNEL); + if (pvLinAddr == NULL) + { + return (BCE_ERROR_OUT_OF_MEMORY); + } + + pPhysAddr->uiAddr = dma; + *pLinAddr = pvLinAddr; + + return (BCE_OK); +#endif +#endif +} + +void BCFreeContigMemory(unsigned long ulSize, + BCE_HANDLE unref__ hMemHandle, + IMG_CPU_VIRTADDR LinAddr, + IMG_CPU_PHYADDR PhysAddr) +{ +#if defined(LMA) + g_ulMemCurrent -= ulSize; + iounmap(LinAddr); +#else +#if defined(BCE_USE_SET_MEMORY) + unsigned long ulAlignedSize = PAGE_ALIGN(ulSize); + int iError; + int iPages = (int)(ulAlignedSize >> PAGE_SHIFT); + + iError = set_memory_wb((unsigned long)LinAddr, iPages); + if (iError != 0) + { + printk(KERN_ERR DRVNAME ": BCFreeContigMemory: set_memory_wb failed (%d)\n", iError); + } + kfree(LinAddr); +#else + dma_free_coherent(NULL, ulSize, LinAddr, (dma_addr_t)PhysAddr.uiAddr); +#endif +#endif +} + +IMG_SYS_PHYADDR CpuPAddrToSysPAddrBC(IMG_CPU_PHYADDR cpu_paddr) +{ + IMG_SYS_PHYADDR sys_paddr; + + + sys_paddr.uiAddr = cpu_paddr.uiAddr; + return sys_paddr; +} + +IMG_CPU_PHYADDR SysPAddrToCpuPAddrBC(IMG_SYS_PHYADDR sys_paddr) +{ + + IMG_CPU_PHYADDR cpu_paddr; + + cpu_paddr.uiAddr = sys_paddr.uiAddr; + return cpu_paddr; +} + +BCE_ERROR BCOpenPVRServices (BCE_HANDLE *phPVRServices) +{ + + *phPVRServices = 0; + return (BCE_OK); +} + + +BCE_ERROR BCClosePVRServices (BCE_HANDLE unref__ hPVRServices) +{ + + return (BCE_OK); +} + +BCE_ERROR BCGetLibFuncAddr (BCE_HANDLE unref__ hExtDrv, char *szFunctionName, PFN_BC_GET_PVRJTABLE *ppfnFuncTable) +{ + if(strcmp("PVRGetBufferClassJTable", szFunctionName) != 0) + { + return (BCE_ERROR_INVALID_PARAMS); + } + + + *ppfnFuncTable = PVRGetBufferClassJTable; + + return (BCE_OK); +} + + +int BC_Example_Bridge(struct inode *inode, struct file *file, unsigned int cmd, unsigned long arg) +{ + int err = -EFAULT; + int command = _IOC_NR(cmd); + BC_Example_ioctl_package *psBridge = (BC_Example_ioctl_package *)arg; + + if(!access_ok(VERIFY_WRITE, psBridge, sizeof(BC_Example_ioctl_package))) + { + return err; + } + + switch(command) + { + case _IOC_NR(BC_Example_ioctl_fill_buffer): + { + if(FillBuffer(psBridge->inputparam) == -1) + { + return err; + } + break; + } + case _IOC_NR(BC_Example_ioctl_get_buffer_count): + { + if(GetBufferCount(&psBridge->outputparam) == -1) + { + return err; + } + break; + } + default: + return err; + } + + return 0; +} + + +module_init(BC_Example_ModInit); +module_exit(BC_Example_ModCleanup); + diff --git a/services4/3rdparty/bufferclass_example/bufferclass_example_linux.h b/services4/3rdparty/bufferclass_example/bufferclass_example_linux.h new file mode 100644 index 0000000..745072b --- /dev/null +++ b/services4/3rdparty/bufferclass_example/bufferclass_example_linux.h @@ -0,0 +1,47 @@ +/********************************************************************** + * + * Copyright(c) 2008 Imagination Technologies Ltd. All rights reserved. + * + * This program is free software; you can redistribute it and/or modify it + * under the terms and conditions of the GNU General Public License, + * version 2, as published by the Free Software Foundation. + * + * This program is distributed in the hope it will be useful but, except + * as otherwise stated in writing, without any warranty; without even the + * implied warranty of merchantability or fitness for a particular purpose. + * See the GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License along with + * this program; if not, write to the Free Software Foundation, Inc., + * 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA. + * + * The full GNU General Public License is included in this distribution in + * the file called "COPYING". + * + * Contact Information: + * Imagination Technologies Ltd. + * Home Park Estate, Kings Langley, Herts, WD4 8LZ, UK + * + ******************************************************************************/ + +#ifndef __BC_EXAMPLE_LINUX_H__ +#define __BC_EXAMPLE_LINUX_H__ + +#include + +typedef struct BC_Example_ioctl_package_TAG +{ + int inputparam; + int outputparam; + +}BC_Example_ioctl_package; + +#define BC_EXAMPLE_IOC_GID 'g' + +#define BC_EXAMPLE_IOWR(INDEX) _IOWR(BC_EXAMPLE_IOC_GID, INDEX, BC_Example_ioctl_package) + +#define BC_Example_ioctl_fill_buffer BC_EXAMPLE_IOWR(0) +#define BC_Example_ioctl_get_buffer_count BC_EXAMPLE_IOWR(1) + +#endif + diff --git a/services4/3rdparty/bufferclass_example/bufferclass_example_private.c b/services4/3rdparty/bufferclass_example/bufferclass_example_private.c new file mode 100644 index 0000000..721b825 --- /dev/null +++ b/services4/3rdparty/bufferclass_example/bufferclass_example_private.c @@ -0,0 +1,214 @@ +/********************************************************************** + * + * Copyright(c) 2008 Imagination Technologies Ltd. All rights reserved. + * + * This program is free software; you can redistribute it and/or modify it + * under the terms and conditions of the GNU General Public License, + * version 2, as published by the Free Software Foundation. + * + * This program is distributed in the hope it will be useful but, except + * as otherwise stated in writing, without any warranty; without even the + * implied warranty of merchantability or fitness for a particular purpose. + * See the GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License along with + * this program; if not, write to the Free Software Foundation, Inc., + * 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA. + * + * The full GNU General Public License is included in this distribution in + * the file called "COPYING". + * + * Contact Information: + * Imagination Technologies Ltd. + * Home Park Estate, Kings Langley, Herts, WD4 8LZ, UK + * + ******************************************************************************/ + +#include "bufferclass_example.h" + +#define MIN(a,b) ((a)<(b)?(a):(b)) + +void FillYUV420Image(void *pvDest, int width, int height, int bytestride) +{ + static int iPhase = 0; + int i, j; + unsigned char u,v,y; + unsigned char *pui8y = (unsigned char *)pvDest; + unsigned short *pui16uv; + unsigned int count = 0; + + for(j=0;j>6)%(2)==0)? 0x7f:0x00; + + pui8y[count++] = y; + } + } + + pui16uv = (unsigned short *)((unsigned char *)pvDest + (width * height)); + count = 0; + + for(j=0;j>6)%(2)==0)? 0x7f:0x00; + + + pui32yuv[count++] = (y1 << 24) | (v << 16) | (y0 << 8) | u; + + } + } + + iPhase++; +} + +void FillRGB565Image(void *pvDest, int width, int height, int bytestride) +{ + int i, Count; + unsigned long *pui32Addr = (unsigned long *)pvDest; + unsigned short *pui16Addr = (unsigned short *)pvDest; + unsigned long Colour32; + unsigned short Colour16; + static unsigned char Colour8 = 0; + + Colour16 = (Colour8>>3) | ((Colour8>>2)<<5) | ((Colour8>>3)<<11); + Colour32 = Colour16 | Colour16 << 16; + + Count = (height * bytestride)>>2; + + for(i=0; i> 2; + + pui32Addr = (unsigned long *)((unsigned char *)pvDest + (bytestride * (MIN(height - 1, 0xFF) - Colour8))); + + for(i=0; ipsSystemBuffer[uiBufferIndex]; + psBufferInfo = &psDevInfo->sBufferInfo; + + + psSyncData = psBuffer->psSyncData; + + if(psSyncData) + { + + if(psSyncData->ui32ReadOpsPending != psSyncData->ui32ReadOpsComplete) + { + return -1; + } + + + psSyncData->ui32WriteOpsPending++; + } + + switch(psBufferInfo->pixelformat) + { + case PVRSRV_PIXEL_FORMAT_RGB565: + default: + { + FillRGB565Image(psBuffer->sCPUVAddr, BC_EXAMPLE_WIDTH, BC_EXAMPLE_HEIGHT, BC_EXAMPLE_STRIDE); + break; + } + case PVRSRV_PIXEL_FORMAT_FOURCC_ORG_UYVY: + { + FillYUV422Image(psBuffer->sCPUVAddr, BC_EXAMPLE_WIDTH, BC_EXAMPLE_HEIGHT, BC_EXAMPLE_STRIDE); + break; + } + case PVRSRV_PIXEL_FORMAT_NV12: + { + FillYUV420Image(psBuffer->sCPUVAddr, BC_EXAMPLE_WIDTH, BC_EXAMPLE_HEIGHT, BC_EXAMPLE_STRIDE); + break; + } + } + + + if(psSyncData) + { + psSyncData->ui32WriteOpsComplete++; + } + + return 0; +} + + +int GetBufferCount(unsigned int *puiBufferCount) +{ + BC_EXAMPLE_DEVINFO *psDevInfo = GetAnchorPtr(); + + + if(psDevInfo == IMG_NULL) + { + return -1; + } + + + *puiBufferCount = (unsigned int)psDevInfo->sBufferInfo.ui32BufferCount; + + return 0; +} + diff --git a/services4/3rdparty/bufferclass_example/kbuild/Makefile b/services4/3rdparty/bufferclass_example/kbuild/Makefile new file mode 100644 index 0000000..d0cbc45 --- /dev/null +++ b/services4/3rdparty/bufferclass_example/kbuild/Makefile @@ -0,0 +1,42 @@ +# +# Copyright(c) 2008 Imagination Technologies Ltd. All rights reserved. +# +# This program is free software; you can redistribute it and/or modify it +# under the terms and conditions of the GNU General Public License, +# version 2, as published by the Free Software Foundation. +# +# This program is distributed in the hope it will be useful but, except +# as otherwise stated in writing, without any warranty; without even the +# implied warranty of merchantability or fitness for a particular purpose. +# See the GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License along with +# this program; if not, write to the Free Software Foundation, Inc., +# 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA. +# +# The full GNU General Public License is included in this distribution in +# the file called "COPYING". +# +# Contact Information: +# Imagination Technologies Ltd. +# Home Park Estate, Kings Langley, Herts, WD4 8LZ, UK +# +# +# + +include $(EURASIAROOT)/eurasiacon/build/linux/kbuild/Makefile.kbuild_subdir_common + +MODULE = bc_example + +INCLUDES = -I$(EURASIAROOT)/include4 \ + -I$(EURASIAROOT)/services4/include \ + -I$(EURASIAROOT)/services4/system/$(PVR_SYSTEM) \ + -I$(EURASIAROOT)/services4/system/include \ + +SOURCES = ../bufferclass_example.c \ + ../bufferclass_example_linux.c \ + ../bufferclass_example_private.c + +SYM_VERS_DEPS = $(EURASIAROOT)/services4/srvkm/env/linux + + diff --git a/services4/3rdparty/bufferclass_ti/Kbuild b/services4/3rdparty/bufferclass_ti/Kbuild new file mode 100755 index 0000000..3dcf003 --- /dev/null +++ b/services4/3rdparty/bufferclass_ti/Kbuild @@ -0,0 +1,11 @@ +EXTRA_CFLAGS = -DLINUX \ + -I$(PVR_BUILD_DIR)/include4 \ + -I$(PVR_BUILD_DIR)/services4/include + +ifeq ($(TI_PLATFORM),ti8168) +EXTRA_CFLAGS += -DPLAT_TI8168 +endif + +obj-m := bufferclass_ti.o +bufferclass_ti-y := bc_cat.o + diff --git a/services4/3rdparty/bufferclass_ti/Makefile b/services4/3rdparty/bufferclass_ti/Makefile new file mode 100644 index 0000000..f261a6b --- /dev/null +++ b/services4/3rdparty/bufferclass_ti/Makefile @@ -0,0 +1,25 @@ +.PHONY: all linstall clean + +-include ../rules.make + +INCS ?= -I$(GSDK_KM_DIR)/include4 \ + -I$(GSDK_KM_DIR)/services4/include + +KBUILD_EXTRA_SYMBOLS ?= $(GSDK_KM_DIR)/Module.symvers + + +CFLAGS = -DLINUX $(INCS) +ifeq ($(OMAP3_ES2x),1) + CFLAGS += -DOMAP3_ES2x +endif + +export CROSS_COMPILE KBUILD_EXTRA_SYMBOLS + +all: + $(MAKE) -C $(KERNEL_DIR) M=`pwd` EXTRA_CFLAGS="$(CFLAGS)" modules + +clean: + $(MAKE) -C $(KERNEL_DIR) M=`pwd` clean + +install: + $(MAKE) -C $(KERNEL_DIR) M=`pwd` INSTALL_MOD_PATH=$(TGTFS_PATH) modules_install diff --git a/services4/3rdparty/bufferclass_ti/bc_cat.c b/services4/3rdparty/bufferclass_ti/bc_cat.c new file mode 100644 index 0000000..0b9f6e0 --- /dev/null +++ b/services4/3rdparty/bufferclass_ti/bc_cat.c @@ -0,0 +1,793 @@ +/********************************************************************** + * + * Copyright (C) 2009 Texas Instruments Incorporated - http://www.ti.com/ + * Copyright(c) 2008 Imagination Technologies Ltd. All rights reserved. + * + * This program is free software; you can redistribute it and/or modify it + * under the terms and conditions of the GNU General Public License, + * version 2, as published by the Free Software Foundation. + * + * This program is distributed in the hope it will be useful but, except + * as otherwise stated in writing, without any warranty; without even the + * implied warranty of merchantability or fitness for a particular purpose. + * See the GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License along with + * this program; if not, write to the Free Software Foundation, Inc., + * 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA. + * + * The full GNU General Public License is included in this distribution in + * the file called "COPYING". + * + * Contact Information: + * Imagination Technologies Ltd. + * Home Park Estate, Kings Langley, Herts, WD4 8LZ, UK + * + ******************************************************************************/ + +#include +#include +#include +#include +#include +#include +#include +#include +#include "bc_cat.h" + +#include + +#include + +#define DEVNAME "bccat" +#define DRVNAME DEVNAME +#define DEVICE_COUNT 1 + +MODULE_SUPPORTED_DEVICE(DEVNAME); + +#define unref__ __attribute__ ((unused)) + +typedef struct BC_CAT_BUFFER_TAG +{ + IMG_UINT32 ui32Size; + IMG_HANDLE hMemHandle; + IMG_SYS_PHYADDR sSysAddr; + IMG_SYS_PHYADDR sPageAlignSysAddr; + IMG_CPU_VIRTADDR sCPUVAddr; + PVRSRV_SYNC_DATA *psSyncData; + struct BC_CAT_BUFFER_TAG *psNext; +} BC_CAT_BUFFER; + + +typedef struct BC_CAT_DEVINFO_TAG +{ + int ref; + IMG_UINT32 ui32DeviceID; + BC_CAT_BUFFER *psSystemBuffer; + BUFFER_INFO sBufferInfo; + IMG_UINT32 ui32NumBuffers; + PVRSRV_BC_BUFFER2SRV_KMJTABLE sPVRJTable; + PVRSRV_BC_SRV2BUFFER_KMJTABLE sBCJTable; + IMG_HANDLE hPVRServices; + IMG_UINT32 ui32RefCount; + enum BC_memory buf_type; +} BC_CAT_DEVINFO; + + +extern IMG_IMPORT IMG_BOOL PVRGetBufferClassJTable( + PVRSRV_BC_BUFFER2SRV_KMJTABLE *psJTable); + +static int bc_open(struct inode *i, struct file *f); +static int bc_release(struct inode *i, struct file *f); +static int bc_ioctl(struct inode *inode, struct file *file, + unsigned int cmd, unsigned long arg); +static int bc_mmap(struct file *filp, struct vm_area_struct *vma); + +static int BC_CreateBuffers(int id, bc_buf_params_t *p); +static PVRSRV_ERROR BC_DestroyBuffers(int id); +static PVRSRV_ERROR BC_Register(int id); +static PVRSRV_ERROR BC_Unregister(int id); + +static PVRSRV_ERROR BCOpenPVRServices(IMG_HANDLE *phPVRServices); +static PVRSRV_ERROR BCClosePVRServices(IMG_HANDLE hPVRServices); + +static IMG_VOID *BCAllocKernelMem(IMG_UINT32 ui32Size); +static IMG_VOID BCFreeKernelMem(IMG_VOID *pvMem); + +static PVRSRV_ERROR BCAllocContigMemory(IMG_UINT32 ui32Size, + IMG_HANDLE * phMemHandle, + IMG_CPU_VIRTADDR *pLinAddr, + IMG_CPU_PHYADDR *pPhysAddr); +static IMG_VOID BCFreeContigMemory(IMG_UINT32 ui32Size, + IMG_HANDLE hMemHandle, + IMG_CPU_VIRTADDR LinAddr, + IMG_CPU_PHYADDR PhysAddr); + +static IMG_SYS_PHYADDR CpuPAddrToSysPAddrBC(IMG_CPU_PHYADDR cpu_paddr); +static IMG_CPU_PHYADDR SysPAddrToCpuPAddrBC(IMG_SYS_PHYADDR sys_paddr); + +static PVRSRV_ERROR BCGetLibFuncAddr(IMG_HANDLE hExtDrv, + IMG_CHAR *szFunctionName, + PFN_BC_GET_PVRJTABLE *ppfnFuncTable); +static BC_CAT_DEVINFO * GetAnchorPtr(int id); + + +static int major; +static struct class *bc_class; +static IMG_VOID *device[DEVICE_COUNT] = { 0 }; +static PFN_BC_GET_PVRJTABLE pfnGetPVRJTable = IMG_NULL; +static int width_align; + +static struct file_operations bc_cat_fops = { + .open = bc_open, + .release = bc_release, + .ioctl = bc_ioctl, + .mmap = bc_mmap, +}; + + +/***************************************************************************** + * func implementation + * **************************************************************************/ + +#define file_to_id(file) (iminor(file->f_path.dentry->d_inode)) + +static BC_CAT_DEVINFO * GetAnchorPtr(int id) +{ + return (BC_CAT_DEVINFO *)device[id]; +} + +static IMG_VOID SetAnchorPtr(int id, BC_CAT_DEVINFO *psDevInfo) +{ + device[id] = (IMG_VOID*)psDevInfo; +} + + +#if 0 +static PVRSRV_ERROR OpenBCDevice(IMG_HANDLE *phDevice) +{ + BC_CAT_DEVINFO *psDevInfo; + + psDevInfo = GetAnchorPtr(id); + *phDevice = (IMG_HANDLE)psDevInfo; + + return PVRSRV_OK; +} +#else + +#define OPEN_FXN(id) \ +static PVRSRV_ERROR OpenBCDevice##id(IMG_HANDLE *phDevice)\ +{ \ + BC_CAT_DEVINFO *psDevInfo; \ + psDevInfo = GetAnchorPtr (id); \ + *phDevice = (IMG_HANDLE) psDevInfo; \ + return PVRSRV_OK; \ +} + +OPEN_FXN(0) +OPEN_FXN(1) +OPEN_FXN(2) +OPEN_FXN(3) +OPEN_FXN(4) +OPEN_FXN(5) +OPEN_FXN(6) +OPEN_FXN(7) +OPEN_FXN(8) +OPEN_FXN(9) +#endif + +static PVRSRV_ERROR CloseBCDevice(IMG_HANDLE hDevice) +{ + PVR_UNREFERENCED_PARAMETER(hDevice); + + return PVRSRV_OK; +} + +static PVRSRV_ERROR GetBCBuffer(IMG_HANDLE hDevice, + IMG_UINT32 ui32BufferNumber, + PVRSRV_SYNC_DATA *psSyncData, + IMG_HANDLE *phBuffer) +{ + BC_CAT_DEVINFO *psDevInfo; + + if (!hDevice || !phBuffer) + return PVRSRV_ERROR_INVALID_PARAMS; + + psDevInfo = (BC_CAT_DEVINFO*)hDevice; + + if (ui32BufferNumber < psDevInfo->sBufferInfo.ui32BufferCount) { + psDevInfo->psSystemBuffer[ui32BufferNumber].psSyncData = psSyncData; + *phBuffer = (IMG_HANDLE)&psDevInfo->psSystemBuffer[ui32BufferNumber]; + } else { + return PVRSRV_ERROR_INVALID_PARAMS; + } + + return PVRSRV_OK; +} + + +static PVRSRV_ERROR GetBCInfo(IMG_HANDLE hDevice, BUFFER_INFO *psBCInfo) +{ + BC_CAT_DEVINFO *psDevInfo; + + if (!hDevice || !psBCInfo) + return PVRSRV_ERROR_INVALID_PARAMS; + + psDevInfo = (BC_CAT_DEVINFO*)hDevice; + *psBCInfo = psDevInfo->sBufferInfo; + + return PVRSRV_OK; +} + + +static PVRSRV_ERROR GetBCBufferAddr(IMG_HANDLE hDevice, + IMG_HANDLE hBuffer, + IMG_SYS_PHYADDR **ppsSysAddr, + IMG_UINT32 *pui32ByteSize, + IMG_VOID **ppvCpuVAddr, + IMG_HANDLE *phOSMapInfo, + IMG_BOOL *pbIsContiguous) +{ + BC_CAT_BUFFER *psBuffer; + + if (!hDevice || !hBuffer || !ppsSysAddr || !pui32ByteSize) + return PVRSRV_ERROR_INVALID_PARAMS; + + psBuffer = (BC_CAT_BUFFER *) hBuffer; + *ppsSysAddr = &psBuffer->sPageAlignSysAddr; + *ppvCpuVAddr = psBuffer->sCPUVAddr; + *pui32ByteSize = psBuffer->ui32Size; + + *phOSMapInfo = IMG_NULL; + *pbIsContiguous = IMG_TRUE; + + return PVRSRV_OK; +} + + +static int BC_CreateBuffers(int id, bc_buf_params_t *p) +{ + BC_CAT_DEVINFO *psDevInfo; + IMG_CPU_PHYADDR paddr; + IMG_UINT32 i, stride, size; + PVRSRV_PIXEL_FORMAT pixel_fmt; + + if (p->count <= 0) + return -EINVAL; + + if (p->width <= 1 || p->width % width_align || p->height <= 1) + return -EINVAL; + + switch (p->fourcc) { + case BC_PIX_FMT_NV12: + pixel_fmt = PVRSRV_PIXEL_FORMAT_NV12; + stride = p->width; + break; + case BC_PIX_FMT_UYVY: + pixel_fmt = PVRSRV_PIXEL_FORMAT_FOURCC_ORG_UYVY; + stride = p->width << 1; + break; + case BC_PIX_FMT_RGB565: + pixel_fmt = PVRSRV_PIXEL_FORMAT_RGB565; + stride = p->width << 1; + break; + case BC_PIX_FMT_YUYV: + pixel_fmt = PVRSRV_PIXEL_FORMAT_FOURCC_ORG_YUYV; + stride = p->width << 1; + break; + default: + return -EINVAL; + break; + } + + if (p->type != BC_MEMORY_MMAP && p->type != BC_MEMORY_USERPTR) + return -EINVAL; + + if ((psDevInfo = GetAnchorPtr(id)) == IMG_NULL) + return -ENODEV; + + if (psDevInfo->ui32NumBuffers) + BC_DestroyBuffers(id); + + psDevInfo->buf_type = p->type; + psDevInfo->psSystemBuffer = + BCAllocKernelMem(sizeof(BC_CAT_BUFFER) * p->count); + + if (!psDevInfo->psSystemBuffer) + return -ENOMEM; + + memset(psDevInfo->psSystemBuffer, 0, sizeof(BC_CAT_BUFFER) * p->count); + + size = p->height * stride; + if (pixel_fmt == PVRSRV_PIXEL_FORMAT_NV12) + size += (stride >> 1) * (p->height >> 1) << 1; + + for (i=0; i < p->count; i++) { + if (psDevInfo->buf_type == BC_MEMORY_MMAP) { + if (BCAllocContigMemory(size, + &psDevInfo->psSystemBuffer[i].hMemHandle, + &psDevInfo->psSystemBuffer[i].sCPUVAddr, + &paddr) != PVRSRV_OK) + /*TODO should free() and return failure*/ + break; + + psDevInfo->psSystemBuffer[i].sSysAddr = CpuPAddrToSysPAddrBC(paddr); + psDevInfo->psSystemBuffer[i].sPageAlignSysAddr.uiAddr = + psDevInfo->psSystemBuffer[i].sSysAddr.uiAddr & 0xFFFFF000; + } + psDevInfo->ui32NumBuffers++; + psDevInfo->psSystemBuffer[i].ui32Size = size; + psDevInfo->psSystemBuffer[i].psSyncData = IMG_NULL; + } + p->count = psDevInfo->ui32NumBuffers; + + psDevInfo->sBufferInfo.ui32BufferCount = psDevInfo->ui32NumBuffers; + psDevInfo->sBufferInfo.pixelformat = pixel_fmt; + psDevInfo->sBufferInfo.ui32Width = p->width; + psDevInfo->sBufferInfo.ui32Height = p->height; + psDevInfo->sBufferInfo.ui32ByteStride = stride; + psDevInfo->sBufferInfo.ui32BufferDeviceID = id; + psDevInfo->sBufferInfo.ui32Flags = PVRSRV_BC_FLAGS_YUVCSC_FULL_RANGE | + PVRSRV_BC_FLAGS_YUVCSC_BT601; + return 0; +} + + +static PVRSRV_ERROR BC_DestroyBuffers(int id) +{ + BC_CAT_DEVINFO *psDevInfo; + IMG_UINT32 i; + + if ((psDevInfo = GetAnchorPtr(id)) == IMG_NULL) + return PVRSRV_ERROR_DEVICE_REGISTER_FAILED; + + if (!psDevInfo->ui32NumBuffers) + return PVRSRV_OK; + + if (psDevInfo->buf_type == BC_MEMORY_MMAP) + for (i = 0; i < psDevInfo->ui32NumBuffers; i++) { + BCFreeContigMemory(psDevInfo->psSystemBuffer[i].ui32Size, + psDevInfo->psSystemBuffer[i].hMemHandle, + psDevInfo->psSystemBuffer[i].sCPUVAddr, + SysPAddrToCpuPAddrBC(psDevInfo->psSystemBuffer[i].sSysAddr)); + } + + BCFreeKernelMem(psDevInfo->psSystemBuffer); + + psDevInfo->ui32NumBuffers = 0; + psDevInfo->sBufferInfo.pixelformat = PVRSRV_PIXEL_FORMAT_UNKNOWN; + psDevInfo->sBufferInfo.ui32Width = 0; + psDevInfo->sBufferInfo.ui32Height = 0; + psDevInfo->sBufferInfo.ui32ByteStride = 0; + psDevInfo->sBufferInfo.ui32BufferDeviceID = id; + psDevInfo->sBufferInfo.ui32Flags = 0; + psDevInfo->sBufferInfo.ui32BufferCount = psDevInfo->ui32NumBuffers; + + return PVRSRV_OK; +} + + +static PVRSRV_ERROR BC_Register(id) +{ + BC_CAT_DEVINFO *psDevInfo; + + psDevInfo = GetAnchorPtr(id); + + if (psDevInfo) { + psDevInfo->ui32RefCount++; + return PVRSRV_OK; + } + + psDevInfo = (BC_CAT_DEVINFO *)BCAllocKernelMem(sizeof(BC_CAT_DEVINFO)); + + if (!psDevInfo) + return PVRSRV_ERROR_OUT_OF_MEMORY; + + psDevInfo->ref = 0; + psDevInfo->ui32RefCount = 0; + SetAnchorPtr(id, (IMG_VOID*)psDevInfo); + + if (BCOpenPVRServices(&psDevInfo->hPVRServices) != PVRSRV_OK) + return PVRSRV_ERROR_INIT_FAILURE; + + if (BCGetLibFuncAddr(psDevInfo->hPVRServices, "PVRGetBufferClassJTable", + &pfnGetPVRJTable) != PVRSRV_OK) + return PVRSRV_ERROR_INIT_FAILURE; + + if (!(*pfnGetPVRJTable)(&psDevInfo->sPVRJTable)) + return PVRSRV_ERROR_INIT_FAILURE; + + psDevInfo->ui32NumBuffers = 0; + + psDevInfo->sBufferInfo.pixelformat = PVRSRV_PIXEL_FORMAT_UNKNOWN; + psDevInfo->sBufferInfo.ui32Width = 0; + psDevInfo->sBufferInfo.ui32Height = 0; + psDevInfo->sBufferInfo.ui32ByteStride = 0; + psDevInfo->sBufferInfo.ui32BufferDeviceID = id; + psDevInfo->sBufferInfo.ui32Flags = 0; + psDevInfo->sBufferInfo.ui32BufferCount = psDevInfo->ui32NumBuffers; + + psDevInfo->sBCJTable.ui32TableSize = sizeof(PVRSRV_BC_SRV2BUFFER_KMJTABLE); +#if 0 + psDevInfo->sBCJTable.pfnOpenBCDevice = OpenBCDevice; +#else + if (id == 0) { + psDevInfo->sBCJTable.pfnOpenBCDevice = OpenBCDevice0; + } else if (id == 1) { + psDevInfo->sBCJTable.pfnOpenBCDevice = OpenBCDevice1; + } else if (id == 2) { + psDevInfo->sBCJTable.pfnOpenBCDevice = OpenBCDevice2; + } else if (id == 3) { + psDevInfo->sBCJTable.pfnOpenBCDevice = OpenBCDevice3; + } else if (id == 4) { + psDevInfo->sBCJTable.pfnOpenBCDevice = OpenBCDevice4; + } else if (id == 5) { + psDevInfo->sBCJTable.pfnOpenBCDevice = OpenBCDevice5; + } else if (id == 6) { + psDevInfo->sBCJTable.pfnOpenBCDevice = OpenBCDevice6; + } else if (id == 7) { + psDevInfo->sBCJTable.pfnOpenBCDevice = OpenBCDevice7; + } else if (id == 8) { + psDevInfo->sBCJTable.pfnOpenBCDevice = OpenBCDevice8; + } else if (id == 9) { + psDevInfo->sBCJTable.pfnOpenBCDevice = OpenBCDevice9; + } else { + printk("bad device id: %d\n", id); + return PVRSRV_ERROR_DEVICE_REGISTER_FAILED; + } +#endif + psDevInfo->sBCJTable.pfnCloseBCDevice = CloseBCDevice; + psDevInfo->sBCJTable.pfnGetBCBuffer = GetBCBuffer; + psDevInfo->sBCJTable.pfnGetBCInfo = GetBCInfo; + psDevInfo->sBCJTable.pfnGetBufferAddr = GetBCBufferAddr; + + if (psDevInfo->sPVRJTable.pfnPVRSRVRegisterBCDevice( + &psDevInfo->sBCJTable, + &psDevInfo->ui32DeviceID) != PVRSRV_OK) + return PVRSRV_ERROR_DEVICE_REGISTER_FAILED; + + psDevInfo->ui32RefCount++; + + return PVRSRV_OK; +} + + +static PVRSRV_ERROR BC_Unregister(int id) +{ + BC_CAT_DEVINFO *psDevInfo; + PVRSRV_BC_BUFFER2SRV_KMJTABLE *psJTable; + + if ((psDevInfo = GetAnchorPtr(id)) == IMG_NULL) + return PVRSRV_ERROR_DEVICE_REGISTER_FAILED; + + psDevInfo->ui32RefCount--; + + if (psDevInfo->ui32RefCount) + return PVRSRV_ERROR_RETRY; + + psJTable = &psDevInfo->sPVRJTable; + + if (psJTable->pfnPVRSRVRemoveBCDevice(psDevInfo->ui32DeviceID) != PVRSRV_OK) + return PVRSRV_ERROR_GENERIC; + + if (BCClosePVRServices(psDevInfo->hPVRServices) != PVRSRV_OK) { + psDevInfo->hPVRServices = IMG_NULL; + return PVRSRV_ERROR_GENERIC; + } + + BCFreeKernelMem(psDevInfo); + SetAnchorPtr(id, IMG_NULL); + + return PVRSRV_OK; +} + + +static int __init bc_cat_init(void) +{ + struct device *bc_dev; + int id; + + /* texture buffer width should be multiple of 8 for OMAP3 ES3.x, + * or 32 for ES2.x */ +#ifdef PLAT_TI8168 + width_align = 8; +#else + width_align = cpu_is_omap3530() && omap_rev_lt_3_0() ? 32 : 8; +#endif + major = register_chrdev(0, DEVNAME, &bc_cat_fops); + + if (major <= 0) { + printk(KERN_ERR DRVNAME ": unable to get major number\n"); + goto ExitDisable; + } + + bc_class = class_create(THIS_MODULE, DEVNAME); + + if (IS_ERR(bc_class)) { + printk(KERN_ERR DRVNAME ": upable to create device class\n"); + goto ExitUnregister; + } + + for (id = 0; id < DEVICE_COUNT; id++) { + bc_dev = device_create(bc_class, NULL, MKDEV(major, id), NULL, + DEVNAME "%d", id); + + if (IS_ERR(bc_dev)) { + printk(KERN_ERR DRVNAME ": unable to create device %d\n", id); + goto ExitDestroyClass; + } + + if (BC_Register(id) != PVRSRV_OK) { + printk (KERN_ERR DRVNAME ": can't register BC service %d\n", id); + if (id > 0) { + /* lets live with the drivers that we were able to create soi + * far, even though it isn't as many as we'd like + */ + break; + } + goto ExitUnregister; + } + } + + return 0; + +ExitDestroyClass: + class_destroy(bc_class); +ExitUnregister: + unregister_chrdev(major, DEVNAME); +ExitDisable: + return -EBUSY; +} + +static void __exit bc_cat_cleanup(void) +{ + int id; + + for (id = 0; id < DEVICE_COUNT; id++) { + if (BC_DestroyBuffers(id) != PVRSRV_OK) { + printk(KERN_ERR DRVNAME ": can't free texture buffers\n"); + return; + } + if (BC_Unregister(id) != PVRSRV_OK) { + printk(KERN_ERR DRVNAME ": can't un-register BC service\n"); + return; + } + device_destroy(bc_class, MKDEV(major, id)); + } + class_destroy(bc_class); + unregister_chrdev(major, DEVNAME); +} + + +static IMG_VOID *BCAllocKernelMem(IMG_UINT32 ui32Size) +{ + return kmalloc(ui32Size, GFP_KERNEL); +} + +static IMG_VOID BCFreeKernelMem(IMG_VOID *pvMem) +{ + kfree(pvMem); +} + +static PVRSRV_ERROR BCAllocContigMemory(IMG_UINT32 ui32Size, + IMG_HANDLE unref__ *phMemHandle, + IMG_CPU_VIRTADDR *pLinAddr, + IMG_CPU_PHYADDR *pPhysAddr) +{ + IMG_VOID *pvLinAddr; + gfp_t mask = GFP_KERNEL; + + pvLinAddr = alloc_pages_exact(ui32Size, mask); +/* printk("pvLinAddr=%p, ui32Size=%ld\n", pvLinAddr, ui32Size);*/ + + if (pvLinAddr == IMG_NULL) + return PVRSRV_ERROR_OUT_OF_MEMORY; + + pPhysAddr->uiAddr = virt_to_phys(pvLinAddr); + + *pLinAddr = pvLinAddr; + + return PVRSRV_OK; +} + +static IMG_VOID BCFreeContigMemory(IMG_UINT32 ui32Size, + IMG_HANDLE unref__ hMemHandle, + IMG_CPU_VIRTADDR LinAddr, + IMG_CPU_PHYADDR PhysAddr) +{ + free_pages_exact(LinAddr, ui32Size); +} + +static IMG_SYS_PHYADDR CpuPAddrToSysPAddrBC(IMG_CPU_PHYADDR cpu_paddr) +{ + IMG_SYS_PHYADDR sys_paddr; + + sys_paddr.uiAddr = cpu_paddr.uiAddr; + return sys_paddr; +} + +static IMG_CPU_PHYADDR SysPAddrToCpuPAddrBC(IMG_SYS_PHYADDR sys_paddr) +{ + IMG_CPU_PHYADDR cpu_paddr; + + cpu_paddr.uiAddr = sys_paddr.uiAddr; + return cpu_paddr; +} + +static PVRSRV_ERROR BCOpenPVRServices (IMG_HANDLE *phPVRServices) +{ + *phPVRServices = 0; + return PVRSRV_OK; +} + + +static PVRSRV_ERROR BCClosePVRServices (IMG_HANDLE unref__ hPVRServices) +{ + return PVRSRV_OK; +} + +static PVRSRV_ERROR BCGetLibFuncAddr(IMG_HANDLE unref__ hExtDrv, + IMG_CHAR *szFunctionName, + PFN_BC_GET_PVRJTABLE *ppfnFuncTable) +{ + if (strcmp("PVRGetBufferClassJTable", szFunctionName) != 0) + return PVRSRV_ERROR_INVALID_PARAMS; + + *ppfnFuncTable = PVRGetBufferClassJTable; + return PVRSRV_OK; +} + + +static int bc_open(struct inode *i, struct file *f) +{ + BC_CAT_DEVINFO *devinfo; + int id = file_to_id(f); + + if ((devinfo = GetAnchorPtr(id)) == IMG_NULL) { + printk("no device %d\n", id); + return -ENODEV; + } + + if (devinfo->ref) { + printk("device %d busy\n", id); + return -EBUSY; + } + + devinfo->ref++; + return 0; +} + + +static int bc_release(struct inode *i, struct file *f) +{ + BC_CAT_DEVINFO *devinfo; + int id = file_to_id(f); + + if ((devinfo = GetAnchorPtr(id)) == IMG_NULL) + return -ENODEV; + + if (devinfo->ref) + devinfo->ref--; + return 0; +} + + +static int bc_mmap(struct file *filp, struct vm_area_struct *vma) +{ +#if defined(DEBUG) + printk("bc_mmap: vma->vm_start = %#lx\n", vma->vm_start); + printk("bc_mmap: vma->vm_pgoff = %#lx\n", vma->vm_pgoff); + printk("bc_mmap: size = %#lx\n", vma->vm_end - vma->vm_start); +#endif + + /*FIXME check start & size*/ + if (remap_pfn_range(vma, vma->vm_start, vma->vm_pgoff, + vma->vm_end - vma->vm_start, + vma->vm_page_prot)) { + printk("bc_mmap: failed remap_pfn_range\n"); + return -EAGAIN; + } + return 0; +} + +static int bc_ioctl(struct inode *inode, struct file *file, + unsigned int cmd, unsigned long arg) +{ + BC_CAT_DEVINFO *devinfo; + int id = file_to_id (file); + + if ((devinfo = GetAnchorPtr(id)) == IMG_NULL) + return -ENODEV; + + switch(_IOC_NR(cmd)) { + case _IOC_NR(BCIOGET_BUFFERCOUNT): + { + BCIO_package *params = (BCIO_package *)arg; + + if (!access_ok(VERIFY_WRITE, params, sizeof(BCIO_package))) + return -EFAULT; + + params->output = devinfo->sBufferInfo.ui32BufferCount; + break; + } + case _IOC_NR(BCIOGET_BUFFERPHYADDR): + { + int idx; + BCIO_package *params = (BCIO_package *)arg; + + if (!access_ok(VERIFY_WRITE, params, sizeof(BCIO_package))) + return -EFAULT; + + idx = params->input; + if (idx < 0 || idx > devinfo->ui32NumBuffers) { + printk(KERN_ERR DRVNAME + ": BCIOGET_BUFFERADDR - idx out of range\n"); + return -EINVAL; + } + params->output = devinfo->psSystemBuffer[idx].sSysAddr.uiAddr; + break; + } + case _IOC_NR(BCIOGET_BUFFERIDX): + { + int idx; + BC_CAT_BUFFER *buffer; + BCIO_package *params = (BCIO_package *)arg; + + if (!access_ok(VERIFY_WRITE, params, sizeof(BCIO_package))) + return -EFAULT; + + for (idx = 0; idx < devinfo->ui32NumBuffers; idx++) { + buffer = &devinfo->psSystemBuffer[idx]; + + if (params->input == (int)buffer->sSysAddr.uiAddr) { + params->output = idx; + return 0; + } + } + printk(KERN_ERR DRVNAME ": BCIOGET_BUFFERIDX- buffer not found\n"); + return -EINVAL; + break; + } + case _IOC_NR(BCIOREQ_BUFFERS): + { + bc_buf_params_t *p = (bc_buf_params_t *) arg; + + if (!access_ok(VERIFY_WRITE, p, sizeof(bc_buf_params_t))) + return -EFAULT; + + return BC_CreateBuffers(id, p); + break; + } + case _IOC_NR(BCIOSET_BUFFERPHYADDR): + { + bc_buf_ptr_t p; + IMG_CPU_PHYADDR img_pa; + + if (copy_from_user(&p, (void __user *)arg, sizeof(p))) + return -EFAULT; + + if (p.index >= devinfo->ui32NumBuffers || !p.pa) + return -EINVAL; + + /*TODO check buffer size*/ + + img_pa.uiAddr = p.pa; + + devinfo->psSystemBuffer[p.index].sCPUVAddr = phys_to_virt(p.pa); + devinfo->psSystemBuffer[p.index].sSysAddr = + CpuPAddrToSysPAddrBC(img_pa); + devinfo->psSystemBuffer[p.index].sPageAlignSysAddr.uiAddr = + devinfo->psSystemBuffer[p.index].sSysAddr.uiAddr & + 0xFFFFF000; + break; + } + default: + return -EFAULT; + } + return 0; +} + +module_init(bc_cat_init); +module_exit(bc_cat_cleanup); + +MODULE_LICENSE("GPL v2"); diff --git a/services4/3rdparty/bufferclass_ti/bc_cat.h b/services4/3rdparty/bufferclass_ti/bc_cat.h new file mode 100644 index 0000000..3ca0b69 --- /dev/null +++ b/services4/3rdparty/bufferclass_ti/bc_cat.h @@ -0,0 +1,84 @@ +/********************************************************************** + * + * Copyright (C) 2009 Texas Instruments Incorporated - http://www.ti.com/ + * Copyright(c) 2008 Imagination Technologies Ltd. All rights reserved. + * + * This program is free software; you can redistribute it and/or modify it + * under the terms and conditions of the GNU General Public License, + * version 2, as published by the Free Software Foundation. + * + * This program is distributed in the hope it will be useful but, except + * as otherwise stated in writing, without any warranty; without even the + * implied warranty of merchantability or fitness for a particular purpose. + * See the GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License along with + * this program; if not, write to the Free Software Foundation, Inc., + * 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA. + * + * The full GNU General Public License is included in this distribution in + * the file called "COPYING". + * + * Contact Information: + * Imagination Technologies Ltd. + * Home Park Estate, Kings Langley, Herts, WD4 8LZ, UK + * + ******************************************************************************/ + +#ifndef __BC_CAT_H__ +#define __BC_CAT_H__ + +#include + +#define BC_FOURCC(a,b,c,d) \ + ((unsigned long) ((a) | (b)<<8 | (c)<<16 | (d)<<24)) + +#define BC_PIX_FMT_NV12 BC_FOURCC('N', 'V', '1', '2') /*YUV 4:2:0*/ +#define BC_PIX_FMT_UYVY BC_FOURCC('U', 'Y', 'V', 'Y') /*YUV 4:2:2*/ +#define BC_PIX_FMT_YUYV BC_FOURCC('Y', 'U', 'Y', 'V') /*YUV 4:2:2*/ +#define BC_PIX_FMT_RGB565 BC_FOURCC('R', 'G', 'B', 'P') /*RGB 5:6:5*/ + +enum BC_memory { + BC_MEMORY_MMAP = 1, + BC_MEMORY_USERPTR = 2, +}; + +typedef struct BCIO_package_TAG { + int input; + int output; +}BCIO_package; + +/* + * the following types are tested for fourcc in struct bc_buf_params_t + * NV12 + * UYVY + * RGB565 - not tested yet + * YUYV + */ +typedef struct bc_buf_params { + int count; /*number of buffers, [in/out]*/ + int width; /*buffer width in pixel, multiple of 8 or 32*/ + int height; /*buffer height in pixel*/ + unsigned int fourcc; /*buffer pixel format*/ + enum BC_memory type; +} bc_buf_params_t; + +typedef struct bc_buf_ptr { + unsigned int index; + int size; + unsigned long pa; +} bc_buf_ptr_t; + +#define BCIO_GID 'g' +#define BC_IOWR(INDEX) _IOWR(BCIO_GID, INDEX, BCIO_package) + +#define BCIOGET_BUFFERCOUNT BC_IOWR(0) /*obsolete, since BCIOREQ_BUFFERS + return the number of buffers*/ +#define BCIOGET_BUFFERPHYADDR BC_IOWR(1) /*get physical address by index*/ +#define BCIOGET_BUFFERIDX BC_IOWR(2) /*get index by physical address*/ + +#define BCIOREQ_BUFFERS BC_IOWR(3) +#define BCIOSET_BUFFERPHYADDR BC_IOWR(4) + +#endif + diff --git a/services4/3rdparty/bufferclass_ti/modules.order b/services4/3rdparty/bufferclass_ti/modules.order new file mode 100644 index 0000000..cc7b6f2 --- /dev/null +++ b/services4/3rdparty/bufferclass_ti/modules.order @@ -0,0 +1 @@ +kernel//proj/AVME10/mahesh/Graphics/Netra/Graphics_SDK_4_00_00_01/GFX_Linux_KM/services4/3rdparty/bufferclass_ti/bufferclass_ti.ko diff --git a/services4/3rdparty/dc_omap3430_linux/Kbuild b/services4/3rdparty/dc_omap3430_linux/Kbuild new file mode 100755 index 0000000..eca3626 --- /dev/null +++ b/services4/3rdparty/dc_omap3430_linux/Kbuild @@ -0,0 +1,16 @@ +SYS_USING_INTERRUPTS = 1 +SUPPORT_TI_DSS_FW = 0 + +SYS_CFLAGS.$(SYS_USING_INTERRUPTS) += -DSYS_USING_INTERRUPTS +SYS_CFLAGS.$(SUPPORT_TI_DSS_FW) += -DSUPPORT_TI_DSS_FW + + +EXTRA_CFLAGS = -DLINUX \ + -I$(PVR_BUILD_DIR)/include4 \ + -I$(PVR_BUILD_DIR)/services4/include \ + -I$(PVR_BUILD_DIR)/services4/system/$(PVR_SYSTEM) \ + -I$(PVR_BUILD_DIR)/services4/system/include \ + $(SYS_CFLAGS.1) \ + +obj-m := omaplfb.o +omaplfb-y := omaplfb_displayclass.o omaplfb_linux.o diff --git a/services4/3rdparty/dc_omap3430_linux/kbuild/Makefile b/services4/3rdparty/dc_omap3430_linux/kbuild/Makefile new file mode 100644 index 0000000..54139af --- /dev/null +++ b/services4/3rdparty/dc_omap3430_linux/kbuild/Makefile @@ -0,0 +1,43 @@ +# +# Copyright(c) 2008 Imagination Technologies Ltd. All rights reserved. +# +# This program is free software; you can redistribute it and/or modify it +# under the terms and conditions of the GNU General Public License, +# version 2, as published by the Free Software Foundation. +# +# This program is distributed in the hope it will be useful but, except +# as otherwise stated in writing, without any warranty; without even the +# implied warranty of merchantability or fitness for a particular purpose. +# See the GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License along with +# this program; if not, write to the Free Software Foundation, Inc., +# 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA. +# +# The full GNU General Public License is included in this distribution in +# the file called "COPYING". +# +# Contact Information: +# Imagination Technologies Ltd. +# Home Park Estate, Kings Langley, Herts, WD4 8LZ, UK +# +# +# + +include $(EURASIAROOT)/eurasiacon/build/linux/kbuild/Makefile.kbuild_subdir_common + +MODULE = omaplfb + +INCLUDES = -I$(EURASIAROOT)/include4 \ + -I$(EURASIAROOT)/services4/include \ + -I$(EURASIAROOT)/services4/system/$(PVR_SYSTEM) \ + -I$(EURASIAROOT)/services4/system/include \ + +SOURCES = ../omaplfb_displayclass.c \ + ../omaplfb_linux.c + +SYM_VERS_DEPS = $(EURASIAROOT)/services4/srvkm/env/linux + + + + diff --git a/services4/3rdparty/dc_omap3430_linux/modules.order b/services4/3rdparty/dc_omap3430_linux/modules.order new file mode 100644 index 0000000..104b655 --- /dev/null +++ b/services4/3rdparty/dc_omap3430_linux/modules.order @@ -0,0 +1 @@ +kernel//proj/AVME10/mahesh/Graphics/Netra/Graphics_SDK_4_00_00_01/GFX_Linux_KM/services4/3rdparty/dc_omap3430_linux/omaplfb.ko diff --git a/services4/3rdparty/dc_omap3430_linux/omaplfb.h b/services4/3rdparty/dc_omap3430_linux/omaplfb.h new file mode 100644 index 0000000..da63959 --- /dev/null +++ b/services4/3rdparty/dc_omap3430_linux/omaplfb.h @@ -0,0 +1,280 @@ +/********************************************************************** + * + * Copyright(c) 2008 Imagination Technologies Ltd. All rights reserved. + * + * This program is free software; you can redistribute it and/or modify it + * under the terms and conditions of the GNU General Public License, + * version 2, as published by the Free Software Foundation. + * + * This program is distributed in the hope it will be useful but, except + * as otherwise stated in writing, without any warranty; without even the + * implied warranty of merchantability or fitness for a particular purpose. + * See the GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License along with + * this program; if not, write to the Free Software Foundation, Inc., + * 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA. + * + * The full GNU General Public License is included in this distribution in + * the file called "COPYING". + * + * Contact Information: + * Imagination Technologies Ltd. + * Home Park Estate, Kings Langley, Herts, WD4 8LZ, UK + * + ******************************************************************************/ + +#ifndef __OMAPLFB_H__ +#define __OMAPLFB_H__ + +extern IMG_BOOL PVRGetDisplayClassJTable(PVRSRV_DC_DISP2SRV_KMJTABLE *psJTable); + +#define OMAPLCD_IRQ 25 + +#define OMAPLCD_SYSCONFIG 0x0410 +#define OMAPLCD_CONFIG 0x0444 +#define OMAPLCD_DEFAULT_COLOR0 0x044C +#define OMAPLCD_TIMING_H 0x0464 +#define OMAPLCD_TIMING_V 0x0468 +#define OMAPLCD_POL_FREQ 0x046C +#define OMAPLCD_DIVISOR 0x0470 +#define OMAPLCD_SIZE_DIG 0x0478 +#define OMAPLCD_SIZE_LCD 0x047C +#define OMAPLCD_GFX_POSITION 0x0488 +#define OMAPLCD_GFX_SIZE 0x048C +#define OMAPLCD_GFX_ATTRIBUTES 0x04a0 +#define OMAPLCD_GFX_FIFO_THRESHOLD 0x04a4 +#define OMAPLCD_GFX_WINDOW_SKIP 0x04b4 + +#define OMAPLCD_IRQSTATUS 0x0418 +#define OMAPLCD_IRQENABLE 0x041c +#define OMAPLCD_CONTROL 0x0440 +#define OMAPLCD_GFX_BA0 0x0480 +#define OMAPLCD_GFX_BA1 0x0484 +#define OMAPLCD_GFX_ROW_INC 0x04ac +#define OMAPLCD_GFX_PIX_INC 0x04b0 +#define OMAPLCD_VID1_BA0 0x04bc +#define OMAPLCD_VID1_BA1 0x04c0 +#define OMAPLCD_VID1_ROW_INC 0x04d8 +#define OMAPLCD_VID1_PIX_INC 0x04dc + +#define OMAP_CONTROL_GODIGITAL (1 << 6) +#define OMAP_CONTROL_GOLCD (1 << 5) +#define OMAP_CONTROL_DIGITALENABLE (1 << 1) +#define OMAP_CONTROL_LCDENABLE (1 << 0) + +#define OMAPLCD_INTMASK_VSYNC (1 << 1) +#define OMAPLCD_INTMASK_OFF 0 + +typedef void * OMAP_HANDLE; + +typedef enum tag_omap_bool +{ + OMAP_FALSE = 0, + OMAP_TRUE = 1, +} OMAP_BOOL, *OMAP_PBOOL; + +typedef struct OMAPLFB_BUFFER_TAG +{ + unsigned long ulBufferSize; + + + + + IMG_SYS_PHYADDR sSysAddr; + IMG_CPU_VIRTADDR sCPUVAddr; + PVRSRV_SYNC_DATA *psSyncData; + + struct OMAPLFB_BUFFER_TAG *psNext; +} OMAPLFB_BUFFER; + +typedef struct OMAPLFB_VSYNC_FLIP_ITEM_TAG +{ + + + + OMAP_HANDLE hCmdComplete; + + unsigned long ulSwapInterval; + + OMAP_BOOL bValid; + + OMAP_BOOL bFlipped; + + OMAP_BOOL bCmdCompleted; + + + + + + IMG_SYS_PHYADDR* sSysAddr; +} OMAPLFB_VSYNC_FLIP_ITEM; + +typedef struct PVRPDP_SWAPCHAIN_TAG +{ + + unsigned long ulBufferCount; + + OMAPLFB_BUFFER *psBuffer; + + OMAPLFB_VSYNC_FLIP_ITEM *psVSyncFlips; + + + unsigned long ulInsertIndex; + + + unsigned long ulRemoveIndex; + + + void *pvRegs; + + + PVRSRV_DC_DISP2SRV_KMJTABLE *psPVRJTable; + + + OMAP_BOOL bFlushCommands; + + + unsigned long ulSetFlushStateRefCount; + + + OMAP_BOOL bBlanked; + + + spinlock_t *psSwapChainLock; +} OMAPLFB_SWAPCHAIN; + +typedef struct OMAPLFB_FBINFO_TAG +{ + unsigned long ulFBSize; + unsigned long ulBufferSize; + unsigned long ulRoundedBufferSize; + unsigned long ulWidth; + unsigned long ulHeight; + unsigned long ulByteStride; + + + + IMG_SYS_PHYADDR sSysAddr; + IMG_CPU_VIRTADDR sCPUVAddr; + + + PVRSRV_PIXEL_FORMAT ePixelFormat; +}OMAPLFB_FBINFO; + +typedef struct OMAPLFB_DEVINFO_TAG +{ + unsigned long ulDeviceID; + + + OMAPLFB_BUFFER sSystemBuffer; + + + PVRSRV_DC_DISP2SRV_KMJTABLE sPVRJTable; + + + PVRSRV_DC_SRV2DISP_KMJTABLE sDCJTable; + + + OMAPLFB_FBINFO sFBInfo; + + + unsigned long ulRefCount; + + + OMAPLFB_SWAPCHAIN *psSwapChain; + + + OMAP_BOOL bFlushCommands; + + + struct fb_info *psLINFBInfo; + + + struct notifier_block sLINNotifBlock; + + + OMAP_BOOL bDeviceSuspended; + + + spinlock_t sSwapChainLock; + + + + + + IMG_DEV_VIRTADDR sDisplayDevVAddr; + + DISPLAY_INFO sDisplayInfo; + + + DISPLAY_FORMAT sDisplayFormat; + + + DISPLAY_DIMS sDisplayDim; + +} OMAPLFB_DEVINFO; + +#define OMAPLFB_PAGE_SIZE 4096 +#define OMAPLFB_PAGE_MASK (OMAPLFB_PAGE_SIZE - 1) +#define OMAPLFB_PAGE_TRUNC (~OMAPLFB_PAGE_MASK) + +#define OMAPLFB_PAGE_ROUNDUP(x) (((x) + OMAPLFB_PAGE_MASK) & OMAPLFB_PAGE_TRUNC) + +#ifdef DEBUG +#define DEBUG_PRINTK(x) printk x +#else +#define DEBUG_PRINTK(x) +#endif + +#define DISPLAY_DEVICE_NAME "PowerVR OMAP Linux Display Driver" +#define DRVNAME "omaplfb" +#define DEVNAME DRVNAME +#define DRIVER_PREFIX DRVNAME + +typedef enum _OMAP_ERROR_ +{ + OMAP_OK = 0, + OMAP_ERROR_GENERIC = 1, + OMAP_ERROR_OUT_OF_MEMORY = 2, + OMAP_ERROR_TOO_FEW_BUFFERS = 3, + OMAP_ERROR_INVALID_PARAMS = 4, + OMAP_ERROR_INIT_FAILURE = 5, + OMAP_ERROR_CANT_REGISTER_CALLBACK = 6, + OMAP_ERROR_INVALID_DEVICE = 7, + OMAP_ERROR_DEVICE_REGISTER_FAILED = 8 +} OMAP_ERROR; + + +#ifndef UNREFERENCED_PARAMETER +#define UNREFERENCED_PARAMETER(param) (param) = (param) +#endif + +OMAP_ERROR OMAPLFBInit(void); +OMAP_ERROR OMAPLFBDeinit(void); + +#ifdef LDM_PLATFORM +void OMAPLFBDriverSuspend(void); +void OMAPLFBDriverResume(void); +#endif + +void *OMAPLFBAllocKernelMem(unsigned long ulSize); +void OMAPLFBFreeKernelMem(void *pvMem); +OMAP_ERROR OMAPLFBGetLibFuncAddr(char *szFunctionName, PFN_DC_GET_PVRJTABLE *ppfnFuncTable); +OMAP_ERROR OMAPLFBInstallVSyncISR (OMAPLFB_SWAPCHAIN *psSwapChain); +OMAP_ERROR OMAPLFBUninstallVSyncISR(OMAPLFB_SWAPCHAIN *psSwapChain); +OMAP_BOOL OMAPLFBVSyncIHandler(OMAPLFB_SWAPCHAIN *psSwapChain); +void OMAPLFBEnableVSyncInterrupt(OMAPLFB_SWAPCHAIN *psSwapChain); +void OMAPLFBDisableVSyncInterrupt(OMAPLFB_SWAPCHAIN *psSwapChain); +#if defined (SUPPORT_TI_DSS_FW) +void OMAPLFBEnableDisplayRegisterAccess(void); +void OMAPLFBDisableDisplayRegisterAccess(void); +#endif +#if defined (CONFIG_OMAP2_DSS) +IMG_VOID OMAPLFBFlipDSS2(OMAPLFB_SWAPCHAIN *psSwapChain, + IMG_UINT32 aPhyAddr); +#endif +void OMAPLFBFlip(OMAPLFB_SWAPCHAIN *psSwapChain, unsigned long aPhyAddr); + +#endif + diff --git a/services4/3rdparty/dc_omap3430_linux/omaplfb_displayclass.c b/services4/3rdparty/dc_omap3430_linux/omaplfb_displayclass.c new file mode 100644 index 0000000..349beb5 --- /dev/null +++ b/services4/3rdparty/dc_omap3430_linux/omaplfb_displayclass.c @@ -0,0 +1,1527 @@ +/********************************************************************** + * + * Copyright(c) 2008 Imagination Technologies Ltd. All rights reserved. + * + * This program is free software; you can redistribute it and/or modify it + * under the terms and conditions of the GNU General Public License, + * version 2, as published by the Free Software Foundation. + * + * This program is distributed in the hope it will be useful but, except + * as otherwise stated in writing, without any warranty; without even the + * implied warranty of merchantability or fitness for a particular purpose. + * See the GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License along with + * this program; if not, write to the Free Software Foundation, Inc., + * 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA. + * + * The full GNU General Public License is included in this distribution in + * the file called "COPYING". + * + * Contact Information: + * Imagination Technologies Ltd. + * Home Park Estate, Kings Langley, Herts, WD4 8LZ, UK + * + ******************************************************************************/ + +#include +#include +#include +#include +#include +#include +#include +#include + +#include "img_defs.h" +#include "servicesext.h" +#include "kerneldisplay.h" +#include "omaplfb.h" + +static void *gpvAnchor; + +static int fb_idx = 0; + +#define OMAPLFB_COMMAND_COUNT 1 + +static PFN_DC_GET_PVRJTABLE pfnGetPVRJTable = 0; + +static OMAPLFB_DEVINFO * GetAnchorPtr(void) +{ + return (OMAPLFB_DEVINFO *)gpvAnchor; +} + +static void SetAnchorPtr(OMAPLFB_DEVINFO *psDevInfo) +{ + gpvAnchor = (void*)psDevInfo; +} + + +static void FlushInternalVSyncQueue(OMAPLFB_SWAPCHAIN *psSwapChain) +{ + OMAPLFB_VSYNC_FLIP_ITEM *psFlipItem; + unsigned long ulMaxIndex; + unsigned long i; + + + psFlipItem = &psSwapChain->psVSyncFlips[psSwapChain->ulRemoveIndex]; + ulMaxIndex = psSwapChain->ulBufferCount - 1; + + for(i = 0; i < psSwapChain->ulBufferCount; i++) + { + if (psFlipItem->bValid == OMAP_FALSE) + { + continue; + } + + DEBUG_PRINTK((KERN_INFO DRIVER_PREFIX ": FlushInternalVSyncQueue: Flushing swap buffer (index %lu)\n", psSwapChain->ulRemoveIndex)); + + if(psFlipItem->bFlipped == OMAP_FALSE) + { + + OMAPLFBFlip(psSwapChain, (unsigned long)psFlipItem->sSysAddr); + } + + if(psFlipItem->bCmdCompleted == OMAP_FALSE) + { + DEBUG_PRINTK((KERN_INFO DRIVER_PREFIX ": FlushInternalVSyncQueue: Calling command complete for swap buffer (index %lu)\n", psSwapChain->ulRemoveIndex)); + + psSwapChain->psPVRJTable->pfnPVRSRVCmdComplete((IMG_HANDLE)psFlipItem->hCmdComplete, IMG_TRUE); + } + + + psSwapChain->ulRemoveIndex++; + + if(psSwapChain->ulRemoveIndex > ulMaxIndex) + { + psSwapChain->ulRemoveIndex = 0; + } + + + psFlipItem->bFlipped = OMAP_FALSE; + psFlipItem->bCmdCompleted = OMAP_FALSE; + psFlipItem->bValid = OMAP_FALSE; + + + psFlipItem = &psSwapChain->psVSyncFlips[psSwapChain->ulRemoveIndex]; + } + + psSwapChain->ulInsertIndex = 0; + psSwapChain->ulRemoveIndex = 0; +} + +static void SetFlushStateInternalNoLock(OMAPLFB_DEVINFO* psDevInfo, + OMAP_BOOL bFlushState) +{ + OMAPLFB_SWAPCHAIN *psSwapChain = psDevInfo->psSwapChain; + + if (psSwapChain == NULL) + { + return; + } + + if (bFlushState) + { + if (psSwapChain->ulSetFlushStateRefCount == 0) + { + OMAPLFBDisableVSyncInterrupt(psSwapChain); + psSwapChain->bFlushCommands = OMAP_TRUE; + FlushInternalVSyncQueue(psSwapChain); + } + psSwapChain->ulSetFlushStateRefCount++; + } + else + { + if (psSwapChain->ulSetFlushStateRefCount != 0) + { + psSwapChain->ulSetFlushStateRefCount--; + if (psSwapChain->ulSetFlushStateRefCount == 0) + { + psSwapChain->bFlushCommands = OMAP_FALSE; + OMAPLFBEnableVSyncInterrupt(psSwapChain); + } + } + } +} + +static IMG_VOID SetFlushStateInternal(OMAPLFB_DEVINFO* psDevInfo, + OMAP_BOOL bFlushState) +{ + unsigned long ulLockFlags; + + spin_lock_irqsave(&psDevInfo->sSwapChainLock, ulLockFlags); + + SetFlushStateInternalNoLock(psDevInfo, bFlushState); + + spin_unlock_irqrestore(&psDevInfo->sSwapChainLock, ulLockFlags); +} + +static void SetFlushStateExternal(OMAPLFB_DEVINFO* psDevInfo, + OMAP_BOOL bFlushState) +{ + unsigned long ulLockFlags; + + spin_lock_irqsave(&psDevInfo->sSwapChainLock, ulLockFlags); + + + if (psDevInfo->bFlushCommands != bFlushState) + { + psDevInfo->bFlushCommands = bFlushState; + SetFlushStateInternalNoLock(psDevInfo, bFlushState); + } + + spin_unlock_irqrestore(&psDevInfo->sSwapChainLock, ulLockFlags); +} + +static IMG_VOID SetDCState(IMG_HANDLE hDevice, IMG_UINT32 ui32State) +{ + OMAPLFB_DEVINFO *psDevInfo = (OMAPLFB_DEVINFO *)hDevice; + + switch (ui32State) + { + case DC_STATE_FLUSH_COMMANDS: + SetFlushStateExternal(psDevInfo, OMAP_TRUE); + break; + case DC_STATE_NO_FLUSH_COMMANDS: + SetFlushStateExternal(psDevInfo, OMAP_FALSE); + break; + default: + break; + } + + return; +} + +static int FrameBufferEvents(struct notifier_block *psNotif, + unsigned long event, void *data) +{ + OMAPLFB_DEVINFO *psDevInfo; + OMAPLFB_SWAPCHAIN *psSwapChain; + struct fb_event *psFBEvent = (struct fb_event *)data; + OMAP_BOOL bBlanked; + + + if (event != FB_EVENT_BLANK) + { + return 0; + } + + psDevInfo = GetAnchorPtr(); + psSwapChain = psDevInfo->psSwapChain; + + bBlanked = (*(IMG_INT *)psFBEvent->data != 0) ? OMAP_TRUE: OMAP_FALSE; + + if (bBlanked != psSwapChain->bBlanked) + { + psSwapChain->bBlanked = bBlanked; + + if (bBlanked) + { + + SetFlushStateInternal(psDevInfo, OMAP_TRUE); + } + else + { + + SetFlushStateInternal(psDevInfo, OMAP_FALSE); + } + } + + return 0; +} + + +static OMAP_ERROR UnblankDisplay(OMAPLFB_DEVINFO *psDevInfo) +{ + int res; + + acquire_console_sem(); + res = fb_blank(psDevInfo->psLINFBInfo, 0); + release_console_sem(); +#if !defined (CONFIG_OMAP2_DSS) + /* DSS2 returns error if unblank from a non-suspend state */ + if (res != 0) + { + printk(KERN_WARNING DRIVER_PREFIX + ": fb_blank failed (%d)", res); + return (OMAP_ERROR_GENERIC); + } +#endif + + return (OMAP_OK); +} + +#if defined (CONFIG_OMAP2_DSS) +#include +struct wq_flip { + struct fb_var_screeninfo var; + struct fb_info *psLINFBInfo; + struct work_struct work; +}; +struct wq_flip wq_flipdss2; + +static void dss2_pan_display (struct work_struct *work) +{ + struct wq_flip *ptrwq_flip = + container_of(work, struct wq_flip, work); + if (ptrwq_flip->psLINFBInfo->fbops->fb_pan_display != NULL) { + ptrwq_flip->psLINFBInfo->fbops->fb_pan_display (&ptrwq_flip->var, ptrwq_flip->psLINFBInfo); + + } + +} + +/* + Flip implementation for DSS2 using fb_pan_display +*/ +IMG_VOID OMAPLFBFlipDSS2(OMAPLFB_SWAPCHAIN *psSwapChain, + IMG_UINT32 aPhyAddr) +{ + OMAPLFB_DEVINFO *psDevInfo = GetAnchorPtr (); + struct fb_info *psLINFBInfo = psDevInfo->psLINFBInfo; + memcpy ( &wq_flipdss2.var, &psLINFBInfo->var, sizeof(struct fb_var_screeninfo)); + wq_flipdss2.var.yoffset = (aPhyAddr-psLINFBInfo->fix.smem_start)/psLINFBInfo->fix.line_length; + wq_flipdss2.psLINFBInfo = psLINFBInfo; + schedule_work (&wq_flipdss2.work); +} +#endif + +static OMAP_ERROR EnableLFBEventNotification(OMAPLFB_DEVINFO *psDevInfo) +{ + int res; + OMAPLFB_SWAPCHAIN *psSwapChain = psDevInfo->psSwapChain; + OMAP_ERROR eError; + + + memset(&psDevInfo->sLINNotifBlock, 0, sizeof(psDevInfo->sLINNotifBlock)); + + psDevInfo->sLINNotifBlock.notifier_call = FrameBufferEvents; + + psSwapChain->bBlanked = OMAP_FALSE; + + res = fb_register_client(&psDevInfo->sLINNotifBlock); + if (res != 0) + { + printk(KERN_WARNING DRIVER_PREFIX + ": fb_register_client failed (%d)", res); + + return (OMAP_ERROR_GENERIC); + } + + eError = UnblankDisplay(psDevInfo); + if (eError != OMAP_OK) + { + DEBUG_PRINTK((KERN_WARNING DRIVER_PREFIX + ": UnblankDisplay failed (%d)", eError)); + return eError; + } + + return (OMAP_OK); +} + +static OMAP_ERROR DisableLFBEventNotification(OMAPLFB_DEVINFO *psDevInfo) +{ + int res; + + + res = fb_unregister_client(&psDevInfo->sLINNotifBlock); + if (res != 0) + { + printk(KERN_WARNING DRIVER_PREFIX + ": fb_unregister_client failed (%d)", res); + return (OMAP_ERROR_GENERIC); + } + + return (OMAP_OK); +} + +static PVRSRV_ERROR OpenDCDevice(IMG_UINT32 ui32DeviceID, + IMG_HANDLE *phDevice, + PVRSRV_SYNC_DATA* psSystemBufferSyncData) +{ + OMAPLFB_DEVINFO *psDevInfo; + OMAP_ERROR eError; + + UNREFERENCED_PARAMETER(ui32DeviceID); + + psDevInfo = GetAnchorPtr(); + + + psDevInfo->sSystemBuffer.psSyncData = psSystemBufferSyncData; + + eError = UnblankDisplay(psDevInfo); + if (eError != OMAP_OK) + { + DEBUG_PRINTK((KERN_WARNING DRIVER_PREFIX + ": UnblankDisplay failed (%d)", eError)); + return (PVRSRV_ERROR_GENERIC); + } + + + *phDevice = (IMG_HANDLE)psDevInfo; + + return (PVRSRV_OK); +} + +static PVRSRV_ERROR CloseDCDevice(IMG_HANDLE hDevice) +{ + UNREFERENCED_PARAMETER(hDevice); + + return (PVRSRV_OK); +} + +static PVRSRV_ERROR EnumDCFormats(IMG_HANDLE hDevice, + IMG_UINT32 *pui32NumFormats, + DISPLAY_FORMAT *psFormat) +{ + OMAPLFB_DEVINFO *psDevInfo; + + if(!hDevice || !pui32NumFormats) + { + return (PVRSRV_ERROR_INVALID_PARAMS); + } + + psDevInfo = (OMAPLFB_DEVINFO*)hDevice; + + *pui32NumFormats = 1; + + if(psFormat) + { + psFormat[0] = psDevInfo->sDisplayFormat; + } + + return (PVRSRV_OK); +} + +static PVRSRV_ERROR EnumDCDims(IMG_HANDLE hDevice, + DISPLAY_FORMAT *psFormat, + IMG_UINT32 *pui32NumDims, + DISPLAY_DIMS *psDim) +{ + OMAPLFB_DEVINFO *psDevInfo; + + if(!hDevice || !psFormat || !pui32NumDims) + { + return (PVRSRV_ERROR_INVALID_PARAMS); + } + + psDevInfo = (OMAPLFB_DEVINFO*)hDevice; + + *pui32NumDims = 1; + + + if(psDim) + { + psDim[0] = psDevInfo->sDisplayDim; + } + + return (PVRSRV_OK); +} + + +static PVRSRV_ERROR GetDCSystemBuffer(IMG_HANDLE hDevice, IMG_HANDLE *phBuffer) +{ + OMAPLFB_DEVINFO *psDevInfo; + + if(!hDevice || !phBuffer) + { + return (PVRSRV_ERROR_INVALID_PARAMS); + } + + psDevInfo = (OMAPLFB_DEVINFO*)hDevice; + + *phBuffer = (IMG_HANDLE)&psDevInfo->sSystemBuffer; + + return (PVRSRV_OK); +} + + +static PVRSRV_ERROR GetDCInfo(IMG_HANDLE hDevice, DISPLAY_INFO *psDCInfo) +{ + OMAPLFB_DEVINFO *psDevInfo; + + if(!hDevice || !psDCInfo) + { + return (PVRSRV_ERROR_INVALID_PARAMS); + } + + psDevInfo = (OMAPLFB_DEVINFO*)hDevice; + + *psDCInfo = psDevInfo->sDisplayInfo; + + return (PVRSRV_OK); +} + +static PVRSRV_ERROR GetDCBufferAddr(IMG_HANDLE hDevice, + IMG_HANDLE hBuffer, + IMG_SYS_PHYADDR **ppsSysAddr, + IMG_UINT32 *pui32ByteSize, + IMG_VOID **ppvCpuVAddr, + IMG_HANDLE *phOSMapInfo, + IMG_BOOL *pbIsContiguous) +{ + OMAPLFB_DEVINFO *psDevInfo; + OMAPLFB_BUFFER *psSystemBuffer; + + if(!hDevice) + { + return (PVRSRV_ERROR_INVALID_PARAMS); + } + psDevInfo = (OMAPLFB_DEVINFO*)hDevice; + + if(!hBuffer) + { + return (PVRSRV_ERROR_INVALID_PARAMS); + } + psSystemBuffer = (OMAPLFB_BUFFER *)hBuffer; + + if (!ppsSysAddr) + { + return (PVRSRV_ERROR_INVALID_PARAMS); + } + + *ppsSysAddr = &psSystemBuffer->sSysAddr; + + if (!pui32ByteSize) + { + return (PVRSRV_ERROR_INVALID_PARAMS); + } + + *pui32ByteSize = (IMG_UINT32)psDevInfo->sFBInfo.ulBufferSize; + + if (ppvCpuVAddr) + { + *ppvCpuVAddr = psSystemBuffer->sCPUVAddr; + } + + if (phOSMapInfo) + { + *phOSMapInfo = (IMG_HANDLE)0; + } + + if (pbIsContiguous) + { + *pbIsContiguous = IMG_TRUE; + } + + return (PVRSRV_OK); +} + +static PVRSRV_ERROR CreateDCSwapChain(IMG_HANDLE hDevice, + IMG_UINT32 ui32Flags, + DISPLAY_SURF_ATTRIBUTES *psDstSurfAttrib, + DISPLAY_SURF_ATTRIBUTES *psSrcSurfAttrib, + IMG_UINT32 ui32BufferCount, + PVRSRV_SYNC_DATA **ppsSyncData, + IMG_UINT32 ui32OEMFlags, + IMG_HANDLE *phSwapChain, + IMG_UINT32 *pui32SwapChainID) +{ + OMAPLFB_DEVINFO *psDevInfo; + OMAPLFB_SWAPCHAIN *psSwapChain; + OMAPLFB_BUFFER *psBuffer; + OMAPLFB_VSYNC_FLIP_ITEM *psVSyncFlips; + IMG_UINT32 i; + PVRSRV_ERROR eError = PVRSRV_ERROR_GENERIC; + unsigned long ulLockFlags; + IMG_UINT32 ui32BuffersToSkip; + + UNREFERENCED_PARAMETER(ui32OEMFlags); + UNREFERENCED_PARAMETER(pui32SwapChainID); + + + if(!hDevice + || !psDstSurfAttrib + || !psSrcSurfAttrib + || !ppsSyncData + || !phSwapChain) + { + return (PVRSRV_ERROR_INVALID_PARAMS); + } + + psDevInfo = (OMAPLFB_DEVINFO*)hDevice; + + + if (psDevInfo->sDisplayInfo.ui32MaxSwapChains == 0) + { + return (PVRSRV_ERROR_NOT_SUPPORTED); + } + + + if(psDevInfo->psSwapChain != NULL) + { + return (PVRSRV_ERROR_FLIP_CHAIN_EXISTS); + } + + + if(ui32BufferCount > psDevInfo->sDisplayInfo.ui32MaxSwapChainBuffers) + { + return (PVRSRV_ERROR_TOOMANYBUFFERS); + } + + if ((psDevInfo->sFBInfo.ulRoundedBufferSize * (unsigned long)ui32BufferCount) > psDevInfo->sFBInfo.ulFBSize) + { + return (PVRSRV_ERROR_TOOMANYBUFFERS); + } + + + ui32BuffersToSkip = psDevInfo->sDisplayInfo.ui32MaxSwapChainBuffers - ui32BufferCount; + + + if(psDstSurfAttrib->pixelformat != psDevInfo->sDisplayFormat.pixelformat + || psDstSurfAttrib->sDims.ui32ByteStride != psDevInfo->sDisplayDim.ui32ByteStride + || psDstSurfAttrib->sDims.ui32Width != psDevInfo->sDisplayDim.ui32Width + || psDstSurfAttrib->sDims.ui32Height != psDevInfo->sDisplayDim.ui32Height) + { + + return (PVRSRV_ERROR_INVALID_PARAMS); + } + + if(psDstSurfAttrib->pixelformat != psSrcSurfAttrib->pixelformat + || psDstSurfAttrib->sDims.ui32ByteStride != psSrcSurfAttrib->sDims.ui32ByteStride + || psDstSurfAttrib->sDims.ui32Width != psSrcSurfAttrib->sDims.ui32Width + || psDstSurfAttrib->sDims.ui32Height != psSrcSurfAttrib->sDims.ui32Height) + { + + return (PVRSRV_ERROR_INVALID_PARAMS); + } + + + UNREFERENCED_PARAMETER(ui32Flags); + + + psSwapChain = (OMAPLFB_SWAPCHAIN*)OMAPLFBAllocKernelMem(sizeof(OMAPLFB_SWAPCHAIN)); + if(!psSwapChain) + { + return (PVRSRV_ERROR_OUT_OF_MEMORY); + } + + psBuffer = (OMAPLFB_BUFFER*)OMAPLFBAllocKernelMem(sizeof(OMAPLFB_BUFFER) * ui32BufferCount); + if(!psBuffer) + { + eError = PVRSRV_ERROR_OUT_OF_MEMORY; + goto ErrorFreeSwapChain; + } + + psVSyncFlips = (OMAPLFB_VSYNC_FLIP_ITEM *)OMAPLFBAllocKernelMem(sizeof(OMAPLFB_VSYNC_FLIP_ITEM) * ui32BufferCount); + if (!psVSyncFlips) + { + eError = PVRSRV_ERROR_OUT_OF_MEMORY; + goto ErrorFreeBuffers; + } + + psSwapChain->ulBufferCount = (unsigned long)ui32BufferCount; + psSwapChain->psBuffer = psBuffer; + psSwapChain->psVSyncFlips = psVSyncFlips; + psSwapChain->ulInsertIndex = 0; + psSwapChain->ulRemoveIndex = 0; + psSwapChain->psPVRJTable = &psDevInfo->sPVRJTable; + psSwapChain->psSwapChainLock = &psDevInfo->sSwapChainLock; + + + for(i=0; isFBInfo.ulRoundedBufferSize; + + psBuffer[i].psSyncData = ppsSyncData[i]; + + psBuffer[i].sSysAddr.uiAddr = psDevInfo->sFBInfo.sSysAddr.uiAddr + ui32BufferOffset; + psBuffer[i].sCPUVAddr = psDevInfo->sFBInfo.sCPUVAddr + ui32BufferOffset; + } + + + for(i=0; ipvRegs = ioremap(psDevInfo->psLINFBInfo->fix.mmio_start, psDevInfo->psLINFBInfo->fix.mmio_len); + if (psSwapChain->pvRegs == NULL) + { + printk(KERN_WARNING DRIVER_PREFIX ": Couldn't map registers needed for flipping\n"); + goto ErrorDisableDisplayRegisters; + } +#endif + if (OMAPLFBInstallVSyncISR(psSwapChain) != OMAP_OK) + { + printk(KERN_WARNING DRIVER_PREFIX ": ISR handler failed to register\n"); + goto ErrorUnmapRegisters; + } + + spin_lock_irqsave(&psDevInfo->sSwapChainLock, ulLockFlags); + + + psDevInfo->psSwapChain = psSwapChain; + + + psSwapChain->bFlushCommands = psDevInfo->bFlushCommands; + + if (psSwapChain->bFlushCommands) + { + psSwapChain->ulSetFlushStateRefCount = 1; + } + else + { + psSwapChain->ulSetFlushStateRefCount = 0; + OMAPLFBEnableVSyncInterrupt(psSwapChain); + } + + spin_unlock_irqrestore(&psDevInfo->sSwapChainLock, ulLockFlags); + + if (EnableLFBEventNotification(psDevInfo)!= OMAP_OK) + { + printk(KERN_WARNING DRIVER_PREFIX ": Couldn't enable framebuffer event notification\n"); + goto ErrorUninstallVSyncInterrupt; + } + + + *phSwapChain = (IMG_HANDLE)psSwapChain; + + return (PVRSRV_OK); + +ErrorUninstallVSyncInterrupt: + if(OMAPLFBUninstallVSyncISR(psSwapChain) != OMAP_OK) + { + printk(KERN_WARNING DRIVER_PREFIX ": Couldn't uninstall VSync ISR\n"); + } +ErrorUnmapRegisters: +#if defined (SUPPORT_TI_DSS_FW) + iounmap(psSwapChain->pvRegs); +ErrorDisableDisplayRegisters: + OMAPLFBDisableDisplayRegisterAccess(); +#endif + OMAPLFBFreeKernelMem(psVSyncFlips); +ErrorFreeBuffers: + OMAPLFBFreeKernelMem(psBuffer); +ErrorFreeSwapChain: + OMAPLFBFreeKernelMem(psSwapChain); + + return eError; +} + +static PVRSRV_ERROR DestroyDCSwapChain(IMG_HANDLE hDevice, + IMG_HANDLE hSwapChain) +{ + OMAPLFB_DEVINFO *psDevInfo; + OMAPLFB_SWAPCHAIN *psSwapChain; + unsigned long ulLockFlags; + OMAP_ERROR eError; + + + if(!hDevice || !hSwapChain) + { + return (PVRSRV_ERROR_INVALID_PARAMS); + } + + psDevInfo = (OMAPLFB_DEVINFO*)hDevice; + psSwapChain = (OMAPLFB_SWAPCHAIN*)hSwapChain; + if (psSwapChain != psDevInfo->psSwapChain) + { + return (PVRSRV_ERROR_INVALID_PARAMS); + } + + eError = DisableLFBEventNotification(psDevInfo); + if (eError != OMAP_OK) + { + printk(KERN_WARNING DRIVER_PREFIX ": Couldn't disable framebuffer event notification\n"); + } + + spin_lock_irqsave(&psDevInfo->sSwapChainLock, ulLockFlags); + + OMAPLFBDisableVSyncInterrupt(psSwapChain); + + + FlushInternalVSyncQueue(psSwapChain); + + + OMAPLFBFlip(psSwapChain, (unsigned long)psDevInfo->sFBInfo.sSysAddr.uiAddr); + + + psDevInfo->psSwapChain = NULL; + + spin_unlock_irqrestore(&psDevInfo->sSwapChainLock, ulLockFlags); + + if(OMAPLFBUninstallVSyncISR(psSwapChain) != OMAP_OK) + { + printk(KERN_WARNING DRIVER_PREFIX ": Couldn't uninstall VSync ISR\n"); + return (PVRSRV_ERROR_GENERIC); + } + +#if defined (SUPPORT_TI_DSS_FW) + + iounmap(psSwapChain->pvRegs); + + OMAPLFBDisableDisplayRegisterAccess(); +#endif + + OMAPLFBFreeKernelMem(psSwapChain->psVSyncFlips); + OMAPLFBFreeKernelMem(psSwapChain->psBuffer); + OMAPLFBFreeKernelMem(psSwapChain); + + return (PVRSRV_OK); +} + +static PVRSRV_ERROR SetDCDstRect(IMG_HANDLE hDevice, + IMG_HANDLE hSwapChain, + IMG_RECT *psRect) +{ + UNREFERENCED_PARAMETER(hDevice); + UNREFERENCED_PARAMETER(hSwapChain); + UNREFERENCED_PARAMETER(psRect); + + + + return (PVRSRV_ERROR_NOT_SUPPORTED); +} + +static PVRSRV_ERROR SetDCSrcRect(IMG_HANDLE hDevice, + IMG_HANDLE hSwapChain, + IMG_RECT *psRect) +{ + UNREFERENCED_PARAMETER(hDevice); + UNREFERENCED_PARAMETER(hSwapChain); + UNREFERENCED_PARAMETER(psRect); + + + + return (PVRSRV_ERROR_NOT_SUPPORTED); +} + +static PVRSRV_ERROR SetDCDstColourKey(IMG_HANDLE hDevice, + IMG_HANDLE hSwapChain, + IMG_UINT32 ui32CKColour) +{ + UNREFERENCED_PARAMETER(hDevice); + UNREFERENCED_PARAMETER(hSwapChain); + UNREFERENCED_PARAMETER(ui32CKColour); + + + + return (PVRSRV_ERROR_NOT_SUPPORTED); +} + +static PVRSRV_ERROR SetDCSrcColourKey(IMG_HANDLE hDevice, + IMG_HANDLE hSwapChain, + IMG_UINT32 ui32CKColour) +{ + UNREFERENCED_PARAMETER(hDevice); + UNREFERENCED_PARAMETER(hSwapChain); + UNREFERENCED_PARAMETER(ui32CKColour); + + + + return (PVRSRV_ERROR_NOT_SUPPORTED); +} + +static PVRSRV_ERROR GetDCBuffers(IMG_HANDLE hDevice, + IMG_HANDLE hSwapChain, + IMG_UINT32 *pui32BufferCount, + IMG_HANDLE *phBuffer) +{ + OMAPLFB_DEVINFO *psDevInfo; + OMAPLFB_SWAPCHAIN *psSwapChain; + unsigned long i; + + + if(!hDevice + || !hSwapChain + || !pui32BufferCount + || !phBuffer) + { + return (PVRSRV_ERROR_INVALID_PARAMS); + } + + psDevInfo = (OMAPLFB_DEVINFO*)hDevice; + psSwapChain = (OMAPLFB_SWAPCHAIN*)hSwapChain; + if (psSwapChain != psDevInfo->psSwapChain) + { + return (PVRSRV_ERROR_INVALID_PARAMS); + } + + + *pui32BufferCount = (IMG_UINT32)psSwapChain->ulBufferCount; + + + for(i=0; iulBufferCount; i++) + { + phBuffer[i] = (IMG_HANDLE)&psSwapChain->psBuffer[i]; + } + + return (PVRSRV_OK); +} + +static PVRSRV_ERROR SwapToDCBuffer(IMG_HANDLE hDevice, + IMG_HANDLE hBuffer, + IMG_UINT32 ui32SwapInterval, + IMG_HANDLE hPrivateTag, + IMG_UINT32 ui32ClipRectCount, + IMG_RECT *psClipRect) +{ + OMAPLFB_DEVINFO *psDevInfo; + + UNREFERENCED_PARAMETER(ui32SwapInterval); + UNREFERENCED_PARAMETER(hPrivateTag); + UNREFERENCED_PARAMETER(psClipRect); + + if(!hDevice + || !hBuffer + || (ui32ClipRectCount != 0)) + { + return (PVRSRV_ERROR_INVALID_PARAMS); + } + + psDevInfo = (OMAPLFB_DEVINFO*)hDevice; + + + return (PVRSRV_OK); +} + +static PVRSRV_ERROR SwapToDCSystem(IMG_HANDLE hDevice, + IMG_HANDLE hSwapChain) +{ + OMAPLFB_DEVINFO *psDevInfo; + OMAPLFB_SWAPCHAIN *psSwapChain; + unsigned long ulLockFlags; + + if(!hDevice || !hSwapChain) + { + return (PVRSRV_ERROR_INVALID_PARAMS); + } + + psDevInfo = (OMAPLFB_DEVINFO*)hDevice; + psSwapChain = (OMAPLFB_SWAPCHAIN*)hSwapChain; + if (psSwapChain != psDevInfo->psSwapChain) + { + return (PVRSRV_ERROR_INVALID_PARAMS); + } + + spin_lock_irqsave(&psDevInfo->sSwapChainLock, ulLockFlags); + + + FlushInternalVSyncQueue(psSwapChain); + + + OMAPLFBFlip(psSwapChain, (unsigned long)psDevInfo->sFBInfo.sSysAddr.uiAddr); + + spin_unlock_irqrestore(&psDevInfo->sSwapChainLock, ulLockFlags); + + return (PVRSRV_OK); +} + +OMAP_BOOL OMAPLFBVSyncIHandler(OMAPLFB_SWAPCHAIN *psSwapChain) +{ + OMAP_BOOL bStatus = OMAP_FALSE; + OMAPLFB_VSYNC_FLIP_ITEM *psFlipItem; + unsigned long ulMaxIndex; + unsigned long ulLockFlags; + + psFlipItem = &psSwapChain->psVSyncFlips[psSwapChain->ulRemoveIndex]; + ulMaxIndex = psSwapChain->ulBufferCount - 1; + + spin_lock_irqsave(psSwapChain->psSwapChainLock, ulLockFlags); + + + if (psSwapChain->bFlushCommands) + { + goto ExitUnlock; + } + + while(psFlipItem->bValid) + { + + if(psFlipItem->bFlipped) + { + + if(!psFlipItem->bCmdCompleted) + { + + psSwapChain->psPVRJTable->pfnPVRSRVCmdComplete((IMG_HANDLE)psFlipItem->hCmdComplete, IMG_TRUE); + + + psFlipItem->bCmdCompleted = OMAP_TRUE; + } + + + psFlipItem->ulSwapInterval--; + + + if(psFlipItem->ulSwapInterval == 0) + { + + psSwapChain->ulRemoveIndex++; + + if(psSwapChain->ulRemoveIndex > ulMaxIndex) + { + psSwapChain->ulRemoveIndex = 0; + } + + + psFlipItem->bCmdCompleted = OMAP_FALSE; + psFlipItem->bFlipped = OMAP_FALSE; + + + psFlipItem->bValid = OMAP_FALSE; + } + else + { + + break; + } + } + else + { + + OMAPLFBFlip(psSwapChain, (unsigned long)psFlipItem->sSysAddr); + + + psFlipItem->bFlipped = OMAP_TRUE; + + + break; + } + + + psFlipItem = &psSwapChain->psVSyncFlips[psSwapChain->ulRemoveIndex]; + } + +ExitUnlock: + spin_unlock_irqrestore(psSwapChain->psSwapChainLock, ulLockFlags); + + return bStatus; +} + +static IMG_BOOL ProcessFlip(IMG_HANDLE hCmdCookie, + IMG_UINT32 ui32DataSize, + IMG_VOID *pvData) +{ + DISPLAYCLASS_FLIP_COMMAND *psFlipCmd; + OMAPLFB_DEVINFO *psDevInfo; + OMAPLFB_BUFFER *psBuffer; + OMAPLFB_SWAPCHAIN *psSwapChain; +#if defined(SYS_USING_INTERRUPTS) + OMAPLFB_VSYNC_FLIP_ITEM* psFlipItem; +#endif + unsigned long ulLockFlags; + + + if(!hCmdCookie || !pvData) + { + return IMG_FALSE; + } + + + psFlipCmd = (DISPLAYCLASS_FLIP_COMMAND*)pvData; + + if (psFlipCmd == IMG_NULL || sizeof(DISPLAYCLASS_FLIP_COMMAND) != ui32DataSize) + { + return IMG_FALSE; + } + + + psDevInfo = (OMAPLFB_DEVINFO*)psFlipCmd->hExtDevice; + + psBuffer = (OMAPLFB_BUFFER*)psFlipCmd->hExtBuffer; + psSwapChain = (OMAPLFB_SWAPCHAIN*) psFlipCmd->hExtSwapChain; + + spin_lock_irqsave(&psDevInfo->sSwapChainLock, ulLockFlags); + + + if (psDevInfo->bDeviceSuspended) + { + psSwapChain->psPVRJTable->pfnPVRSRVCmdComplete(hCmdCookie, IMG_TRUE); + goto ExitTrueUnlock; + } + +#if defined(SYS_USING_INTERRUPTS) + + if(psFlipCmd->ui32SwapInterval == 0 || psSwapChain->bFlushCommands == OMAP_TRUE) + { +#endif + + OMAPLFBFlip(psSwapChain, (unsigned long)psBuffer->sSysAddr.uiAddr); + + + psSwapChain->psPVRJTable->pfnPVRSRVCmdComplete(hCmdCookie, IMG_TRUE); + +#if defined(SYS_USING_INTERRUPTS) + goto ExitTrueUnlock; + } + + psFlipItem = &psSwapChain->psVSyncFlips[psSwapChain->ulInsertIndex]; + + + if(psFlipItem->bValid == OMAP_FALSE) + { + unsigned long ulMaxIndex = psSwapChain->ulBufferCount - 1; + + if(psSwapChain->ulInsertIndex == psSwapChain->ulRemoveIndex) + { + + OMAPLFBFlip(psSwapChain, (unsigned long)psBuffer->sSysAddr.uiAddr); + + psFlipItem->bFlipped = OMAP_TRUE; + } + else + { + psFlipItem->bFlipped = OMAP_FALSE; + } + + psFlipItem->hCmdComplete = (OMAP_HANDLE)hCmdCookie; + psFlipItem->ulSwapInterval = (unsigned long)psFlipCmd->ui32SwapInterval; + psFlipItem->sSysAddr = &psBuffer->sSysAddr; + psFlipItem->bValid = OMAP_TRUE; + + psSwapChain->ulInsertIndex++; + if(psSwapChain->ulInsertIndex > ulMaxIndex) + { + psSwapChain->ulInsertIndex = 0; + } + + goto ExitTrueUnlock; + } + + spin_unlock_irqrestore(&psDevInfo->sSwapChainLock, ulLockFlags); + return IMG_FALSE; +#endif + +ExitTrueUnlock: + spin_unlock_irqrestore(&psDevInfo->sSwapChainLock, ulLockFlags); + return IMG_TRUE; +} + + +static OMAP_ERROR InitDev(OMAPLFB_DEVINFO *psDevInfo) +{ + struct fb_info *psLINFBInfo; + struct module *psLINFBOwner; + OMAPLFB_FBINFO *psPVRFBInfo = &psDevInfo->sFBInfo; + OMAP_ERROR eError = OMAP_ERROR_GENERIC; + unsigned long FBSize; + + acquire_console_sem(); + + if (fb_idx < 0 || fb_idx >= num_registered_fb) + { + eError = OMAP_ERROR_INVALID_DEVICE; + goto errRelSem; + } + + psLINFBInfo = registered_fb[fb_idx]; + + psLINFBOwner = psLINFBInfo->fbops->owner; + if (!try_module_get(psLINFBOwner)) + { + printk(KERN_INFO DRIVER_PREFIX + ": Couldn't get framebuffer module\n"); + + goto errRelSem; + } + + if (psLINFBInfo->fbops->fb_open != NULL) + { + int res; + + res = psLINFBInfo->fbops->fb_open(psLINFBInfo, 0); + if (res != 0) + { + printk(KERN_INFO DRIVER_PREFIX + ": Couldn't open framebuffer: %d\n", res); + + goto errModPut; + } + } + + psDevInfo->psLINFBInfo = psLINFBInfo; + + FBSize = (psLINFBInfo->screen_size) != 0 ? + psLINFBInfo->screen_size : + psLINFBInfo->fix.smem_len; + DEBUG_PRINTK((KERN_INFO DRIVER_PREFIX + ": Framebuffer physical address: 0x%lx\n", + psLINFBInfo->fix.smem_start)); + DEBUG_PRINTK((KERN_INFO DRIVER_PREFIX + ": Framebuffer virtual address: 0x%lx\n", + (unsigned long)psLINFBInfo->screen_base)); + DEBUG_PRINTK((KERN_INFO DRIVER_PREFIX + ": Framebuffer size: %lu\n", + FBSize)); + DEBUG_PRINTK((KERN_INFO DRIVER_PREFIX + ": Framebuffer virtual width: %u\n", + psLINFBInfo->var.xres_virtual)); + DEBUG_PRINTK((KERN_INFO DRIVER_PREFIX + ": Framebuffer virtual height: %u\n", + psLINFBInfo->var.yres_virtual)); + DEBUG_PRINTK((KERN_INFO DRIVER_PREFIX + ": Framebuffer width: %u\n", + psLINFBInfo->var.xres)); + DEBUG_PRINTK((KERN_INFO DRIVER_PREFIX + ": Framebuffer height: %u\n", + psLINFBInfo->var.yres)); + DEBUG_PRINTK((KERN_INFO DRIVER_PREFIX + ": Framebuffer stride: %u\n", + psLINFBInfo->fix.line_length)); + + + psPVRFBInfo->sSysAddr.uiAddr = psLINFBInfo->fix.smem_start; + psPVRFBInfo->sCPUVAddr = psLINFBInfo->screen_base; + if ((psLINFBInfo->var.rotate == FB_ROTATE_CW) + || (psLINFBInfo->var.rotate == FB_ROTATE_CCW) ) { + psPVRFBInfo->ulWidth = psLINFBInfo->var.yres; + psPVRFBInfo->ulHeight = psLINFBInfo->var.xres; + } else { + psPVRFBInfo->ulWidth = psLINFBInfo->var.xres; + psPVRFBInfo->ulHeight = psLINFBInfo->var.yres; + } + + psPVRFBInfo->ulByteStride = psLINFBInfo->fix.line_length; + psPVRFBInfo->ulFBSize = FBSize; + psPVRFBInfo->ulBufferSize = psPVRFBInfo->ulHeight * psPVRFBInfo->ulByteStride; + + + +#ifdef CONFIG_OMAP2_DSS + psPVRFBInfo->ulRoundedBufferSize = psPVRFBInfo->ulBufferSize; +#else + psPVRFBInfo->ulRoundedBufferSize = OMAPLFB_PAGE_ROUNDUP(psPVRFBInfo->ulBufferSize); +#endif + if(psLINFBInfo->var.bits_per_pixel == 16) + { + if((psLINFBInfo->var.red.length == 5) && + (psLINFBInfo->var.green.length == 6) && + (psLINFBInfo->var.blue.length == 5) && + (psLINFBInfo->var.red.offset == 11) && + (psLINFBInfo->var.green.offset == 5) && + (psLINFBInfo->var.blue.offset == 0) && + (psLINFBInfo->var.red.msb_right == 0)) + { + psPVRFBInfo->ePixelFormat = PVRSRV_PIXEL_FORMAT_RGB565; + } + else + { + printk("Unknown FB format\n"); + } + } + else if(psLINFBInfo->var.bits_per_pixel == 32) + { + if((psLINFBInfo->var.red.length == 8) && + (psLINFBInfo->var.green.length == 8) && + (psLINFBInfo->var.blue.length == 8) && + (psLINFBInfo->var.red.offset == 16) && + (psLINFBInfo->var.green.offset == 8) && + (psLINFBInfo->var.blue.offset == 0) && + (psLINFBInfo->var.red.msb_right == 0)) + { + printk ("PVRSRV_PIXEL_FORMAT_ARGB8888\n"); + psPVRFBInfo->ePixelFormat = PVRSRV_PIXEL_FORMAT_ARGB8888; + } + else + { + printk("Unknown FB format\n"); + } + } + else + { + printk("Unknown FB format\n"); + } + + + psDevInfo->sFBInfo.sSysAddr.uiAddr = psPVRFBInfo->sSysAddr.uiAddr; + psDevInfo->sFBInfo.sCPUVAddr = psPVRFBInfo->sCPUVAddr; + +#ifdef CONFIG_OMAP2_DSS + INIT_WORK (&wq_flipdss2.work, dss2_pan_display); +#endif + + eError = OMAP_OK; + goto errRelSem; + +errModPut: + module_put(psLINFBOwner); +errRelSem: + release_console_sem(); + return eError; +} + +static void DeInitDev(OMAPLFB_DEVINFO *psDevInfo) +{ + struct fb_info *psLINFBInfo = psDevInfo->psLINFBInfo; + struct module *psLINFBOwner; + + acquire_console_sem(); + + psLINFBOwner = psLINFBInfo->fbops->owner; + + if (psLINFBInfo->fbops->fb_release != NULL) + { + (void) psLINFBInfo->fbops->fb_release(psLINFBInfo, 0); + } + + module_put(psLINFBOwner); + + release_console_sem(); +} + +OMAP_ERROR OMAPLFBInit(void) +{ + OMAPLFB_DEVINFO *psDevInfo; + + psDevInfo = GetAnchorPtr(); + + if (psDevInfo == NULL) + { + PFN_CMD_PROC pfnCmdProcList[OMAPLFB_COMMAND_COUNT]; + IMG_UINT32 aui32SyncCountList[OMAPLFB_COMMAND_COUNT][2]; + + psDevInfo = (OMAPLFB_DEVINFO *)OMAPLFBAllocKernelMem(sizeof(OMAPLFB_DEVINFO)); + + if(!psDevInfo) + { + return (OMAP_ERROR_OUT_OF_MEMORY); + } + + + memset(psDevInfo, 0, sizeof(OMAPLFB_DEVINFO)); + + + SetAnchorPtr((void*)psDevInfo); + + + psDevInfo->ulRefCount = 0; + + + if(InitDev(psDevInfo) != OMAP_OK) + { + return (OMAP_ERROR_INIT_FAILURE); + } + + if(OMAPLFBGetLibFuncAddr ("PVRGetDisplayClassJTable", &pfnGetPVRJTable) != OMAP_OK) + { + return (OMAP_ERROR_INIT_FAILURE); + } + + + if(!(*pfnGetPVRJTable)(&psDevInfo->sPVRJTable)) + { + return (OMAP_ERROR_INIT_FAILURE); + } + + + spin_lock_init(&psDevInfo->sSwapChainLock); + + psDevInfo->psSwapChain = 0; + psDevInfo->bFlushCommands = OMAP_FALSE; + psDevInfo->bDeviceSuspended = OMAP_FALSE; + + psDevInfo->sDisplayInfo.ui32MaxSwapChainBuffers = (IMG_UINT32)(psDevInfo->sFBInfo.ulFBSize / psDevInfo->sFBInfo.ulRoundedBufferSize); +#if !defined (SUPPORT_TI_DSS_FW) + /* DSS2 have trouble with ui32MaxSwapChainBuffers > 3 */ + if (psDevInfo->sDisplayInfo.ui32MaxSwapChainBuffers > 3) + psDevInfo->sDisplayInfo.ui32MaxSwapChainBuffers = 3; +#endif + + if (psDevInfo->sDisplayInfo.ui32MaxSwapChainBuffers == 0) + { + psDevInfo->sDisplayInfo.ui32MaxSwapChains = 0; + psDevInfo->sDisplayInfo.ui32MaxSwapInterval = 0; + } + else + { + psDevInfo->sDisplayInfo.ui32MaxSwapChains = 1; + psDevInfo->sDisplayInfo.ui32MaxSwapInterval = 3; + } + psDevInfo->sDisplayInfo.ui32MinSwapInterval = 0; + + strncpy(psDevInfo->sDisplayInfo.szDisplayName, DISPLAY_DEVICE_NAME, MAX_DISPLAY_NAME_SIZE); + + psDevInfo->sDisplayFormat.pixelformat = psDevInfo->sFBInfo.ePixelFormat; + psDevInfo->sDisplayDim.ui32Width = (IMG_UINT32)psDevInfo->sFBInfo.ulWidth; + psDevInfo->sDisplayDim.ui32Height = (IMG_UINT32)psDevInfo->sFBInfo.ulHeight; + psDevInfo->sDisplayDim.ui32ByteStride = (IMG_UINT32)psDevInfo->sFBInfo.ulByteStride; + + DEBUG_PRINTK((KERN_INFO DRIVER_PREFIX + ": Maximum number of swap chain buffers: %lu\n", + psDevInfo->sDisplayInfo.ui32MaxSwapChainBuffers)); + + + psDevInfo->sSystemBuffer.sSysAddr = psDevInfo->sFBInfo.sSysAddr; + psDevInfo->sSystemBuffer.sCPUVAddr = psDevInfo->sFBInfo.sCPUVAddr; + psDevInfo->sSystemBuffer.ulBufferSize = psDevInfo->sFBInfo.ulRoundedBufferSize; + + + + psDevInfo->sDCJTable.ui32TableSize = sizeof(PVRSRV_DC_SRV2DISP_KMJTABLE); + psDevInfo->sDCJTable.pfnOpenDCDevice = OpenDCDevice; + psDevInfo->sDCJTable.pfnCloseDCDevice = CloseDCDevice; + psDevInfo->sDCJTable.pfnEnumDCFormats = EnumDCFormats; + psDevInfo->sDCJTable.pfnEnumDCDims = EnumDCDims; + psDevInfo->sDCJTable.pfnGetDCSystemBuffer = GetDCSystemBuffer; + psDevInfo->sDCJTable.pfnGetDCInfo = GetDCInfo; + psDevInfo->sDCJTable.pfnGetBufferAddr = GetDCBufferAddr; + psDevInfo->sDCJTable.pfnCreateDCSwapChain = CreateDCSwapChain; + psDevInfo->sDCJTable.pfnDestroyDCSwapChain = DestroyDCSwapChain; + psDevInfo->sDCJTable.pfnSetDCDstRect = SetDCDstRect; + psDevInfo->sDCJTable.pfnSetDCSrcRect = SetDCSrcRect; + psDevInfo->sDCJTable.pfnSetDCDstColourKey = SetDCDstColourKey; + psDevInfo->sDCJTable.pfnSetDCSrcColourKey = SetDCSrcColourKey; + psDevInfo->sDCJTable.pfnGetDCBuffers = GetDCBuffers; + psDevInfo->sDCJTable.pfnSwapToDCBuffer = SwapToDCBuffer; + psDevInfo->sDCJTable.pfnSwapToDCSystem = SwapToDCSystem; + psDevInfo->sDCJTable.pfnSetDCState = SetDCState; + + + if(psDevInfo->sPVRJTable.pfnPVRSRVRegisterDCDevice ( + &psDevInfo->sDCJTable, + &psDevInfo->ulDeviceID ) != PVRSRV_OK) + { + return (OMAP_ERROR_DEVICE_REGISTER_FAILED); + } + + + pfnCmdProcList[DC_FLIP_COMMAND] = ProcessFlip; + + + aui32SyncCountList[DC_FLIP_COMMAND][0] = 0; + aui32SyncCountList[DC_FLIP_COMMAND][1] = 2; + + + + + + if (psDevInfo->sPVRJTable.pfnPVRSRVRegisterCmdProcList (psDevInfo->ulDeviceID, + &pfnCmdProcList[0], + aui32SyncCountList, + OMAPLFB_COMMAND_COUNT) != PVRSRV_OK) + { + printk(KERN_WARNING DRIVER_PREFIX ": Can't register callback\n"); + return (OMAP_ERROR_CANT_REGISTER_CALLBACK); + } + + } + + + psDevInfo->ulRefCount++; + + + return (OMAP_OK); + + } + +OMAP_ERROR OMAPLFBDeinit(void) +{ + OMAPLFB_DEVINFO *psDevInfo, *psDevFirst; + + psDevFirst = GetAnchorPtr(); + psDevInfo = psDevFirst; + + + if (psDevInfo == NULL) + { + return (OMAP_ERROR_GENERIC); + } + + + psDevInfo->ulRefCount--; + + if (psDevInfo->ulRefCount == 0) + { + + PVRSRV_DC_DISP2SRV_KMJTABLE *psJTable = &psDevInfo->sPVRJTable; + + if (psDevInfo->sPVRJTable.pfnPVRSRVRemoveCmdProcList (psDevInfo->ulDeviceID, OMAPLFB_COMMAND_COUNT) != PVRSRV_OK) + { + return (OMAP_ERROR_GENERIC); + } + + + if (psJTable->pfnPVRSRVRemoveDCDevice(psDevInfo->ulDeviceID) != PVRSRV_OK) + { + return (OMAP_ERROR_GENERIC); + } + + DeInitDev(psDevInfo); + + + OMAPLFBFreeKernelMem(psDevInfo); + } + + + SetAnchorPtr(NULL); + + + return (OMAP_OK); +} + + +#if defined(LDM_PLATFORM) +void OMAPLFBDriverSuspend(void) +{ + OMAPLFB_DEVINFO *psDevInfo = GetAnchorPtr(); + unsigned long ulLockFlags; + + spin_lock_irqsave(&psDevInfo->sSwapChainLock, ulLockFlags); + + if (psDevInfo->bDeviceSuspended) + { + goto ExitUnlock; + } + psDevInfo->bDeviceSuspended = OMAP_TRUE; + + + SetFlushStateInternalNoLock(psDevInfo, OMAP_TRUE); + + spin_unlock_irqrestore(&psDevInfo->sSwapChainLock, ulLockFlags); + + +#if defined (SUPPORT_TI_DSS_FW) + if (psDevInfo->psSwapChain != NULL) + { + OMAPLFBDisableDisplayRegisterAccess(); + } +#endif + return; + +ExitUnlock: + spin_unlock_irqrestore(&psDevInfo->sSwapChainLock, ulLockFlags); +} + +void OMAPLFBDriverResume(void) +{ + OMAPLFB_DEVINFO *psDevInfo = GetAnchorPtr(); + unsigned long ulLockFlags; + + if (psDevInfo->bDeviceSuspended == OMAP_FALSE) + { + return; + } +#if defined (SUPPORT_TI_DSS_FW) + if (psDevInfo->psSwapChain != NULL) + { + OMAPLFBEnableDisplayRegisterAccess(); + } +#endif + spin_lock_irqsave(&psDevInfo->sSwapChainLock, ulLockFlags); + + + SetFlushStateInternalNoLock(psDevInfo, OMAP_FALSE); + + psDevInfo->bDeviceSuspended = OMAP_FALSE; + + spin_unlock_irqrestore(&psDevInfo->sSwapChainLock, ulLockFlags); +} +#endif + diff --git a/services4/3rdparty/dc_omap3430_linux/omaplfb_linux.c b/services4/3rdparty/dc_omap3430_linux/omaplfb_linux.c new file mode 100644 index 0000000..9690796 --- /dev/null +++ b/services4/3rdparty/dc_omap3430_linux/omaplfb_linux.c @@ -0,0 +1,381 @@ +/********************************************************************** + * + * Copyright(c) 2008 Imagination Technologies Ltd. All rights reserved. + * + * This program is free software; you can redistribute it and/or modify it + * under the terms and conditions of the GNU General Public License, + * version 2, as published by the Free Software Foundation. + * + * This program is distributed in the hope it will be useful but, except + * as otherwise stated in writing, without any warranty; without even the + * implied warranty of merchantability or fitness for a particular purpose. + * See the GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License along with + * this program; if not, write to the Free Software Foundation, Inc., + * 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA. + * + * The full GNU General Public License is included in this distribution in + * the file called "COPYING". + * + * Contact Information: + * Imagination Technologies Ltd. + * Home Park Estate, Kings Langley, Herts, WD4 8LZ, UK + * + ******************************************************************************/ + +#ifndef AUTOCONF_INCLUDED +#include +#endif + +#include +#include + +#include +#include +#include +#include +#include + +#if defined(LDM_PLATFORM) +#include +#endif + +#if defined (SUPPORT_TI_DSS_FW) +#include + +#if (LINUX_VERSION_CODE > KERNEL_VERSION(2,6,26)) +#include +#else +#include +#endif +#else +#if !defined (CONFIG_OMAP2_DSS) +#define DISPC_IRQ_VSYNC 0x0002 +extern int omap_dispc_request_irq(unsigned long, void (*)(void *), void *); +extern void omap_dispc_free_irq(unsigned long, void (*)(void *), void *); +extern void omap_dispc_set_plane_base(int plane, IMG_UINT32 phys_addr); +#else +#include +#include +#include +static omap_dispc_isr_t *pOMAPLFBVSyncISRHandle = NULL; +#endif +#endif + + + +#include "img_defs.h" +#include "servicesext.h" +#include "kerneldisplay.h" +#include "omaplfb.h" +#include "pvrmodule.h" + +MODULE_SUPPORTED_DEVICE(DEVNAME); + +#define unref__ __attribute__ ((unused)) + +void *OMAPLFBAllocKernelMem(unsigned long ulSize) +{ + return kmalloc(ulSize, GFP_KERNEL); +} + +void OMAPLFBFreeKernelMem(void *pvMem) +{ + kfree(pvMem); +} + + +OMAP_ERROR OMAPLFBGetLibFuncAddr (char *szFunctionName, PFN_DC_GET_PVRJTABLE *ppfnFuncTable) +{ + if(strcmp("PVRGetDisplayClassJTable", szFunctionName) != 0) + { + return (OMAP_ERROR_INVALID_PARAMS); + } + + + *ppfnFuncTable = PVRGetDisplayClassJTable; + + return (OMAP_OK); +} +#if !defined (SUPPORT_TI_DSS_FW) +IMG_VOID OMAPLFBEnableVSyncInterrupt(OMAPLFB_SWAPCHAIN *psSwapChain) +{ + if (pOMAPLFBVSyncISRHandle == NULL) + OMAPLFBInstallVSyncISR (psSwapChain); +} + +IMG_VOID OMAPLFBDisableVSyncInterrupt(OMAPLFB_SWAPCHAIN *psSwapChain) +{ + if (pOMAPLFBVSyncISRHandle != NULL) + OMAPLFBUninstallVSyncISR (psSwapChain); +} +#else +static void OMAPLFBVSyncWriteReg(OMAPLFB_SWAPCHAIN *psSwapChain, unsigned long ulOffset, unsigned long ulValue) +{ + void *pvRegAddr = (void *)((char *)psSwapChain->pvRegs + ulOffset); + + + writel(ulValue, pvRegAddr); +} + +static unsigned long OMAPLFBVSyncReadReg(OMAPLFB_SWAPCHAIN *psSwapChain, unsigned long ulOffset) +{ + return readl((char *)psSwapChain->pvRegs + ulOffset); +} + +void OMAPLFBEnableVSyncInterrupt(OMAPLFB_SWAPCHAIN *psSwapChain) +{ +#if defined(SYS_USING_INTERRUPTS) + + unsigned long ulInterruptEnable = OMAPLFBVSyncReadReg(psSwapChain, OMAPLCD_IRQENABLE); + ulInterruptEnable |= OMAPLCD_INTMASK_VSYNC; + OMAPLFBVSyncWriteReg(psSwapChain, OMAPLCD_IRQENABLE, ulInterruptEnable ); +#endif +} + +void OMAPLFBDisableVSyncInterrupt(OMAPLFB_SWAPCHAIN *psSwapChain) +{ +#if defined(SYS_USING_INTERRUPTS) + + unsigned long ulInterruptEnable = OMAPLFBVSyncReadReg(psSwapChain, OMAPLCD_IRQENABLE); + ulInterruptEnable &= ~(OMAPLCD_INTMASK_VSYNC); + OMAPLFBVSyncWriteReg(psSwapChain, OMAPLCD_IRQENABLE, ulInterruptEnable); +#endif +} +#endif +#if defined(SYS_USING_INTERRUPTS) +static void +#if defined (SUPPORT_TI_DSS_FW) +OMAPLFBVSyncISR(void *arg, struct pt_regs unref__ *regs) +#else +#if defined (CONFIG_OMAP2_DSS) +OMAPLFBVSyncISR(void *arg, u32 mask) +#else +OMAPLFBVSyncISR(void *arg) +#endif +#endif +{ + OMAPLFB_SWAPCHAIN *psSwapChain= (OMAPLFB_SWAPCHAIN *)arg; + + (void) OMAPLFBVSyncIHandler(psSwapChain); +} +#endif +#if !defined (SUPPORT_TI_DSS_FW) +OMAP_ERROR OMAPLFBInstallVSyncISR(OMAPLFB_SWAPCHAIN *psSwapChain) +{ +#if !defined (CONFIG_OMAP2_DSS) + if (omap_dispc_request_irq(DISPC_IRQ_VSYNC, OMAPLFBVSyncISR, psSwapChain) != 0) +#else + pOMAPLFBVSyncISRHandle = omap_dispc_register_isr( + (omap_dispc_isr_t)OMAPLFBVSyncISR, psSwapChain, DISPC_IRQ_VSYNC); + + if (pOMAPLFBVSyncISRHandle != NULL) +#endif + return PVRSRV_ERROR_OUT_OF_MEMORY; /* not worth a proper mapping */ + return OMAP_OK; +} + + +OMAP_ERROR OMAPLFBUninstallVSyncISR (OMAPLFB_SWAPCHAIN *psSwapChain) +{ +#if !defined (CONFIG_OMAP2_DSS) + omap_dispc_free_irq(DISPC_IRQ_VSYNC, OMAPLFBVSyncISR, psSwapChain); +#else + omap_dispc_unregister_isr (OMAPLFBVSyncISR, psSwapChain, DISPC_IRQ_VSYNC); +#endif + return OMAP_OK; +} + + +IMG_VOID OMAPLFBFlip(OMAPLFB_SWAPCHAIN *psSwapChain, + IMG_UINT32 aPhyAddr) +{ +#if !defined (CONFIG_OMAP2_DSS) + omap_dispc_set_plane_base(0, aPhyAddr); +#else + OMAPLFBFlipDSS2 (psSwapChain, aPhyAddr); +#endif +} +#else + +OMAP_ERROR OMAPLFBInstallVSyncISR(OMAPLFB_SWAPCHAIN *psSwapChain) +{ +#if defined(SYS_USING_INTERRUPTS) + OMAPLFBDisableVSyncInterrupt(psSwapChain); + + if (omap2_disp_register_isr(OMAPLFBVSyncISR, psSwapChain, + DISPC_IRQSTATUS_VSYNC)) + { + printk(KERN_INFO DRIVER_PREFIX ": OMAPLFBInstallVSyncISR: Request OMAPLCD IRQ failed\n"); + return (OMAP_ERROR_INIT_FAILURE); + } + +#endif + return (OMAP_OK); +} + + +OMAP_ERROR OMAPLFBUninstallVSyncISR (OMAPLFB_SWAPCHAIN *psSwapChain) +{ +#if defined(SYS_USING_INTERRUPTS) + OMAPLFBDisableVSyncInterrupt(psSwapChain); + + omap2_disp_unregister_isr(OMAPLFBVSyncISR); + +#endif + return (OMAP_OK); +} + +void OMAPLFBEnableDisplayRegisterAccess(void) +{ + omap2_disp_get_dss(); +} + +void OMAPLFBDisableDisplayRegisterAccess(void) +{ + omap2_disp_put_dss(); +} + +void OMAPLFBFlip(OMAPLFB_SWAPCHAIN *psSwapChain, unsigned long aPhyAddr) +{ + unsigned long control; + + + OMAPLFBVSyncWriteReg(psSwapChain, OMAPLCD_GFX_BA0, aPhyAddr); + OMAPLFBVSyncWriteReg(psSwapChain, OMAPLCD_GFX_BA1, aPhyAddr); + + control = OMAPLFBVSyncReadReg(psSwapChain, OMAPLCD_CONTROL); + control |= OMAP_CONTROL_GOLCD; + OMAPLFBVSyncWriteReg(psSwapChain, OMAPLCD_CONTROL, control); +} +#endif + +#if defined(LDM_PLATFORM) + +static OMAP_BOOL bDeviceSuspended; + +static void OMAPLFBCommonSuspend(void) +{ + if (bDeviceSuspended) + { + return; + } + + OMAPLFBDriverSuspend(); + + bDeviceSuspended = OMAP_TRUE; +} + +static int OMAPLFBDriverSuspend_Entry(struct platform_device unref__ *pDevice, pm_message_t unref__ state) +{ + DEBUG_PRINTK((KERN_INFO DRIVER_PREFIX ": OMAPLFBDriverSuspend_Entry\n")); + + OMAPLFBCommonSuspend(); + + return 0; +} + +static int OMAPLFBDriverResume_Entry(struct platform_device unref__ *pDevice) +{ + DEBUG_PRINTK((KERN_INFO DRIVER_PREFIX ": OMAPLFBDriverResume_Entry\n")); + + OMAPLFBDriverResume(); + + bDeviceSuspended = OMAP_FALSE; + + return 0; +} + +static IMG_VOID OMAPLFBDriverShutdown_Entry(struct platform_device unref__ *pDevice) +{ + DEBUG_PRINTK((KERN_INFO DRIVER_PREFIX ": OMAPLFBDriverShutdown_Entry\n")); + + OMAPLFBCommonSuspend(); +} + +static void OMAPLFBDeviceRelease_Entry(struct device unref__ *pDevice) +{ + DEBUG_PRINTK((KERN_INFO DRIVER_PREFIX ": OMAPLFBDriverRelease_Entry\n")); + + OMAPLFBCommonSuspend(); +} + +static struct platform_driver omaplfb_driver = { + .driver = { + .name = DRVNAME, + }, + .suspend = OMAPLFBDriverSuspend_Entry, + .resume = OMAPLFBDriverResume_Entry, + .shutdown = OMAPLFBDriverShutdown_Entry, +}; + +static struct platform_device omaplfb_device = { + .name = DEVNAME, + .id = -1, + .dev = { + .release = OMAPLFBDeviceRelease_Entry + } +}; +#endif + +static int __init OMAPLFB_Init(void) +{ +#if defined(LDM_PLATFORM) + int error; +#endif + + if(OMAPLFBInit() != OMAP_OK) + { + printk(KERN_WARNING DRIVER_PREFIX ": OMAPLFB_Init: OMAPLFBInit failed\n"); + return -ENODEV; + } + +#if defined(LDM_PLATFORM) + if ((error = platform_driver_register(&omaplfb_driver)) != 0) + { + printk(KERN_WARNING DRIVER_PREFIX ": OMAPLFB_Init: Unable to register platform driver (%d)\n", error); + + goto ExitDeinit; + } + + if ((error = platform_device_register(&omaplfb_device)) != 0) + { + printk(KERN_WARNING DRIVER_PREFIX ": OMAPLFB_Init: Unable to register platform device (%d)\n", error); + + goto ExitDriverUnregister; + } +#endif + + return 0; + +#if defined(LDM_PLATFORM) +ExitDriverUnregister: + platform_driver_unregister(&omaplfb_driver); + +ExitDeinit: + if(OMAPLFBDeinit() != OMAP_OK) + { + printk(KERN_WARNING DRIVER_PREFIX ": OMAPLFB_Init: OMAPLFBDeinit failed\n"); + } + + return -ENODEV; +#endif +} + +static IMG_VOID __exit OMAPLFB_Cleanup(IMG_VOID) +{ +#if defined (LDM_PLATFORM) + platform_device_unregister(&omaplfb_device); + platform_driver_unregister(&omaplfb_driver); +#endif + + if(OMAPLFBDeinit() != OMAP_OK) + { + printk(KERN_WARNING DRIVER_PREFIX ": OMAPLFB_Cleanup: OMAPLFBDeinit failed\n"); + } +} + +module_init(OMAPLFB_Init); +module_exit(OMAPLFB_Cleanup); + diff --git a/services4/3rdparty/dc_ti8168_linux/Kbuild b/services4/3rdparty/dc_ti8168_linux/Kbuild new file mode 100755 index 0000000..aba88c9 --- /dev/null +++ b/services4/3rdparty/dc_ti8168_linux/Kbuild @@ -0,0 +1,17 @@ +SYS_USING_INTERRUPTS = 1 +SUPPORT_TI_DSS_FW = 0 + +SYS_CFLAGS.$(SYS_USING_INTERRUPTS) += -DSYS_USING_INTERRUPTS +SYS_CFLAGS.$(SUPPORT_TI_DSS_FW) += -DSUPPORT_TI_DSS_FW + + +EXTRA_CFLAGS = -DLINUX \ + -DCONFIG_OMAP2_DSS \ + -I$(PVR_BUILD_DIR)/include4 \ + -I$(PVR_BUILD_DIR)/services4/include \ + -I$(PVR_BUILD_DIR)/services4/system/$(PVR_SYSTEM) \ + -I$(PVR_BUILD_DIR)/services4/system/include \ + $(SYS_CFLAGS.1) \ + +obj-m := omaplfb.o +omaplfb-y := omaplfb_displayclass.o omaplfb_linux.o diff --git a/services4/3rdparty/dc_ti8168_linux/kbuild/Makefile b/services4/3rdparty/dc_ti8168_linux/kbuild/Makefile new file mode 100644 index 0000000..54139af --- /dev/null +++ b/services4/3rdparty/dc_ti8168_linux/kbuild/Makefile @@ -0,0 +1,43 @@ +# +# Copyright(c) 2008 Imagination Technologies Ltd. All rights reserved. +# +# This program is free software; you can redistribute it and/or modify it +# under the terms and conditions of the GNU General Public License, +# version 2, as published by the Free Software Foundation. +# +# This program is distributed in the hope it will be useful but, except +# as otherwise stated in writing, without any warranty; without even the +# implied warranty of merchantability or fitness for a particular purpose. +# See the GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License along with +# this program; if not, write to the Free Software Foundation, Inc., +# 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA. +# +# The full GNU General Public License is included in this distribution in +# the file called "COPYING". +# +# Contact Information: +# Imagination Technologies Ltd. +# Home Park Estate, Kings Langley, Herts, WD4 8LZ, UK +# +# +# + +include $(EURASIAROOT)/eurasiacon/build/linux/kbuild/Makefile.kbuild_subdir_common + +MODULE = omaplfb + +INCLUDES = -I$(EURASIAROOT)/include4 \ + -I$(EURASIAROOT)/services4/include \ + -I$(EURASIAROOT)/services4/system/$(PVR_SYSTEM) \ + -I$(EURASIAROOT)/services4/system/include \ + +SOURCES = ../omaplfb_displayclass.c \ + ../omaplfb_linux.c + +SYM_VERS_DEPS = $(EURASIAROOT)/services4/srvkm/env/linux + + + + diff --git a/services4/3rdparty/dc_ti8168_linux/modules.order b/services4/3rdparty/dc_ti8168_linux/modules.order new file mode 100644 index 0000000..f1f4a73 --- /dev/null +++ b/services4/3rdparty/dc_ti8168_linux/modules.order @@ -0,0 +1 @@ +kernel//proj/AVME10/mahesh/Graphics/Netra/Graphics_SDK_4_00_00_01/GFX_Linux_KM/services4/3rdparty/dc_ti8168_linux/omaplfb.ko diff --git a/services4/3rdparty/dc_ti8168_linux/omaplfb.h b/services4/3rdparty/dc_ti8168_linux/omaplfb.h new file mode 100644 index 0000000..66ff328 --- /dev/null +++ b/services4/3rdparty/dc_ti8168_linux/omaplfb.h @@ -0,0 +1,282 @@ +/********************************************************************** + * + * Copyright(c) 2008 Imagination Technologies Ltd. All rights reserved. + * + * This program is free software; you can redistribute it and/or modify it + * under the terms and conditions of the GNU General Public License, + * version 2, as published by the Free Software Foundation. + * + * This program is distributed in the hope it will be useful but, except + * as otherwise stated in writing, without any warranty; without even the + * implied warranty of merchantability or fitness for a particular purpose. + * See the GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License along with + * this program; if not, write to the Free Software Foundation, Inc., + * 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA. + * + * The full GNU General Public License is included in this distribution in + * the file called "COPYING". + * + * Contact Information: + * Imagination Technologies Ltd. + * Home Park Estate, Kings Langley, Herts, WD4 8LZ, UK + * + ******************************************************************************/ + +#ifndef __OMAPLFB_H__ +#define __OMAPLFB_H__ + +extern IMG_BOOL PVRGetDisplayClassJTable(PVRSRV_DC_DISP2SRV_KMJTABLE *psJTable); + +#define OMAPLCD_IRQ 25 + +#define OMAPLCD_SYSCONFIG 0x0410 +#define OMAPLCD_CONFIG 0x0444 +#define OMAPLCD_DEFAULT_COLOR0 0x044C +#define OMAPLCD_TIMING_H 0x0464 +#define OMAPLCD_TIMING_V 0x0468 +#define OMAPLCD_POL_FREQ 0x046C +#define OMAPLCD_DIVISOR 0x0470 +#define OMAPLCD_SIZE_DIG 0x0478 +#define OMAPLCD_SIZE_LCD 0x047C +#define OMAPLCD_GFX_POSITION 0x0488 +#define OMAPLCD_GFX_SIZE 0x048C +#define OMAPLCD_GFX_ATTRIBUTES 0x04a0 +#define OMAPLCD_GFX_FIFO_THRESHOLD 0x04a4 +#define OMAPLCD_GFX_WINDOW_SKIP 0x04b4 + +#define OMAPLCD_IRQSTATUS 0x0418 +#define OMAPLCD_IRQENABLE 0x041c +#define OMAPLCD_CONTROL 0x0440 +#define OMAPLCD_GFX_BA0 0x0480 +#define OMAPLCD_GFX_BA1 0x0484 +#define OMAPLCD_GFX_ROW_INC 0x04ac +#define OMAPLCD_GFX_PIX_INC 0x04b0 +#define OMAPLCD_VID1_BA0 0x04bc +#define OMAPLCD_VID1_BA1 0x04c0 +#define OMAPLCD_VID1_ROW_INC 0x04d8 +#define OMAPLCD_VID1_PIX_INC 0x04dc + +#define OMAP_CONTROL_GODIGITAL (1 << 6) +#define OMAP_CONTROL_GOLCD (1 << 5) +#define OMAP_CONTROL_DIGITALENABLE (1 << 1) +#define OMAP_CONTROL_LCDENABLE (1 << 0) + +#define OMAPLCD_INTMASK_VSYNC (1 << 1) +#define OMAPLCD_INTMASK_OFF 0 + +typedef void * OMAP_HANDLE; + +typedef enum tag_omap_bool +{ + OMAP_FALSE = 0, + OMAP_TRUE = 1, +} OMAP_BOOL, *OMAP_PBOOL; + +typedef struct OMAPLFB_BUFFER_TAG +{ + unsigned long ulBufferSize; + + + + + IMG_SYS_PHYADDR sSysAddr; + IMG_CPU_VIRTADDR sCPUVAddr; + PVRSRV_SYNC_DATA *psSyncData; + + struct OMAPLFB_BUFFER_TAG *psNext; +} OMAPLFB_BUFFER; + +typedef struct OMAPLFB_VSYNC_FLIP_ITEM_TAG +{ + + + + OMAP_HANDLE hCmdComplete; + + unsigned long ulSwapInterval; + + OMAP_BOOL bValid; + + OMAP_BOOL bFlipped; + + OMAP_BOOL bCmdCompleted; + + + + + + IMG_SYS_PHYADDR* sSysAddr; +} OMAPLFB_VSYNC_FLIP_ITEM; + +typedef struct PVRPDP_SWAPCHAIN_TAG +{ + + unsigned long ulBufferCount; + + OMAPLFB_BUFFER *psBuffer; + + OMAPLFB_VSYNC_FLIP_ITEM *psVSyncFlips; + + + unsigned long ulInsertIndex; + + + unsigned long ulRemoveIndex; + + + void *pvRegs; + + + PVRSRV_DC_DISP2SRV_KMJTABLE *psPVRJTable; + + + OMAP_BOOL bFlushCommands; + + + unsigned long ulSetFlushStateRefCount; + + + OMAP_BOOL bBlanked; + + + spinlock_t *psSwapChainLock; +} OMAPLFB_SWAPCHAIN; + +typedef struct OMAPLFB_FBINFO_TAG +{ + unsigned long ulFBSize; + unsigned long ulBufferSize; + unsigned long ulRoundedBufferSize; + unsigned long ulWidth; + unsigned long ulHeight; + unsigned long ulByteStride; + + + + IMG_SYS_PHYADDR sSysAddr; + IMG_CPU_VIRTADDR sCPUVAddr; + + + PVRSRV_PIXEL_FORMAT ePixelFormat; +}OMAPLFB_FBINFO; + +typedef struct OMAPLFB_DEVINFO_TAG +{ + unsigned long ulDeviceID; + + + OMAPLFB_BUFFER sSystemBuffer; + + + PVRSRV_DC_DISP2SRV_KMJTABLE sPVRJTable; + + + PVRSRV_DC_SRV2DISP_KMJTABLE sDCJTable; + + + OMAPLFB_FBINFO sFBInfo; + + + unsigned long ulRefCount; + + + OMAPLFB_SWAPCHAIN *psSwapChain; + + + OMAP_BOOL bFlushCommands; + + + struct fb_info *psLINFBInfo; + + + struct notifier_block sLINNotifBlock; + + + OMAP_BOOL bDeviceSuspended; + + + spinlock_t sSwapChainLock; + + + + + + IMG_DEV_VIRTADDR sDisplayDevVAddr; + + DISPLAY_INFO sDisplayInfo; + + + DISPLAY_FORMAT sDisplayFormat; + + + DISPLAY_DIMS sDisplayDim; + +} OMAPLFB_DEVINFO; + +#define OMAPLFB_PAGE_SIZE 4096 +#define OMAPLFB_PAGE_MASK (OMAPLFB_PAGE_SIZE - 1) +#define OMAPLFB_PAGE_TRUNC (~OMAPLFB_PAGE_MASK) + +#define OMAPLFB_PAGE_ROUNDUP(x) (((x) + OMAPLFB_PAGE_MASK) & OMAPLFB_PAGE_TRUNC) + +//#define DEBUG + +#ifdef DEBUG +#define DEBUG_PRINTK(x) printk x +#else +#define DEBUG_PRINTK(x) +#endif + +#define DISPLAY_DEVICE_NAME "PowerVR OMAP Linux Display Driver" +#define DRVNAME "omaplfb" +#define DEVNAME DRVNAME +#define DRIVER_PREFIX DRVNAME + +typedef enum _OMAP_ERROR_ +{ + OMAP_OK = 0, + OMAP_ERROR_GENERIC = 1, + OMAP_ERROR_OUT_OF_MEMORY = 2, + OMAP_ERROR_TOO_FEW_BUFFERS = 3, + OMAP_ERROR_INVALID_PARAMS = 4, + OMAP_ERROR_INIT_FAILURE = 5, + OMAP_ERROR_CANT_REGISTER_CALLBACK = 6, + OMAP_ERROR_INVALID_DEVICE = 7, + OMAP_ERROR_DEVICE_REGISTER_FAILED = 8 +} OMAP_ERROR; + + +#ifndef UNREFERENCED_PARAMETER +#define UNREFERENCED_PARAMETER(param) (param) = (param) +#endif + +OMAP_ERROR OMAPLFBInit(void); +OMAP_ERROR OMAPLFBDeinit(void); + +#ifdef LDM_PLATFORM +void OMAPLFBDriverSuspend(void); +void OMAPLFBDriverResume(void); +#endif + +void *OMAPLFBAllocKernelMem(unsigned long ulSize); +void OMAPLFBFreeKernelMem(void *pvMem); +OMAP_ERROR OMAPLFBGetLibFuncAddr(char *szFunctionName, PFN_DC_GET_PVRJTABLE *ppfnFuncTable); +OMAP_ERROR OMAPLFBInstallVSyncISR (OMAPLFB_SWAPCHAIN *psSwapChain); +OMAP_ERROR OMAPLFBUninstallVSyncISR(OMAPLFB_SWAPCHAIN *psSwapChain); +OMAP_BOOL OMAPLFBVSyncIHandler(OMAPLFB_SWAPCHAIN *psSwapChain); +void OMAPLFBEnableVSyncInterrupt(OMAPLFB_SWAPCHAIN *psSwapChain); +void OMAPLFBDisableVSyncInterrupt(OMAPLFB_SWAPCHAIN *psSwapChain); +#if defined (SUPPORT_TI_DSS_FW) +void OMAPLFBEnableDisplayRegisterAccess(void); +void OMAPLFBDisableDisplayRegisterAccess(void); +#endif +#if defined (CONFIG_OMAP2_DSS) +IMG_VOID OMAPLFBFlipDSS2(OMAPLFB_SWAPCHAIN *psSwapChain, + IMG_UINT32 aPhyAddr); +#endif +void OMAPLFBFlip(OMAPLFB_SWAPCHAIN *psSwapChain, unsigned long aPhyAddr); + +#endif + diff --git a/services4/3rdparty/dc_ti8168_linux/omaplfb_displayclass.c b/services4/3rdparty/dc_ti8168_linux/omaplfb_displayclass.c new file mode 100644 index 0000000..8282c0b --- /dev/null +++ b/services4/3rdparty/dc_ti8168_linux/omaplfb_displayclass.c @@ -0,0 +1,1545 @@ +/********************************************************************** + * + * Copyright(c) 2008 Imagination Technologies Ltd. All rights reserved. + * + * This program is free software; you can redistribute it and/or modify it + * under the terms and conditions of the GNU General Public License, + * version 2, as published by the Free Software Foundation. + * + * This program is distributed in the hope it will be useful but, except + * as otherwise stated in writing, without any warranty; without even the + * implied warranty of merchantability or fitness for a particular purpose. + * See the GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License along with + * this program; if not, write to the Free Software Foundation, Inc., + * 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA. + * + * The full GNU General Public License is included in this distribution in + * the file called "COPYING". + * + * Contact Information: + * Imagination Technologies Ltd. + * Home Park Estate, Kings Langley, Herts, WD4 8LZ, UK + * + ******************************************************************************/ + +#include +#include +#include +#include +#include +#include +#include +#include + +#include "img_defs.h" +#include "servicesext.h" +#include "kerneldisplay.h" +#include "omaplfb.h" + +static void *gpvAnchor; + +static int fb_idx = 0; + +#define OMAPLFB_COMMAND_COUNT 1 + +static PFN_DC_GET_PVRJTABLE pfnGetPVRJTable = 0; + +static OMAPLFB_DEVINFO * GetAnchorPtr(void) +{ + return (OMAPLFB_DEVINFO *)gpvAnchor; +} + +static void SetAnchorPtr(OMAPLFB_DEVINFO *psDevInfo) +{ + gpvAnchor = (void*)psDevInfo; +} + + +static void FlushInternalVSyncQueue(OMAPLFB_SWAPCHAIN *psSwapChain) +{ + OMAPLFB_VSYNC_FLIP_ITEM *psFlipItem; + unsigned long ulMaxIndex; + unsigned long i; + + + psFlipItem = &psSwapChain->psVSyncFlips[psSwapChain->ulRemoveIndex]; + ulMaxIndex = psSwapChain->ulBufferCount - 1; + + for(i = 0; i < psSwapChain->ulBufferCount; i++) + { + if (psFlipItem->bValid == OMAP_FALSE) + { + continue; + } + + DEBUG_PRINTK((KERN_INFO DRIVER_PREFIX ": FlushInternalVSyncQueue: Flushing swap buffer (index %lu)\n", psSwapChain->ulRemoveIndex)); + + if(psFlipItem->bFlipped == OMAP_FALSE) + { + + OMAPLFBFlip(psSwapChain, (unsigned long)psFlipItem->sSysAddr); + } + + if(psFlipItem->bCmdCompleted == OMAP_FALSE) + { + DEBUG_PRINTK((KERN_INFO DRIVER_PREFIX ": FlushInternalVSyncQueue: Calling command complete for swap buffer (index %lu)\n", psSwapChain->ulRemoveIndex)); + + psSwapChain->psPVRJTable->pfnPVRSRVCmdComplete((IMG_HANDLE)psFlipItem->hCmdComplete, IMG_TRUE); + } + + + psSwapChain->ulRemoveIndex++; + + if(psSwapChain->ulRemoveIndex > ulMaxIndex) + { + psSwapChain->ulRemoveIndex = 0; + } + + + psFlipItem->bFlipped = OMAP_FALSE; + psFlipItem->bCmdCompleted = OMAP_FALSE; + psFlipItem->bValid = OMAP_FALSE; + + + psFlipItem = &psSwapChain->psVSyncFlips[psSwapChain->ulRemoveIndex]; + } + + psSwapChain->ulInsertIndex = 0; + psSwapChain->ulRemoveIndex = 0; +} + +static void SetFlushStateInternalNoLock(OMAPLFB_DEVINFO* psDevInfo, + OMAP_BOOL bFlushState) +{ + OMAPLFB_SWAPCHAIN *psSwapChain = psDevInfo->psSwapChain; + + if (psSwapChain == NULL) + { + return; + } + + if (bFlushState) + { + if (psSwapChain->ulSetFlushStateRefCount == 0) + { + OMAPLFBDisableVSyncInterrupt(psSwapChain); + psSwapChain->bFlushCommands = OMAP_TRUE; + FlushInternalVSyncQueue(psSwapChain); + } + psSwapChain->ulSetFlushStateRefCount++; + } + else + { + if (psSwapChain->ulSetFlushStateRefCount != 0) + { + psSwapChain->ulSetFlushStateRefCount--; + if (psSwapChain->ulSetFlushStateRefCount == 0) + { + psSwapChain->bFlushCommands = OMAP_FALSE; + OMAPLFBEnableVSyncInterrupt(psSwapChain); + } + } + } +} + +static IMG_VOID SetFlushStateInternal(OMAPLFB_DEVINFO* psDevInfo, + OMAP_BOOL bFlushState) +{ + unsigned long ulLockFlags; + + spin_lock_irqsave(&psDevInfo->sSwapChainLock, ulLockFlags); + + SetFlushStateInternalNoLock(psDevInfo, bFlushState); + + spin_unlock_irqrestore(&psDevInfo->sSwapChainLock, ulLockFlags); +} + +static void SetFlushStateExternal(OMAPLFB_DEVINFO* psDevInfo, + OMAP_BOOL bFlushState) +{ + unsigned long ulLockFlags; + + spin_lock_irqsave(&psDevInfo->sSwapChainLock, ulLockFlags); + + + if (psDevInfo->bFlushCommands != bFlushState) + { + psDevInfo->bFlushCommands = bFlushState; + SetFlushStateInternalNoLock(psDevInfo, bFlushState); + } + + spin_unlock_irqrestore(&psDevInfo->sSwapChainLock, ulLockFlags); +} + +static IMG_VOID SetDCState(IMG_HANDLE hDevice, IMG_UINT32 ui32State) +{ + OMAPLFB_DEVINFO *psDevInfo = (OMAPLFB_DEVINFO *)hDevice; + + switch (ui32State) + { + case DC_STATE_FLUSH_COMMANDS: + SetFlushStateExternal(psDevInfo, OMAP_TRUE); + break; + case DC_STATE_NO_FLUSH_COMMANDS: + SetFlushStateExternal(psDevInfo, OMAP_FALSE); + break; + default: + break; + } + + return; +} + +static int FrameBufferEvents(struct notifier_block *psNotif, + unsigned long event, void *data) +{ + OMAPLFB_DEVINFO *psDevInfo; + OMAPLFB_SWAPCHAIN *psSwapChain; + struct fb_event *psFBEvent = (struct fb_event *)data; + OMAP_BOOL bBlanked; + + + if (event != FB_EVENT_BLANK) + { + return 0; + } + + psDevInfo = GetAnchorPtr(); + psSwapChain = psDevInfo->psSwapChain; + + bBlanked = (*(IMG_INT *)psFBEvent->data != 0) ? OMAP_TRUE: OMAP_FALSE; + + if (bBlanked != psSwapChain->bBlanked) + { + psSwapChain->bBlanked = bBlanked; + + if (bBlanked) + { + + SetFlushStateInternal(psDevInfo, OMAP_TRUE); + } + else + { + + SetFlushStateInternal(psDevInfo, OMAP_FALSE); + } + } + + return 0; +} + + +static OMAP_ERROR UnblankDisplay(OMAPLFB_DEVINFO *psDevInfo) +{ + int res; + + acquire_console_sem(); + res = fb_blank(psDevInfo->psLINFBInfo, 0); + release_console_sem(); +#if !defined (CONFIG_OMAP2_DSS) + /* DSS2 returns error if unblank from a non-suspend state */ + if (res != 0) + { + printk(KERN_WARNING DRIVER_PREFIX + ": fb_blank failed (%d)", res); + return (OMAP_ERROR_GENERIC); + } +#endif + + return (OMAP_OK); +} + +#if defined (CONFIG_OMAP2_DSS) +#include +struct wq_flip { + struct fb_var_screeninfo var; + struct fb_info *psLINFBInfo; + struct work_struct work; +}; +struct wq_flip wq_flipdss2; + +static void dss2_pan_display (struct work_struct *work) +{ + struct wq_flip *ptrwq_flip = + container_of(work, struct wq_flip, work); + if (ptrwq_flip->psLINFBInfo->fbops->fb_pan_display != NULL) { + ptrwq_flip->psLINFBInfo->fbops->fb_pan_display (&ptrwq_flip->var, ptrwq_flip->psLINFBInfo); + + } + +} + +/* + Flip implementation for DSS2 using fb_pan_display +*/ +IMG_VOID OMAPLFBFlipDSS2(OMAPLFB_SWAPCHAIN *psSwapChain, + IMG_UINT32 aPhyAddr) +{ + OMAPLFB_DEVINFO *psDevInfo = GetAnchorPtr (); + struct fb_info *psLINFBInfo = psDevInfo->psLINFBInfo; + memcpy ( &wq_flipdss2.var, &psLINFBInfo->var, sizeof(struct fb_var_screeninfo)); + wq_flipdss2.var.yoffset = (aPhyAddr-psLINFBInfo->fix.smem_start)/psLINFBInfo->fix.line_length; + wq_flipdss2.psLINFBInfo = psLINFBInfo; + schedule_work (&wq_flipdss2.work); +} +#endif + +static OMAP_ERROR EnableLFBEventNotification(OMAPLFB_DEVINFO *psDevInfo) +{ + int res; + OMAPLFB_SWAPCHAIN *psSwapChain = psDevInfo->psSwapChain; + OMAP_ERROR eError; + + + memset(&psDevInfo->sLINNotifBlock, 0, sizeof(psDevInfo->sLINNotifBlock)); + + psDevInfo->sLINNotifBlock.notifier_call = FrameBufferEvents; + + psSwapChain->bBlanked = OMAP_FALSE; + + res = fb_register_client(&psDevInfo->sLINNotifBlock); + if (res != 0) + { + printk(KERN_WARNING DRIVER_PREFIX + ": fb_register_client failed (%d)", res); + + return (OMAP_ERROR_GENERIC); + } + + eError = UnblankDisplay(psDevInfo); + if (eError != OMAP_OK) + { + DEBUG_PRINTK((KERN_WARNING DRIVER_PREFIX + ": UnblankDisplay failed (%d)", eError)); + return eError; + } + + return (OMAP_OK); +} + +static OMAP_ERROR DisableLFBEventNotification(OMAPLFB_DEVINFO *psDevInfo) +{ + int res; + + + res = fb_unregister_client(&psDevInfo->sLINNotifBlock); + if (res != 0) + { + printk(KERN_WARNING DRIVER_PREFIX + ": fb_unregister_client failed (%d)", res); + return (OMAP_ERROR_GENERIC); + } + + return (OMAP_OK); +} + +static PVRSRV_ERROR OpenDCDevice(IMG_UINT32 ui32DeviceID, + IMG_HANDLE *phDevice, + PVRSRV_SYNC_DATA* psSystemBufferSyncData) +{ + OMAPLFB_DEVINFO *psDevInfo; + OMAP_ERROR eError; + + UNREFERENCED_PARAMETER(ui32DeviceID); + + psDevInfo = GetAnchorPtr(); + + + psDevInfo->sSystemBuffer.psSyncData = psSystemBufferSyncData; + + eError = UnblankDisplay(psDevInfo); + if (eError != OMAP_OK) + { + DEBUG_PRINTK((KERN_WARNING DRIVER_PREFIX + ": UnblankDisplay failed (%d)", eError)); + return (PVRSRV_ERROR_GENERIC); + } + + + *phDevice = (IMG_HANDLE)psDevInfo; + + return (PVRSRV_OK); +} + +static PVRSRV_ERROR CloseDCDevice(IMG_HANDLE hDevice) +{ + UNREFERENCED_PARAMETER(hDevice); + + return (PVRSRV_OK); +} + +static PVRSRV_ERROR EnumDCFormats(IMG_HANDLE hDevice, + IMG_UINT32 *pui32NumFormats, + DISPLAY_FORMAT *psFormat) +{ + OMAPLFB_DEVINFO *psDevInfo; + + if(!hDevice || !pui32NumFormats) + { + return (PVRSRV_ERROR_INVALID_PARAMS); + } + + psDevInfo = (OMAPLFB_DEVINFO*)hDevice; + + *pui32NumFormats = 1; + + if(psFormat) + { + psFormat[0] = psDevInfo->sDisplayFormat; + } + + return (PVRSRV_OK); +} + +static PVRSRV_ERROR EnumDCDims(IMG_HANDLE hDevice, + DISPLAY_FORMAT *psFormat, + IMG_UINT32 *pui32NumDims, + DISPLAY_DIMS *psDim) +{ + OMAPLFB_DEVINFO *psDevInfo; + + if(!hDevice || !psFormat || !pui32NumDims) + { + return (PVRSRV_ERROR_INVALID_PARAMS); + } + + psDevInfo = (OMAPLFB_DEVINFO*)hDevice; + + *pui32NumDims = 1; + + + if(psDim) + { + psDim[0] = psDevInfo->sDisplayDim; + } + + return (PVRSRV_OK); +} + + +static PVRSRV_ERROR GetDCSystemBuffer(IMG_HANDLE hDevice, IMG_HANDLE *phBuffer) +{ + OMAPLFB_DEVINFO *psDevInfo; + + if(!hDevice || !phBuffer) + { + return (PVRSRV_ERROR_INVALID_PARAMS); + } + + psDevInfo = (OMAPLFB_DEVINFO*)hDevice; + + *phBuffer = (IMG_HANDLE)&psDevInfo->sSystemBuffer; + + return (PVRSRV_OK); +} + + +static PVRSRV_ERROR GetDCInfo(IMG_HANDLE hDevice, DISPLAY_INFO *psDCInfo) +{ + OMAPLFB_DEVINFO *psDevInfo; + + if(!hDevice || !psDCInfo) + { + return (PVRSRV_ERROR_INVALID_PARAMS); + } + + psDevInfo = (OMAPLFB_DEVINFO*)hDevice; + + *psDCInfo = psDevInfo->sDisplayInfo; + + return (PVRSRV_OK); +} + +static PVRSRV_ERROR GetDCBufferAddr(IMG_HANDLE hDevice, + IMG_HANDLE hBuffer, + IMG_SYS_PHYADDR **ppsSysAddr, + IMG_UINT32 *pui32ByteSize, + IMG_VOID **ppvCpuVAddr, + IMG_HANDLE *phOSMapInfo, + IMG_BOOL *pbIsContiguous) +{ + OMAPLFB_DEVINFO *psDevInfo; + OMAPLFB_BUFFER *psSystemBuffer; + + if(!hDevice) + { + return (PVRSRV_ERROR_INVALID_PARAMS); + } + psDevInfo = (OMAPLFB_DEVINFO*)hDevice; + + if(!hBuffer) + { + return (PVRSRV_ERROR_INVALID_PARAMS); + } + psSystemBuffer = (OMAPLFB_BUFFER *)hBuffer; + + if (!ppsSysAddr) + { + return (PVRSRV_ERROR_INVALID_PARAMS); + } + + *ppsSysAddr = &psSystemBuffer->sSysAddr; + + if (!pui32ByteSize) + { + return (PVRSRV_ERROR_INVALID_PARAMS); + } + + *pui32ByteSize = (IMG_UINT32)psDevInfo->sFBInfo.ulBufferSize; + + if (ppvCpuVAddr) + { + *ppvCpuVAddr = psSystemBuffer->sCPUVAddr; + } + + if (phOSMapInfo) + { + *phOSMapInfo = (IMG_HANDLE)0; + } + + if (pbIsContiguous) + { + *pbIsContiguous = IMG_TRUE; + } + + return (PVRSRV_OK); +} + +static PVRSRV_ERROR CreateDCSwapChain(IMG_HANDLE hDevice, + IMG_UINT32 ui32Flags, + DISPLAY_SURF_ATTRIBUTES *psDstSurfAttrib, + DISPLAY_SURF_ATTRIBUTES *psSrcSurfAttrib, + IMG_UINT32 ui32BufferCount, + PVRSRV_SYNC_DATA **ppsSyncData, + IMG_UINT32 ui32OEMFlags, + IMG_HANDLE *phSwapChain, + IMG_UINT32 *pui32SwapChainID) +{ + OMAPLFB_DEVINFO *psDevInfo; + OMAPLFB_SWAPCHAIN *psSwapChain; + OMAPLFB_BUFFER *psBuffer; + OMAPLFB_VSYNC_FLIP_ITEM *psVSyncFlips; + IMG_UINT32 i; + PVRSRV_ERROR eError = PVRSRV_ERROR_GENERIC; + unsigned long ulLockFlags; + IMG_UINT32 ui32BuffersToSkip; + + UNREFERENCED_PARAMETER(ui32OEMFlags); + UNREFERENCED_PARAMETER(pui32SwapChainID); + + + if(!hDevice + || !psDstSurfAttrib + || !psSrcSurfAttrib + || !ppsSyncData + || !phSwapChain) + { + return (PVRSRV_ERROR_INVALID_PARAMS); + } + + psDevInfo = (OMAPLFB_DEVINFO*)hDevice; + + + if (psDevInfo->sDisplayInfo.ui32MaxSwapChains == 0) + { + return (PVRSRV_ERROR_NOT_SUPPORTED); + } + + + if(psDevInfo->psSwapChain != NULL) + { + return (PVRSRV_ERROR_FLIP_CHAIN_EXISTS); + } + + + if(ui32BufferCount > psDevInfo->sDisplayInfo.ui32MaxSwapChainBuffers) + { + return (PVRSRV_ERROR_TOOMANYBUFFERS); + } + + if ((psDevInfo->sFBInfo.ulRoundedBufferSize * (unsigned long)ui32BufferCount) > psDevInfo->sFBInfo.ulFBSize) + { + return (PVRSRV_ERROR_TOOMANYBUFFERS); + } + + + ui32BuffersToSkip = psDevInfo->sDisplayInfo.ui32MaxSwapChainBuffers - ui32BufferCount; + + + if(psDstSurfAttrib->pixelformat != psDevInfo->sDisplayFormat.pixelformat + || psDstSurfAttrib->sDims.ui32ByteStride != psDevInfo->sDisplayDim.ui32ByteStride + || psDstSurfAttrib->sDims.ui32Width != psDevInfo->sDisplayDim.ui32Width + || psDstSurfAttrib->sDims.ui32Height != psDevInfo->sDisplayDim.ui32Height) + { + + return (PVRSRV_ERROR_INVALID_PARAMS); + } + + if(psDstSurfAttrib->pixelformat != psSrcSurfAttrib->pixelformat + || psDstSurfAttrib->sDims.ui32ByteStride != psSrcSurfAttrib->sDims.ui32ByteStride + || psDstSurfAttrib->sDims.ui32Width != psSrcSurfAttrib->sDims.ui32Width + || psDstSurfAttrib->sDims.ui32Height != psSrcSurfAttrib->sDims.ui32Height) + { + + return (PVRSRV_ERROR_INVALID_PARAMS); + } + + + UNREFERENCED_PARAMETER(ui32Flags); + + + psSwapChain = (OMAPLFB_SWAPCHAIN*)OMAPLFBAllocKernelMem(sizeof(OMAPLFB_SWAPCHAIN)); + if(!psSwapChain) + { + return (PVRSRV_ERROR_OUT_OF_MEMORY); + } + + psBuffer = (OMAPLFB_BUFFER*)OMAPLFBAllocKernelMem(sizeof(OMAPLFB_BUFFER) * ui32BufferCount); + if(!psBuffer) + { + eError = PVRSRV_ERROR_OUT_OF_MEMORY; + goto ErrorFreeSwapChain; + } + + psVSyncFlips = (OMAPLFB_VSYNC_FLIP_ITEM *)OMAPLFBAllocKernelMem(sizeof(OMAPLFB_VSYNC_FLIP_ITEM) * ui32BufferCount); + if (!psVSyncFlips) + { + eError = PVRSRV_ERROR_OUT_OF_MEMORY; + goto ErrorFreeBuffers; + } + + psSwapChain->ulBufferCount = (unsigned long)ui32BufferCount; + psSwapChain->psBuffer = psBuffer; + psSwapChain->psVSyncFlips = psVSyncFlips; + psSwapChain->ulInsertIndex = 0; + psSwapChain->ulRemoveIndex = 0; + psSwapChain->psPVRJTable = &psDevInfo->sPVRJTable; + psSwapChain->psSwapChainLock = &psDevInfo->sSwapChainLock; + + + for(i=0; isFBInfo.ulRoundedBufferSize; + + psBuffer[i].psSyncData = ppsSyncData[i]; + + psBuffer[i].sSysAddr.uiAddr = psDevInfo->sFBInfo.sSysAddr.uiAddr + ui32BufferOffset; + psBuffer[i].sCPUVAddr = psDevInfo->sFBInfo.sCPUVAddr + ui32BufferOffset; + } + + + for(i=0; ipvRegs = ioremap(psDevInfo->psLINFBInfo->fix.mmio_start, psDevInfo->psLINFBInfo->fix.mmio_len); + if (psSwapChain->pvRegs == NULL) + { + printk(KERN_WARNING DRIVER_PREFIX ": Couldn't map registers needed for flipping\n"); + goto ErrorDisableDisplayRegisters; + } +#endif + if (OMAPLFBInstallVSyncISR(psSwapChain) != OMAP_OK) + { + printk(KERN_WARNING DRIVER_PREFIX ": ISR handler failed to register\n"); + goto ErrorUnmapRegisters; + } + + spin_lock_irqsave(&psDevInfo->sSwapChainLock, ulLockFlags); + + + psDevInfo->psSwapChain = psSwapChain; + + + psSwapChain->bFlushCommands = psDevInfo->bFlushCommands; + + if (psSwapChain->bFlushCommands) + { + psSwapChain->ulSetFlushStateRefCount = 1; + } + else + { + psSwapChain->ulSetFlushStateRefCount = 0; + OMAPLFBEnableVSyncInterrupt(psSwapChain); + } + + spin_unlock_irqrestore(&psDevInfo->sSwapChainLock, ulLockFlags); + + if (EnableLFBEventNotification(psDevInfo)!= OMAP_OK) + { + printk(KERN_WARNING DRIVER_PREFIX ": Couldn't enable framebuffer event notification\n"); + goto ErrorUninstallVSyncInterrupt; + } + + + *phSwapChain = (IMG_HANDLE)psSwapChain; + + return (PVRSRV_OK); + +ErrorUninstallVSyncInterrupt: + if(OMAPLFBUninstallVSyncISR(psSwapChain) != OMAP_OK) + { + printk(KERN_WARNING DRIVER_PREFIX ": Couldn't uninstall VSync ISR\n"); + } +ErrorUnmapRegisters: +#if defined (SUPPORT_TI_DSS_FW) + iounmap(psSwapChain->pvRegs); +ErrorDisableDisplayRegisters: + OMAPLFBDisableDisplayRegisterAccess(); +#endif + OMAPLFBFreeKernelMem(psVSyncFlips); +ErrorFreeBuffers: + OMAPLFBFreeKernelMem(psBuffer); +ErrorFreeSwapChain: + OMAPLFBFreeKernelMem(psSwapChain); + + return eError; +} + +static PVRSRV_ERROR DestroyDCSwapChain(IMG_HANDLE hDevice, + IMG_HANDLE hSwapChain) +{ + OMAPLFB_DEVINFO *psDevInfo; + OMAPLFB_SWAPCHAIN *psSwapChain; + unsigned long ulLockFlags; + OMAP_ERROR eError; + + + if(!hDevice || !hSwapChain) + { + return (PVRSRV_ERROR_INVALID_PARAMS); + } + + psDevInfo = (OMAPLFB_DEVINFO*)hDevice; + psSwapChain = (OMAPLFB_SWAPCHAIN*)hSwapChain; + if (psSwapChain != psDevInfo->psSwapChain) + { + return (PVRSRV_ERROR_INVALID_PARAMS); + } + + eError = DisableLFBEventNotification(psDevInfo); + if (eError != OMAP_OK) + { + printk(KERN_WARNING DRIVER_PREFIX ": Couldn't disable framebuffer event notification\n"); + } + + spin_lock_irqsave(&psDevInfo->sSwapChainLock, ulLockFlags); + + OMAPLFBDisableVSyncInterrupt(psSwapChain); + + + FlushInternalVSyncQueue(psSwapChain); + + + OMAPLFBFlip(psSwapChain, (unsigned long)psDevInfo->sFBInfo.sSysAddr.uiAddr); + + + psDevInfo->psSwapChain = NULL; + + spin_unlock_irqrestore(&psDevInfo->sSwapChainLock, ulLockFlags); + + if(OMAPLFBUninstallVSyncISR(psSwapChain) != OMAP_OK) + { + printk(KERN_WARNING DRIVER_PREFIX ": Couldn't uninstall VSync ISR\n"); + return (PVRSRV_ERROR_GENERIC); + } + +#if defined (SUPPORT_TI_DSS_FW) + + iounmap(psSwapChain->pvRegs); + + OMAPLFBDisableDisplayRegisterAccess(); +#endif + + OMAPLFBFreeKernelMem(psSwapChain->psVSyncFlips); + OMAPLFBFreeKernelMem(psSwapChain->psBuffer); + OMAPLFBFreeKernelMem(psSwapChain); + + return (PVRSRV_OK); +} + +static PVRSRV_ERROR SetDCDstRect(IMG_HANDLE hDevice, + IMG_HANDLE hSwapChain, + IMG_RECT *psRect) +{ + UNREFERENCED_PARAMETER(hDevice); + UNREFERENCED_PARAMETER(hSwapChain); + UNREFERENCED_PARAMETER(psRect); + + + + return (PVRSRV_ERROR_NOT_SUPPORTED); +} + +static PVRSRV_ERROR SetDCSrcRect(IMG_HANDLE hDevice, + IMG_HANDLE hSwapChain, + IMG_RECT *psRect) +{ + UNREFERENCED_PARAMETER(hDevice); + UNREFERENCED_PARAMETER(hSwapChain); + UNREFERENCED_PARAMETER(psRect); + + + + return (PVRSRV_ERROR_NOT_SUPPORTED); +} + +static PVRSRV_ERROR SetDCDstColourKey(IMG_HANDLE hDevice, + IMG_HANDLE hSwapChain, + IMG_UINT32 ui32CKColour) +{ + UNREFERENCED_PARAMETER(hDevice); + UNREFERENCED_PARAMETER(hSwapChain); + UNREFERENCED_PARAMETER(ui32CKColour); + + + + return (PVRSRV_ERROR_NOT_SUPPORTED); +} + +static PVRSRV_ERROR SetDCSrcColourKey(IMG_HANDLE hDevice, + IMG_HANDLE hSwapChain, + IMG_UINT32 ui32CKColour) +{ + UNREFERENCED_PARAMETER(hDevice); + UNREFERENCED_PARAMETER(hSwapChain); + UNREFERENCED_PARAMETER(ui32CKColour); + + + + return (PVRSRV_ERROR_NOT_SUPPORTED); +} + +static PVRSRV_ERROR GetDCBuffers(IMG_HANDLE hDevice, + IMG_HANDLE hSwapChain, + IMG_UINT32 *pui32BufferCount, + IMG_HANDLE *phBuffer) +{ + OMAPLFB_DEVINFO *psDevInfo; + OMAPLFB_SWAPCHAIN *psSwapChain; + unsigned long i; + + + if(!hDevice + || !hSwapChain + || !pui32BufferCount + || !phBuffer) + { + return (PVRSRV_ERROR_INVALID_PARAMS); + } + + psDevInfo = (OMAPLFB_DEVINFO*)hDevice; + psSwapChain = (OMAPLFB_SWAPCHAIN*)hSwapChain; + if (psSwapChain != psDevInfo->psSwapChain) + { + return (PVRSRV_ERROR_INVALID_PARAMS); + } + + + *pui32BufferCount = (IMG_UINT32)psSwapChain->ulBufferCount; + + + for(i=0; iulBufferCount; i++) + { + phBuffer[i] = (IMG_HANDLE)&psSwapChain->psBuffer[i]; + } + + return (PVRSRV_OK); +} + +static PVRSRV_ERROR SwapToDCBuffer(IMG_HANDLE hDevice, + IMG_HANDLE hBuffer, + IMG_UINT32 ui32SwapInterval, + IMG_HANDLE hPrivateTag, + IMG_UINT32 ui32ClipRectCount, + IMG_RECT *psClipRect) +{ + OMAPLFB_DEVINFO *psDevInfo; + + UNREFERENCED_PARAMETER(ui32SwapInterval); + UNREFERENCED_PARAMETER(hPrivateTag); + UNREFERENCED_PARAMETER(psClipRect); + + if(!hDevice + || !hBuffer + || (ui32ClipRectCount != 0)) + { + return (PVRSRV_ERROR_INVALID_PARAMS); + } + + psDevInfo = (OMAPLFB_DEVINFO*)hDevice; + + + return (PVRSRV_OK); +} + +static PVRSRV_ERROR SwapToDCSystem(IMG_HANDLE hDevice, + IMG_HANDLE hSwapChain) +{ + OMAPLFB_DEVINFO *psDevInfo; + OMAPLFB_SWAPCHAIN *psSwapChain; + unsigned long ulLockFlags; + + if(!hDevice || !hSwapChain) + { + return (PVRSRV_ERROR_INVALID_PARAMS); + } + + psDevInfo = (OMAPLFB_DEVINFO*)hDevice; + psSwapChain = (OMAPLFB_SWAPCHAIN*)hSwapChain; + if (psSwapChain != psDevInfo->psSwapChain) + { + return (PVRSRV_ERROR_INVALID_PARAMS); + } + + spin_lock_irqsave(&psDevInfo->sSwapChainLock, ulLockFlags); + + + FlushInternalVSyncQueue(psSwapChain); + + + OMAPLFBFlip(psSwapChain, (unsigned long)psDevInfo->sFBInfo.sSysAddr.uiAddr); + + spin_unlock_irqrestore(&psDevInfo->sSwapChainLock, ulLockFlags); + + return (PVRSRV_OK); +} + +OMAP_BOOL OMAPLFBVSyncIHandler(OMAPLFB_SWAPCHAIN *psSwapChain) +{ + OMAP_BOOL bStatus = OMAP_FALSE; + OMAPLFB_VSYNC_FLIP_ITEM *psFlipItem; + unsigned long ulMaxIndex; + unsigned long ulLockFlags; + + psFlipItem = &psSwapChain->psVSyncFlips[psSwapChain->ulRemoveIndex]; + ulMaxIndex = psSwapChain->ulBufferCount - 1; + + spin_lock_irqsave(psSwapChain->psSwapChainLock, ulLockFlags); + + + if (psSwapChain->bFlushCommands) + { + goto ExitUnlock; + } + + while(psFlipItem->bValid) + { + + if(psFlipItem->bFlipped) + { + + if(!psFlipItem->bCmdCompleted) + { + + psSwapChain->psPVRJTable->pfnPVRSRVCmdComplete((IMG_HANDLE)psFlipItem->hCmdComplete, IMG_TRUE); + + + psFlipItem->bCmdCompleted = OMAP_TRUE; + } + + + psFlipItem->ulSwapInterval--; + + + if(psFlipItem->ulSwapInterval == 0) + { + + psSwapChain->ulRemoveIndex++; + + if(psSwapChain->ulRemoveIndex > ulMaxIndex) + { + psSwapChain->ulRemoveIndex = 0; + } + + + psFlipItem->bCmdCompleted = OMAP_FALSE; + psFlipItem->bFlipped = OMAP_FALSE; + + + psFlipItem->bValid = OMAP_FALSE; + } + else + { + + break; + } + } + else + { + + OMAPLFBFlip(psSwapChain, (unsigned long)psFlipItem->sSysAddr); + + + psFlipItem->bFlipped = OMAP_TRUE; + + + break; + } + + + psFlipItem = &psSwapChain->psVSyncFlips[psSwapChain->ulRemoveIndex]; + } + +ExitUnlock: + spin_unlock_irqrestore(psSwapChain->psSwapChainLock, ulLockFlags); + + return bStatus; +} + +static IMG_BOOL ProcessFlip(IMG_HANDLE hCmdCookie, + IMG_UINT32 ui32DataSize, + IMG_VOID *pvData) +{ + DISPLAYCLASS_FLIP_COMMAND *psFlipCmd; + OMAPLFB_DEVINFO *psDevInfo; + OMAPLFB_BUFFER *psBuffer; + OMAPLFB_SWAPCHAIN *psSwapChain; +#if defined(SYS_USING_INTERRUPTS) + OMAPLFB_VSYNC_FLIP_ITEM* psFlipItem; +#endif + unsigned long ulLockFlags; + + + if(!hCmdCookie || !pvData) + { + return IMG_FALSE; + } + + + psFlipCmd = (DISPLAYCLASS_FLIP_COMMAND*)pvData; + + if (psFlipCmd == IMG_NULL || sizeof(DISPLAYCLASS_FLIP_COMMAND) != ui32DataSize) + { + return IMG_FALSE; + } + + + psDevInfo = (OMAPLFB_DEVINFO*)psFlipCmd->hExtDevice; + + psBuffer = (OMAPLFB_BUFFER*)psFlipCmd->hExtBuffer; + psSwapChain = (OMAPLFB_SWAPCHAIN*) psFlipCmd->hExtSwapChain; + + spin_lock_irqsave(&psDevInfo->sSwapChainLock, ulLockFlags); + + + if (psDevInfo->bDeviceSuspended) + { + psSwapChain->psPVRJTable->pfnPVRSRVCmdComplete(hCmdCookie, IMG_TRUE); + goto ExitTrueUnlock; + } + +#if defined(SYS_USING_INTERRUPTS) + + if(psFlipCmd->ui32SwapInterval == 0 || psSwapChain->bFlushCommands == OMAP_TRUE) + { +#endif + + OMAPLFBFlip(psSwapChain, (unsigned long)psBuffer->sSysAddr.uiAddr); + + + psSwapChain->psPVRJTable->pfnPVRSRVCmdComplete(hCmdCookie, IMG_TRUE); + +#if defined(SYS_USING_INTERRUPTS) + goto ExitTrueUnlock; + } + + psFlipItem = &psSwapChain->psVSyncFlips[psSwapChain->ulInsertIndex]; + + + if(psFlipItem->bValid == OMAP_FALSE) + { + unsigned long ulMaxIndex = psSwapChain->ulBufferCount - 1; + + if(psSwapChain->ulInsertIndex == psSwapChain->ulRemoveIndex) + { + + OMAPLFBFlip(psSwapChain, (unsigned long)psBuffer->sSysAddr.uiAddr); + + psFlipItem->bFlipped = OMAP_TRUE; + } + else + { + psFlipItem->bFlipped = OMAP_FALSE; + } + + psFlipItem->hCmdComplete = (OMAP_HANDLE)hCmdCookie; + psFlipItem->ulSwapInterval = (unsigned long)psFlipCmd->ui32SwapInterval; + psFlipItem->sSysAddr = &psBuffer->sSysAddr; + psFlipItem->bValid = OMAP_TRUE; + + psSwapChain->ulInsertIndex++; + if(psSwapChain->ulInsertIndex > ulMaxIndex) + { + psSwapChain->ulInsertIndex = 0; + } + + goto ExitTrueUnlock; + } + + spin_unlock_irqrestore(&psDevInfo->sSwapChainLock, ulLockFlags); + return IMG_FALSE; +#endif + +ExitTrueUnlock: + spin_unlock_irqrestore(&psDevInfo->sSwapChainLock, ulLockFlags); + return IMG_TRUE; +} + + +static OMAP_ERROR InitDev(OMAPLFB_DEVINFO *psDevInfo) +{ + struct fb_info *psLINFBInfo; + struct module *psLINFBOwner; + OMAPLFB_FBINFO *psPVRFBInfo = &psDevInfo->sFBInfo; + OMAP_ERROR eError = OMAP_ERROR_GENERIC; + unsigned long FBSize; + + acquire_console_sem(); + + if (fb_idx < 0 || fb_idx >= num_registered_fb) + { + eError = OMAP_ERROR_INVALID_DEVICE; + goto errRelSem; + } + + psLINFBInfo = registered_fb[fb_idx]; + + psLINFBOwner = psLINFBInfo->fbops->owner; + if (!try_module_get(psLINFBOwner)) + { + printk(KERN_INFO DRIVER_PREFIX + ": Couldn't get framebuffer module\n"); + + goto errRelSem; + } + + if (psLINFBInfo->fbops->fb_open != NULL) + { + int res; + + res = psLINFBInfo->fbops->fb_open(psLINFBInfo, 0); + if (res != 0) + { + printk(KERN_INFO DRIVER_PREFIX + ": Couldn't open framebuffer: %d\n", res); + + goto errModPut; + } + } + + + psDevInfo->psLINFBInfo = psLINFBInfo; + + DEBUG_PRINTK((KERN_INFO DRIVER_PREFIX + ": psLINFBInfo->screen_size: 0x%lx\n", + psLINFBInfo->screen_size)); + DEBUG_PRINTK((KERN_INFO DRIVER_PREFIX + ": psLINFBInfo->fix.smem_len : 0x%lx\n", + psLINFBInfo->fix.smem_len)); + + + FBSize = (psLINFBInfo->screen_size) != 0 ? + psLINFBInfo->screen_size : + psLINFBInfo->fix.smem_len; + + DEBUG_PRINTK((KERN_INFO DRIVER_PREFIX + ": Framebuffer physical address: 0x%lx\n", + psLINFBInfo->fix.smem_start)); + DEBUG_PRINTK((KERN_INFO DRIVER_PREFIX + ": Framebuffer virtual address: 0x%lx\n", + (unsigned long)psLINFBInfo->screen_base)); + DEBUG_PRINTK((KERN_INFO DRIVER_PREFIX + ": Framebuffer size: %lu\n", + FBSize)); + DEBUG_PRINTK((KERN_INFO DRIVER_PREFIX + ": Framebuffer virtual width: %u\n", + psLINFBInfo->var.xres_virtual)); + DEBUG_PRINTK((KERN_INFO DRIVER_PREFIX + ": Framebuffer virtual height: %u\n", + psLINFBInfo->var.yres_virtual)); + DEBUG_PRINTK((KERN_INFO DRIVER_PREFIX + ": Framebuffer width: %u\n", + psLINFBInfo->var.xres)); + DEBUG_PRINTK((KERN_INFO DRIVER_PREFIX + ": Framebuffer height: %u\n", + psLINFBInfo->var.yres)); + DEBUG_PRINTK((KERN_INFO DRIVER_PREFIX + ": Framebuffer stride: %u\n", + psLINFBInfo->fix.line_length)); + + + psPVRFBInfo->sSysAddr.uiAddr = psLINFBInfo->fix.smem_start; + psPVRFBInfo->sCPUVAddr = psLINFBInfo->screen_base; + if ((psLINFBInfo->var.rotate == FB_ROTATE_CW) + || (psLINFBInfo->var.rotate == FB_ROTATE_CCW) ) { + psPVRFBInfo->ulWidth = psLINFBInfo->var.yres; + psPVRFBInfo->ulHeight = psLINFBInfo->var.xres; + } else { + psPVRFBInfo->ulWidth = psLINFBInfo->var.xres; + psPVRFBInfo->ulHeight = psLINFBInfo->var.yres; + } + + psPVRFBInfo->ulByteStride = psLINFBInfo->fix.line_length; + psPVRFBInfo->ulFBSize = FBSize; + psPVRFBInfo->ulBufferSize = psPVRFBInfo->ulHeight * psPVRFBInfo->ulByteStride; + + + +#ifdef CONFIG_OMAP2_DSS + psPVRFBInfo->ulRoundedBufferSize = psPVRFBInfo->ulBufferSize; +#else + psPVRFBInfo->ulRoundedBufferSize = OMAPLFB_PAGE_ROUNDUP(psPVRFBInfo->ulBufferSize); +#endif + if(psLINFBInfo->var.bits_per_pixel == 16) + { + if((psLINFBInfo->var.red.length == 5) && + (psLINFBInfo->var.green.length == 6) && + (psLINFBInfo->var.blue.length == 5) && + (psLINFBInfo->var.red.offset == 11) && + (psLINFBInfo->var.green.offset == 5) && + (psLINFBInfo->var.blue.offset == 0) && + (psLINFBInfo->var.red.msb_right == 0)) + { + psPVRFBInfo->ePixelFormat = PVRSRV_PIXEL_FORMAT_RGB565; + } + else + { + printk("Unknown FB format\n"); + } + } + else if(psLINFBInfo->var.bits_per_pixel == 32) + { + if((psLINFBInfo->var.red.length == 8) && + (psLINFBInfo->var.green.length == 8) && + (psLINFBInfo->var.blue.length == 8) && + (psLINFBInfo->var.red.offset == 16) && + (psLINFBInfo->var.green.offset == 8) && + (psLINFBInfo->var.blue.offset == 0) && + (psLINFBInfo->var.red.msb_right == 0)) + { + printk ("PVRSRV_PIXEL_FORMAT_ARGB8888\n"); + psPVRFBInfo->ePixelFormat = PVRSRV_PIXEL_FORMAT_ARGB8888; + } + else + { + printk("Unknown FB format\n"); + } + } + else + { + printk("Unknown FB format\n"); + } + + + psDevInfo->sFBInfo.sSysAddr.uiAddr = psPVRFBInfo->sSysAddr.uiAddr; + psDevInfo->sFBInfo.sCPUVAddr = psPVRFBInfo->sCPUVAddr; + +#ifdef CONFIG_OMAP2_DSS + INIT_WORK (&wq_flipdss2.work, dss2_pan_display); +#endif + + eError = OMAP_OK; + goto errRelSem; + +errModPut: + module_put(psLINFBOwner); +errRelSem: + release_console_sem(); + return eError; +} + +static void DeInitDev(OMAPLFB_DEVINFO *psDevInfo) +{ + struct fb_info *psLINFBInfo = psDevInfo->psLINFBInfo; + struct module *psLINFBOwner; + + acquire_console_sem(); + + psLINFBOwner = psLINFBInfo->fbops->owner; + + if (psLINFBInfo->fbops->fb_release != NULL) + { + (void) psLINFBInfo->fbops->fb_release(psLINFBInfo, 0); + } + + module_put(psLINFBOwner); + + release_console_sem(); +} + +OMAP_ERROR OMAPLFBInit(void) +{ + OMAPLFB_DEVINFO *psDevInfo; + + psDevInfo = GetAnchorPtr(); + + if (psDevInfo == NULL) + { + PFN_CMD_PROC pfnCmdProcList[OMAPLFB_COMMAND_COUNT]; + IMG_UINT32 aui32SyncCountList[OMAPLFB_COMMAND_COUNT][2]; + + psDevInfo = (OMAPLFB_DEVINFO *)OMAPLFBAllocKernelMem(sizeof(OMAPLFB_DEVINFO)); + + if(!psDevInfo) + { + return (OMAP_ERROR_OUT_OF_MEMORY); + } + + + memset(psDevInfo, 0, sizeof(OMAPLFB_DEVINFO)); + + + SetAnchorPtr((void*)psDevInfo); + + + psDevInfo->ulRefCount = 0; + + + if(InitDev(psDevInfo) != OMAP_OK) + { + return (OMAP_ERROR_INIT_FAILURE); + } + + if(OMAPLFBGetLibFuncAddr ("PVRGetDisplayClassJTable", &pfnGetPVRJTable) != OMAP_OK) + { + return (OMAP_ERROR_INIT_FAILURE); + } + + + if(!(*pfnGetPVRJTable)(&psDevInfo->sPVRJTable)) + { + return (OMAP_ERROR_INIT_FAILURE); + } + + + spin_lock_init(&psDevInfo->sSwapChainLock); + + psDevInfo->psSwapChain = 0; + psDevInfo->bFlushCommands = OMAP_FALSE; + psDevInfo->bDeviceSuspended = OMAP_FALSE; + + psDevInfo->sDisplayInfo.ui32MaxSwapChainBuffers = (IMG_UINT32)(psDevInfo->sFBInfo.ulFBSize / psDevInfo->sFBInfo.ulRoundedBufferSize); +#if !defined (SUPPORT_TI_DSS_FW) + /* Limiting the ui32MaxSwapChainBuffers to 3 */ + if (psDevInfo->sDisplayInfo.ui32MaxSwapChainBuffers > 3) + psDevInfo->sDisplayInfo.ui32MaxSwapChainBuffers = 3; +#endif +#if 1 + /* for fb_pan_display to work, yres_virtual should be set to number of buffers multiplied yres */ + psDevInfo->psLINFBInfo->var.yres_virtual = psDevInfo->sDisplayInfo.ui32MaxSwapChainBuffers * psDevInfo->psLINFBInfo->var.yres; + if (fb_set_var(psDevInfo->psLINFBInfo, &psDevInfo->psLINFBInfo->var) != 0) + { + printk(KERN_INFO DRIVER_PREFIX ": Couldn't set framebuffer paramter: "); + + } +#endif + if (psDevInfo->sDisplayInfo.ui32MaxSwapChainBuffers == 0) + { + psDevInfo->sDisplayInfo.ui32MaxSwapChains = 0; + psDevInfo->sDisplayInfo.ui32MaxSwapInterval = 0; + } + else + { + psDevInfo->sDisplayInfo.ui32MaxSwapChains = 1; + psDevInfo->sDisplayInfo.ui32MaxSwapInterval = 3; + } + psDevInfo->sDisplayInfo.ui32MinSwapInterval = 0; + + strncpy(psDevInfo->sDisplayInfo.szDisplayName, DISPLAY_DEVICE_NAME, MAX_DISPLAY_NAME_SIZE); + + psDevInfo->sDisplayFormat.pixelformat = psDevInfo->sFBInfo.ePixelFormat; + psDevInfo->sDisplayDim.ui32Width = (IMG_UINT32)psDevInfo->sFBInfo.ulWidth; + psDevInfo->sDisplayDim.ui32Height = (IMG_UINT32)psDevInfo->sFBInfo.ulHeight; + psDevInfo->sDisplayDim.ui32ByteStride = (IMG_UINT32)psDevInfo->sFBInfo.ulByteStride; + + DEBUG_PRINTK((KERN_INFO DRIVER_PREFIX + ": Maximum number of swap chain buffers: %lu\n", + psDevInfo->sDisplayInfo.ui32MaxSwapChainBuffers)); + + + psDevInfo->sSystemBuffer.sSysAddr = psDevInfo->sFBInfo.sSysAddr; + psDevInfo->sSystemBuffer.sCPUVAddr = psDevInfo->sFBInfo.sCPUVAddr; + psDevInfo->sSystemBuffer.ulBufferSize = psDevInfo->sFBInfo.ulRoundedBufferSize; + + + + psDevInfo->sDCJTable.ui32TableSize = sizeof(PVRSRV_DC_SRV2DISP_KMJTABLE); + psDevInfo->sDCJTable.pfnOpenDCDevice = OpenDCDevice; + psDevInfo->sDCJTable.pfnCloseDCDevice = CloseDCDevice; + psDevInfo->sDCJTable.pfnEnumDCFormats = EnumDCFormats; + psDevInfo->sDCJTable.pfnEnumDCDims = EnumDCDims; + psDevInfo->sDCJTable.pfnGetDCSystemBuffer = GetDCSystemBuffer; + psDevInfo->sDCJTable.pfnGetDCInfo = GetDCInfo; + psDevInfo->sDCJTable.pfnGetBufferAddr = GetDCBufferAddr; + psDevInfo->sDCJTable.pfnCreateDCSwapChain = CreateDCSwapChain; + psDevInfo->sDCJTable.pfnDestroyDCSwapChain = DestroyDCSwapChain; + psDevInfo->sDCJTable.pfnSetDCDstRect = SetDCDstRect; + psDevInfo->sDCJTable.pfnSetDCSrcRect = SetDCSrcRect; + psDevInfo->sDCJTable.pfnSetDCDstColourKey = SetDCDstColourKey; + psDevInfo->sDCJTable.pfnSetDCSrcColourKey = SetDCSrcColourKey; + psDevInfo->sDCJTable.pfnGetDCBuffers = GetDCBuffers; + psDevInfo->sDCJTable.pfnSwapToDCBuffer = SwapToDCBuffer; + psDevInfo->sDCJTable.pfnSwapToDCSystem = SwapToDCSystem; + psDevInfo->sDCJTable.pfnSetDCState = SetDCState; + + + if(psDevInfo->sPVRJTable.pfnPVRSRVRegisterDCDevice ( + &psDevInfo->sDCJTable, + &psDevInfo->ulDeviceID ) != PVRSRV_OK) + { + return (OMAP_ERROR_DEVICE_REGISTER_FAILED); + } + + + pfnCmdProcList[DC_FLIP_COMMAND] = ProcessFlip; + + + aui32SyncCountList[DC_FLIP_COMMAND][0] = 0; + aui32SyncCountList[DC_FLIP_COMMAND][1] = 2; + + + + + + if (psDevInfo->sPVRJTable.pfnPVRSRVRegisterCmdProcList (psDevInfo->ulDeviceID, + &pfnCmdProcList[0], + aui32SyncCountList, + OMAPLFB_COMMAND_COUNT) != PVRSRV_OK) + { + printk(KERN_WARNING DRIVER_PREFIX ": Can't register callback\n"); + return (OMAP_ERROR_CANT_REGISTER_CALLBACK); + } + + } + + + psDevInfo->ulRefCount++; + + + return (OMAP_OK); + + } + +OMAP_ERROR OMAPLFBDeinit(void) +{ + OMAPLFB_DEVINFO *psDevInfo, *psDevFirst; + + psDevFirst = GetAnchorPtr(); + psDevInfo = psDevFirst; + + + if (psDevInfo == NULL) + { + return (OMAP_ERROR_GENERIC); + } + + + psDevInfo->ulRefCount--; + + if (psDevInfo->ulRefCount == 0) + { + + PVRSRV_DC_DISP2SRV_KMJTABLE *psJTable = &psDevInfo->sPVRJTable; + + if (psDevInfo->sPVRJTable.pfnPVRSRVRemoveCmdProcList (psDevInfo->ulDeviceID, OMAPLFB_COMMAND_COUNT) != PVRSRV_OK) + { + return (OMAP_ERROR_GENERIC); + } + + + if (psJTable->pfnPVRSRVRemoveDCDevice(psDevInfo->ulDeviceID) != PVRSRV_OK) + { + return (OMAP_ERROR_GENERIC); + } + + DeInitDev(psDevInfo); + + + OMAPLFBFreeKernelMem(psDevInfo); + } + + + SetAnchorPtr(NULL); + + + return (OMAP_OK); +} + + +#if defined(LDM_PLATFORM) +void OMAPLFBDriverSuspend(void) +{ + OMAPLFB_DEVINFO *psDevInfo = GetAnchorPtr(); + unsigned long ulLockFlags; + + spin_lock_irqsave(&psDevInfo->sSwapChainLock, ulLockFlags); + + if (psDevInfo->bDeviceSuspended) + { + goto ExitUnlock; + } + psDevInfo->bDeviceSuspended = OMAP_TRUE; + + + SetFlushStateInternalNoLock(psDevInfo, OMAP_TRUE); + + spin_unlock_irqrestore(&psDevInfo->sSwapChainLock, ulLockFlags); + + +#if defined (SUPPORT_TI_DSS_FW) + if (psDevInfo->psSwapChain != NULL) + { + OMAPLFBDisableDisplayRegisterAccess(); + } +#endif + return; + +ExitUnlock: + spin_unlock_irqrestore(&psDevInfo->sSwapChainLock, ulLockFlags); +} + +void OMAPLFBDriverResume(void) +{ + OMAPLFB_DEVINFO *psDevInfo = GetAnchorPtr(); + unsigned long ulLockFlags; + + if (psDevInfo->bDeviceSuspended == OMAP_FALSE) + { + return; + } +#if defined (SUPPORT_TI_DSS_FW) + if (psDevInfo->psSwapChain != NULL) + { + OMAPLFBEnableDisplayRegisterAccess(); + } +#endif + spin_lock_irqsave(&psDevInfo->sSwapChainLock, ulLockFlags); + + + SetFlushStateInternalNoLock(psDevInfo, OMAP_FALSE); + + psDevInfo->bDeviceSuspended = OMAP_FALSE; + + spin_unlock_irqrestore(&psDevInfo->sSwapChainLock, ulLockFlags); +} +#endif + diff --git a/services4/3rdparty/dc_ti8168_linux/omaplfb_linux.c b/services4/3rdparty/dc_ti8168_linux/omaplfb_linux.c new file mode 100644 index 0000000..9002cba --- /dev/null +++ b/services4/3rdparty/dc_ti8168_linux/omaplfb_linux.c @@ -0,0 +1,405 @@ +/********************************************************************** + * + * Copyright(c) 2008 Imagination Technologies Ltd. All rights reserved. + * + * This program is free software; you can redistribute it and/or modify it + * under the terms and conditions of the GNU General Public License, + * version 2, as published by the Free Software Foundation. + * + * This program is distributed in the hope it will be useful but, except + * as otherwise stated in writing, without any warranty; without even the + * implied warranty of merchantability or fitness for a particular purpose. + * See the GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License along with + * this program; if not, write to the Free Software Foundation, Inc., + * 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA. + * + * The full GNU General Public License is included in this distribution in + * the file called "COPYING". + * + * Contact Information: + * Imagination Technologies Ltd. + * Home Park Estate, Kings Langley, Herts, WD4 8LZ, UK + * + ******************************************************************************/ + +#ifndef AUTOCONF_INCLUDED +#include +#endif + +#include +#include + +#include +#include +#include +#include +#include + + +#include "img_defs.h" +#include "servicesext.h" +#include "kerneldisplay.h" +#include "omaplfb.h" +#include "pvrmodule.h" + +#include + +#if defined(LDM_PLATFORM) +#include +#endif + +#if defined (SUPPORT_TI_DSS_FW) +#include + +#if (LINUX_VERSION_CODE > KERNEL_VERSION(2,6,26)) +#include +#else +#include +#endif +#else +#if !defined (CONFIG_OMAP2_DSS) +#define DISPC_IRQ_VSYNC 0x0002 +int omap_dispc_request_irq(unsigned long irq_mask, void (*callback)(void *data), + void *data) +{ + printk(" omap_dispc_request_irq NOT Implemented \n"); + return (0); +} +void omap_dispc_free_irq(unsigned long irq_mask, void (*callback)(void *data), + void *data) +{ + printk("omap_dispc_free_irq NOT Implemented \n"); +} + +void omap_dispc_set_plane_base(int plane, IMG_UINT32 phys_addr) +{ + printk (" omap_dispc_set_plane_base NOT Implemented \n"); +} + +#else +#include +#include +#include +static int pOMAPLFBVSyncISRHandle = 0; +#endif +#endif + +MODULE_SUPPORTED_DEVICE(DEVNAME); + +#define unref__ __attribute__ ((unused)) + +void *OMAPLFBAllocKernelMem(unsigned long ulSize) +{ + return kmalloc(ulSize, GFP_KERNEL); +} + +void OMAPLFBFreeKernelMem(void *pvMem) +{ + kfree(pvMem); +} + + +OMAP_ERROR OMAPLFBGetLibFuncAddr (char *szFunctionName, PFN_DC_GET_PVRJTABLE *ppfnFuncTable) +{ + if(strcmp("PVRGetDisplayClassJTable", szFunctionName) != 0) + { + return (OMAP_ERROR_INVALID_PARAMS); + } + + + *ppfnFuncTable = PVRGetDisplayClassJTable; + + return (OMAP_OK); +} +#if !defined (SUPPORT_TI_DSS_FW) +IMG_VOID OMAPLFBEnableVSyncInterrupt(OMAPLFB_SWAPCHAIN *psSwapChain) +{ +#if defined (CONFIG_OMAP2_DSS) + if (pOMAPLFBVSyncISRHandle == 0) +#endif + OMAPLFBInstallVSyncISR (psSwapChain); +} + +IMG_VOID OMAPLFBDisableVSyncInterrupt(OMAPLFB_SWAPCHAIN *psSwapChain) +{ +#if defined (CONFIG_OMAP2_DSS) + if (pOMAPLFBVSyncISRHandle != 0) +#endif + OMAPLFBUninstallVSyncISR (psSwapChain); +} +#else +static void OMAPLFBVSyncWriteReg(OMAPLFB_SWAPCHAIN *psSwapChain, unsigned long ulOffset, unsigned long ulValue) +{ + void *pvRegAddr = (void *)((char *)psSwapChain->pvRegs + ulOffset); + + + writel(ulValue, pvRegAddr); +} + +static unsigned long OMAPLFBVSyncReadReg(OMAPLFB_SWAPCHAIN *psSwapChain, unsigned long ulOffset) +{ + return readl((char *)psSwapChain->pvRegs + ulOffset); +} + +void OMAPLFBEnableVSyncInterrupt(OMAPLFB_SWAPCHAIN *psSwapChain) +{ +#if defined(SYS_USING_INTERRUPTS) + + unsigned long ulInterruptEnable = OMAPLFBVSyncReadReg(psSwapChain, OMAPLCD_IRQENABLE); + ulInterruptEnable |= OMAPLCD_INTMASK_VSYNC; + OMAPLFBVSyncWriteReg(psSwapChain, OMAPLCD_IRQENABLE, ulInterruptEnable ); +#endif +} + +void OMAPLFBDisableVSyncInterrupt(OMAPLFB_SWAPCHAIN *psSwapChain) +{ +#if defined(SYS_USING_INTERRUPTS) + + unsigned long ulInterruptEnable = OMAPLFBVSyncReadReg(psSwapChain, OMAPLCD_IRQENABLE); + ulInterruptEnable &= ~(OMAPLCD_INTMASK_VSYNC); + OMAPLFBVSyncWriteReg(psSwapChain, OMAPLCD_IRQENABLE, ulInterruptEnable); +#endif +} +#endif +#if defined(SYS_USING_INTERRUPTS) +static void +#if defined (SUPPORT_TI_DSS_FW) +OMAPLFBVSyncISR(void *arg, struct pt_regs unref__ *regs) +#else +#if defined (CONFIG_OMAP2_DSS) +OMAPLFBVSyncISR(void *arg) +#else +OMAPLFBVSyncISR(void *arg) +#endif +#endif +{ + OMAPLFB_SWAPCHAIN *psSwapChain= (OMAPLFB_SWAPCHAIN *)arg; + (void) OMAPLFBVSyncIHandler(psSwapChain); +} +#endif +#if !defined (SUPPORT_TI_DSS_FW) +OMAP_ERROR OMAPLFBInstallVSyncISR(OMAPLFB_SWAPCHAIN *psSwapChain) +{ +#if !defined (CONFIG_OMAP2_DSS) + if (omap_dispc_request_irq(DISPC_IRQ_VSYNC, OMAPLFBVSyncISR, psSwapChain) != 0) +#else + int ret; + ret = vps_grpx_register_isr ((vsync_callback_t)OMAPLFBVSyncISR, psSwapChain, 0); // fb_idx = 0 + if ( ret == 0) + pOMAPLFBVSyncISRHandle = 1; + else + pOMAPLFBVSyncISRHandle = 0; + + if (pOMAPLFBVSyncISRHandle == 0) +#endif + return PVRSRV_ERROR_OUT_OF_MEMORY; /* not worth a proper mapping */ + return OMAP_OK; +} + + +OMAP_ERROR OMAPLFBUninstallVSyncISR (OMAPLFB_SWAPCHAIN *psSwapChain) +{ +#if !defined (CONFIG_OMAP2_DSS) + omap_dispc_free_irq(DISPC_IRQ_VSYNC, OMAPLFBVSyncISR, psSwapChain); +#else + int ret; + ret = vps_grpx_unregister_isr((vsync_callback_t) OMAPLFBVSyncISR, (void *)psSwapChain, 0); // fb_idx = 0 + +#endif + return OMAP_OK; +} + + +IMG_VOID OMAPLFBFlip(OMAPLFB_SWAPCHAIN *psSwapChain, + IMG_UINT32 aPhyAddr) +{ +#if !defined (CONFIG_OMAP2_DSS) + omap_dispc_set_plane_base(0, aPhyAddr); +#else + OMAPLFBFlipDSS2 (psSwapChain, aPhyAddr); +#endif +} +#else + +OMAP_ERROR OMAPLFBInstallVSyncISR(OMAPLFB_SWAPCHAIN *psSwapChain) +{ +#if defined(SYS_USING_INTERRUPTS) + OMAPLFBDisableVSyncInterrupt(psSwapChain); + + if (omap2_disp_register_isr(OMAPLFBVSyncISR, psSwapChain, + DISPC_IRQSTATUS_VSYNC)) + { + printk(KERN_INFO DRIVER_PREFIX ": OMAPLFBInstallVSyncISR: Request OMAPLCD IRQ failed\n"); + return (OMAP_ERROR_INIT_FAILURE); + } + +#endif + return (OMAP_OK); +} + + +OMAP_ERROR OMAPLFBUninstallVSyncISR (OMAPLFB_SWAPCHAIN *psSwapChain) +{ +#if defined(SYS_USING_INTERRUPTS) + OMAPLFBDisableVSyncInterrupt(psSwapChain); + + omap2_disp_unregister_isr(OMAPLFBVSyncISR); + +#endif + return (OMAP_OK); +} + +void OMAPLFBEnableDisplayRegisterAccess(void) +{ + omap2_disp_get_dss(); +} + +void OMAPLFBDisableDisplayRegisterAccess(void) +{ + omap2_disp_put_dss(); +} + +void OMAPLFBFlip(OMAPLFB_SWAPCHAIN *psSwapChain, unsigned long aPhyAddr) +{ + unsigned long control; + + + OMAPLFBVSyncWriteReg(psSwapChain, OMAPLCD_GFX_BA0, aPhyAddr); + OMAPLFBVSyncWriteReg(psSwapChain, OMAPLCD_GFX_BA1, aPhyAddr); + + control = OMAPLFBVSyncReadReg(psSwapChain, OMAPLCD_CONTROL); + control |= OMAP_CONTROL_GOLCD; + OMAPLFBVSyncWriteReg(psSwapChain, OMAPLCD_CONTROL, control); +} +#endif + +#if defined(LDM_PLATFORM) + +static OMAP_BOOL bDeviceSuspended; + +static void OMAPLFBCommonSuspend(void) +{ + if (bDeviceSuspended) + { + return; + } + + OMAPLFBDriverSuspend(); + + bDeviceSuspended = OMAP_TRUE; +} + +static int OMAPLFBDriverSuspend_Entry(struct platform_device unref__ *pDevice, pm_message_t unref__ state) +{ + DEBUG_PRINTK((KERN_INFO DRIVER_PREFIX ": OMAPLFBDriverSuspend_Entry\n")); + + OMAPLFBCommonSuspend(); + + return 0; +} + +static int OMAPLFBDriverResume_Entry(struct platform_device unref__ *pDevice) +{ + DEBUG_PRINTK((KERN_INFO DRIVER_PREFIX ": OMAPLFBDriverResume_Entry\n")); + + OMAPLFBDriverResume(); + + bDeviceSuspended = OMAP_FALSE; + + return 0; +} + +static IMG_VOID OMAPLFBDriverShutdown_Entry(struct platform_device unref__ *pDevice) +{ + DEBUG_PRINTK((KERN_INFO DRIVER_PREFIX ": OMAPLFBDriverShutdown_Entry\n")); + + OMAPLFBCommonSuspend(); +} + +static void OMAPLFBDeviceRelease_Entry(struct device unref__ *pDevice) +{ + DEBUG_PRINTK((KERN_INFO DRIVER_PREFIX ": OMAPLFBDriverRelease_Entry\n")); + + OMAPLFBCommonSuspend(); +} + +static struct platform_driver omaplfb_driver = { + .driver = { + .name = DRVNAME, + }, + .suspend = OMAPLFBDriverSuspend_Entry, + .resume = OMAPLFBDriverResume_Entry, + .shutdown = OMAPLFBDriverShutdown_Entry, +}; + +static struct platform_device omaplfb_device = { + .name = DEVNAME, + .id = -1, + .dev = { + .release = OMAPLFBDeviceRelease_Entry + } +}; +#endif + +static int __init OMAPLFB_Init(void) +{ +#if defined(LDM_PLATFORM) + int error; +#endif + + if(OMAPLFBInit() != OMAP_OK) + { + printk(KERN_WARNING DRIVER_PREFIX ": OMAPLFB_Init: OMAPLFBInit failed\n"); + return -ENODEV; + } + +#if defined(LDM_PLATFORM) + if ((error = platform_driver_register(&omaplfb_driver)) != 0) + { + printk(KERN_WARNING DRIVER_PREFIX ": OMAPLFB_Init: Unable to register platform driver (%d)\n", error); + + goto ExitDeinit; + } + + if ((error = platform_device_register(&omaplfb_device)) != 0) + { + printk(KERN_WARNING DRIVER_PREFIX ": OMAPLFB_Init: Unable to register platform device (%d)\n", error); + + goto ExitDriverUnregister; + } +#endif + + return 0; + +#if defined(LDM_PLATFORM) +ExitDriverUnregister: + platform_driver_unregister(&omaplfb_driver); + +ExitDeinit: + if(OMAPLFBDeinit() != OMAP_OK) + { + printk(KERN_WARNING DRIVER_PREFIX ": OMAPLFB_Init: OMAPLFBDeinit failed\n"); + } + + return -ENODEV; +#endif +} + +static IMG_VOID __exit OMAPLFB_Cleanup(IMG_VOID) +{ +#if defined (LDM_PLATFORM) + platform_device_unregister(&omaplfb_device); + platform_driver_unregister(&omaplfb_driver); +#endif + + if(OMAPLFBDeinit() != OMAP_OK) + { + printk(KERN_WARNING DRIVER_PREFIX ": OMAPLFB_Cleanup: OMAPLFBDeinit failed\n"); + } +} + +module_init(OMAPLFB_Init); +module_exit(OMAPLFB_Cleanup); + diff --git a/services4/include/kernelbuffer.h b/services4/include/kernelbuffer.h new file mode 100644 index 0000000..58f4e8c --- /dev/null +++ b/services4/include/kernelbuffer.h @@ -0,0 +1,60 @@ +/********************************************************************** + * + * Copyright(c) 2008 Imagination Technologies Ltd. All rights reserved. + * + * This program is free software; you can redistribute it and/or modify it + * under the terms and conditions of the GNU General Public License, + * version 2, as published by the Free Software Foundation. + * + * This program is distributed in the hope it will be useful but, except + * as otherwise stated in writing, without any warranty; without even the + * implied warranty of merchantability or fitness for a particular purpose. + * See the GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License along with + * this program; if not, write to the Free Software Foundation, Inc., + * 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA. + * + * The full GNU General Public License is included in this distribution in + * the file called "COPYING". + * + * Contact Information: + * Imagination Technologies Ltd. + * Home Park Estate, Kings Langley, Herts, WD4 8LZ, UK + * + ******************************************************************************/ + +#if !defined (__KERNELBUFFER_H__) +#define __KERNELBUFFER_H__ + +typedef PVRSRV_ERROR (*PFN_OPEN_BC_DEVICE)(IMG_HANDLE*); +typedef PVRSRV_ERROR (*PFN_CLOSE_BC_DEVICE)(IMG_HANDLE); +typedef PVRSRV_ERROR (*PFN_GET_BC_INFO)(IMG_HANDLE, BUFFER_INFO*); +typedef PVRSRV_ERROR (*PFN_GET_BC_BUFFER)(IMG_HANDLE, IMG_UINT32, PVRSRV_SYNC_DATA*, IMG_HANDLE*); + +typedef struct PVRSRV_BC_SRV2BUFFER_KMJTABLE_TAG +{ + IMG_UINT32 ui32TableSize; + PFN_OPEN_BC_DEVICE pfnOpenBCDevice; + PFN_CLOSE_BC_DEVICE pfnCloseBCDevice; + PFN_GET_BC_INFO pfnGetBCInfo; + PFN_GET_BC_BUFFER pfnGetBCBuffer; + PFN_GET_BUFFER_ADDR pfnGetBufferAddr; + +} PVRSRV_BC_SRV2BUFFER_KMJTABLE; + + +typedef PVRSRV_ERROR (*PFN_BC_REGISTER_BUFFER_DEV)(PVRSRV_BC_SRV2BUFFER_KMJTABLE*, IMG_UINT32*); +typedef PVRSRV_ERROR (*PFN_BC_REMOVE_BUFFER_DEV)(IMG_UINT32); + +typedef struct PVRSRV_BC_BUFFER2SRV_KMJTABLE_TAG +{ + IMG_UINT32 ui32TableSize; + PFN_BC_REGISTER_BUFFER_DEV pfnPVRSRVRegisterBCDevice; + PFN_BC_REMOVE_BUFFER_DEV pfnPVRSRVRemoveBCDevice; + +} PVRSRV_BC_BUFFER2SRV_KMJTABLE, *PPVRSRV_BC_BUFFER2SRV_KMJTABLE; + +typedef IMG_BOOL (*PFN_BC_GET_PVRJTABLE) (PPVRSRV_BC_BUFFER2SRV_KMJTABLE); + +#endif diff --git a/services4/include/kerneldisplay.h b/services4/include/kerneldisplay.h new file mode 100644 index 0000000..266814d --- /dev/null +++ b/services4/include/kerneldisplay.h @@ -0,0 +1,155 @@ +/********************************************************************** + * + * Copyright(c) 2008 Imagination Technologies Ltd. All rights reserved. + * + * This program is free software; you can redistribute it and/or modify it + * under the terms and conditions of the GNU General Public License, + * version 2, as published by the Free Software Foundation. + * + * This program is distributed in the hope it will be useful but, except + * as otherwise stated in writing, without any warranty; without even the + * implied warranty of merchantability or fitness for a particular purpose. + * See the GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License along with + * this program; if not, write to the Free Software Foundation, Inc., + * 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA. + * + * The full GNU General Public License is included in this distribution in + * the file called "COPYING". + * + * Contact Information: + * Imagination Technologies Ltd. + * Home Park Estate, Kings Langley, Herts, WD4 8LZ, UK + * + ******************************************************************************/ + +#if !defined (__KERNELDISPLAY_H__) +#define __KERNELDISPLAY_H__ + +typedef PVRSRV_ERROR (*PFN_OPEN_DC_DEVICE)(IMG_UINT32, IMG_HANDLE*, PVRSRV_SYNC_DATA*); +typedef PVRSRV_ERROR (*PFN_CLOSE_DC_DEVICE)(IMG_HANDLE); +typedef PVRSRV_ERROR (*PFN_ENUM_DC_FORMATS)(IMG_HANDLE, IMG_UINT32*, DISPLAY_FORMAT*); +typedef PVRSRV_ERROR (*PFN_ENUM_DC_DIMS)(IMG_HANDLE, + DISPLAY_FORMAT*, + IMG_UINT32*, + DISPLAY_DIMS*); +typedef PVRSRV_ERROR (*PFN_GET_DC_SYSTEMBUFFER)(IMG_HANDLE, IMG_HANDLE*); +typedef PVRSRV_ERROR (*PFN_GET_DC_INFO)(IMG_HANDLE, DISPLAY_INFO*); +typedef PVRSRV_ERROR (*PFN_CREATE_DC_SWAPCHAIN)(IMG_HANDLE, + IMG_UINT32, + DISPLAY_SURF_ATTRIBUTES*, + DISPLAY_SURF_ATTRIBUTES*, + IMG_UINT32, + PVRSRV_SYNC_DATA**, + IMG_UINT32, + IMG_HANDLE*, + IMG_UINT32*); +typedef PVRSRV_ERROR (*PFN_DESTROY_DC_SWAPCHAIN)(IMG_HANDLE, + IMG_HANDLE); +typedef PVRSRV_ERROR (*PFN_SET_DC_DSTRECT)(IMG_HANDLE, IMG_HANDLE, IMG_RECT*); +typedef PVRSRV_ERROR (*PFN_SET_DC_SRCRECT)(IMG_HANDLE, IMG_HANDLE, IMG_RECT*); +typedef PVRSRV_ERROR (*PFN_SET_DC_DSTCK)(IMG_HANDLE, IMG_HANDLE, IMG_UINT32); +typedef PVRSRV_ERROR (*PFN_SET_DC_SRCCK)(IMG_HANDLE, IMG_HANDLE, IMG_UINT32); +typedef PVRSRV_ERROR (*PFN_GET_DC_BUFFERS)(IMG_HANDLE, + IMG_HANDLE, + IMG_UINT32*, + IMG_HANDLE*); +typedef PVRSRV_ERROR (*PFN_SWAP_TO_DC_BUFFER)(IMG_HANDLE, + IMG_HANDLE, + IMG_UINT32, + IMG_HANDLE, + IMG_UINT32, + IMG_RECT*); +typedef PVRSRV_ERROR (*PFN_SWAP_TO_DC_SYSTEM)(IMG_HANDLE, IMG_HANDLE); +typedef IMG_VOID (*PFN_SET_DC_STATE)(IMG_HANDLE, IMG_UINT32); + +typedef struct PVRSRV_DC_SRV2DISP_KMJTABLE_TAG +{ + IMG_UINT32 ui32TableSize; + PFN_OPEN_DC_DEVICE pfnOpenDCDevice; + PFN_CLOSE_DC_DEVICE pfnCloseDCDevice; + PFN_ENUM_DC_FORMATS pfnEnumDCFormats; + PFN_ENUM_DC_DIMS pfnEnumDCDims; + PFN_GET_DC_SYSTEMBUFFER pfnGetDCSystemBuffer; + PFN_GET_DC_INFO pfnGetDCInfo; + PFN_GET_BUFFER_ADDR pfnGetBufferAddr; + PFN_CREATE_DC_SWAPCHAIN pfnCreateDCSwapChain; + PFN_DESTROY_DC_SWAPCHAIN pfnDestroyDCSwapChain; + PFN_SET_DC_DSTRECT pfnSetDCDstRect; + PFN_SET_DC_SRCRECT pfnSetDCSrcRect; + PFN_SET_DC_DSTCK pfnSetDCDstColourKey; + PFN_SET_DC_SRCCK pfnSetDCSrcColourKey; + PFN_GET_DC_BUFFERS pfnGetDCBuffers; + PFN_SWAP_TO_DC_BUFFER pfnSwapToDCBuffer; + PFN_SWAP_TO_DC_SYSTEM pfnSwapToDCSystem; + PFN_SET_DC_STATE pfnSetDCState; + +} PVRSRV_DC_SRV2DISP_KMJTABLE; + +typedef IMG_BOOL (*PFN_ISR_HANDLER)(IMG_VOID*); + +typedef PVRSRV_ERROR (*PFN_DC_REGISTER_DISPLAY_DEV)(PVRSRV_DC_SRV2DISP_KMJTABLE*, IMG_UINT32*); +typedef PVRSRV_ERROR (*PFN_DC_REMOVE_DISPLAY_DEV)(IMG_UINT32); +typedef PVRSRV_ERROR (*PFN_DC_OEM_FUNCTION)(IMG_UINT32, IMG_VOID*, IMG_UINT32, IMG_VOID*, IMG_UINT32); +typedef PVRSRV_ERROR (*PFN_DC_REGISTER_COMMANDPROCLIST)(IMG_UINT32, PPFN_CMD_PROC,IMG_UINT32[][2], IMG_UINT32); +typedef PVRSRV_ERROR (*PFN_DC_REMOVE_COMMANDPROCLIST)(IMG_UINT32, IMG_UINT32); +typedef IMG_VOID (*PFN_DC_CMD_COMPLETE)(IMG_HANDLE, IMG_BOOL); +typedef PVRSRV_ERROR (*PFN_DC_REGISTER_SYS_ISR)(PFN_ISR_HANDLER, IMG_VOID*, IMG_UINT32, IMG_UINT32); +typedef PVRSRV_ERROR (*PFN_DC_REGISTER_POWER)(IMG_UINT32, PFN_PRE_POWER, PFN_POST_POWER, + PFN_PRE_CLOCKSPEED_CHANGE, PFN_POST_CLOCKSPEED_CHANGE, + IMG_HANDLE, PVR_POWER_STATE, PVR_POWER_STATE); + +typedef struct PVRSRV_DC_DISP2SRV_KMJTABLE_TAG +{ + IMG_UINT32 ui32TableSize; + PFN_DC_REGISTER_DISPLAY_DEV pfnPVRSRVRegisterDCDevice; + PFN_DC_REMOVE_DISPLAY_DEV pfnPVRSRVRemoveDCDevice; + PFN_DC_OEM_FUNCTION pfnPVRSRVOEMFunction; + PFN_DC_REGISTER_COMMANDPROCLIST pfnPVRSRVRegisterCmdProcList; + PFN_DC_REMOVE_COMMANDPROCLIST pfnPVRSRVRemoveCmdProcList; + PFN_DC_CMD_COMPLETE pfnPVRSRVCmdComplete; + PFN_DC_REGISTER_SYS_ISR pfnPVRSRVRegisterSystemISRHandler; + PFN_DC_REGISTER_POWER pfnPVRSRVRegisterPowerDevice; +} PVRSRV_DC_DISP2SRV_KMJTABLE, *PPVRSRV_DC_DISP2SRV_KMJTABLE; + + +typedef struct DISPLAYCLASS_FLIP_COMMAND_TAG +{ + + IMG_HANDLE hExtDevice; + + + IMG_HANDLE hExtSwapChain; + + + IMG_HANDLE hExtBuffer; + + + IMG_HANDLE hPrivateTag; + + + IMG_UINT32 ui32ClipRectCount; + + + IMG_RECT *psClipRect; + + + IMG_UINT32 ui32SwapInterval; + +} DISPLAYCLASS_FLIP_COMMAND; + +#define DC_FLIP_COMMAND 0 + +#define DC_STATE_NO_FLUSH_COMMANDS 0 +#define DC_STATE_FLUSH_COMMANDS 1 +#define DC_STATE_SUSPEND_COMMANDS 2 +#define DC_STATE_RESUME_COMMANDS 3 + + +typedef IMG_BOOL (*PFN_DC_GET_PVRJTABLE)(PPVRSRV_DC_DISP2SRV_KMJTABLE); + + + +#endif + diff --git a/services4/include/pvr_bridge.h b/services4/include/pvr_bridge.h new file mode 100644 index 0000000..1ef24dc --- /dev/null +++ b/services4/include/pvr_bridge.h @@ -0,0 +1,1374 @@ +/********************************************************************** + * + * Copyright(c) 2008 Imagination Technologies Ltd. All rights reserved. + * + * This program is free software; you can redistribute it and/or modify it + * under the terms and conditions of the GNU General Public License, + * version 2, as published by the Free Software Foundation. + * + * This program is distributed in the hope it will be useful but, except + * as otherwise stated in writing, without any warranty; without even the + * implied warranty of merchantability or fitness for a particular purpose. + * See the GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License along with + * this program; if not, write to the Free Software Foundation, Inc., + * 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA. + * + * The full GNU General Public License is included in this distribution in + * the file called "COPYING". + * + * Contact Information: + * Imagination Technologies Ltd. + * Home Park Estate, Kings Langley, Herts, WD4 8LZ, UK + * + ******************************************************************************/ + +#ifndef __PVR_BRIDGE_H__ +#define __PVR_BRIDGE_H__ + +#if defined (__cplusplus) +extern "C" { +#endif + +#include "servicesint.h" + +#ifdef __linux__ + + #include + + #define PVRSRV_IOC_GID 'g' + #define PVRSRV_IO(INDEX) _IO(PVRSRV_IOC_GID, INDEX, PVRSRV_BRIDGE_PACKAGE) + #define PVRSRV_IOW(INDEX) _IOW(PVRSRV_IOC_GID, INDEX, PVRSRV_BRIDGE_PACKAGE) + #define PVRSRV_IOR(INDEX) _IOR(PVRSRV_IOC_GID, INDEX, PVRSRV_BRIDGE_PACKAGE) + #define PVRSRV_IOWR(INDEX) _IOWR(PVRSRV_IOC_GID, INDEX, PVRSRV_BRIDGE_PACKAGE) + +#else + + #error Unknown platform: Cannot define ioctls + + #define PVRSRV_IO(INDEX) (PVRSRV_IOC_GID + INDEX) + #define PVRSRV_IOW(INDEX) (PVRSRV_IOC_GID + INDEX) + #define PVRSRV_IOR(INDEX) (PVRSRV_IOC_GID + INDEX) + #define PVRSRV_IOWR(INDEX) (PVRSRV_IOC_GID + INDEX) + + #define PVRSRV_BRIDGE_BASE PVRSRV_IOC_GID +#endif + + +#define PVRSRV_BRIDGE_CORE_CMD_FIRST 0 +#define PVRSRV_BRIDGE_ENUM_DEVICES PVRSRV_IOWR(PVRSRV_BRIDGE_CORE_CMD_FIRST+0) +#define PVRSRV_BRIDGE_ACQUIRE_DEVICEINFO PVRSRV_IOWR(PVRSRV_BRIDGE_CORE_CMD_FIRST+1) +#define PVRSRV_BRIDGE_RELEASE_DEVICEINFO PVRSRV_IOWR(PVRSRV_BRIDGE_CORE_CMD_FIRST+2) +#define PVRSRV_BRIDGE_CREATE_DEVMEMCONTEXT PVRSRV_IOWR(PVRSRV_BRIDGE_CORE_CMD_FIRST+3) +#define PVRSRV_BRIDGE_DESTROY_DEVMEMCONTEXT PVRSRV_IOWR(PVRSRV_BRIDGE_CORE_CMD_FIRST+4) +#define PVRSRV_BRIDGE_GET_DEVMEM_HEAPINFO PVRSRV_IOWR(PVRSRV_BRIDGE_CORE_CMD_FIRST+5) +#define PVRSRV_BRIDGE_ALLOC_DEVICEMEM PVRSRV_IOWR(PVRSRV_BRIDGE_CORE_CMD_FIRST+6) +#define PVRSRV_BRIDGE_FREE_DEVICEMEM PVRSRV_IOWR(PVRSRV_BRIDGE_CORE_CMD_FIRST+7) +#define PVRSRV_BRIDGE_GETFREE_DEVICEMEM PVRSRV_IOWR(PVRSRV_BRIDGE_CORE_CMD_FIRST+8) +#define PVRSRV_BRIDGE_CREATE_COMMANDQUEUE PVRSRV_IOWR(PVRSRV_BRIDGE_CORE_CMD_FIRST+9) +#define PVRSRV_BRIDGE_DESTROY_COMMANDQUEUE PVRSRV_IOWR(PVRSRV_BRIDGE_CORE_CMD_FIRST+10) +#define PVRSRV_BRIDGE_MHANDLE_TO_MMAP_DATA PVRSRV_IOWR(PVRSRV_BRIDGE_CORE_CMD_FIRST+11) +#define PVRSRV_BRIDGE_CONNECT_SERVICES PVRSRV_IOWR(PVRSRV_BRIDGE_CORE_CMD_FIRST+12) +#define PVRSRV_BRIDGE_DISCONNECT_SERVICES PVRSRV_IOWR(PVRSRV_BRIDGE_CORE_CMD_FIRST+13) +#define PVRSRV_BRIDGE_WRAP_DEVICE_MEM PVRSRV_IOWR(PVRSRV_BRIDGE_CORE_CMD_FIRST+14) +#define PVRSRV_BRIDGE_GET_DEVICEMEMINFO PVRSRV_IOWR(PVRSRV_BRIDGE_CORE_CMD_FIRST+15) +#define PVRSRV_BRIDGE_RESERVE_DEV_VIRTMEM PVRSRV_IOWR(PVRSRV_BRIDGE_CORE_CMD_FIRST+16) +#define PVRSRV_BRIDGE_FREE_DEV_VIRTMEM PVRSRV_IOWR(PVRSRV_BRIDGE_CORE_CMD_FIRST+17) +#define PVRSRV_BRIDGE_MAP_EXT_MEMORY PVRSRV_IOWR(PVRSRV_BRIDGE_CORE_CMD_FIRST+18) +#define PVRSRV_BRIDGE_UNMAP_EXT_MEMORY PVRSRV_IOWR(PVRSRV_BRIDGE_CORE_CMD_FIRST+19) +#define PVRSRV_BRIDGE_MAP_DEV_MEMORY PVRSRV_IOWR(PVRSRV_BRIDGE_CORE_CMD_FIRST+20) +#define PVRSRV_BRIDGE_UNMAP_DEV_MEMORY PVRSRV_IOWR(PVRSRV_BRIDGE_CORE_CMD_FIRST+21) +#define PVRSRV_BRIDGE_MAP_DEVICECLASS_MEMORY PVRSRV_IOWR(PVRSRV_BRIDGE_CORE_CMD_FIRST+22) +#define PVRSRV_BRIDGE_UNMAP_DEVICECLASS_MEMORY PVRSRV_IOWR(PVRSRV_BRIDGE_CORE_CMD_FIRST+23) +#define PVRSRV_BRIDGE_MAP_MEM_INFO_TO_USER PVRSRV_IOWR(PVRSRV_BRIDGE_CORE_CMD_FIRST+24) +#define PVRSRV_BRIDGE_UNMAP_MEM_INFO_FROM_USER PVRSRV_IOWR(PVRSRV_BRIDGE_CORE_CMD_FIRST+25) +#define PVRSRV_BRIDGE_EXPORT_DEVICEMEM PVRSRV_IOWR(PVRSRV_BRIDGE_CORE_CMD_FIRST+26) +#define PVRSRV_BRIDGE_RELEASE_MMAP_DATA PVRSRV_IOWR(PVRSRV_BRIDGE_CORE_CMD_FIRST+27) +#define PVRSRV_BRIDGE_CORE_CMD_LAST (PVRSRV_BRIDGE_CORE_CMD_FIRST+27) + +#define PVRSRV_BRIDGE_SIM_CMD_FIRST (PVRSRV_BRIDGE_CORE_CMD_LAST+1) +#define PVRSRV_BRIDGE_PROCESS_SIMISR_EVENT PVRSRV_IOWR(PVRSRV_BRIDGE_SIM_CMD_FIRST+0) +#define PVRSRV_BRIDGE_REGISTER_SIM_PROCESS PVRSRV_IOWR(PVRSRV_BRIDGE_SIM_CMD_FIRST+1) +#define PVRSRV_BRIDGE_UNREGISTER_SIM_PROCESS PVRSRV_IOWR(PVRSRV_BRIDGE_SIM_CMD_FIRST+2) +#define PVRSRV_BRIDGE_SIM_CMD_LAST (PVRSRV_BRIDGE_SIM_CMD_FIRST+2) + +#define PVRSRV_BRIDGE_MAPPING_CMD_FIRST (PVRSRV_BRIDGE_SIM_CMD_LAST+1) +#define PVRSRV_BRIDGE_MAPPHYSTOUSERSPACE PVRSRV_IOWR(PVRSRV_BRIDGE_MAPPING_CMD_FIRST+0) +#define PVRSRV_BRIDGE_UNMAPPHYSTOUSERSPACE PVRSRV_IOWR(PVRSRV_BRIDGE_MAPPING_CMD_FIRST+1) +#define PVRSRV_BRIDGE_GETPHYSTOUSERSPACEMAP PVRSRV_IOWR(PVRSRV_BRIDGE_MAPPING_CMD_FIRST+2) +#define PVRSRV_BRIDGE_MAPPING_CMD_LAST (PVRSRV_BRIDGE_MAPPING_CMD_FIRST+2) + +#define PVRSRV_BRIDGE_STATS_CMD_FIRST (PVRSRV_BRIDGE_MAPPING_CMD_LAST+1) +#define PVRSRV_BRIDGE_GET_FB_STATS PVRSRV_IOWR(PVRSRV_BRIDGE_STATS_CMD_FIRST+0) +#define PVRSRV_BRIDGE_STATS_CMD_LAST (PVRSRV_BRIDGE_STATS_CMD_FIRST+0) + +#define PVRSRV_BRIDGE_MISC_CMD_FIRST (PVRSRV_BRIDGE_STATS_CMD_LAST+1) +#define PVRSRV_BRIDGE_GET_MISC_INFO PVRSRV_IOWR(PVRSRV_BRIDGE_MISC_CMD_FIRST+0) +#define PVRSRV_BRIDGE_RELEASE_MISC_INFO PVRSRV_IOWR(PVRSRV_BRIDGE_MISC_CMD_FIRST+1) +#define PVRSRV_BRIDGE_MISC_CMD_LAST (PVRSRV_BRIDGE_MISC_CMD_FIRST+1) + +#define PVRSRV_BRIDGE_OVERLAY_CMD_FIRST (PVRSRV_BRIDGE_MISC_CMD_LAST+1) +#if defined (SUPPORT_OVERLAY_ROTATE_BLIT) +#define PVRSRV_BRIDGE_INIT_3D_OVL_BLT_RES PVRSRV_IOWR(PVRSRV_BRIDGE_OVERLAY_CMD_FIRST+0) +#define PVRSRV_BRIDGE_DEINIT_3D_OVL_BLT_RES PVRSRV_IOWR(PVRSRV_BRIDGE_OVERLAY_CMD_FIRST+1) +#endif +#define PVRSRV_BRIDGE_OVERLAY_CMD_LAST (PVRSRV_BRIDGE_OVERLAY_CMD_FIRST+1) + +#if defined(PDUMP) +#define PVRSRV_BRIDGE_PDUMP_CMD_FIRST (PVRSRV_BRIDGE_OVERLAY_CMD_FIRST+1) +#define PVRSRV_BRIDGE_PDUMP_INIT PVRSRV_IOWR(PVRSRV_BRIDGE_PDUMP_CMD_FIRST+0) +#define PVRSRV_BRIDGE_PDUMP_MEMPOL PVRSRV_IOWR(PVRSRV_BRIDGE_PDUMP_CMD_FIRST+1) +#define PVRSRV_BRIDGE_PDUMP_DUMPMEM PVRSRV_IOWR(PVRSRV_BRIDGE_PDUMP_CMD_FIRST+2) +#define PVRSRV_BRIDGE_PDUMP_REG PVRSRV_IOWR(PVRSRV_BRIDGE_PDUMP_CMD_FIRST+3) +#define PVRSRV_BRIDGE_PDUMP_REGPOL PVRSRV_IOWR(PVRSRV_BRIDGE_PDUMP_CMD_FIRST+4) +#define PVRSRV_BRIDGE_PDUMP_COMMENT PVRSRV_IOWR(PVRSRV_BRIDGE_PDUMP_CMD_FIRST+5) +#define PVRSRV_BRIDGE_PDUMP_SETFRAME PVRSRV_IOWR(PVRSRV_BRIDGE_PDUMP_CMD_FIRST+6) +#define PVRSRV_BRIDGE_PDUMP_ISCAPTURING PVRSRV_IOWR(PVRSRV_BRIDGE_PDUMP_CMD_FIRST+7) +#define PVRSRV_BRIDGE_PDUMP_DUMPBITMAP PVRSRV_IOWR(PVRSRV_BRIDGE_PDUMP_CMD_FIRST+8) +#define PVRSRV_BRIDGE_PDUMP_DUMPREADREG PVRSRV_IOWR(PVRSRV_BRIDGE_PDUMP_CMD_FIRST+9) +#define PVRSRV_BRIDGE_PDUMP_SYNCPOL PVRSRV_IOWR(PVRSRV_BRIDGE_PDUMP_CMD_FIRST+10) +#define PVRSRV_BRIDGE_PDUMP_DUMPSYNC PVRSRV_IOWR(PVRSRV_BRIDGE_PDUMP_CMD_FIRST+11) +#define PVRSRV_BRIDGE_PDUMP_MEMPAGES PVRSRV_IOWR(PVRSRV_BRIDGE_PDUMP_CMD_FIRST+12) +#define PVRSRV_BRIDGE_PDUMP_DRIVERINFO PVRSRV_IOWR(PVRSRV_BRIDGE_PDUMP_CMD_FIRST+13) +#define PVRSRV_BRIDGE_PDUMP_PDREG PVRSRV_IOWR(PVRSRV_BRIDGE_PDUMP_CMD_FIRST+14) +#define PVRSRV_BRIDGE_PDUMP_DUMPPDDEVPADDR PVRSRV_IOWR(PVRSRV_BRIDGE_PDUMP_CMD_FIRST+15) +#define PVRSRV_BRIDGE_PDUMP_CYCLE_COUNT_REG_READ PVRSRV_IOWR(PVRSRV_BRIDGE_PDUMP_CMD_FIRST+16) +#define PVRSRV_BRIDGE_PDUMP_STARTINITPHASE PVRSRV_IOWR(PVRSRV_BRIDGE_PDUMP_CMD_FIRST+17) +#define PVRSRV_BRIDGE_PDUMP_STOPINITPHASE PVRSRV_IOWR(PVRSRV_BRIDGE_PDUMP_CMD_FIRST+18) +#define PVRSRV_BRIDGE_PDUMP_CMD_LAST (PVRSRV_BRIDGE_PDUMP_CMD_FIRST+18) +#else +#define PVRSRV_BRIDGE_PDUMP_CMD_LAST PVRSRV_BRIDGE_OVERLAY_CMD_LAST +#endif + +#define PVRSRV_BRIDGE_OEM_CMD_FIRST (PVRSRV_BRIDGE_PDUMP_CMD_LAST+1) +#define PVRSRV_BRIDGE_GET_OEMJTABLE PVRSRV_IOWR(PVRSRV_BRIDGE_OEM_CMD_FIRST+0) +#define PVRSRV_BRIDGE_OEM_CMD_LAST (PVRSRV_BRIDGE_OEM_CMD_FIRST+0) + +#define PVRSRV_BRIDGE_DEVCLASS_CMD_FIRST (PVRSRV_BRIDGE_OEM_CMD_LAST+1) +#define PVRSRV_BRIDGE_ENUM_CLASS PVRSRV_IOWR(PVRSRV_BRIDGE_DEVCLASS_CMD_FIRST+0) +#define PVRSRV_BRIDGE_DEVCLASS_CMD_LAST (PVRSRV_BRIDGE_DEVCLASS_CMD_FIRST+0) + +#define PVRSRV_BRIDGE_DISPCLASS_CMD_FIRST (PVRSRV_BRIDGE_DEVCLASS_CMD_LAST+1) +#define PVRSRV_BRIDGE_OPEN_DISPCLASS_DEVICE PVRSRV_IOWR(PVRSRV_BRIDGE_DISPCLASS_CMD_FIRST+0) +#define PVRSRV_BRIDGE_CLOSE_DISPCLASS_DEVICE PVRSRV_IOWR(PVRSRV_BRIDGE_DISPCLASS_CMD_FIRST+1) +#define PVRSRV_BRIDGE_ENUM_DISPCLASS_FORMATS PVRSRV_IOWR(PVRSRV_BRIDGE_DISPCLASS_CMD_FIRST+2) +#define PVRSRV_BRIDGE_ENUM_DISPCLASS_DIMS PVRSRV_IOWR(PVRSRV_BRIDGE_DISPCLASS_CMD_FIRST+3) +#define PVRSRV_BRIDGE_GET_DISPCLASS_SYSBUFFER PVRSRV_IOWR(PVRSRV_BRIDGE_DISPCLASS_CMD_FIRST+4) +#define PVRSRV_BRIDGE_GET_DISPCLASS_INFO PVRSRV_IOWR(PVRSRV_BRIDGE_DISPCLASS_CMD_FIRST+5) +#define PVRSRV_BRIDGE_CREATE_DISPCLASS_SWAPCHAIN PVRSRV_IOWR(PVRSRV_BRIDGE_DISPCLASS_CMD_FIRST+6) +#define PVRSRV_BRIDGE_DESTROY_DISPCLASS_SWAPCHAIN PVRSRV_IOWR(PVRSRV_BRIDGE_DISPCLASS_CMD_FIRST+7) +#define PVRSRV_BRIDGE_SET_DISPCLASS_DSTRECT PVRSRV_IOWR(PVRSRV_BRIDGE_DISPCLASS_CMD_FIRST+8) +#define PVRSRV_BRIDGE_SET_DISPCLASS_SRCRECT PVRSRV_IOWR(PVRSRV_BRIDGE_DISPCLASS_CMD_FIRST+9) +#define PVRSRV_BRIDGE_SET_DISPCLASS_DSTCOLOURKEY PVRSRV_IOWR(PVRSRV_BRIDGE_DISPCLASS_CMD_FIRST+10) +#define PVRSRV_BRIDGE_SET_DISPCLASS_SRCCOLOURKEY PVRSRV_IOWR(PVRSRV_BRIDGE_DISPCLASS_CMD_FIRST+11) +#define PVRSRV_BRIDGE_GET_DISPCLASS_BUFFERS PVRSRV_IOWR(PVRSRV_BRIDGE_DISPCLASS_CMD_FIRST+12) +#define PVRSRV_BRIDGE_SWAP_DISPCLASS_TO_BUFFER PVRSRV_IOWR(PVRSRV_BRIDGE_DISPCLASS_CMD_FIRST+13) +#define PVRSRV_BRIDGE_SWAP_DISPCLASS_TO_SYSTEM PVRSRV_IOWR(PVRSRV_BRIDGE_DISPCLASS_CMD_FIRST+14) +#define PVRSRV_BRIDGE_DISPCLASS_CMD_LAST (PVRSRV_BRIDGE_DISPCLASS_CMD_FIRST+14) + + +#define PVRSRV_BRIDGE_BUFCLASS_CMD_FIRST (PVRSRV_BRIDGE_DISPCLASS_CMD_LAST+1) +#define PVRSRV_BRIDGE_OPEN_BUFFERCLASS_DEVICE PVRSRV_IOWR(PVRSRV_BRIDGE_BUFCLASS_CMD_FIRST+0) +#define PVRSRV_BRIDGE_CLOSE_BUFFERCLASS_DEVICE PVRSRV_IOWR(PVRSRV_BRIDGE_BUFCLASS_CMD_FIRST+1) +#define PVRSRV_BRIDGE_GET_BUFFERCLASS_INFO PVRSRV_IOWR(PVRSRV_BRIDGE_BUFCLASS_CMD_FIRST+2) +#define PVRSRV_BRIDGE_GET_BUFFERCLASS_BUFFER PVRSRV_IOWR(PVRSRV_BRIDGE_BUFCLASS_CMD_FIRST+3) +#define PVRSRV_BRIDGE_BUFCLASS_CMD_LAST (PVRSRV_BRIDGE_BUFCLASS_CMD_FIRST+3) + +#define PVRSRV_BRIDGE_WRAP_CMD_FIRST (PVRSRV_BRIDGE_BUFCLASS_CMD_LAST+1) +#define PVRSRV_BRIDGE_WRAP_EXT_MEMORY PVRSRV_IOWR(PVRSRV_BRIDGE_WRAP_CMD_FIRST+0) +#define PVRSRV_BRIDGE_UNWRAP_EXT_MEMORY PVRSRV_IOWR(PVRSRV_BRIDGE_WRAP_CMD_FIRST+1) +#define PVRSRV_BRIDGE_WRAP_CMD_LAST (PVRSRV_BRIDGE_WRAP_CMD_FIRST+1) + +#define PVRSRV_BRIDGE_SHAREDMEM_CMD_FIRST (PVRSRV_BRIDGE_WRAP_CMD_LAST+1) +#define PVRSRV_BRIDGE_ALLOC_SHARED_SYS_MEM PVRSRV_IOWR(PVRSRV_BRIDGE_SHAREDMEM_CMD_FIRST+0) +#define PVRSRV_BRIDGE_FREE_SHARED_SYS_MEM PVRSRV_IOWR(PVRSRV_BRIDGE_SHAREDMEM_CMD_FIRST+1) +#define PVRSRV_BRIDGE_MAP_MEMINFO_MEM PVRSRV_IOWR(PVRSRV_BRIDGE_SHAREDMEM_CMD_FIRST+2) +#define PVRSRV_BRIDGE_UNMAP_MEMINFO_MEM PVRSRV_IOWR(PVRSRV_BRIDGE_SHAREDMEM_CMD_FIRST+3) +#define PVRSRV_BRIDGE_SHAREDMEM_CMD_LAST (PVRSRV_BRIDGE_SHAREDMEM_CMD_FIRST+3) + +#define PVRSRV_BRIDGE_SERVICES4_TMP_CMD_FIRST (PVRSRV_BRIDGE_SHAREDMEM_CMD_LAST+1) +#define PVRSRV_BRIDGE_GETMMU_PD_DEVPADDR PVRSRV_IOWR(PVRSRV_BRIDGE_SERVICES4_TMP_CMD_FIRST+0) +#define PVRSRV_BRIDGE_SERVICES4_TMP_CMD_LAST (PVRSRV_BRIDGE_SERVICES4_TMP_CMD_FIRST+0) + +#define PVRSRV_BRIDGE_INITSRV_CMD_FIRST (PVRSRV_BRIDGE_SERVICES4_TMP_CMD_LAST+1) +#define PVRSRV_BRIDGE_INITSRV_CONNECT PVRSRV_IOWR(PVRSRV_BRIDGE_INITSRV_CMD_FIRST+0) +#define PVRSRV_BRIDGE_INITSRV_DISCONNECT PVRSRV_IOWR(PVRSRV_BRIDGE_INITSRV_CMD_FIRST+1) +#define PVRSRV_BRIDGE_INITSRV_CMD_LAST (PVRSRV_BRIDGE_INITSRV_CMD_FIRST+1) + +#define PVRSRV_BRIDGE_EVENT_OBJECT_CMD_FIRST (PVRSRV_BRIDGE_INITSRV_CMD_LAST+1) +#define PVRSRV_BRIDGE_EVENT_OBJECT_WAIT PVRSRV_IOWR(PVRSRV_BRIDGE_EVENT_OBJECT_CMD_FIRST+0) +#define PVRSRV_BRIDGE_EVENT_OBJECT_OPEN PVRSRV_IOWR(PVRSRV_BRIDGE_EVENT_OBJECT_CMD_FIRST+1) +#define PVRSRV_BRIDGE_EVENT_OBJECT_CLOSE PVRSRV_IOWR(PVRSRV_BRIDGE_EVENT_OBJECT_CMD_FIRST+2) +#define PVRSRV_BRIDGE_EVENT_OBJECT_CMD_LAST (PVRSRV_BRIDGE_EVENT_OBJECT_CMD_FIRST+2) + +#define PVRSRV_BRIDGE_SYNC_OPS_CMD_FIRST (PVRSRV_BRIDGE_EVENT_OBJECT_CMD_LAST+1) +#define PVRSRV_BRIDGE_MODIFY_SYNC_OPS PVRSRV_IOWR(PVRSRV_BRIDGE_SYNC_OPS_CMD_FIRST+0) +#define PVRSRV_BRIDGE_SYNC_OPS_CMD_LAST (PVRSRV_BRIDGE_SYNC_OPS_CMD_FIRST+0) + +#define PVRSRV_BRIDGE_LAST_NON_DEVICE_CMD (PVRSRV_BRIDGE_SYNC_OPS_CMD_LAST+1) + + +#define PVRSRV_KERNEL_MODE_CLIENT 1 + +typedef struct PVRSRV_BRIDGE_RETURN_TAG +{ + PVRSRV_ERROR eError; + IMG_VOID *pvData; + +}PVRSRV_BRIDGE_RETURN; + + +typedef struct PVRSRV_BRIDGE_PACKAGE_TAG +{ + IMG_UINT32 ui32BridgeID; + IMG_UINT32 ui32Size; + IMG_VOID *pvParamIn; + IMG_UINT32 ui32InBufferSize; + IMG_VOID *pvParamOut; + IMG_UINT32 ui32OutBufferSize; + + IMG_HANDLE hKernelServices; +}PVRSRV_BRIDGE_PACKAGE; + + + + + +typedef struct PVRSRV_BRIDGE_IN_ACQUIRE_DEVICEINFO_TAG +{ + IMG_UINT32 ui32BridgeFlags; + IMG_UINT32 uiDevIndex; + PVRSRV_DEVICE_TYPE eDeviceType; + +} PVRSRV_BRIDGE_IN_ACQUIRE_DEVICEINFO; + + +typedef struct PVRSRV_BRIDGE_IN_ENUMCLASS_TAG +{ + IMG_UINT32 ui32BridgeFlags; + PVRSRV_DEVICE_CLASS sDeviceClass; +} PVRSRV_BRIDGE_IN_ENUMCLASS; + + +typedef struct PVRSRV_BRIDGE_IN_CLOSE_DISPCLASS_DEVICE_TAG +{ + IMG_UINT32 ui32BridgeFlags; + IMG_HANDLE hDeviceKM; +} PVRSRV_BRIDGE_IN_CLOSE_DISPCLASS_DEVICE; + + +typedef struct PVRSRV_BRIDGE_IN_ENUM_DISPCLASS_FORMATS_TAG +{ + IMG_UINT32 ui32BridgeFlags; + IMG_HANDLE hDeviceKM; +} PVRSRV_BRIDGE_IN_ENUM_DISPCLASS_FORMATS; + + +typedef struct PVRSRV_BRIDGE_IN_GET_DISPCLASS_SYSBUFFER_TAG +{ + IMG_UINT32 ui32BridgeFlags; + IMG_HANDLE hDeviceKM; +} PVRSRV_BRIDGE_IN_GET_DISPCLASS_SYSBUFFER; + + +typedef struct PVRSRV_BRIDGE_IN_GET_DISPCLASS_INFO_TAG +{ + IMG_UINT32 ui32BridgeFlags; + IMG_HANDLE hDeviceKM; +} PVRSRV_BRIDGE_IN_GET_DISPCLASS_INFO; + + +typedef struct PVRSRV_BRIDGE_IN_CLOSE_BUFFERCLASS_DEVICE_TAG +{ + IMG_UINT32 ui32BridgeFlags; + IMG_HANDLE hDeviceKM; +} PVRSRV_BRIDGE_IN_CLOSE_BUFFERCLASS_DEVICE; + + +typedef struct PVRSRV_BRIDGE_IN_GET_BUFFERCLASS_INFO_TAG +{ + IMG_UINT32 ui32BridgeFlags; + IMG_HANDLE hDeviceKM; +} PVRSRV_BRIDGE_IN_GET_BUFFERCLASS_INFO; + + + +typedef struct PVRSRV_BRIDGE_IN_RELEASE_DEVICEINFO_TAG +{ + IMG_UINT32 ui32BridgeFlags; + IMG_HANDLE hDevCookie; + +} PVRSRV_BRIDGE_IN_RELEASE_DEVICEINFO; + + + +typedef struct PVRSRV_BRIDGE_IN_FREE_CLASSDEVICEINFO_TAG +{ + IMG_UINT32 ui32BridgeFlags; + PVRSRV_DEVICE_CLASS DeviceClass; + IMG_VOID* pvDevInfo; + +}PVRSRV_BRIDGE_IN_FREE_CLASSDEVICEINFO; + + + +typedef struct PVRSRV_BRIDGE_IN_GET_DEVMEM_HEAPINFO_TAG +{ + IMG_UINT32 ui32BridgeFlags; + IMG_HANDLE hDevCookie; + IMG_HANDLE hDevMemContext; + +}PVRSRV_BRIDGE_IN_GET_DEVMEM_HEAPINFO; + + + +typedef struct PVRSRV_BRIDGE_IN_CREATE_DEVMEMCONTEXT_TAG +{ + IMG_UINT32 ui32BridgeFlags; + IMG_HANDLE hDevCookie; + +}PVRSRV_BRIDGE_IN_CREATE_DEVMEMCONTEXT; + + + +typedef struct PVRSRV_BRIDGE_IN_DESTROY_DEVMEMCONTEXT_TAG +{ + IMG_UINT32 ui32BridgeFlags; + IMG_HANDLE hDevCookie; + IMG_HANDLE hDevMemContext; + +}PVRSRV_BRIDGE_IN_DESTROY_DEVMEMCONTEXT; + + + +typedef struct PVRSRV_BRIDGE_IN_ALLOCDEVICEMEM_TAG +{ + IMG_UINT32 ui32BridgeFlags; + IMG_HANDLE hDevCookie; + IMG_HANDLE hDevMemHeap; + IMG_UINT32 ui32Attribs; + IMG_UINT32 ui32Size; + IMG_UINT32 ui32Alignment; + +}PVRSRV_BRIDGE_IN_ALLOCDEVICEMEM; + + +typedef struct PVRSRV_BRIDGE_IN_MAPMEMINFOTOUSER_TAG +{ + IMG_UINT32 ui32BridgeFlags; + PVRSRV_KERNEL_MEM_INFO *psKernelMemInfo; + +}PVRSRV_BRIDGE_IN_MAPMEMINFOTOUSER; + + +typedef struct PVRSRV_BRIDGE_IN_UNMAPMEMINFOFROMUSER_TAG +{ + IMG_UINT32 ui32BridgeFlags; + PVRSRV_KERNEL_MEM_INFO *psKernelMemInfo; + IMG_PVOID pvLinAddr; + IMG_HANDLE hMappingInfo; + +}PVRSRV_BRIDGE_IN_UNMAPMEMINFOFROMUSER; + + +typedef struct PVRSRV_BRIDGE_IN_FREEDEVICEMEM_TAG +{ + IMG_UINT32 ui32BridgeFlags; + IMG_HANDLE hDevCookie; + PVRSRV_KERNEL_MEM_INFO *psKernelMemInfo; + PVRSRV_CLIENT_MEM_INFO sClientMemInfo; + +}PVRSRV_BRIDGE_IN_FREEDEVICEMEM; + + +typedef struct PVRSRV_BRIDGE_IN_EXPORTDEVICEMEM_TAG +{ + IMG_UINT32 ui32BridgeFlags; + IMG_HANDLE hDevCookie; + PVRSRV_KERNEL_MEM_INFO *psKernelMemInfo; + +}PVRSRV_BRIDGE_IN_EXPORTDEVICEMEM; + + +typedef struct PVRSRV_BRIDGE_IN_GETFREEDEVICEMEM_TAG +{ + IMG_UINT32 ui32BridgeFlags; + IMG_UINT32 ui32Flags; + +} PVRSRV_BRIDGE_IN_GETFREEDEVICEMEM; + + +typedef struct PVRSRV_BRIDGE_IN_CREATECOMMANDQUEUE_TAG +{ + IMG_UINT32 ui32BridgeFlags; + IMG_HANDLE hDevCookie; + IMG_UINT32 ui32QueueSize; + +}PVRSRV_BRIDGE_IN_CREATECOMMANDQUEUE; + + + +typedef struct PVRSRV_BRIDGE_IN_DESTROYCOMMANDQUEUE_TAG +{ + IMG_UINT32 ui32BridgeFlags; + IMG_HANDLE hDevCookie; + PVRSRV_QUEUE_INFO *psQueueInfo; + +}PVRSRV_BRIDGE_IN_DESTROYCOMMANDQUEUE; + + + +typedef struct PVRSRV_BRIDGE_IN_MHANDLE_TO_MMAP_DATA_TAG +{ + IMG_UINT32 ui32BridgeFlags; + IMG_HANDLE hMHandle; +} PVRSRV_BRIDGE_IN_MHANDLE_TO_MMAP_DATA; + + + +typedef struct PVRSRV_BRIDGE_IN_RELEASE_MMAP_DATA_TAG +{ + IMG_UINT32 ui32BridgeFlags; + IMG_HANDLE hMHandle; +} PVRSRV_BRIDGE_IN_RELEASE_MMAP_DATA; + + + +typedef struct PVRSRV_BRIDGE_IN_RESERVE_DEV_VIRTMEM_TAG +{ + IMG_UINT32 ui32BridgeFlags; + IMG_HANDLE hDevMemHeap; + IMG_DEV_VIRTADDR *psDevVAddr; + IMG_UINT32 ui32Size; + IMG_UINT32 ui32Alignment; + +}PVRSRV_BRIDGE_IN_RESERVE_DEV_VIRTMEM; + + +typedef struct PVRSRV_BRIDGE_OUT_CONNECT_SERVICES_TAG +{ + PVRSRV_ERROR eError; + IMG_HANDLE hKernelServices; +}PVRSRV_BRIDGE_OUT_CONNECT_SERVICES; + + +typedef struct PVRSRV_BRIDGE_OUT_RESERVE_DEV_VIRTMEM_TAG +{ + PVRSRV_ERROR eError; + PVRSRV_KERNEL_MEM_INFO *psKernelMemInfo; + PVRSRV_KERNEL_SYNC_INFO *psKernelSyncInfo; + PVRSRV_CLIENT_MEM_INFO sClientMemInfo; + PVRSRV_CLIENT_SYNC_INFO sClientSyncInfo; + +}PVRSRV_BRIDGE_OUT_RESERVE_DEV_VIRTMEM; + + + +typedef struct PVRSRV_BRIDGE_IN_FREE_DEV_VIRTMEM_TAG +{ + IMG_UINT32 ui32BridgeFlags; + PVRSRV_KERNEL_MEM_INFO *psKernelMemInfo; + PVRSRV_CLIENT_MEM_INFO sClientMemInfo; + PVRSRV_CLIENT_SYNC_INFO sClientSyncInfo; + +}PVRSRV_BRIDGE_IN_FREE_DEV_VIRTMEM; + + + +typedef struct PVRSRV_BRIDGE_IN_MAP_DEV_MEMORY_TAG +{ + IMG_UINT32 ui32BridgeFlags; + IMG_HANDLE hKernelMemInfo; + IMG_HANDLE hDstDevMemHeap; + +}PVRSRV_BRIDGE_IN_MAP_DEV_MEMORY; + + + +typedef struct PVRSRV_BRIDGE_OUT_MAP_DEV_MEMORY_TAG +{ + PVRSRV_ERROR eError; + PVRSRV_KERNEL_MEM_INFO *psDstKernelMemInfo; + PVRSRV_KERNEL_SYNC_INFO *psDstKernelSyncInfo; + PVRSRV_CLIENT_MEM_INFO sDstClientMemInfo; + PVRSRV_CLIENT_SYNC_INFO sDstClientSyncInfo; + +}PVRSRV_BRIDGE_OUT_MAP_DEV_MEMORY; + + + +typedef struct PVRSRV_BRIDGE_IN_UNMAP_DEV_MEMORY_TAG +{ + IMG_UINT32 ui32BridgeFlags; + PVRSRV_KERNEL_MEM_INFO *psKernelMemInfo; + PVRSRV_CLIENT_MEM_INFO sClientMemInfo; + PVRSRV_CLIENT_SYNC_INFO sClientSyncInfo; + +}PVRSRV_BRIDGE_IN_UNMAP_DEV_MEMORY; + + + +typedef struct PVRSRV_BRIDGE_IN_MAP_EXT_MEMORY_TAG +{ + IMG_UINT32 ui32BridgeFlags; + PVRSRV_KERNEL_MEM_INFO *psKernelMemInfo; + IMG_SYS_PHYADDR *psSysPAddr; + IMG_UINT32 ui32Flags; + +}PVRSRV_BRIDGE_IN_MAP_EXT_MEMORY; + + +typedef struct PVRSRV_BRIDGE_IN_UNMAP_EXT_MEMORY_TAG +{ + IMG_UINT32 ui32BridgeFlags; + PVRSRV_CLIENT_MEM_INFO sClientMemInfo; + PVRSRV_CLIENT_SYNC_INFO sClientSyncInfo; + IMG_UINT32 ui32Flags; + +}PVRSRV_BRIDGE_IN_UNMAP_EXT_MEMORY; + + +typedef struct PVRSRV_BRIDGE_IN_MAP_DEVICECLASS_MEMORY_TAG +{ + IMG_UINT32 ui32BridgeFlags; + IMG_HANDLE hDeviceClassBuffer; + IMG_HANDLE hDevMemContext; + +}PVRSRV_BRIDGE_IN_MAP_DEVICECLASS_MEMORY; + + + +typedef struct PVRSRV_BRIDGE_OUT_MAP_DEVICECLASS_MEMORY_TAG +{ + PVRSRV_ERROR eError; + PVRSRV_CLIENT_MEM_INFO sClientMemInfo; + PVRSRV_CLIENT_SYNC_INFO sClientSyncInfo; + PVRSRV_KERNEL_MEM_INFO *psKernelMemInfo; + PVRSRV_KERNEL_SYNC_INFO *psKernelSyncInfo; + IMG_HANDLE hMappingInfo; + +}PVRSRV_BRIDGE_OUT_MAP_DEVICECLASS_MEMORY; + + + +typedef struct PVRSRV_BRIDGE_IN_UNMAP_DEVICECLASS_MEMORY_TAG +{ + IMG_UINT32 ui32BridgeFlags; + PVRSRV_KERNEL_MEM_INFO *psKernelMemInfo; + PVRSRV_CLIENT_MEM_INFO sClientMemInfo; + PVRSRV_CLIENT_SYNC_INFO sClientSyncInfo; + +}PVRSRV_BRIDGE_IN_UNMAP_DEVICECLASS_MEMORY; + + + +typedef struct PVRSRV_BRIDGE_IN_PDUMP_MEMPOL_TAG +{ + IMG_UINT32 ui32BridgeFlags; + PVRSRV_KERNEL_MEM_INFO *psKernelMemInfo; + IMG_UINT32 ui32Offset; + IMG_UINT32 ui32Value; + IMG_UINT32 ui32Mask; + IMG_BOOL bLastFrame; + IMG_BOOL bOverwrite; + +}PVRSRV_BRIDGE_IN_PDUMP_MEMPOL; + + +typedef struct PVRSRV_BRIDGE_IN_PDUMP_SYNCPOL_TAG +{ + IMG_UINT32 ui32BridgeFlags; + PVRSRV_KERNEL_SYNC_INFO *psKernelSyncInfo; + IMG_BOOL bIsRead; + IMG_UINT32 ui32Value; + IMG_UINT32 ui32Mask; + +}PVRSRV_BRIDGE_IN_PDUMP_SYNCPOL; + + + +typedef struct PVRSRV_BRIDGE_IN_PDUMP_DUMPMEM_TAG +{ + IMG_UINT32 ui32BridgeFlags; + IMG_PVOID pvLinAddr; + IMG_PVOID pvAltLinAddr; + PVRSRV_KERNEL_MEM_INFO *psKernelMemInfo; + IMG_UINT32 ui32Offset; + IMG_UINT32 ui32Bytes; + IMG_UINT32 ui32Flags; + +}PVRSRV_BRIDGE_IN_PDUMP_DUMPMEM; + + + +typedef struct PVRSRV_BRIDGE_IN_PDUMP_DUMPSYNC_TAG +{ + IMG_UINT32 ui32BridgeFlags; + IMG_PVOID pvAltLinAddr; + PVRSRV_KERNEL_SYNC_INFO *psKernelSyncInfo; + IMG_UINT32 ui32Offset; + IMG_UINT32 ui32Bytes; + +}PVRSRV_BRIDGE_IN_PDUMP_DUMPSYNC; + + + +typedef struct PVRSRV_BRIDGE_IN_PDUMP_DUMPREG_TAG +{ + IMG_UINT32 ui32BridgeFlags; + PVRSRV_HWREG sHWReg; + IMG_UINT32 ui32Flags; + +}PVRSRV_BRIDGE_IN_PDUMP_DUMPREG; + + +typedef struct PVRSRV_BRIDGE_IN_PDUMP_REGPOL_TAG +{ + IMG_UINT32 ui32BridgeFlags; + PVRSRV_HWREG sHWReg; + IMG_UINT32 ui32Mask; + IMG_UINT32 ui32Flags; +}PVRSRV_BRIDGE_IN_PDUMP_REGPOL; + + +typedef struct PVRSRV_BRIDGE_IN_PDUMP_DUMPPDREG_TAG +{ + IMG_UINT32 ui32BridgeFlags; + PVRSRV_HWREG sHWReg; + IMG_UINT32 ui32Flags; + +}PVRSRV_BRIDGE_IN_PDUMP_DUMPPDREG; + + +typedef struct PVRSRV_BRIDGE_IN_PDUMP_MEMPAGES_TAG +{ + IMG_UINT32 ui32BridgeFlags; + IMG_HANDLE hKernelMemInfo; + IMG_DEV_PHYADDR *pPages; + IMG_UINT32 ui32NumPages; + IMG_DEV_VIRTADDR sDevAddr; + IMG_UINT32 ui32Start; + IMG_UINT32 ui32Length; + IMG_BOOL bContinuous; + +}PVRSRV_BRIDGE_IN_PDUMP_MEMPAGES; + + +typedef struct PVRSRV_BRIDGE_IN_PDUMP_COMMENT_TAG +{ + IMG_UINT32 ui32BridgeFlags; + IMG_CHAR szComment[PVRSRV_PDUMP_MAX_COMMENT_SIZE]; + IMG_UINT32 ui32Flags; + +}PVRSRV_BRIDGE_IN_PDUMP_COMMENT; + + + +typedef struct PVRSRV_BRIDGE_IN_PDUMP_SETFRAME_TAG +{ + IMG_UINT32 ui32BridgeFlags; + IMG_UINT32 ui32Frame; + +}PVRSRV_BRIDGE_IN_PDUMP_SETFRAME; + + + + +typedef struct PVRSRV_BRIDGE_IN_PDUMP_BITMAP_TAG +{ + IMG_UINT32 ui32BridgeFlags; + IMG_CHAR szFileName[PVRSRV_PDUMP_MAX_FILENAME_SIZE]; + IMG_UINT32 ui32FileOffset; + IMG_UINT32 ui32Width; + IMG_UINT32 ui32Height; + IMG_UINT32 ui32StrideInBytes; + IMG_DEV_VIRTADDR sDevBaseAddr; + IMG_UINT32 ui32Size; + PDUMP_PIXEL_FORMAT ePixelFormat; + PDUMP_MEM_FORMAT eMemFormat; + IMG_UINT32 ui32Flags; + +}PVRSRV_BRIDGE_IN_PDUMP_BITMAP; + + + +typedef struct PVRSRV_BRIDGE_IN_PDUMP_READREG_TAG +{ + IMG_UINT32 ui32BridgeFlags; + IMG_CHAR szFileName[PVRSRV_PDUMP_MAX_FILENAME_SIZE]; + IMG_UINT32 ui32FileOffset; + IMG_UINT32 ui32Address; + IMG_UINT32 ui32Size; + IMG_UINT32 ui32Flags; + +}PVRSRV_BRIDGE_IN_PDUMP_READREG; + + +typedef struct PVRSRV_BRIDGE_IN_PDUMP_DRIVERINFO_TAG +{ + IMG_UINT32 ui32BridgeFlags; + IMG_CHAR szString[PVRSRV_PDUMP_MAX_COMMENT_SIZE]; + IMG_BOOL bContinuous; + +}PVRSRV_BRIDGE_IN_PDUMP_DRIVERINFO; + +typedef struct PVRSRV_BRIDGE_IN_PDUMP_DUMPPDDEVPADDR_TAG +{ + IMG_UINT32 ui32BridgeFlags; + IMG_HANDLE hKernelMemInfo; + IMG_UINT32 ui32Offset; + IMG_DEV_PHYADDR sPDDevPAddr; +}PVRSRV_BRIDGE_IN_PDUMP_DUMPPDDEVPADDR; + + +typedef struct PVRSRV_BRIDGE_PDUM_IN_CYCLE_COUNT_REG_READ_TAG +{ + IMG_UINT32 ui32BridgeFlags; + IMG_UINT32 ui32RegOffset; + IMG_BOOL bLastFrame; +}PVRSRV_BRIDGE_IN_PDUMP_CYCLE_COUNT_REG_READ; + + +typedef struct PVRSRV_BRIDGE_OUT_ENUMDEVICE_TAG +{ + PVRSRV_ERROR eError; + IMG_UINT32 ui32NumDevices; + PVRSRV_DEVICE_IDENTIFIER asDeviceIdentifier[PVRSRV_MAX_DEVICES]; + +}PVRSRV_BRIDGE_OUT_ENUMDEVICE; + + + +typedef struct PVRSRV_BRIDGE_OUT_ACQUIRE_DEVICEINFO_TAG +{ + + PVRSRV_ERROR eError; + IMG_HANDLE hDevCookie; + +} PVRSRV_BRIDGE_OUT_ACQUIRE_DEVICEINFO; + + + +typedef struct PVRSRV_BRIDGE_OUT_ENUMCLASS_TAG +{ + PVRSRV_ERROR eError; + IMG_UINT32 ui32NumDevices; + IMG_UINT32 ui32DevID[PVRSRV_MAX_DEVICES]; + +}PVRSRV_BRIDGE_OUT_ENUMCLASS; + + + +typedef struct PVRSRV_BRIDGE_IN_OPEN_DISPCLASS_DEVICE_TAG +{ + IMG_UINT32 ui32BridgeFlags; + IMG_UINT32 ui32DeviceID; + IMG_HANDLE hDevCookie; + +}PVRSRV_BRIDGE_IN_OPEN_DISPCLASS_DEVICE; + + +typedef struct PVRSRV_BRIDGE_OUT_OPEN_DISPCLASS_DEVICE_TAG +{ + PVRSRV_ERROR eError; + IMG_HANDLE hDeviceKM; + +}PVRSRV_BRIDGE_OUT_OPEN_DISPCLASS_DEVICE; + + + +typedef struct PVRSRV_BRIDGE_IN_WRAP_EXT_MEMORY_TAG +{ + IMG_UINT32 ui32BridgeFlags; + IMG_HANDLE hDevCookie; + IMG_HANDLE hDevMemContext; + IMG_VOID *pvLinAddr; + IMG_UINT32 ui32ByteSize; + IMG_UINT32 ui32PageOffset; + IMG_BOOL bPhysContig; + IMG_UINT32 ui32NumPageTableEntries; + IMG_SYS_PHYADDR *psSysPAddr; + +}PVRSRV_BRIDGE_IN_WRAP_EXT_MEMORY; + + +typedef struct PVRSRV_BRIDGE_OUT_WRAP_EXT_MEMORY_TAG +{ + PVRSRV_ERROR eError; + PVRSRV_CLIENT_MEM_INFO sClientMemInfo; + PVRSRV_CLIENT_SYNC_INFO sClientSyncInfo; + +}PVRSRV_BRIDGE_OUT_WRAP_EXT_MEMORY; + + +typedef struct PVRSRV_BRIDGE_IN_UNWRAP_EXT_MEMORY_TAG +{ + IMG_UINT32 ui32BridgeFlags; + IMG_HANDLE hKernelMemInfo; + PVRSRV_CLIENT_MEM_INFO sClientMemInfo; + PVRSRV_CLIENT_SYNC_INFO sClientSyncInfo; + +}PVRSRV_BRIDGE_IN_UNWRAP_EXT_MEMORY; + + +#define PVRSRV_MAX_DC_DISPLAY_FORMATS 10 +#define PVRSRV_MAX_DC_DISPLAY_DIMENSIONS 10 +#define PVRSRV_MAX_DC_SWAPCHAIN_BUFFERS 4 +#define PVRSRV_MAX_DC_CLIP_RECTS 32 + + +typedef struct PVRSRV_BRIDGE_OUT_ENUM_DISPCLASS_FORMATS_TAG +{ + PVRSRV_ERROR eError; + IMG_UINT32 ui32Count; + DISPLAY_FORMAT asFormat[PVRSRV_MAX_DC_DISPLAY_FORMATS]; + +}PVRSRV_BRIDGE_OUT_ENUM_DISPCLASS_FORMATS; + + + +typedef struct PVRSRV_BRIDGE_IN_ENUM_DISPCLASS_DIMS_TAG +{ + IMG_UINT32 ui32BridgeFlags; + IMG_HANDLE hDeviceKM; + DISPLAY_FORMAT sFormat; + +}PVRSRV_BRIDGE_IN_ENUM_DISPCLASS_DIMS; + + + +typedef struct PVRSRV_BRIDGE_OUT_ENUM_DISPCLASS_DIMS_TAG +{ + PVRSRV_ERROR eError; + IMG_UINT32 ui32Count; + DISPLAY_DIMS asDim[PVRSRV_MAX_DC_DISPLAY_DIMENSIONS]; + +}PVRSRV_BRIDGE_OUT_ENUM_DISPCLASS_DIMS; + + + +typedef struct PVRSRV_BRIDGE_OUT_GET_DISPCLASS_INFO_TAG +{ + PVRSRV_ERROR eError; + DISPLAY_INFO sDisplayInfo; + +}PVRSRV_BRIDGE_OUT_GET_DISPCLASS_INFO; + + + +typedef struct PVRSRV_BRIDGE_OUT_GET_DISPCLASS_SYSBUFFER_TAG +{ + PVRSRV_ERROR eError; + IMG_HANDLE hBuffer; + +}PVRSRV_BRIDGE_OUT_GET_DISPCLASS_SYSBUFFER; + + + +typedef struct PVRSRV_BRIDGE_IN_CREATE_DISPCLASS_SWAPCHAIN_TAG +{ + IMG_UINT32 ui32BridgeFlags; + IMG_HANDLE hDeviceKM; + IMG_UINT32 ui32Flags; + DISPLAY_SURF_ATTRIBUTES sDstSurfAttrib; + DISPLAY_SURF_ATTRIBUTES sSrcSurfAttrib; + IMG_UINT32 ui32BufferCount; + IMG_UINT32 ui32OEMFlags; + IMG_UINT32 ui32SwapChainID; + +} PVRSRV_BRIDGE_IN_CREATE_DISPCLASS_SWAPCHAIN; + + + +typedef struct PVRSRV_BRIDGE_OUT_CREATE_DISPCLASS_SWAPCHAIN_TAG +{ + PVRSRV_ERROR eError; + IMG_HANDLE hSwapChain; + IMG_UINT32 ui32SwapChainID; + +} PVRSRV_BRIDGE_OUT_CREATE_DISPCLASS_SWAPCHAIN; + + + +typedef struct PVRSRV_BRIDGE_IN_DESTROY_DISPCLASS_SWAPCHAIN_TAG +{ + IMG_UINT32 ui32BridgeFlags; + IMG_HANDLE hDeviceKM; + IMG_HANDLE hSwapChain; + +} PVRSRV_BRIDGE_IN_DESTROY_DISPCLASS_SWAPCHAIN; + + + +typedef struct PVRSRV_BRIDGE_IN_SET_DISPCLASS_RECT_TAG +{ + IMG_UINT32 ui32BridgeFlags; + IMG_HANDLE hDeviceKM; + IMG_HANDLE hSwapChain; + IMG_RECT sRect; + +} PVRSRV_BRIDGE_IN_SET_DISPCLASS_RECT; + + + +typedef struct PVRSRV_BRIDGE_IN_SET_DISPCLASS_COLOURKEY_TAG +{ + IMG_UINT32 ui32BridgeFlags; + IMG_HANDLE hDeviceKM; + IMG_HANDLE hSwapChain; + IMG_UINT32 ui32CKColour; + +} PVRSRV_BRIDGE_IN_SET_DISPCLASS_COLOURKEY; + + + +typedef struct PVRSRV_BRIDGE_IN_GET_DISPCLASS_BUFFERS_TAG +{ + IMG_UINT32 ui32BridgeFlags; + IMG_HANDLE hDeviceKM; + IMG_HANDLE hSwapChain; + +} PVRSRV_BRIDGE_IN_GET_DISPCLASS_BUFFERS; + + + +typedef struct PVRSRV_BRIDGE_OUT_GET_DISPCLASS_BUFFERS_TAG +{ + PVRSRV_ERROR eError; + IMG_UINT32 ui32BufferCount; + IMG_HANDLE ahBuffer[PVRSRV_MAX_DC_SWAPCHAIN_BUFFERS]; + +} PVRSRV_BRIDGE_OUT_GET_DISPCLASS_BUFFERS; + + + +typedef struct PVRSRV_BRIDGE_IN_SWAP_DISPCLASS_TO_BUFFER_TAG +{ + IMG_UINT32 ui32BridgeFlags; + IMG_HANDLE hDeviceKM; + IMG_HANDLE hBuffer; + IMG_UINT32 ui32SwapInterval; + IMG_HANDLE hPrivateTag; + IMG_UINT32 ui32ClipRectCount; + IMG_RECT sClipRect[PVRSRV_MAX_DC_CLIP_RECTS]; + +} PVRSRV_BRIDGE_IN_SWAP_DISPCLASS_TO_BUFFER; + + + +typedef struct PVRSRV_BRIDGE_IN_SWAP_DISPCLASS_TO_SYSTEM_TAG +{ + IMG_UINT32 ui32BridgeFlags; + IMG_HANDLE hDeviceKM; + IMG_HANDLE hSwapChain; + +} PVRSRV_BRIDGE_IN_SWAP_DISPCLASS_TO_SYSTEM; + + + +typedef struct PVRSRV_BRIDGE_IN_OPEN_BUFFERCLASS_DEVICE_TAG +{ + IMG_UINT32 ui32BridgeFlags; + IMG_UINT32 ui32DeviceID; + IMG_HANDLE hDevCookie; + +} PVRSRV_BRIDGE_IN_OPEN_BUFFERCLASS_DEVICE; + + + +typedef struct PVRSRV_BRIDGE_OUT_OPEN_BUFFERCLASS_DEVICE_TAG +{ + PVRSRV_ERROR eError; + IMG_HANDLE hDeviceKM; + +} PVRSRV_BRIDGE_OUT_OPEN_BUFFERCLASS_DEVICE; + + + +typedef struct PVRSRV_BRIDGE_OUT_GET_BUFFERCLASS_INFO_TAG +{ + PVRSRV_ERROR eError; + BUFFER_INFO sBufferInfo; + +} PVRSRV_BRIDGE_OUT_GET_BUFFERCLASS_INFO; + + + +typedef struct PVRSRV_BRIDGE_IN_GET_BUFFERCLASS_BUFFER_TAG +{ + IMG_UINT32 ui32BridgeFlags; + IMG_HANDLE hDeviceKM; + IMG_UINT32 ui32BufferIndex; + +} PVRSRV_BRIDGE_IN_GET_BUFFERCLASS_BUFFER; + + + +typedef struct PVRSRV_BRIDGE_OUT_GET_BUFFERCLASS_BUFFER_TAG +{ + PVRSRV_ERROR eError; + IMG_HANDLE hBuffer; + +} PVRSRV_BRIDGE_OUT_GET_BUFFERCLASS_BUFFER; + + + +typedef struct PVRSRV_BRIDGE_OUT_GET_DEVMEM_HEAPINFO_TAG +{ + PVRSRV_ERROR eError; + IMG_UINT32 ui32ClientHeapCount; + PVRSRV_HEAP_INFO sHeapInfo[PVRSRV_MAX_CLIENT_HEAPS]; + +} PVRSRV_BRIDGE_OUT_GET_DEVMEM_HEAPINFO; + + + +typedef struct PVRSRV_BRIDGE_OUT_CREATE_DEVMEMCONTEXT_TAG +{ + PVRSRV_ERROR eError; + IMG_HANDLE hDevMemContext; + IMG_UINT32 ui32ClientHeapCount; + PVRSRV_HEAP_INFO sHeapInfo[PVRSRV_MAX_CLIENT_HEAPS]; + +} PVRSRV_BRIDGE_OUT_CREATE_DEVMEMCONTEXT; + + + +typedef struct PVRSRV_BRIDGE_OUT_CREATE_DEVMEMHEAP_TAG +{ + PVRSRV_ERROR eError; + IMG_HANDLE hDevMemHeap; + +} PVRSRV_BRIDGE_OUT_CREATE_DEVMEMHEAP; + + + +typedef struct PVRSRV_BRIDGE_OUT_ALLOCDEVICEMEM_TAG +{ + PVRSRV_ERROR eError; + PVRSRV_KERNEL_MEM_INFO *psKernelMemInfo; + PVRSRV_KERNEL_SYNC_INFO *psKernelSyncInfo; + PVRSRV_CLIENT_MEM_INFO sClientMemInfo; + PVRSRV_CLIENT_SYNC_INFO sClientSyncInfo; + +} PVRSRV_BRIDGE_OUT_ALLOCDEVICEMEM; + + + +typedef struct PVRSRV_BRIDGE_OUT_EXPORTDEVICEMEM_TAG +{ + PVRSRV_ERROR eError; + IMG_HANDLE hMemInfo; + +} PVRSRV_BRIDGE_OUT_EXPORTDEVICEMEM; + + +typedef struct PVRSRV_BRIDGE_OUT_MAPMEMINFOTOUSER_TAG +{ + PVRSRV_ERROR eError; + IMG_PVOID pvLinAddr; + IMG_HANDLE hMappingInfo; + +}PVRSRV_BRIDGE_OUT_MAPMEMINFOTOUSER; + + + +typedef struct PVRSRV_BRIDGE_OUT_GETFREEDEVICEMEM_TAG +{ + PVRSRV_ERROR eError; + IMG_UINT32 ui32Total; + IMG_UINT32 ui32Free; + IMG_UINT32 ui32LargestBlock; + +} PVRSRV_BRIDGE_OUT_GETFREEDEVICEMEM; + + +#include "pvrmmap.h" +typedef struct PVRSRV_BRIDGE_OUT_MHANDLE_TO_MMAP_DATA_TAG +{ + PVRSRV_ERROR eError; + + + IMG_UINT32 ui32MMapOffset; + + + IMG_UINT32 ui32ByteOffset; + + + IMG_UINT32 ui32RealByteSize; + + + IMG_UINT32 ui32UserVAddr; + +} PVRSRV_BRIDGE_OUT_MHANDLE_TO_MMAP_DATA; + +typedef struct PVRSRV_BRIDGE_OUT_RELEASE_MMAP_DATA_TAG +{ + PVRSRV_ERROR eError; + + + IMG_BOOL bMUnmap; + + + IMG_UINT32 ui32UserVAddr; + + + IMG_UINT32 ui32RealByteSize; +} PVRSRV_BRIDGE_OUT_RELEASE_MMAP_DATA; + +typedef struct PVRSRV_BRIDGE_IN_GET_MISC_INFO_TAG +{ + IMG_UINT32 ui32BridgeFlags; + PVRSRV_MISC_INFO sMiscInfo; + +}PVRSRV_BRIDGE_IN_GET_MISC_INFO; + + + +typedef struct PVRSRV_BRIDGE_OUT_GET_MISC_INFO_TAG +{ + PVRSRV_ERROR eError; + PVRSRV_MISC_INFO sMiscInfo; + +}PVRSRV_BRIDGE_OUT_GET_MISC_INFO; + + + +typedef struct PVRSRV_BRIDGE_IN_RELEASE_MISC_INFO_TAG +{ + IMG_UINT32 ui32BridgeFlags; + PVRSRV_MISC_INFO sMiscInfo; + +}PVRSRV_BRIDGE_IN_RELEASE_MISC_INFO; + + + +typedef struct PVRSRV_BRIDGE_OUT_RELEASE_MISC_INFO_TAG +{ + PVRSRV_ERROR eError; + PVRSRV_MISC_INFO sMiscInfo; + +}PVRSRV_BRIDGE_OUT_RELEASE_MISC_INFO; + + + + +typedef struct PVRSRV_BRIDGE_OUT_PDUMP_ISCAPTURING_TAG +{ + PVRSRV_ERROR eError; + IMG_BOOL bIsCapturing; + +} PVRSRV_BRIDGE_OUT_PDUMP_ISCAPTURING; + + +typedef struct PVRSRV_BRIDGE_IN_GET_FB_STATS_TAG +{ + IMG_UINT32 ui32BridgeFlags; + IMG_UINT32 ui32Total; + IMG_UINT32 ui32Available; + +} PVRSRV_BRIDGE_IN_GET_FB_STATS; + + + +typedef struct PVRSRV_BRIDGE_IN_MAPPHYSTOUSERSPACE_TAG +{ + IMG_UINT32 ui32BridgeFlags; + IMG_HANDLE hDevCookie; + IMG_SYS_PHYADDR sSysPhysAddr; + IMG_UINT32 uiSizeInBytes; + +} PVRSRV_BRIDGE_IN_MAPPHYSTOUSERSPACE; + + + +typedef struct PVRSRV_BRIDGE_OUT_MAPPHYSTOUSERSPACE_TAG +{ + IMG_PVOID pvUserAddr; + IMG_UINT32 uiActualSize; + IMG_PVOID pvProcess; + +} PVRSRV_BRIDGE_OUT_MAPPHYSTOUSERSPACE; + + + +typedef struct PVRSRV_BRIDGE_IN_UNMAPPHYSTOUSERSPACE_TAG +{ + IMG_UINT32 ui32BridgeFlags; + IMG_HANDLE hDevCookie; + IMG_PVOID pvUserAddr; + IMG_PVOID pvProcess; + +} PVRSRV_BRIDGE_IN_UNMAPPHYSTOUSERSPACE; + + + +typedef struct PVRSRV_BRIDGE_OUT_GETPHYSTOUSERSPACEMAP_TAG +{ + IMG_PVOID *ppvTbl; + IMG_UINT32 uiTblSize; + +} PVRSRV_BRIDGE_OUT_GETPHYSTOUSERSPACEMAP; + + + +typedef struct PVRSRV_BRIDGE_IN_REGISTER_SIM_PROCESS_TAG +{ + IMG_UINT32 ui32BridgeFlags; + IMG_HANDLE hDevCookie; + IMG_PVOID pvProcess; + +} PVRSRV_BRIDGE_IN_REGISTER_SIM_PROCESS; + + +typedef struct PVRSRV_BRIDGE_OUT_REGISTER_SIM_PROCESS_TAG +{ + IMG_SYS_PHYADDR sRegsPhysBase; + IMG_VOID *pvRegsBase; + IMG_PVOID pvProcess; + IMG_UINT32 ulNoOfEntries; + IMG_PVOID pvTblLinAddr; + +} PVRSRV_BRIDGE_OUT_REGISTER_SIM_PROCESS; + + +typedef struct PVRSRV_BRIDGE_IN_UNREGISTER_SIM_PROCESS_TAG +{ + IMG_UINT32 ui32BridgeFlags; + IMG_HANDLE hDevCookie; + IMG_PVOID pvProcess; + IMG_VOID *pvRegsBase; + +} PVRSRV_BRIDGE_IN_UNREGISTER_SIM_PROCESS; + +typedef struct PVRSRV_BRIDGE_IN_PROCESS_SIMISR_EVENT_TAG +{ + IMG_UINT32 ui32BridgeFlags; + IMG_HANDLE hDevCookie; + IMG_UINT32 ui32StatusAndMask; + PVRSRV_ERROR eError; + +} PVRSRV_BRIDGE_IN_PROCESS_SIMISR_EVENT; + +typedef struct PVRSRV_BRIDGE_IN_INITSRV_DISCONNECT_TAG +{ + IMG_UINT32 ui32BridgeFlags; + IMG_BOOL bInitSuccesful; +} PVRSRV_BRIDGE_IN_INITSRV_DISCONNECT; + + +typedef struct PVRSRV_BRIDGE_IN_ALLOC_SHARED_SYS_MEM_TAG +{ + IMG_UINT32 ui32BridgeFlags; + IMG_UINT32 ui32Flags; + IMG_UINT32 ui32Size; +}PVRSRV_BRIDGE_IN_ALLOC_SHARED_SYS_MEM; + +typedef struct PVRSRV_BRIDGE_OUT_ALLOC_SHARED_SYS_MEM_TAG +{ + PVRSRV_ERROR eError; + PVRSRV_KERNEL_MEM_INFO *psKernelMemInfo; + PVRSRV_CLIENT_MEM_INFO sClientMemInfo; +}PVRSRV_BRIDGE_OUT_ALLOC_SHARED_SYS_MEM; + +typedef struct PVRSRV_BRIDGE_IN_FREE_SHARED_SYS_MEM_TAG +{ + IMG_UINT32 ui32BridgeFlags; + PVRSRV_KERNEL_MEM_INFO *psKernelMemInfo; + PVRSRV_CLIENT_MEM_INFO sClientMemInfo; +}PVRSRV_BRIDGE_IN_FREE_SHARED_SYS_MEM; + +typedef struct PVRSRV_BRIDGE_OUT_FREE_SHARED_SYS_MEM_TAG +{ + PVRSRV_ERROR eError; +}PVRSRV_BRIDGE_OUT_FREE_SHARED_SYS_MEM; + +typedef struct PVRSRV_BRIDGE_IN_MAP_MEMINFO_MEM_TAG +{ + IMG_UINT32 ui32BridgeFlags; + IMG_HANDLE hKernelMemInfo; +}PVRSRV_BRIDGE_IN_MAP_MEMINFO_MEM; + +typedef struct PVRSRV_BRIDGE_OUT_MAP_MEMINFO_MEM_TAG +{ + PVRSRV_CLIENT_MEM_INFO sClientMemInfo; + PVRSRV_CLIENT_SYNC_INFO sClientSyncInfo; + PVRSRV_KERNEL_MEM_INFO *psKernelMemInfo; + PVRSRV_KERNEL_SYNC_INFO *psKernelSyncInfo; + PVRSRV_ERROR eError; +}PVRSRV_BRIDGE_OUT_MAP_MEMINFO_MEM; + +typedef struct PVRSRV_BRIDGE_IN_UNMAP_MEMINFO_MEM_TAG +{ + IMG_UINT32 ui32BridgeFlags; + PVRSRV_CLIENT_MEM_INFO sClientMemInfo; +}PVRSRV_BRIDGE_IN_UNMAP_MEMINFO_MEM; + +typedef struct PVRSRV_BRIDGE_OUT_UNMAP_MEMINFO_MEM_TAG +{ + PVRSRV_ERROR eError; +}PVRSRV_BRIDGE_OUT_UNMAP_MEMINFO_MEM; + +typedef struct PVRSRV_BRIDGE_IN_GETMMU_PD_DEVPADDR_TAG +{ + IMG_UINT32 ui32BridgeFlags; + IMG_HANDLE hDevMemContext; +}PVRSRV_BRIDGE_IN_GETMMU_PD_DEVPADDR; + +typedef struct PVRSRV_BRIDGE_OUT_GETMMU_PD_DEVPADDR_TAG +{ + IMG_DEV_PHYADDR sPDDevPAddr; + PVRSRV_ERROR eError; +}PVRSRV_BRIDGE_OUT_GETMMU_PD_DEVPADDR; + +typedef struct PVRSRV_BRIDGE_IN_EVENT_OBJECT_WAI_TAG +{ + IMG_UINT32 ui32BridgeFlags; + IMG_HANDLE hOSEventKM; +} PVRSRV_BRIDGE_IN_EVENT_OBJECT_WAIT; + +typedef struct PVRSRV_BRIDGE_IN_EVENT_OBJECT_OPEN_TAG +{ + PVRSRV_EVENTOBJECT sEventObject; +} PVRSRV_BRIDGE_IN_EVENT_OBJECT_OPEN; + +typedef struct PVRSRV_BRIDGE_OUT_EVENT_OBJECT_OPEN_TAG +{ + IMG_HANDLE hOSEvent; + PVRSRV_ERROR eError; +} PVRSRV_BRIDGE_OUT_EVENT_OBJECT_OPEN; + +typedef struct PVRSRV_BRIDGE_IN_EVENT_OBJECT_CLOSE_TAG +{ + PVRSRV_EVENTOBJECT sEventObject; + IMG_HANDLE hOSEventKM; +} PVRSRV_BRIDGE_IN_EVENT_OBJECT_CLOSE; + + +typedef struct PVRSRV_BRIDGE_IN_MODIFY_SYNC_OPS_TAG +{ + IMG_UINT32 ui32BridgeFlags; + IMG_HANDLE hKernelSyncInfo; + IMG_UINT32 ui32ModifyFlags; + +} PVRSRV_BRIDGE_IN_MODIFY_SYNC_OPS; + +typedef struct PVRSRV_BRIDGE_OUT_MODIFY_SYNC_OPS_TAG +{ + PVRSRV_ERROR eError; + + + IMG_UINT32 ui32ReadOpsPending; + IMG_UINT32 ui32ReadOpsComplete; + IMG_UINT32 ui32WriteOpsPending; + IMG_UINT32 ui32WriteOpsComplete; + +} PVRSRV_BRIDGE_OUT_MODIFY_SYNC_OPS; + +#if defined (__cplusplus) +} +#endif + +#endif + diff --git a/services4/include/pvr_bridge_km.h b/services4/include/pvr_bridge_km.h new file mode 100644 index 0000000..b171b7f --- /dev/null +++ b/services4/include/pvr_bridge_km.h @@ -0,0 +1,275 @@ +/********************************************************************** + * + * Copyright(c) 2008 Imagination Technologies Ltd. All rights reserved. + * + * This program is free software; you can redistribute it and/or modify it + * under the terms and conditions of the GNU General Public License, + * version 2, as published by the Free Software Foundation. + * + * This program is distributed in the hope it will be useful but, except + * as otherwise stated in writing, without any warranty; without even the + * implied warranty of merchantability or fitness for a particular purpose. + * See the GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License along with + * this program; if not, write to the Free Software Foundation, Inc., + * 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA. + * + * The full GNU General Public License is included in this distribution in + * the file called "COPYING". + * + * Contact Information: + * Imagination Technologies Ltd. + * Home Park Estate, Kings Langley, Herts, WD4 8LZ, UK + * + ******************************************************************************/ + +#ifndef __PVR_BRIDGE_KM_H_ +#define __PVR_BRIDGE_KM_H_ + +#if defined (__cplusplus) +extern "C" { +#endif + +#include "pvr_bridge.h" +#include "perproc.h" + +#if defined(__linux__) +PVRSRV_ERROR LinuxBridgeInit(IMG_VOID); +IMG_VOID LinuxBridgeDeInit(IMG_VOID); +#endif + +IMG_IMPORT +PVRSRV_ERROR IMG_CALLCONV PVRSRVEnumerateDevicesKM(IMG_UINT32 *pui32NumDevices, + PVRSRV_DEVICE_IDENTIFIER *psDevIdList); + +IMG_IMPORT +PVRSRV_ERROR IMG_CALLCONV PVRSRVAcquireDeviceDataKM(IMG_UINT32 uiDevIndex, + PVRSRV_DEVICE_TYPE eDeviceType, + IMG_HANDLE *phDevCookie); + +IMG_IMPORT +PVRSRV_ERROR IMG_CALLCONV PVRSRVCreateCommandQueueKM(IMG_UINT32 ui32QueueSize, + PVRSRV_QUEUE_INFO **ppsQueueInfo); + +IMG_IMPORT +PVRSRV_ERROR IMG_CALLCONV PVRSRVDestroyCommandQueueKM(PVRSRV_QUEUE_INFO *psQueueInfo); + +IMG_IMPORT +PVRSRV_ERROR IMG_CALLCONV PVRSRVGetDeviceMemHeapsKM(IMG_HANDLE hDevCookie, + PVRSRV_HEAP_INFO *psHeapInfo); + +IMG_IMPORT +PVRSRV_ERROR IMG_CALLCONV PVRSRVCreateDeviceMemContextKM(IMG_HANDLE hDevCookie, + PVRSRV_PER_PROCESS_DATA *psPerProc, + IMG_HANDLE *phDevMemContext, + IMG_UINT32 *pui32ClientHeapCount, + PVRSRV_HEAP_INFO *psHeapInfo, + IMG_BOOL *pbCreated, + IMG_BOOL *pbShared); + + +IMG_IMPORT +PVRSRV_ERROR IMG_CALLCONV PVRSRVDestroyDeviceMemContextKM(IMG_HANDLE hDevCookie, + IMG_HANDLE hDevMemContext, + IMG_BOOL *pbCreated); + + +IMG_IMPORT +PVRSRV_ERROR IMG_CALLCONV PVRSRVGetDeviceMemHeapInfoKM(IMG_HANDLE hDevCookie, + IMG_HANDLE hDevMemContext, + IMG_UINT32 *pui32ClientHeapCount, + PVRSRV_HEAP_INFO *psHeapInfo, + IMG_BOOL *pbShared + ); + + +IMG_IMPORT +PVRSRV_ERROR IMG_CALLCONV PVRSRVAllocDeviceMemKM(IMG_HANDLE hDevCookie, + PVRSRV_PER_PROCESS_DATA *psPerProc, + IMG_HANDLE hDevMemHeap, + IMG_UINT32 ui32Flags, + IMG_UINT32 ui32Size, + IMG_UINT32 ui32Alignment, + PVRSRV_KERNEL_MEM_INFO **ppsMemInfo); + +IMG_IMPORT +PVRSRV_ERROR IMG_CALLCONV PVRSRVFreeDeviceMemKM(IMG_HANDLE hDevCookie, + PVRSRV_KERNEL_MEM_INFO *psMemInfo); + +IMG_IMPORT +PVRSRV_ERROR IMG_CALLCONV PVRSRVDissociateDeviceMemKM(IMG_HANDLE hDevCookie, + PVRSRV_KERNEL_MEM_INFO *psMemInfo); + +IMG_IMPORT +PVRSRV_ERROR IMG_CALLCONV PVRSRVReserveDeviceVirtualMemKM(IMG_HANDLE hDevMemHeap, + IMG_DEV_VIRTADDR *psDevVAddr, + IMG_UINT32 ui32Size, + IMG_UINT32 ui32Alignment, + PVRSRV_KERNEL_MEM_INFO **ppsMemInfo); + +IMG_IMPORT +PVRSRV_ERROR IMG_CALLCONV PVRSRVFreeDeviceVirtualMemKM(PVRSRV_KERNEL_MEM_INFO *psMemInfo); + +IMG_IMPORT +PVRSRV_ERROR IMG_CALLCONV PVRSRVMapDeviceMemoryKM(PVRSRV_PER_PROCESS_DATA *psPerProc, + PVRSRV_KERNEL_MEM_INFO *psSrcMemInfo, + IMG_HANDLE hDstDevMemHeap, + PVRSRV_KERNEL_MEM_INFO **ppsDstMemInfo); + +IMG_IMPORT +PVRSRV_ERROR IMG_CALLCONV PVRSRVUnmapDeviceMemoryKM(PVRSRV_KERNEL_MEM_INFO *psMemInfo); + +IMG_IMPORT +PVRSRV_ERROR IMG_CALLCONV PVRSRVWrapExtMemoryKM(IMG_HANDLE hDevCookie, + PVRSRV_PER_PROCESS_DATA *psPerProc, + IMG_HANDLE hDevMemContext, + IMG_UINT32 ui32ByteSize, + IMG_UINT32 ui32PageOffset, + IMG_BOOL bPhysContig, + IMG_SYS_PHYADDR *psSysAddr, + IMG_VOID *pvLinAddr, + PVRSRV_KERNEL_MEM_INFO **ppsMemInfo); + +IMG_IMPORT +PVRSRV_ERROR IMG_CALLCONV PVRSRVUnwrapExtMemoryKM(PVRSRV_KERNEL_MEM_INFO *psMemInfo); + +IMG_IMPORT +PVRSRV_ERROR PVRSRVEnumerateDCKM(PVRSRV_DEVICE_CLASS DeviceClass, + IMG_UINT32 *pui32DevCount, + IMG_UINT32 *pui32DevID ); + +IMG_IMPORT +PVRSRV_ERROR PVRSRVOpenDCDeviceKM(PVRSRV_PER_PROCESS_DATA *psPerProc, + IMG_UINT32 ui32DeviceID, + IMG_HANDLE hDevCookie, + IMG_HANDLE *phDeviceKM); + +IMG_IMPORT +PVRSRV_ERROR PVRSRVCloseDCDeviceKM(IMG_HANDLE hDeviceKM, IMG_BOOL bResManCallback); + +IMG_IMPORT +PVRSRV_ERROR PVRSRVEnumDCFormatsKM(IMG_HANDLE hDeviceKM, + IMG_UINT32 *pui32Count, + DISPLAY_FORMAT *psFormat); + +IMG_IMPORT +PVRSRV_ERROR PVRSRVEnumDCDimsKM(IMG_HANDLE hDeviceKM, + DISPLAY_FORMAT *psFormat, + IMG_UINT32 *pui32Count, + DISPLAY_DIMS *psDim); + +IMG_IMPORT +PVRSRV_ERROR PVRSRVGetDCSystemBufferKM(IMG_HANDLE hDeviceKM, + IMG_HANDLE *phBuffer); + +IMG_IMPORT +PVRSRV_ERROR PVRSRVGetDCInfoKM(IMG_HANDLE hDeviceKM, + DISPLAY_INFO *psDisplayInfo); +IMG_IMPORT +PVRSRV_ERROR PVRSRVCreateDCSwapChainKM(PVRSRV_PER_PROCESS_DATA *psPerProc, + IMG_HANDLE hDeviceKM, + IMG_UINT32 ui32Flags, + DISPLAY_SURF_ATTRIBUTES *psDstSurfAttrib, + DISPLAY_SURF_ATTRIBUTES *psSrcSurfAttrib, + IMG_UINT32 ui32BufferCount, + IMG_UINT32 ui32OEMFlags, + IMG_HANDLE *phSwapChain, + IMG_UINT32 *pui32SwapChainID); +IMG_IMPORT +PVRSRV_ERROR PVRSRVDestroyDCSwapChainKM(IMG_HANDLE hSwapChain); +IMG_IMPORT +PVRSRV_ERROR PVRSRVSetDCDstRectKM(IMG_HANDLE hDeviceKM, + IMG_HANDLE hSwapChain, + IMG_RECT *psRect); +IMG_IMPORT +PVRSRV_ERROR PVRSRVSetDCSrcRectKM(IMG_HANDLE hDeviceKM, + IMG_HANDLE hSwapChain, + IMG_RECT *psRect); +IMG_IMPORT +PVRSRV_ERROR PVRSRVSetDCDstColourKeyKM(IMG_HANDLE hDeviceKM, + IMG_HANDLE hSwapChain, + IMG_UINT32 ui32CKColour); +IMG_IMPORT +PVRSRV_ERROR PVRSRVSetDCSrcColourKeyKM(IMG_HANDLE hDeviceKM, + IMG_HANDLE hSwapChain, + IMG_UINT32 ui32CKColour); +IMG_IMPORT +PVRSRV_ERROR PVRSRVGetDCBuffersKM(IMG_HANDLE hDeviceKM, + IMG_HANDLE hSwapChain, + IMG_UINT32 *pui32BufferCount, + IMG_HANDLE *phBuffer); +IMG_IMPORT +PVRSRV_ERROR PVRSRVSwapToDCBufferKM(IMG_HANDLE hDeviceKM, + IMG_HANDLE hBuffer, + IMG_UINT32 ui32SwapInterval, + IMG_HANDLE hPrivateTag, + IMG_UINT32 ui32ClipRectCount, + IMG_RECT *psClipRect); +IMG_IMPORT +PVRSRV_ERROR PVRSRVSwapToDCSystemKM(IMG_HANDLE hDeviceKM, + IMG_HANDLE hSwapChain); + +IMG_IMPORT +PVRSRV_ERROR PVRSRVOpenBCDeviceKM(PVRSRV_PER_PROCESS_DATA *psPerProc, + IMG_UINT32 ui32DeviceID, + IMG_HANDLE hDevCookie, + IMG_HANDLE *phDeviceKM); +IMG_IMPORT +PVRSRV_ERROR PVRSRVCloseBCDeviceKM(IMG_HANDLE hDeviceKM, IMG_BOOL bResManCallback); + +IMG_IMPORT +PVRSRV_ERROR PVRSRVGetBCInfoKM(IMG_HANDLE hDeviceKM, + BUFFER_INFO *psBufferInfo); +IMG_IMPORT +PVRSRV_ERROR PVRSRVGetBCBufferKM(IMG_HANDLE hDeviceKM, + IMG_UINT32 ui32BufferIndex, + IMG_HANDLE *phBuffer); + + +IMG_IMPORT +PVRSRV_ERROR IMG_CALLCONV PVRSRVMapDeviceClassMemoryKM(PVRSRV_PER_PROCESS_DATA *psPerProc, + IMG_HANDLE hDevMemContext, + IMG_HANDLE hDeviceClassBuffer, + PVRSRV_KERNEL_MEM_INFO **ppsMemInfo, + IMG_HANDLE *phOSMapInfo); + +IMG_IMPORT +PVRSRV_ERROR IMG_CALLCONV PVRSRVUnmapDeviceClassMemoryKM(PVRSRV_KERNEL_MEM_INFO *psMemInfo); + +IMG_IMPORT +PVRSRV_ERROR IMG_CALLCONV PVRSRVGetFreeDeviceMemKM(IMG_UINT32 ui32Flags, + IMG_UINT32 *pui32Total, + IMG_UINT32 *pui32Free, + IMG_UINT32 *pui32LargestBlock); +IMG_IMPORT +PVRSRV_ERROR IMG_CALLCONV PVRSRVAllocSyncInfoKM(IMG_HANDLE hDevCookie, + IMG_HANDLE hDevMemContext, + PVRSRV_KERNEL_SYNC_INFO **ppsKernelSyncInfo); +IMG_IMPORT +PVRSRV_ERROR IMG_CALLCONV PVRSRVFreeSyncInfoKM(PVRSRV_KERNEL_SYNC_INFO *psKernelSyncInfo); + +IMG_IMPORT +PVRSRV_ERROR IMG_CALLCONV PVRSRVGetMiscInfoKM(PVRSRV_MISC_INFO *psMiscInfo); + +PVRSRV_ERROR PVRSRVGetFBStatsKM(IMG_UINT32 *pui32Total, + IMG_UINT32 *pui32Available); + +IMG_IMPORT PVRSRV_ERROR +PVRSRVAllocSharedSysMemoryKM(PVRSRV_PER_PROCESS_DATA *psPerProc, + IMG_UINT32 ui32Flags, + IMG_UINT32 ui32Size, + PVRSRV_KERNEL_MEM_INFO **ppsKernelMemInfo); + +IMG_IMPORT PVRSRV_ERROR +PVRSRVFreeSharedSysMemoryKM(PVRSRV_KERNEL_MEM_INFO *psKernelMemInfo); + +IMG_IMPORT PVRSRV_ERROR +PVRSRVDissociateMemFromResmanKM(PVRSRV_KERNEL_MEM_INFO *psKernelMemInfo); + +#if defined (__cplusplus) +} +#endif + +#endif + diff --git a/services4/include/pvrmmap.h b/services4/include/pvrmmap.h new file mode 100644 index 0000000..4404d88 --- /dev/null +++ b/services4/include/pvrmmap.h @@ -0,0 +1,36 @@ +/********************************************************************** + * + * Copyright(c) 2008 Imagination Technologies Ltd. All rights reserved. + * + * This program is free software; you can redistribute it and/or modify it + * under the terms and conditions of the GNU General Public License, + * version 2, as published by the Free Software Foundation. + * + * This program is distributed in the hope it will be useful but, except + * as otherwise stated in writing, without any warranty; without even the + * implied warranty of merchantability or fitness for a particular purpose. + * See the GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License along with + * this program; if not, write to the Free Software Foundation, Inc., + * 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA. + * + * The full GNU General Public License is included in this distribution in + * the file called "COPYING". + * + * Contact Information: + * Imagination Technologies Ltd. + * Home Park Estate, Kings Langley, Herts, WD4 8LZ, UK + * + ******************************************************************************/ + +#ifndef __PVRMMAP_H__ +#define __PVRMMAP_H__ + +PVRSRV_ERROR PVRPMapKMem(IMG_HANDLE hModule, IMG_VOID **ppvLinAddr, IMG_VOID *pvLinAddrKM, IMG_HANDLE *phMappingInfo, IMG_HANDLE hMHandle); + + +IMG_BOOL PVRUnMapKMem(IMG_HANDLE hModule, IMG_HANDLE hMappingInfo, IMG_HANDLE hMHandle); + +#endif + diff --git a/services4/include/servicesint.h b/services4/include/servicesint.h new file mode 100644 index 0000000..7b74f8e --- /dev/null +++ b/services4/include/servicesint.h @@ -0,0 +1,246 @@ +/********************************************************************** + * + * Copyright(c) 2008 Imagination Technologies Ltd. All rights reserved. + * + * This program is free software; you can redistribute it and/or modify it + * under the terms and conditions of the GNU General Public License, + * version 2, as published by the Free Software Foundation. + * + * This program is distributed in the hope it will be useful but, except + * as otherwise stated in writing, without any warranty; without even the + * implied warranty of merchantability or fitness for a particular purpose. + * See the GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License along with + * this program; if not, write to the Free Software Foundation, Inc., + * 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA. + * + * The full GNU General Public License is included in this distribution in + * the file called "COPYING". + * + * Contact Information: + * Imagination Technologies Ltd. + * Home Park Estate, Kings Langley, Herts, WD4 8LZ, UK + * + ******************************************************************************/ + +#if !defined (__SERVICESINT_H__) +#define __SERVICESINT_H__ + +#if defined (__cplusplus) +extern "C" { +#endif + +#include "services.h" +#include "sysinfo.h" + +#define HWREC_DEFAULT_TIMEOUT (500) + +#define DRIVERNAME_MAXLENGTH (100) + + + +typedef struct _PVRSRV_KERNEL_MEM_INFO_ +{ + + IMG_PVOID pvLinAddrKM; + + + IMG_DEV_VIRTADDR sDevVAddr; + + + IMG_UINT32 ui32Flags; + + + IMG_UINT32 ui32AllocSize; + + + PVRSRV_MEMBLK sMemBlk; + + + IMG_PVOID pvSysBackupBuffer; + + + IMG_UINT32 ui32RefCount; + + + + struct _PVRSRV_KERNEL_SYNC_INFO_ *psKernelSyncInfo; + +} PVRSRV_KERNEL_MEM_INFO; + + +typedef struct _PVRSRV_KERNEL_SYNC_INFO_ +{ + + PVRSRV_SYNC_DATA *psSyncData; + + + IMG_DEV_VIRTADDR sWriteOpsCompleteDevVAddr; + + + IMG_DEV_VIRTADDR sReadOpsCompleteDevVAddr; + + + PVRSRV_KERNEL_MEM_INFO *psSyncDataMemInfoKM; + +} PVRSRV_KERNEL_SYNC_INFO; + +typedef struct _PVRSRV_DEVICE_SYNC_OBJECT_ +{ + + IMG_UINT32 ui32ReadOpsPendingVal; + IMG_DEV_VIRTADDR sReadOpsCompleteDevVAddr; + IMG_UINT32 ui32WriteOpsPendingVal; + IMG_DEV_VIRTADDR sWriteOpsCompleteDevVAddr; +} PVRSRV_DEVICE_SYNC_OBJECT; + +typedef struct _PVRSRV_SYNC_OBJECT +{ + PVRSRV_KERNEL_SYNC_INFO *psKernelSyncInfoKM; + IMG_UINT32 ui32WriteOpsPending; + IMG_UINT32 ui32ReadOpsPending; + +}PVRSRV_SYNC_OBJECT, *PPVRSRV_SYNC_OBJECT; + +typedef struct _PVRSRV_COMMAND +{ + IMG_UINT32 ui32CmdSize; + IMG_UINT32 ui32DevIndex; + IMG_UINT32 CommandType; + IMG_UINT32 ui32DstSyncCount; + IMG_UINT32 ui32SrcSyncCount; + PVRSRV_SYNC_OBJECT *psDstSync; + PVRSRV_SYNC_OBJECT *psSrcSync; + IMG_UINT32 ui32DataSize; + IMG_UINT32 ui32ProcessID; + IMG_VOID *pvData; +}PVRSRV_COMMAND, *PPVRSRV_COMMAND; + + +typedef struct _PVRSRV_QUEUE_INFO_ +{ + IMG_VOID *pvLinQueueKM; + IMG_VOID *pvLinQueueUM; + volatile IMG_UINT32 ui32ReadOffset; + volatile IMG_UINT32 ui32WriteOffset; + IMG_UINT32 *pui32KickerAddrKM; + IMG_UINT32 *pui32KickerAddrUM; + IMG_UINT32 ui32QueueSize; + + IMG_UINT32 ui32ProcessID; + + IMG_HANDLE hMemBlock[2]; + + struct _PVRSRV_QUEUE_INFO_ *psNextKM; +}PVRSRV_QUEUE_INFO; + +typedef PVRSRV_ERROR (*PFN_INSERT_CMD) (PVRSRV_QUEUE_INFO*, + PVRSRV_COMMAND**, + IMG_UINT32, + IMG_UINT16, + IMG_UINT32, + PVRSRV_KERNEL_SYNC_INFO*[], + IMG_UINT32, + PVRSRV_KERNEL_SYNC_INFO*[], + IMG_UINT32); +typedef PVRSRV_ERROR (*PFN_SUBMIT_CMD) (PVRSRV_QUEUE_INFO*, PVRSRV_COMMAND*, IMG_BOOL); + + +typedef struct PVRSRV_DEVICECLASS_BUFFER_TAG +{ + PFN_GET_BUFFER_ADDR pfnGetBufferAddr; + IMG_HANDLE hDevMemContext; + IMG_HANDLE hExtDevice; + IMG_HANDLE hExtBuffer; + PVRSRV_KERNEL_SYNC_INFO *psKernelSyncInfo; + +} PVRSRV_DEVICECLASS_BUFFER; + + +typedef struct PVRSRV_CLIENT_DEVICECLASS_INFO_TAG +{ + IMG_HANDLE hDeviceKM; + IMG_HANDLE hServices; +} PVRSRV_CLIENT_DEVICECLASS_INFO; + + +#ifdef INLINE_IS_PRAGMA +#pragma inline(PVRSRVGetWriteOpsPending) +#endif +static INLINE +IMG_UINT32 PVRSRVGetWriteOpsPending(PVRSRV_KERNEL_SYNC_INFO *psSyncInfo, IMG_BOOL bIsReadOp) +{ + IMG_UINT32 ui32WriteOpsPending; + + if(bIsReadOp) + { + ui32WriteOpsPending = psSyncInfo->psSyncData->ui32WriteOpsPending; + } + else + { + + + + ui32WriteOpsPending = psSyncInfo->psSyncData->ui32WriteOpsPending++; + } + + return ui32WriteOpsPending; +} + +#ifdef INLINE_IS_PRAGMA +#pragma inline(PVRSRVGetReadOpsPending) +#endif +static INLINE +IMG_UINT32 PVRSRVGetReadOpsPending(PVRSRV_KERNEL_SYNC_INFO *psSyncInfo, IMG_BOOL bIsReadOp) +{ + IMG_UINT32 ui32ReadOpsPending; + + if(bIsReadOp) + { + ui32ReadOpsPending = psSyncInfo->psSyncData->ui32ReadOpsPending++; + } + else + { + ui32ReadOpsPending = psSyncInfo->psSyncData->ui32ReadOpsPending; + } + + return ui32ReadOpsPending; +} + +IMG_IMPORT +PVRSRV_ERROR PVRSRVQueueCommand(IMG_HANDLE hQueueInfo, + PVRSRV_COMMAND *psCommand); + + + +IMG_IMPORT PVRSRV_ERROR IMG_CALLCONV +PVRSRVGetMMUContextPDDevPAddr(const PVRSRV_CONNECTION *psConnection, + IMG_HANDLE hDevMemContext, + IMG_DEV_PHYADDR *sPDDevPAddr); + +IMG_IMPORT PVRSRV_ERROR IMG_CALLCONV +PVRSRVAllocSharedSysMem(const PVRSRV_CONNECTION *psConnection, + IMG_UINT32 ui32Flags, + IMG_UINT32 ui32Size, + PVRSRV_CLIENT_MEM_INFO **ppsClientMemInfo); + +IMG_IMPORT PVRSRV_ERROR IMG_CALLCONV +PVRSRVFreeSharedSysMem(const PVRSRV_CONNECTION *psConnection, + PVRSRV_CLIENT_MEM_INFO *psClientMemInfo); + +IMG_IMPORT PVRSRV_ERROR +PVRSRVUnrefSharedSysMem(const PVRSRV_CONNECTION *psConnection, + PVRSRV_CLIENT_MEM_INFO *psClientMemInfo); + +IMG_IMPORT PVRSRV_ERROR IMG_CALLCONV +PVRSRVMapMemInfoMem(const PVRSRV_CONNECTION *psConnection, + IMG_HANDLE hKernelMemInfo, + PVRSRV_CLIENT_MEM_INFO **ppsClientMemInfo); + + +#if defined (__cplusplus) +} +#endif +#endif + diff --git a/services4/include/sgx_bridge.h b/services4/include/sgx_bridge.h new file mode 100644 index 0000000..c9b67cb --- /dev/null +++ b/services4/include/sgx_bridge.h @@ -0,0 +1,483 @@ +/********************************************************************** + * + * Copyright(c) 2008 Imagination Technologies Ltd. All rights reserved. + * + * This program is free software; you can redistribute it and/or modify it + * under the terms and conditions of the GNU General Public License, + * version 2, as published by the Free Software Foundation. + * + * This program is distributed in the hope it will be useful but, except + * as otherwise stated in writing, without any warranty; without even the + * implied warranty of merchantability or fitness for a particular purpose. + * See the GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License along with + * this program; if not, write to the Free Software Foundation, Inc., + * 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA. + * + * The full GNU General Public License is included in this distribution in + * the file called "COPYING". + * + * Contact Information: + * Imagination Technologies Ltd. + * Home Park Estate, Kings Langley, Herts, WD4 8LZ, UK + * + ******************************************************************************/ + +#if !defined(__SGX_BRIDGE_H__) +#define __SGX_BRIDGE_H__ + +#include "sgxapi_km.h" +#include "sgxinfo.h" +#include "pvr_bridge.h" + +#if defined (__cplusplus) +extern "C" { +#endif + + +#define PVRSRV_BRIDGE_SGX_CMD_BASE (PVRSRV_BRIDGE_LAST_NON_DEVICE_CMD+1) +#define PVRSRV_BRIDGE_SGX_GETCLIENTINFO PVRSRV_IOWR(PVRSRV_BRIDGE_SGX_CMD_BASE+0) +#define PVRSRV_BRIDGE_SGX_RELEASECLIENTINFO PVRSRV_IOWR(PVRSRV_BRIDGE_SGX_CMD_BASE+1) +#define PVRSRV_BRIDGE_SGX_GETINTERNALDEVINFO PVRSRV_IOWR(PVRSRV_BRIDGE_SGX_CMD_BASE+2) +#define PVRSRV_BRIDGE_SGX_DOKICK PVRSRV_IOWR(PVRSRV_BRIDGE_SGX_CMD_BASE+3) +#define PVRSRV_BRIDGE_SGX_GETPHYSPAGEADDR PVRSRV_IOWR(PVRSRV_BRIDGE_SGX_CMD_BASE+4) +#define PVRSRV_BRIDGE_SGX_READREGISTRYDWORD PVRSRV_IOWR(PVRSRV_BRIDGE_SGX_CMD_BASE+5) +#define PVRSRV_BRIDGE_SGX_SCHEDULECOMMAND PVRSRV_IOWR(PVRSRV_BRIDGE_SGX_CMD_BASE+6) + +#define PVRSRV_BRIDGE_SGX_2DQUERYBLTSCOMPLETE PVRSRV_IOWR(PVRSRV_BRIDGE_SGX_CMD_BASE+9) + +#define PVRSRV_BRIDGE_SGX_GETMMUPDADDR PVRSRV_IOWR(PVRSRV_BRIDGE_SGX_CMD_BASE+10) + +#if defined(TRANSFER_QUEUE) +#define PVRSRV_BRIDGE_SGX_SUBMITTRANSFER PVRSRV_IOWR(PVRSRV_BRIDGE_SGX_CMD_BASE+13) +#endif +#define PVRSRV_BRIDGE_SGX_GETMISCINFO PVRSRV_IOWR(PVRSRV_BRIDGE_SGX_CMD_BASE+14) +#define PVRSRV_BRIDGE_SGXINFO_FOR_SRVINIT PVRSRV_IOWR(PVRSRV_BRIDGE_SGX_CMD_BASE+15) +#define PVRSRV_BRIDGE_SGX_DEVINITPART2 PVRSRV_IOWR(PVRSRV_BRIDGE_SGX_CMD_BASE+16) + +#define PVRSRV_BRIDGE_SGX_FINDSHAREDPBDESC PVRSRV_IOWR(PVRSRV_BRIDGE_SGX_CMD_BASE+17) +#define PVRSRV_BRIDGE_SGX_UNREFSHAREDPBDESC PVRSRV_IOWR(PVRSRV_BRIDGE_SGX_CMD_BASE+18) +#define PVRSRV_BRIDGE_SGX_ADDSHAREDPBDESC PVRSRV_IOWR(PVRSRV_BRIDGE_SGX_CMD_BASE+19) +#define PVRSRV_BRIDGE_SGX_REGISTER_HW_RENDER_CONTEXT PVRSRV_IOWR(PVRSRV_BRIDGE_SGX_CMD_BASE+20) +#define PVRSRV_BRIDGE_SGX_FLUSH_HW_RENDER_TARGET PVRSRV_IOWR(PVRSRV_BRIDGE_SGX_CMD_BASE+21) +#define PVRSRV_BRIDGE_SGX_UNREGISTER_HW_RENDER_CONTEXT PVRSRV_IOWR(PVRSRV_BRIDGE_SGX_CMD_BASE+22) +#if defined(SGX_FEATURE_2D_HARDWARE) +#define PVRSRV_BRIDGE_SGX_SUBMIT2D PVRSRV_IOWR(PVRSRV_BRIDGE_SGX_CMD_BASE+23) +#define PVRSRV_BRIDGE_SGX_REGISTER_HW_2D_CONTEXT PVRSRV_IOWR(PVRSRV_BRIDGE_SGX_CMD_BASE+24) +#define PVRSRV_BRIDGE_SGX_UNREGISTER_HW_2D_CONTEXT PVRSRV_IOWR(PVRSRV_BRIDGE_SGX_CMD_BASE+25) +#endif +#define PVRSRV_BRIDGE_SGX_REGISTER_HW_TRANSFER_CONTEXT PVRSRV_IOWR(PVRSRV_BRIDGE_SGX_CMD_BASE+26) +#define PVRSRV_BRIDGE_SGX_UNREGISTER_HW_TRANSFER_CONTEXT PVRSRV_IOWR(PVRSRV_BRIDGE_SGX_CMD_BASE+27) + +#define PVRSRV_BRIDGE_SGX_SCHEDULE_PROCESS_QUEUES PVRSRV_IOWR(PVRSRV_BRIDGE_SGX_CMD_BASE+28) + +#if defined(SUPPORT_SGX_HWPERF) +#define PVRSRV_BRIDGE_SGX_READ_DIFF_COUNTERS PVRSRV_IOWR(PVRSRV_BRIDGE_SGX_CMD_BASE+29) +#define PVRSRV_BRIDGE_SGX_READ_HWPERF_CB PVRSRV_IOWR(PVRSRV_BRIDGE_SGX_CMD_BASE+30) +#endif + +#if defined(PDUMP) +#define PVRSRV_BRIDGE_SGX_PDUMP_BUFFER_ARRAY PVRSRV_IOWR(PVRSRV_BRIDGE_SGX_CMD_BASE+31) +#define PVRSRV_BRIDGE_SGX_PDUMP_3D_SIGNATURE_REGISTERS PVRSRV_IOWR(PVRSRV_BRIDGE_SGX_CMD_BASE+32) +#define PVRSRV_BRIDGE_SGX_PDUMP_COUNTER_REGISTERS PVRSRV_IOWR(PVRSRV_BRIDGE_SGX_CMD_BASE+33) +#define PVRSRV_BRIDGE_SGX_PDUMP_TA_SIGNATURE_REGISTERS PVRSRV_IOWR(PVRSRV_BRIDGE_SGX_CMD_BASE+34) +#define PVRSRV_BRIDGE_SGX_PDUMP_HWPERFCB PVRSRV_IOWR(PVRSRV_BRIDGE_SGX_CMD_BASE+35) +#endif + + + +#define PVRSRV_BRIDGE_LAST_SGX_CMD (PVRSRV_BRIDGE_SGX_CMD_BASE+35) + + +typedef struct PVRSRV_BRIDGE_IN_GETPHYSPAGEADDR +{ + IMG_UINT32 ui32BridgeFlags; + IMG_HANDLE hDevMemHeap; + IMG_DEV_VIRTADDR sDevVAddr; +}PVRSRV_BRIDGE_IN_GETPHYSPAGEADDR; + + +typedef struct PVRSRV_BRIDGE_OUT_GETPHYSPAGEADDR +{ + PVRSRV_ERROR eError; + IMG_DEV_PHYADDR DevPAddr; + IMG_CPU_PHYADDR CpuPAddr; +}PVRSRV_BRIDGE_OUT_GETPHYSPAGEADDR; + + +typedef struct PVRSRV_BRIDGE_IN_SGX_GETMMU_PDADDR_TAG +{ + IMG_UINT32 ui32BridgeFlags; + IMG_HANDLE hDevCookie; + IMG_HANDLE hDevMemContext; +}PVRSRV_BRIDGE_IN_SGX_GETMMU_PDADDR; + + +typedef struct PVRSRV_BRIDGE_OUT_SGX_GETMMU_PDADDR_TAG +{ + IMG_DEV_PHYADDR sPDDevPAddr; + PVRSRV_ERROR eError; +}PVRSRV_BRIDGE_OUT_SGX_GETMMU_PDADDR; + + +typedef struct PVRSRV_BRIDGE_IN_GETCLIENTINFO_TAG +{ + IMG_UINT32 ui32BridgeFlags; + IMG_HANDLE hDevCookie; +}PVRSRV_BRIDGE_IN_GETCLIENTINFO; + + +typedef struct PVRSRV_BRIDGE_OUT_GETINTERNALDEVINFO_TAG +{ + SGX_INTERNAL_DEVINFO sSGXInternalDevInfo; + PVRSRV_ERROR eError; +}PVRSRV_BRIDGE_OUT_GETINTERNALDEVINFO; + + +typedef struct PVRSRV_BRIDGE_IN_GETINTERNALDEVINFO_TAG +{ + IMG_UINT32 ui32BridgeFlags; + IMG_HANDLE hDevCookie; +}PVRSRV_BRIDGE_IN_GETINTERNALDEVINFO; + + +typedef struct PVRSRV_BRIDGE_OUT_GETCLIENTINFO_TAG +{ + SGX_CLIENT_INFO sClientInfo; + PVRSRV_ERROR eError; +}PVRSRV_BRIDGE_OUT_GETCLIENTINFO; + + +typedef struct PVRSRV_BRIDGE_IN_RELEASECLIENTINFO_TAG +{ + IMG_UINT32 ui32BridgeFlags; + IMG_HANDLE hDevCookie; + SGX_CLIENT_INFO sClientInfo; +}PVRSRV_BRIDGE_IN_RELEASECLIENTINFO; + + +typedef struct PVRSRV_BRIDGE_IN_ISPBREAKPOLL_TAG +{ + IMG_UINT32 ui32BridgeFlags; + IMG_HANDLE hDevCookie; +}PVRSRV_BRIDGE_IN_ISPBREAKPOLL; + + +typedef struct PVRSRV_BRIDGE_IN_DOKICK_TAG +{ + IMG_UINT32 ui32BridgeFlags; + IMG_HANDLE hDevCookie; + SGX_CCB_KICK sCCBKick; +}PVRSRV_BRIDGE_IN_DOKICK; + + +typedef struct PVRSRV_BRIDGE_IN_SGX_SCHEDULE_PROCESS_QUEUES_TAG +{ + IMG_UINT32 ui32BridgeFlags; + IMG_HANDLE hDevCookie; +}PVRSRV_BRIDGE_IN_SGX_SCHEDULE_PROCESS_QUEUES; + + +#if defined(TRANSFER_QUEUE) + +typedef struct PVRSRV_BRIDGE_IN_SUBMITTRANSFER_TAG +{ + IMG_UINT32 ui32BridgeFlags; + IMG_HANDLE hDevCookie; + PVRSRV_TRANSFER_SGX_KICK sKick; +}PVRSRV_BRIDGE_IN_SUBMITTRANSFER; + +#if defined(SGX_FEATURE_2D_HARDWARE) + +typedef struct PVRSRV_BRIDGE_IN_SUBMIT2D_TAG +{ + IMG_UINT32 ui32BridgeFlags; + IMG_HANDLE hDevCookie; + PVRSRV_2D_SGX_KICK sKick; +} PVRSRV_BRIDGE_IN_SUBMIT2D; +#endif +#endif + + +typedef struct PVRSRV_BRIDGE_IN_READREGDWORD_TAG +{ + IMG_UINT32 ui32BridgeFlags; + IMG_HANDLE hDevCookie; + IMG_PCHAR pszKey; + IMG_PCHAR pszValue; +}PVRSRV_BRIDGE_IN_READREGDWORD; + + +typedef struct PVRSRV_BRIDGE_OUT_READREGDWORD_TAG +{ + PVRSRV_ERROR eError; + IMG_UINT32 ui32Data; +}PVRSRV_BRIDGE_OUT_READREGDWORD; + + +typedef struct PVRSRV_BRIDGE_IN_SCHEDULECOMMAND_TAG +{ + IMG_UINT32 ui32BridgeFlags; + IMG_HANDLE hDevCookie; + SGXMKIF_COMMAND_TYPE eCommandType; + SGXMKIF_COMMAND *psCommandData; + +}PVRSRV_BRIDGE_IN_SCHEDULECOMMAND; + +typedef struct PVRSRV_BRIDGE_IN_SGXGETMISCINFO_TAG +{ + IMG_UINT32 ui32BridgeFlags; + IMG_HANDLE hDevCookie; + SGX_MISC_INFO *psMiscInfo; +}PVRSRV_BRIDGE_IN_SGXGETMISCINFO; + +typedef struct PVRSRV_BRIDGE_IN_SGXINFO_FOR_SRVINIT_TAG +{ + IMG_UINT32 ui32BridgeFlags; + IMG_HANDLE hDevCookie; +}PVRSRV_BRIDGE_IN_SGXINFO_FOR_SRVINIT; + +typedef struct PVRSRV_BRIDGE_OUT_SGXINFO_FOR_SRVINIT_TAG +{ + PVRSRV_ERROR eError; + SGX_BRIDGE_INFO_FOR_SRVINIT sInitInfo; +}PVRSRV_BRIDGE_OUT_SGXINFO_FOR_SRVINIT; + +typedef struct PVRSRV_BRIDGE_IN_SGXDEVINITPART2_TAG +{ + IMG_UINT32 ui32BridgeFlags; + IMG_HANDLE hDevCookie; + SGX_BRIDGE_INIT_INFO sInitInfo; +}PVRSRV_BRIDGE_IN_SGXDEVINITPART2; + + +typedef struct PVRSRV_BRIDGE_IN_2DQUERYBLTSCOMPLETE_TAG +{ + IMG_UINT32 ui32BridgeFlags; + IMG_HANDLE hDevCookie; + IMG_HANDLE hKernSyncInfo; + IMG_BOOL bWaitForComplete; +}PVRSRV_BRIDGE_IN_2DQUERYBLTSCOMPLETE; + + +#define PVRSRV_BRIDGE_SGX_SHAREDPBDESC_MAX_SUBMEMINFOS 10 + +typedef struct PVRSRV_BRIDGE_IN_SGXFINDSHAREDPBDESC_TAG +{ + IMG_UINT32 ui32BridgeFlags; + IMG_HANDLE hDevCookie; + IMG_BOOL bLockOnFailure; + IMG_UINT32 ui32TotalPBSize; +}PVRSRV_BRIDGE_IN_SGXFINDSHAREDPBDESC; + +typedef struct PVRSRV_BRIDGE_OUT_SGXFINDSHAREDPBDESC_TAG +{ + IMG_HANDLE hKernelMemInfo; + IMG_HANDLE hSharedPBDesc; + IMG_HANDLE hSharedPBDescKernelMemInfoHandle; + IMG_HANDLE hHWPBDescKernelMemInfoHandle; + IMG_HANDLE hBlockKernelMemInfoHandle; + IMG_HANDLE ahSharedPBDescSubKernelMemInfoHandles[PVRSRV_BRIDGE_SGX_SHAREDPBDESC_MAX_SUBMEMINFOS]; + IMG_UINT32 ui32SharedPBDescSubKernelMemInfoHandlesCount; + PVRSRV_ERROR eError; +}PVRSRV_BRIDGE_OUT_SGXFINDSHAREDPBDESC; + +typedef struct PVRSRV_BRIDGE_IN_SGXUNREFSHAREDPBDESC_TAG +{ + IMG_UINT32 ui32BridgeFlags; + IMG_HANDLE hSharedPBDesc; +}PVRSRV_BRIDGE_IN_SGXUNREFSHAREDPBDESC; + +typedef struct PVRSRV_BRIDGE_OUT_SGXUNREFSHAREDPBDESC_TAG +{ + PVRSRV_ERROR eError; +}PVRSRV_BRIDGE_OUT_SGXUNREFSHAREDPBDESC; + + +typedef struct PVRSRV_BRIDGE_IN_SGXADDSHAREDPBDESC_TAG +{ + IMG_UINT32 ui32BridgeFlags; + IMG_HANDLE hDevCookie; + IMG_HANDLE hSharedPBDescKernelMemInfo; + IMG_HANDLE hHWPBDescKernelMemInfo; + IMG_HANDLE hBlockKernelMemInfo; + IMG_UINT32 ui32TotalPBSize; + IMG_HANDLE *phKernelMemInfoHandles; + IMG_UINT32 ui32KernelMemInfoHandlesCount; +}PVRSRV_BRIDGE_IN_SGXADDSHAREDPBDESC; + +typedef struct PVRSRV_BRIDGE_OUT_SGXADDSHAREDPBDESC_TAG +{ + PVRSRV_ERROR eError; + IMG_HANDLE hSharedPBDesc; +}PVRSRV_BRIDGE_OUT_SGXADDSHAREDPBDESC; + + +#ifdef PDUMP +typedef struct PVRSRV_BRIDGE_IN_PDUMP_BUFFER_ARRAY_TAG +{ + IMG_UINT32 ui32BridgeFlags; + SGX_KICKTA_DUMP_BUFFER *psBufferArray; + IMG_UINT32 ui32BufferArrayLength; + IMG_BOOL bDumpPolls; +} PVRSRV_BRIDGE_IN_PDUMP_BUFFER_ARRAY; + +typedef struct PVRSRV_BRIDGE_IN_PDUMP_3D_SIGNATURE_REGISTERS_TAG +{ + IMG_UINT32 ui32BridgeFlags; + IMG_UINT32 ui32DumpFrameNum; + IMG_BOOL bLastFrame; + IMG_UINT32 *pui32Registers; + IMG_UINT32 ui32NumRegisters; +}PVRSRV_BRIDGE_IN_PDUMP_3D_SIGNATURE_REGISTERS; + +typedef struct PVRSRV_BRIDGE_IN_PDUMPCOUNTER_REGISTERS_TAG +{ + IMG_UINT32 ui32BridgeFlags; + IMG_UINT32 ui32DumpFrameNum; + IMG_BOOL bLastFrame; + IMG_UINT32 *pui32Registers; + IMG_UINT32 ui32NumRegisters; +}PVRSRV_BRIDGE_IN_PDUMP_COUNTER_REGISTERS; + +typedef struct PVRSRV_BRIDGE_IN_PDUMP_TA_SIGNATURE_REGISTERS_TAG +{ + IMG_UINT32 ui32BridgeFlags; + IMG_UINT32 ui32DumpFrameNum; + IMG_UINT32 ui32TAKickCount; + IMG_BOOL bLastFrame; + IMG_UINT32 *pui32Registers; + IMG_UINT32 ui32NumRegisters; +}PVRSRV_BRIDGE_IN_PDUMP_TA_SIGNATURE_REGISTERS; + +typedef struct PVRSRV_BRIDGE_IN_PDUMP_HWPERFCB_TAG +{ + IMG_UINT32 ui32BridgeFlags; + IMG_HANDLE hDevCookie; + IMG_CHAR szFileName[PVRSRV_PDUMP_MAX_FILENAME_SIZE]; + IMG_UINT32 ui32FileOffset; + IMG_UINT32 ui32PDumpFlags; + +}PVRSRV_BRIDGE_IN_PDUMP_HWPERFCB; + +#endif + +typedef struct PVRSRV_BRIDGE_IN_SGX_REGISTER_HW_RENDER_CONTEXT_TAG +{ + IMG_UINT32 ui32BridgeFlags; + IMG_HANDLE hDevCookie; + IMG_DEV_VIRTADDR sHWRenderContextDevVAddr; +}PVRSRV_BRIDGE_IN_SGX_REGISTER_HW_RENDER_CONTEXT; + +typedef struct PVRSRV_BRIDGE_OUT_SGX_REGISTER_HW_RENDER_CONTEXT_TAG +{ + PVRSRV_ERROR eError; + IMG_HANDLE hHWRenderContext; +}PVRSRV_BRIDGE_OUT_SGX_REGISTER_HW_RENDER_CONTEXT; + +typedef struct PVRSRV_BRIDGE_IN_SGX_UNREGISTER_HW_RENDER_CONTEXT_TAG +{ + IMG_UINT32 ui32BridgeFlags; + IMG_HANDLE hDevCookie; + IMG_HANDLE hHWRenderContext; +}PVRSRV_BRIDGE_IN_SGX_UNREGISTER_HW_RENDER_CONTEXT; + +typedef struct PVRSRV_BRIDGE_IN_SGX_REGISTER_HW_TRANSFER_CONTEXT_TAG +{ + IMG_UINT32 ui32BridgeFlags; + IMG_HANDLE hDevCookie; + IMG_DEV_VIRTADDR sHWTransferContextDevVAddr; +}PVRSRV_BRIDGE_IN_SGX_REGISTER_HW_TRANSFER_CONTEXT; + +typedef struct PVRSRV_BRIDGE_OUT_SGX_REGISTER_HW_TRANSFER_CONTEXT_TAG +{ + PVRSRV_ERROR eError; + IMG_HANDLE hHWTransferContext; +}PVRSRV_BRIDGE_OUT_SGX_REGISTER_HW_TRANSFER_CONTEXT; + +typedef struct PVRSRV_BRIDGE_IN_SGX_UNREGISTER_HW_TRANSFER_CONTEXT_TAG +{ + IMG_UINT32 ui32BridgeFlags; + IMG_HANDLE hDevCookie; + IMG_HANDLE hHWTransferContext; +}PVRSRV_BRIDGE_IN_SGX_UNREGISTER_HW_TRANSFER_CONTEXT; + +typedef struct PVRSRV_BRIDGE_IN_SGX_FLUSH_HW_RENDER_TARGET_TAG +{ + IMG_UINT32 ui32BridgeFlags; + IMG_HANDLE hDevCookie; + IMG_DEV_VIRTADDR sHWRTDataSetDevVAddr; +}PVRSRV_BRIDGE_IN_SGX_FLUSH_HW_RENDER_TARGET; + + +#if defined(SGX_FEATURE_2D_HARDWARE) +typedef struct PVRSRV_BRIDGE_IN_SGX_REGISTER_HW_2D_CONTEXT_TAG +{ + IMG_UINT32 ui32BridgeFlags; + IMG_HANDLE hDevCookie; + IMG_DEV_VIRTADDR sHW2DContextDevVAddr; +}PVRSRV_BRIDGE_IN_SGX_REGISTER_HW_2D_CONTEXT; + +typedef struct PVRSRV_BRIDGE_OUT_SGX_REGISTER_HW_2D_CONTEXT_TAG +{ + PVRSRV_ERROR eError; + IMG_HANDLE hHW2DContext; +}PVRSRV_BRIDGE_OUT_SGX_REGISTER_HW_2D_CONTEXT; + +typedef struct PVRSRV_BRIDGE_IN_SGX_UNREGISTER_HW_2D_CONTEXT_TAG +{ + IMG_UINT32 ui32BridgeFlags; + IMG_HANDLE hDevCookie; + IMG_HANDLE hHW2DContext; +}PVRSRV_BRIDGE_IN_SGX_UNREGISTER_HW_2D_CONTEXT; + +#define SGX2D_MAX_BLT_CMD_SIZ 256 +#endif + + +typedef struct PVRSRV_BRIDGE_IN_SGX_READ_DIFF_COUNTERS_TAG +{ + IMG_UINT32 ui32BridgeFlags; + IMG_HANDLE hDevCookie; + IMG_UINT32 ui32Reg; + IMG_BOOL bNew; + IMG_UINT32 ui32New; + IMG_UINT32 ui32NewReset; + IMG_UINT32 ui32CountersReg; +} PVRSRV_BRIDGE_IN_SGX_READ_DIFF_COUNTERS; + +typedef struct PVRSRV_BRIDGE_OUT_SGX_READ_DIFF_COUNTERS_TAG +{ + PVRSRV_ERROR eError; + IMG_UINT32 ui32Old; + IMG_UINT32 ui32Time; + IMG_BOOL bActive; + PVRSRV_SGXDEV_DIFF_INFO sDiffs; +} PVRSRV_BRIDGE_OUT_SGX_READ_DIFF_COUNTERS; + + +#if defined(SUPPORT_SGX_HWPERF) +typedef struct PVRSRV_BRIDGE_IN_SGX_READ_HWPERF_CB_TAG +{ + IMG_UINT32 ui32BridgeFlags; + IMG_HANDLE hDevCookie; + IMG_UINT32 ui32ArraySize; + PVRSRV_SGX_HWPERF_CB_ENTRY *psHWPerfCBData; +} PVRSRV_BRIDGE_IN_SGX_READ_HWPERF_CB; + +typedef struct PVRSRV_BRIDGE_OUT_SGX_READ_HWPERF_CB_TAG +{ + PVRSRV_ERROR eError; + IMG_UINT32 ui32DataCount; + IMG_UINT32 ui32ClockSpeed; + IMG_UINT32 ui32HostTimeStamp; +} PVRSRV_BRIDGE_OUT_SGX_READ_HWPERF_CB; +#endif + +#if defined (__cplusplus) +} +#endif + +#endif + diff --git a/services4/include/sgxinfo.h b/services4/include/sgxinfo.h new file mode 100644 index 0000000..0c7d690 --- /dev/null +++ b/services4/include/sgxinfo.h @@ -0,0 +1,475 @@ +/********************************************************************** + * + * Copyright(c) 2008 Imagination Technologies Ltd. All rights reserved. + * + * This program is free software; you can redistribute it and/or modify it + * under the terms and conditions of the GNU General Public License, + * version 2, as published by the Free Software Foundation. + * + * This program is distributed in the hope it will be useful but, except + * as otherwise stated in writing, without any warranty; without even the + * implied warranty of merchantability or fitness for a particular purpose. + * See the GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License along with + * this program; if not, write to the Free Software Foundation, Inc., + * 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA. + * + * The full GNU General Public License is included in this distribution in + * the file called "COPYING". + * + * Contact Information: + * Imagination Technologies Ltd. + * Home Park Estate, Kings Langley, Herts, WD4 8LZ, UK + * + ******************************************************************************/ + +#if !defined (__SGXINFO_H__) +#define __SGXINFO_H__ + +#include "sgxscript.h" +#include "servicesint.h" +#include "services.h" +#include "sgxapi_km.h" + +#if defined(NO_HARDWARE) && defined(SUPPORT_HW_RECOVERY) + #error "sgxinfo.h: NO_HARDWARE and SUPPORT_HW_RECOVERY cannot be defined together" +#endif + +#if defined(SGX_FEATURE_MP) + #define SGX_REG_BANK_SHIFT (12) + #define SGX_REG_BANK_SIZE (0x4000) + #define SGX_REG_BANK_BASE_INDEX (1) + #define SGX_MP_CORE_SELECT(x,i) (x + ((i + SGX_REG_BANK_BASE_INDEX) * SGX_REG_BANK_SIZE)) + #define SGX_MP_MASTER_SELECT(x) (x + ((SGX_REG_BANK_BASE_INDEX + SGX_FEATURE_MP_CORE_COUNT) * SGX_REG_BANK_SIZE)) +#else + #define SGX_MP_CORE_SELECT(x,i) (x) +#endif + +#define SGX_MAX_DEV_DATA 24 +#define SGX_MAX_INIT_MEM_HANDLES 16 + +#if defined(SGX_FEATURE_BIF_NUM_DIRLISTS) +#define SGX_BIF_DIR_LIST_INDEX_EDM (SGX_FEATURE_BIF_NUM_DIRLISTS - 1) +#else +#define SGX_BIF_DIR_LIST_INDEX_EDM (0) +#endif + +typedef struct _SGX_BRIDGE_INFO_FOR_SRVINIT +{ + IMG_DEV_PHYADDR sPDDevPAddr; + PVRSRV_HEAP_INFO asHeapInfo[PVRSRV_MAX_CLIENT_HEAPS]; +} SGX_BRIDGE_INFO_FOR_SRVINIT; + +typedef struct _SGX_BRIDGE_INIT_INFO_ { + IMG_HANDLE hKernelCCBMemInfo; + IMG_HANDLE hKernelCCBCtlMemInfo; + IMG_HANDLE hKernelCCBEventKickerMemInfo; + IMG_HANDLE hKernelSGXHostCtlMemInfo; + IMG_HANDLE hKernelSGXTA3DCtlMemInfo; + IMG_HANDLE hKernelSGXMiscMemInfo; + IMG_UINT32 ui32HostKickAddress; + IMG_UINT32 ui32GetMiscInfoAddress; +#if defined(SGX_SUPPORT_HWPROFILING) + IMG_HANDLE hKernelHWProfilingMemInfo; +#endif +#if defined(SUPPORT_SGX_HWPERF) + IMG_HANDLE hKernelHWPerfCBMemInfo; +#endif +#if defined(PVRSRV_USSE_EDM_STATUS_DEBUG) + IMG_HANDLE hKernelEDMStatusBufferMemInfo; +#endif +#if defined(SGX_FEATURE_OVERLAPPED_SPM) + IMG_HANDLE hKernelTmpRgnHeaderMemInfo; +#endif +#if defined(SGX_FEATURE_SPM_MODE_0) + IMG_HANDLE hKernelTmpDPMStateMemInfo; +#endif + + IMG_UINT32 ui32EDMTaskReg0; + IMG_UINT32 ui32EDMTaskReg1; + + IMG_UINT32 ui32ClkGateStatusReg; + IMG_UINT32 ui32ClkGateStatusMask; +#if defined(SGX_FEATURE_MP) + IMG_UINT32 ui32MasterClkGateStatusReg; + IMG_UINT32 ui32MasterClkGateStatusMask; +#endif + + IMG_UINT32 ui32CacheControl; + + IMG_UINT32 asInitDevData[SGX_MAX_DEV_DATA]; + IMG_HANDLE asInitMemHandles[SGX_MAX_INIT_MEM_HANDLES]; + + SGX_INIT_SCRIPTS sScripts; + +} SGX_BRIDGE_INIT_INFO; + +typedef struct _SGXMKIF_COMMAND_ +{ + IMG_UINT32 ui32ServiceAddress; + IMG_UINT32 ui32Data[3]; +} SGXMKIF_COMMAND; + + +typedef struct _PVRSRV_SGX_KERNEL_CCB_ +{ + SGXMKIF_COMMAND asCommands[256]; +} PVRSRV_SGX_KERNEL_CCB; + + +typedef struct _PVRSRV_SGX_CCB_CTL_ +{ + IMG_UINT32 ui32WriteOffset; + IMG_UINT32 ui32ReadOffset; +} PVRSRV_SGX_CCB_CTL; + + +#define SGX_AUXCCBFLAGS_SHARED 0x00000001 + +typedef enum _SGXMKIF_COMMAND_TYPE_ +{ + SGXMKIF_COMMAND_EDM_KICK = 0, + SGXMKIF_COMMAND_VIDEO_KICK = 1, + SGXMKIF_COMMAND_REQUEST_SGXMISCINFO = 2, + + SGXMKIF_COMMAND_FORCE_I32 = -1, + +}SGXMKIF_COMMAND_TYPE; + +#define PVRSRV_CCBFLAGS_RASTERCMD 0x1 +#define PVRSRV_CCBFLAGS_TRANSFERCMD 0x2 +#define PVRSRV_CCBFLAGS_PROCESS_QUEUESCMD 0x3 +#if defined(SGX_FEATURE_2D_HARDWARE) +#define PVRSRV_CCBFLAGS_2DCMD 0x4 +#endif +#define PVRSRV_CCBFLAGS_POWERCMD 0x5 + +#define PVRSRV_POWERCMD_POWEROFF 0x1 +#define PVRSRV_POWERCMD_IDLE 0x2 + +#define SGX_BIF_INVALIDATE_PTCACHE 0x1 +#define SGX_BIF_INVALIDATE_PDCACHE 0x2 + +typedef struct _SGXMKIF_HWDEVICE_SYNC_LIST_ +{ + IMG_DEV_VIRTADDR sAccessDevAddr; + IMG_UINT32 ui32NumSyncObjects; + + PVRSRV_DEVICE_SYNC_OBJECT asSyncData[1]; +} SGXMKIF_HWDEVICE_SYNC_LIST, *PSGXMKIF_HWDEVICE_SYNC_LIST; + +typedef struct _SGX_DEVICE_SYNC_LIST_ +{ + PSGXMKIF_HWDEVICE_SYNC_LIST psHWDeviceSyncList; + + IMG_HANDLE hKernelHWSyncListMemInfo; + PVRSRV_CLIENT_MEM_INFO *psHWDeviceSyncListClientMemInfo; + PVRSRV_CLIENT_MEM_INFO *psAccessResourceClientMemInfo; + + volatile IMG_UINT32 *pui32Lock; + + struct _SGX_DEVICE_SYNC_LIST_ *psNext; + + + IMG_UINT32 ui32NumSyncObjects; + IMG_HANDLE ahSyncHandles[1]; +} SGX_DEVICE_SYNC_LIST, *PSGX_DEVICE_SYNC_LIST; + + +typedef struct _SGX_INTERNEL_STATUS_UPDATE_ +{ + CTL_STATUS sCtlStatus; + IMG_HANDLE hKernelMemInfo; + + IMG_UINT32 ui32LastStatusUpdateDumpVal; +} SGX_INTERNEL_STATUS_UPDATE; + + +typedef struct _SGX_CCB_KICK_ +{ + SGXMKIF_COMMAND_TYPE eCommand; + SGXMKIF_COMMAND sCommand; + IMG_HANDLE hCCBKernelMemInfo; + + IMG_UINT32 ui32NumDstSyncObjects; + IMG_HANDLE hKernelHWSyncListMemInfo; +#if defined(SGX_FEATURE_RENDER_TARGET_ARRAYS) + IMG_HANDLE *pasDstSyncHandles; +#else + IMG_HANDLE sDstSyncHandle; +#endif + + IMG_UINT32 ui32NumTAStatusVals; + IMG_UINT32 ui32Num3DStatusVals; + +#if defined(SUPPORT_SGX_NEW_STATUS_VALS) + SGX_INTERNEL_STATUS_UPDATE asTAStatusUpdate[SGX_MAX_TA_STATUS_VALS]; + SGX_INTERNEL_STATUS_UPDATE as3DStatusUpdate[SGX_MAX_3D_STATUS_VALS]; +#else + IMG_HANDLE ahTAStatusSyncInfo[SGX_MAX_TA_STATUS_VALS]; + IMG_HANDLE ah3DStatusSyncInfo[SGX_MAX_3D_STATUS_VALS]; +#endif + + IMG_BOOL bFirstKickOrResume; +#if (defined(NO_HARDWARE) || defined(PDUMP)) + IMG_BOOL bTerminateOrAbort; +#endif +#if defined(SUPPORT_SGX_HWPERF) + IMG_BOOL bKickRender; +#endif + + + IMG_UINT32 ui32CCBOffset; + + + IMG_UINT32 ui32NumSrcSyncs; + IMG_HANDLE ahSrcKernelSyncInfo[SGX_MAX_SRC_SYNCS]; + + + IMG_BOOL bTADependency; + IMG_HANDLE hTA3DSyncInfo; + + IMG_HANDLE hTASyncInfo; + IMG_HANDLE h3DSyncInfo; +#if defined(PDUMP) + IMG_UINT32 ui32CCBDumpWOff; +#endif +#if defined(NO_HARDWARE) + IMG_UINT32 ui32WriteOpsPendingVal; +#endif +} SGX_CCB_KICK; + + +#define SGX_KERNEL_USE_CODE_BASE_INDEX 15 + +typedef struct _SGXMKIF_HOST_CTL_ +{ + + volatile IMG_UINT32 ui32PowerStatus; +#if defined(SUPPORT_HW_RECOVERY) + IMG_UINT32 ui32uKernelDetectedLockups; + IMG_UINT32 ui32HostDetectedLockups; + IMG_UINT32 ui32HWRecoverySampleRate; +#endif + IMG_UINT32 ui32ActivePowManSampleRate; + IMG_UINT32 ui32InterruptFlags; + IMG_UINT32 ui32InterruptClearFlags; + + IMG_UINT32 ui32ResManFlags; + IMG_DEV_VIRTADDR sResManCleanupData; + + IMG_UINT32 ui32NumActivePowerEvents; + +#if defined(SUPPORT_SGX_HWPERF) + IMG_UINT32 ui32HWPerfFlags; +#endif + +#if defined(PVRSRV_USSE_EDM_STATUS_DEBUG) + IMG_DEV_VIRTADDR sEDMStatusBuffer; +#endif + + + IMG_UINT32 ui32TimeWraps; +} SGXMKIF_HOST_CTL; + + +typedef struct _SGX_CLIENT_INFO_ +{ + IMG_UINT32 ui32ProcessID; + IMG_VOID *pvProcess; + PVRSRV_MISC_INFO sMiscInfo; + + IMG_UINT32 asDevData[SGX_MAX_DEV_DATA]; + +} SGX_CLIENT_INFO; + +typedef struct _SGX_INTERNAL_DEVINFO_ +{ + IMG_UINT32 ui32Flags; + IMG_HANDLE hHostCtlKernelMemInfoHandle; + IMG_BOOL bForcePTOff; +} SGX_INTERNAL_DEVINFO; + + +#if defined(TRANSFER_QUEUE) +#define SGXTQ_MAX_STATUS SGX_MAX_TRANSFER_STATUS_VALS + 2 + +#define SGXMKIF_TQFLAGS_NOSYNCUPDATE 0x00000001 +#define SGXMKIF_TQFLAGS_KEEPPENDING 0x00000002 +#define SGXMKIF_TQFLAGS_TATQ_SYNC 0x00000004 +#define SGXMKIF_TQFLAGS_3DTQ_SYNC 0x00000008 +#if defined(SGX_FEATURE_FAST_RENDER_CONTEXT_SWITCH) +#define SGXMKIF_TQFLAGS_CTXSWITCH 0x00000010 +#endif +#define SGXMKIF_TQFLAGS_DUMMYTRANSFER 0x00000020 + +typedef struct _SGXMKIF_CMDTA_SHARED_ +{ + IMG_UINT32 ui32NumTAStatusVals; + IMG_UINT32 ui32Num3DStatusVals; + + + IMG_UINT32 ui32TATQSyncWriteOpsPendingVal; + IMG_DEV_VIRTADDR sTATQSyncWriteOpsCompleteDevVAddr; + IMG_UINT32 ui32TATQSyncReadOpsPendingVal; + IMG_DEV_VIRTADDR sTATQSyncReadOpsCompleteDevVAddr; + + + IMG_UINT32 ui323DTQSyncWriteOpsPendingVal; + IMG_DEV_VIRTADDR s3DTQSyncWriteOpsCompleteDevVAddr; + IMG_UINT32 ui323DTQSyncReadOpsPendingVal; + IMG_DEV_VIRTADDR s3DTQSyncReadOpsCompleteDevVAddr; + + + IMG_UINT32 ui32NumSrcSyncs; + PVRSRV_DEVICE_SYNC_OBJECT asSrcSyncs[SGX_MAX_SRC_SYNCS]; + + CTL_STATUS sCtlTAStatusInfo[SGX_MAX_TA_STATUS_VALS]; + CTL_STATUS sCtl3DStatusInfo[SGX_MAX_3D_STATUS_VALS]; + + PVRSRV_DEVICE_SYNC_OBJECT sTA3DDependency; + +} SGXMKIF_CMDTA_SHARED; + +typedef struct _SGXMKIF_TRANSFERCMD_SHARED_ +{ + + + IMG_UINT32 ui32SrcReadOpPendingVal; + IMG_DEV_VIRTADDR sSrcReadOpsCompleteDevAddr; + + IMG_UINT32 ui32SrcWriteOpPendingVal; + IMG_DEV_VIRTADDR sSrcWriteOpsCompleteDevAddr; + + + + IMG_UINT32 ui32DstReadOpPendingVal; + IMG_DEV_VIRTADDR sDstReadOpsCompleteDevAddr; + + IMG_UINT32 ui32DstWriteOpPendingVal; + IMG_DEV_VIRTADDR sDstWriteOpsCompleteDevAddr; + + + IMG_UINT32 ui32TASyncWriteOpsPendingVal; + IMG_DEV_VIRTADDR sTASyncWriteOpsCompleteDevVAddr; + IMG_UINT32 ui32TASyncReadOpsPendingVal; + IMG_DEV_VIRTADDR sTASyncReadOpsCompleteDevVAddr; + + + IMG_UINT32 ui323DSyncWriteOpsPendingVal; + IMG_DEV_VIRTADDR s3DSyncWriteOpsCompleteDevVAddr; + IMG_UINT32 ui323DSyncReadOpsPendingVal; + IMG_DEV_VIRTADDR s3DSyncReadOpsCompleteDevVAddr; + + IMG_UINT32 ui32NumStatusVals; + CTL_STATUS sCtlStatusInfo[SGXTQ_MAX_STATUS]; +} SGXMKIF_TRANSFERCMD_SHARED, *PSGXMKIF_TRANSFERCMD_SHARED; + +typedef struct _PVRSRV_TRANSFER_SGX_KICK_ +{ + IMG_HANDLE hCCBMemInfo; + IMG_UINT32 ui32SharedCmdCCBOffset; + + IMG_DEV_VIRTADDR sHWTransferContextDevVAddr; + + IMG_HANDLE hTASyncInfo; + IMG_HANDLE h3DSyncInfo; + + IMG_UINT32 ui32NumSrcSync; + IMG_HANDLE ahSrcSyncInfo[SGX_MAX_TRANSFER_SYNC_OPS]; + + IMG_UINT32 ui32NumDstSync; + IMG_HANDLE ahDstSyncInfo[SGX_MAX_TRANSFER_SYNC_OPS]; + + IMG_UINT32 ui32Flags; + + IMG_UINT32 ui32PDumpFlags; +#if defined(PDUMP) + IMG_UINT32 ui32CCBDumpWOff; +#endif +} PVRSRV_TRANSFER_SGX_KICK, *PPVRSRV_TRANSFER_SGX_KICK; + +#if defined(SGX_FEATURE_2D_HARDWARE) +typedef struct _SGXMKIF_2DCMD_SHARED_ { + + IMG_UINT32 ui32NumSrcSync; + PVRSRV_DEVICE_SYNC_OBJECT sSrcSyncData[SGX_MAX_2D_SRC_SYNC_OPS]; + + + PVRSRV_DEVICE_SYNC_OBJECT sDstSyncData; + + + PVRSRV_DEVICE_SYNC_OBJECT sTASyncData; + + + PVRSRV_DEVICE_SYNC_OBJECT s3DSyncData; +} SGXMKIF_2DCMD_SHARED, *PSGXMKIF_2DCMD_SHARED; + +typedef struct _PVRSRV_2D_SGX_KICK_ +{ + IMG_HANDLE hCCBMemInfo; + IMG_UINT32 ui32SharedCmdCCBOffset; + + IMG_DEV_VIRTADDR sHW2DContextDevVAddr; + + IMG_UINT32 ui32NumSrcSync; + IMG_HANDLE ahSrcSyncInfo[SGX_MAX_2D_SRC_SYNC_OPS]; + + + IMG_HANDLE hDstSyncInfo; + + + IMG_HANDLE hTASyncInfo; + + + IMG_HANDLE h3DSyncInfo; + + IMG_UINT32 ui32PDumpFlags; +#if defined(PDUMP) + IMG_UINT32 ui32CCBDumpWOff; +#endif +} PVRSRV_2D_SGX_KICK, *PPVRSRV_2D_SGX_KICK; +#endif +#endif + +#define PVRSRV_SGX_DIFF_NUM_COUNTERS 9 + +typedef struct _PVRSRV_SGXDEV_DIFF_INFO_ +{ + IMG_UINT32 aui32Counters[PVRSRV_SGX_DIFF_NUM_COUNTERS]; + IMG_UINT32 ui32Time[2]; + IMG_UINT32 ui32Marker[2]; +} PVRSRV_SGXDEV_DIFF_INFO, *PPVRSRV_SGXDEV_DIFF_INFO; + + +#define SGXMKIF_HWPERF_CB_SIZE 0x100 + +#if defined(SUPPORT_SGX_HWPERF) +typedef struct _SGXMKIF_HWPERF_CB_ENTRY_ +{ + IMG_UINT32 ui32FrameNo; + IMG_UINT32 ui32Type; + IMG_UINT32 ui32Ordinal; + IMG_UINT32 ui32TimeWraps; + IMG_UINT32 ui32Time; + IMG_UINT32 ui32Counters[PVRSRV_SGX_HWPERF_NUM_COUNTERS]; +} SGXMKIF_HWPERF_CB_ENTRY; + +typedef struct _SGXMKIF_HWPERF_CB_ +{ + IMG_UINT32 ui32Woff; + IMG_UINT32 ui32Roff; + IMG_UINT32 ui32OrdinalGRAPHICS; + IMG_UINT32 ui32OrdinalMK_EXECUTION; + SGXMKIF_HWPERF_CB_ENTRY psHWPerfCBData[SGXMKIF_HWPERF_CB_SIZE]; +} SGXMKIF_HWPERF_CB; +#endif + +typedef struct _PVRSRV_SGX_MISCINFO_INFO +{ + IMG_UINT32 ui32MiscInfoFlags; + PVRSRV_SGX_MISCINFO_FEATURES sSGXFeatures; +} PVRSRV_SGX_MISCINFO_INFO; + +#endif diff --git a/services4/srvkm/bridged/bridged_pvr_bridge.c b/services4/srvkm/bridged/bridged_pvr_bridge.c new file mode 100644 index 0000000..0a92f26 --- /dev/null +++ b/services4/srvkm/bridged/bridged_pvr_bridge.c @@ -0,0 +1,3281 @@ +/********************************************************************** + * + * Copyright(c) 2008 Imagination Technologies Ltd. All rights reserved. + * + * This program is free software; you can redistribute it and/or modify it + * under the terms and conditions of the GNU General Public License, + * version 2, as published by the Free Software Foundation. + * + * This program is distributed in the hope it will be useful but, except + * as otherwise stated in writing, without any warranty; without even the + * implied warranty of merchantability or fitness for a particular purpose. + * See the GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License along with + * this program; if not, write to the Free Software Foundation, Inc., + * 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA. + * + * The full GNU General Public License is included in this distribution in + * the file called "COPYING". + * + * Contact Information: + * Imagination Technologies Ltd. + * Home Park Estate, Kings Langley, Herts, WD4 8LZ, UK + * + ******************************************************************************/ + + + +#include + +#include "img_defs.h" +#include "services.h" +#include "pvr_bridge_km.h" +#include "pvr_debug.h" +#include "ra.h" +#include "pvr_bridge.h" +#if defined(SUPPORT_SGX) +#include "sgx_bridge.h" +#endif +#if defined(SUPPORT_VGX) +#include "vgx_bridge.h" +#endif +#include "perproc.h" +#include "device.h" +#include "buffer_manager.h" + +#include "pdump_km.h" +#include "syscommon.h" + +#include "bridged_pvr_bridge.h" +#if defined(SUPPORT_SGX) +#include "bridged_sgx_bridge.h" +#endif +#if defined(SUPPORT_VGX) +#include "bridged_vgx_bridge.h" +#endif +#include "env_data.h" + +#if defined (__linux__) +#include "mmap.h" +#endif + +PVRSRV_BRIDGE_DISPATCH_TABLE_ENTRY g_BridgeDispatchTable[BRIDGE_DISPATCH_TABLE_ENTRY_COUNT]; + +#if defined(DEBUG_BRIDGE_KM) +PVRSRV_BRIDGE_GLOBAL_STATS g_BridgeGlobalStats; +#endif + +#if defined(PVR_SECURE_HANDLES) +static IMG_BOOL abSharedDeviceMemHeap[PVRSRV_MAX_CLIENT_HEAPS]; +static IMG_BOOL *pbSharedDeviceMemHeap = abSharedDeviceMemHeap; +#else +static IMG_BOOL *pbSharedDeviceMemHeap = (IMG_BOOL*)IMG_NULL; +#endif + + +#if defined(DEBUG_BRIDGE_KM) +PVRSRV_ERROR +CopyFromUserWrapper(PVRSRV_PER_PROCESS_DATA *pProcData, + IMG_UINT32 ui32BridgeID, + IMG_VOID *pvDest, + IMG_VOID *pvSrc, + IMG_UINT32 ui32Size) +{ + g_BridgeDispatchTable[ui32BridgeID].ui32CopyFromUserTotalBytes+=ui32Size; + g_BridgeGlobalStats.ui32TotalCopyFromUserBytes+=ui32Size; + return OSCopyFromUser(pProcData, pvDest, pvSrc, ui32Size); +} +PVRSRV_ERROR +CopyToUserWrapper(PVRSRV_PER_PROCESS_DATA *pProcData, + IMG_UINT32 ui32BridgeID, + IMG_VOID *pvDest, + IMG_VOID *pvSrc, + IMG_UINT32 ui32Size) +{ + g_BridgeDispatchTable[ui32BridgeID].ui32CopyToUserTotalBytes+=ui32Size; + g_BridgeGlobalStats.ui32TotalCopyToUserBytes+=ui32Size; + return OSCopyToUser(pProcData, pvDest, pvSrc, ui32Size); +} +#endif + + +static IMG_INT +PVRSRVEnumerateDevicesBW(IMG_UINT32 ui32BridgeID, + IMG_VOID *psBridgeIn, + PVRSRV_BRIDGE_OUT_ENUMDEVICE *psEnumDeviceOUT, + PVRSRV_PER_PROCESS_DATA *psPerProc) +{ + PVRSRV_BRIDGE_ASSERT_CMD(ui32BridgeID, PVRSRV_BRIDGE_ENUM_DEVICES); + + PVR_UNREFERENCED_PARAMETER(psPerProc); + PVR_UNREFERENCED_PARAMETER(psBridgeIn); + + psEnumDeviceOUT->eError = + PVRSRVEnumerateDevicesKM(&psEnumDeviceOUT->ui32NumDevices, + psEnumDeviceOUT->asDeviceIdentifier); + + return 0; +} + +static IMG_INT +PVRSRVAcquireDeviceDataBW(IMG_UINT32 ui32BridgeID, + PVRSRV_BRIDGE_IN_ACQUIRE_DEVICEINFO *psAcquireDevInfoIN, + PVRSRV_BRIDGE_OUT_ACQUIRE_DEVICEINFO *psAcquireDevInfoOUT, + PVRSRV_PER_PROCESS_DATA *psPerProc) +{ + IMG_HANDLE hDevCookieInt; + + PVRSRV_BRIDGE_ASSERT_CMD(ui32BridgeID, PVRSRV_BRIDGE_ACQUIRE_DEVICEINFO); + + psAcquireDevInfoOUT->eError = + PVRSRVAcquireDeviceDataKM(psAcquireDevInfoIN->uiDevIndex, + psAcquireDevInfoIN->eDeviceType, + &hDevCookieInt); + if(psAcquireDevInfoOUT->eError != PVRSRV_OK) + { + return 0; + } + + + psAcquireDevInfoOUT->eError = + PVRSRVAllocHandle(psPerProc->psHandleBase, + &psAcquireDevInfoOUT->hDevCookie, + hDevCookieInt, + PVRSRV_HANDLE_TYPE_DEV_NODE, + PVRSRV_HANDLE_ALLOC_FLAG_SHARED); + + return 0; +} + + +static IMG_INT +PVRSRVCreateDeviceMemContextBW(IMG_UINT32 ui32BridgeID, + PVRSRV_BRIDGE_IN_CREATE_DEVMEMCONTEXT *psCreateDevMemContextIN, + PVRSRV_BRIDGE_OUT_CREATE_DEVMEMCONTEXT *psCreateDevMemContextOUT, + PVRSRV_PER_PROCESS_DATA *psPerProc) +{ + IMG_HANDLE hDevCookieInt; + IMG_HANDLE hDevMemContextInt; + IMG_UINT32 i; + IMG_BOOL bCreated; + + PVRSRV_BRIDGE_ASSERT_CMD(ui32BridgeID, PVRSRV_BRIDGE_CREATE_DEVMEMCONTEXT); + + + NEW_HANDLE_BATCH_OR_ERROR(psCreateDevMemContextOUT->eError, psPerProc, PVRSRV_MAX_CLIENT_HEAPS + 1); + + psCreateDevMemContextOUT->eError = + PVRSRVLookupHandle(psPerProc->psHandleBase, &hDevCookieInt, + psCreateDevMemContextIN->hDevCookie, + PVRSRV_HANDLE_TYPE_DEV_NODE); + + if(psCreateDevMemContextOUT->eError != PVRSRV_OK) + { + return 0; + } + + psCreateDevMemContextOUT->eError = + PVRSRVCreateDeviceMemContextKM(hDevCookieInt, + psPerProc, + &hDevMemContextInt, + &psCreateDevMemContextOUT->ui32ClientHeapCount, + &psCreateDevMemContextOUT->sHeapInfo[0], + &bCreated, + pbSharedDeviceMemHeap); + + if(psCreateDevMemContextOUT->eError != PVRSRV_OK) + { + return 0; + } + + + if(bCreated) + { + PVRSRVAllocHandleNR(psPerProc->psHandleBase, + &psCreateDevMemContextOUT->hDevMemContext, + hDevMemContextInt, + PVRSRV_HANDLE_TYPE_DEV_MEM_CONTEXT, + PVRSRV_HANDLE_ALLOC_FLAG_NONE); + } + else + { + psCreateDevMemContextOUT->eError = + PVRSRVFindHandle(psPerProc->psHandleBase, + &psCreateDevMemContextOUT->hDevMemContext, + hDevMemContextInt, + PVRSRV_HANDLE_TYPE_DEV_MEM_CONTEXT); + if(psCreateDevMemContextOUT->eError != PVRSRV_OK) + { + return 0; + } + } + + for(i = 0; i < psCreateDevMemContextOUT->ui32ClientHeapCount; i++) + { + IMG_HANDLE hDevMemHeapExt; + +#if defined(PVR_SECURE_HANDLES) + if(abSharedDeviceMemHeap[i]) +#endif + { + + PVRSRVAllocHandleNR(psPerProc->psHandleBase, &hDevMemHeapExt, + psCreateDevMemContextOUT->sHeapInfo[i].hDevMemHeap, + PVRSRV_HANDLE_TYPE_DEV_MEM_HEAP, + PVRSRV_HANDLE_ALLOC_FLAG_SHARED); + } +#if defined(PVR_SECURE_HANDLES) + else + { + + if(bCreated) + { + PVRSRVAllocSubHandleNR(psPerProc->psHandleBase, &hDevMemHeapExt, + psCreateDevMemContextOUT->sHeapInfo[i].hDevMemHeap, + PVRSRV_HANDLE_TYPE_DEV_MEM_HEAP, + PVRSRV_HANDLE_ALLOC_FLAG_NONE, + psCreateDevMemContextOUT->hDevMemContext); + } + else + { + psCreateDevMemContextOUT->eError = + PVRSRVFindHandle(psPerProc->psHandleBase, &hDevMemHeapExt, + psCreateDevMemContextOUT->sHeapInfo[i].hDevMemHeap, + PVRSRV_HANDLE_TYPE_DEV_MEM_HEAP); + if(psCreateDevMemContextOUT->eError != PVRSRV_OK) + { + return 0; + } + } + } +#endif + psCreateDevMemContextOUT->sHeapInfo[i].hDevMemHeap = hDevMemHeapExt; + } + + COMMIT_HANDLE_BATCH_OR_ERROR(psCreateDevMemContextOUT->eError, psPerProc); + + return 0; +} + +static IMG_INT +PVRSRVDestroyDeviceMemContextBW(IMG_UINT32 ui32BridgeID, + PVRSRV_BRIDGE_IN_DESTROY_DEVMEMCONTEXT *psDestroyDevMemContextIN, + PVRSRV_BRIDGE_RETURN *psRetOUT, + PVRSRV_PER_PROCESS_DATA *psPerProc) +{ + IMG_HANDLE hDevCookieInt; + IMG_HANDLE hDevMemContextInt; + IMG_BOOL bDestroyed; + + PVRSRV_BRIDGE_ASSERT_CMD(ui32BridgeID, PVRSRV_BRIDGE_DESTROY_DEVMEMCONTEXT); + + psRetOUT->eError = + PVRSRVLookupHandle(psPerProc->psHandleBase, &hDevCookieInt, + psDestroyDevMemContextIN->hDevCookie, + PVRSRV_HANDLE_TYPE_DEV_NODE); + + if(psRetOUT->eError != PVRSRV_OK) + { + return 0; + } + + psRetOUT->eError = + PVRSRVLookupHandle(psPerProc->psHandleBase, &hDevMemContextInt, + psDestroyDevMemContextIN->hDevMemContext, + PVRSRV_HANDLE_TYPE_DEV_MEM_CONTEXT); + + if(psRetOUT->eError != PVRSRV_OK) + { + return 0; + } + + psRetOUT->eError = + PVRSRVDestroyDeviceMemContextKM(hDevCookieInt, hDevMemContextInt, &bDestroyed); + + if(psRetOUT->eError != PVRSRV_OK) + { + return 0; + } + + if(bDestroyed) + { + psRetOUT->eError = + PVRSRVReleaseHandle(psPerProc->psHandleBase, + psDestroyDevMemContextIN->hDevMemContext, + PVRSRV_HANDLE_TYPE_DEV_MEM_CONTEXT); + } + + return 0; +} + + +static IMG_INT +PVRSRVGetDeviceMemHeapInfoBW(IMG_UINT32 ui32BridgeID, + PVRSRV_BRIDGE_IN_GET_DEVMEM_HEAPINFO *psGetDevMemHeapInfoIN, + PVRSRV_BRIDGE_OUT_GET_DEVMEM_HEAPINFO *psGetDevMemHeapInfoOUT, + PVRSRV_PER_PROCESS_DATA *psPerProc) +{ + IMG_HANDLE hDevCookieInt; + IMG_HANDLE hDevMemContextInt; + IMG_UINT32 i; + + PVRSRV_BRIDGE_ASSERT_CMD(ui32BridgeID, PVRSRV_BRIDGE_GET_DEVMEM_HEAPINFO); + + NEW_HANDLE_BATCH_OR_ERROR(psGetDevMemHeapInfoOUT->eError, psPerProc, PVRSRV_MAX_CLIENT_HEAPS); + + psGetDevMemHeapInfoOUT->eError = + PVRSRVLookupHandle(psPerProc->psHandleBase, &hDevCookieInt, + psGetDevMemHeapInfoIN->hDevCookie, + PVRSRV_HANDLE_TYPE_DEV_NODE); + + if(psGetDevMemHeapInfoOUT->eError != PVRSRV_OK) + { + return 0; + } + + psGetDevMemHeapInfoOUT->eError = + PVRSRVLookupHandle(psPerProc->psHandleBase, &hDevMemContextInt, + psGetDevMemHeapInfoIN->hDevMemContext, + PVRSRV_HANDLE_TYPE_DEV_MEM_CONTEXT); + + if(psGetDevMemHeapInfoOUT->eError != PVRSRV_OK) + { + return 0; + } + + psGetDevMemHeapInfoOUT->eError = + PVRSRVGetDeviceMemHeapInfoKM(hDevCookieInt, + hDevMemContextInt, + &psGetDevMemHeapInfoOUT->ui32ClientHeapCount, + &psGetDevMemHeapInfoOUT->sHeapInfo[0], + pbSharedDeviceMemHeap); + + if(psGetDevMemHeapInfoOUT->eError != PVRSRV_OK) + { + return 0; + } + + for(i = 0; i < psGetDevMemHeapInfoOUT->ui32ClientHeapCount; i++) + { + IMG_HANDLE hDevMemHeapExt; + +#if defined(PVR_SECURE_HANDLES) + if(abSharedDeviceMemHeap[i]) +#endif + { + + PVRSRVAllocHandleNR(psPerProc->psHandleBase, &hDevMemHeapExt, + psGetDevMemHeapInfoOUT->sHeapInfo[i].hDevMemHeap, + PVRSRV_HANDLE_TYPE_DEV_MEM_HEAP, + PVRSRV_HANDLE_ALLOC_FLAG_SHARED); + } +#if defined(PVR_SECURE_HANDLES) + else + { + + psGetDevMemHeapInfoOUT->eError = + PVRSRVFindHandle(psPerProc->psHandleBase, &hDevMemHeapExt, + psGetDevMemHeapInfoOUT->sHeapInfo[i].hDevMemHeap, + PVRSRV_HANDLE_TYPE_DEV_MEM_HEAP); + if(psGetDevMemHeapInfoOUT->eError != PVRSRV_OK) + { + return 0; + } + } +#endif + psGetDevMemHeapInfoOUT->sHeapInfo[i].hDevMemHeap = hDevMemHeapExt; + } + + COMMIT_HANDLE_BATCH_OR_ERROR(psGetDevMemHeapInfoOUT->eError, psPerProc); + + return 0; +} + + +#if defined(OS_PVRSRV_ALLOC_DEVICE_MEM_BW) +IMG_INT +PVRSRVAllocDeviceMemBW(IMG_UINT32 ui32BridgeID, + PVRSRV_BRIDGE_IN_ALLOCDEVICEMEM *psAllocDeviceMemIN, + PVRSRV_BRIDGE_OUT_ALLOCDEVICEMEM *psAllocDeviceMemOUT, + PVRSRV_PER_PROCESS_DATA *psPerProc); +#else +static IMG_INT +PVRSRVAllocDeviceMemBW(IMG_UINT32 ui32BridgeID, + PVRSRV_BRIDGE_IN_ALLOCDEVICEMEM *psAllocDeviceMemIN, + PVRSRV_BRIDGE_OUT_ALLOCDEVICEMEM *psAllocDeviceMemOUT, + PVRSRV_PER_PROCESS_DATA *psPerProc) +{ + PVRSRV_KERNEL_MEM_INFO *psMemInfo; + IMG_HANDLE hDevCookieInt; + IMG_HANDLE hDevMemHeapInt; + + PVRSRV_BRIDGE_ASSERT_CMD(ui32BridgeID, PVRSRV_BRIDGE_ALLOC_DEVICEMEM); + + NEW_HANDLE_BATCH_OR_ERROR(psAllocDeviceMemOUT->eError, psPerProc, 2); + + psAllocDeviceMemOUT->eError = + PVRSRVLookupHandle(psPerProc->psHandleBase, &hDevCookieInt, + psAllocDeviceMemIN->hDevCookie, + PVRSRV_HANDLE_TYPE_DEV_NODE); + + if(psAllocDeviceMemOUT->eError != PVRSRV_OK) + { + return 0; + } + + psAllocDeviceMemOUT->eError = + PVRSRVLookupHandle(psPerProc->psHandleBase, &hDevMemHeapInt, + psAllocDeviceMemIN->hDevMemHeap, + PVRSRV_HANDLE_TYPE_DEV_MEM_HEAP); + + if(psAllocDeviceMemOUT->eError != PVRSRV_OK) + { + return 0; + } + + psAllocDeviceMemOUT->eError = + PVRSRVAllocDeviceMemKM(hDevCookieInt, + psPerProc, + hDevMemHeapInt, + psAllocDeviceMemIN->ui32Attribs, + psAllocDeviceMemIN->ui32Size, + psAllocDeviceMemIN->ui32Alignment, + &psMemInfo); + + if(psAllocDeviceMemOUT->eError != PVRSRV_OK) + { + return 0; + } + + OSMemSet(&psAllocDeviceMemOUT->sClientMemInfo, + 0, + sizeof(psAllocDeviceMemOUT->sClientMemInfo)); + + psAllocDeviceMemOUT->sClientMemInfo.pvLinAddrKM = + psMemInfo->pvLinAddrKM; + +#if defined (__linux__) + psAllocDeviceMemOUT->sClientMemInfo.pvLinAddr = 0; +#else + psAllocDeviceMemOUT->sClientMemInfo.pvLinAddr = psMemInfo->pvLinAddrKM; +#endif + psAllocDeviceMemOUT->sClientMemInfo.sDevVAddr = psMemInfo->sDevVAddr; + psAllocDeviceMemOUT->sClientMemInfo.ui32Flags = psMemInfo->ui32Flags; + psAllocDeviceMemOUT->sClientMemInfo.ui32AllocSize = psMemInfo->ui32AllocSize; + psAllocDeviceMemOUT->sClientMemInfo.hMappingInfo = psMemInfo->sMemBlk.hOSMemHandle; + + PVRSRVAllocHandleNR(psPerProc->psHandleBase, + &psAllocDeviceMemOUT->sClientMemInfo.hKernelMemInfo, + psMemInfo, + PVRSRV_HANDLE_TYPE_MEM_INFO, + PVRSRV_HANDLE_ALLOC_FLAG_NONE); + + if(psAllocDeviceMemIN->ui32Attribs & PVRSRV_MEM_NO_SYNCOBJ) + { + + OSMemSet(&psAllocDeviceMemOUT->sClientSyncInfo, + 0, + sizeof (PVRSRV_CLIENT_SYNC_INFO)); + psAllocDeviceMemOUT->sClientMemInfo.psClientSyncInfo = IMG_NULL; + psAllocDeviceMemOUT->psKernelSyncInfo = IMG_NULL; + } + else + { + + psAllocDeviceMemOUT->psKernelSyncInfo = psMemInfo->psKernelSyncInfo; + + psAllocDeviceMemOUT->sClientSyncInfo.psSyncData = + psMemInfo->psKernelSyncInfo->psSyncData; + psAllocDeviceMemOUT->sClientSyncInfo.sWriteOpsCompleteDevVAddr = + psMemInfo->psKernelSyncInfo->sWriteOpsCompleteDevVAddr; + psAllocDeviceMemOUT->sClientSyncInfo.sReadOpsCompleteDevVAddr = + psMemInfo->psKernelSyncInfo->sReadOpsCompleteDevVAddr; + + psAllocDeviceMemOUT->sClientSyncInfo.hMappingInfo = + psMemInfo->psKernelSyncInfo->psSyncDataMemInfoKM->sMemBlk.hOSMemHandle; + + PVRSRVAllocSubHandleNR(psPerProc->psHandleBase, + &psAllocDeviceMemOUT->sClientSyncInfo.hKernelSyncInfo, + psMemInfo->psKernelSyncInfo, + PVRSRV_HANDLE_TYPE_SYNC_INFO, + PVRSRV_HANDLE_ALLOC_FLAG_NONE, + psAllocDeviceMemOUT->sClientMemInfo.hKernelMemInfo); + + psAllocDeviceMemOUT->sClientMemInfo.psClientSyncInfo = + &psAllocDeviceMemOUT->sClientSyncInfo; + + } + + COMMIT_HANDLE_BATCH_OR_ERROR(psAllocDeviceMemOUT->eError, psPerProc); + + return 0; +} + +#endif + +static IMG_INT +PVRSRVFreeDeviceMemBW(IMG_UINT32 ui32BridgeID, + PVRSRV_BRIDGE_IN_FREEDEVICEMEM *psFreeDeviceMemIN, + PVRSRV_BRIDGE_RETURN *psRetOUT, + PVRSRV_PER_PROCESS_DATA *psPerProc) +{ + IMG_HANDLE hDevCookieInt; + IMG_VOID *pvKernelMemInfo; + PVRSRV_KERNEL_MEM_INFO *psKernelMemInfo; + + + PVRSRV_BRIDGE_ASSERT_CMD(ui32BridgeID, PVRSRV_BRIDGE_FREE_DEVICEMEM); + + psRetOUT->eError = + PVRSRVLookupHandle(psPerProc->psHandleBase, &hDevCookieInt, + psFreeDeviceMemIN->hDevCookie, + PVRSRV_HANDLE_TYPE_DEV_NODE); + + if(psRetOUT->eError != PVRSRV_OK) + { + return 0; + } + + psRetOUT->eError = + PVRSRVLookupHandle(psPerProc->psHandleBase, &pvKernelMemInfo, + psFreeDeviceMemIN->psKernelMemInfo, + PVRSRV_HANDLE_TYPE_MEM_INFO); + + if(psRetOUT->eError != PVRSRV_OK) + { + return 0; + } + + + psKernelMemInfo = (PVRSRV_KERNEL_MEM_INFO*)pvKernelMemInfo; + if (psKernelMemInfo->ui32RefCount != 1) + { + PVR_DPF((PVR_DBG_ERROR, "PVRSRVFreeDeviceMemBW: mappings are open in other processes")); + psRetOUT->eError = PVRSRV_ERROR_GENERIC; + return 0; + } + + psRetOUT->eError = + PVRSRVFreeDeviceMemKM(hDevCookieInt, pvKernelMemInfo); + + if(psRetOUT->eError != PVRSRV_OK) + { + return 0; + } + + psRetOUT->eError = + PVRSRVReleaseHandle(psPerProc->psHandleBase, + psFreeDeviceMemIN->psKernelMemInfo, + PVRSRV_HANDLE_TYPE_MEM_INFO); + + return 0; +} + + +static IMG_INT +PVRSRVExportDeviceMemBW(IMG_UINT32 ui32BridgeID, + PVRSRV_BRIDGE_IN_EXPORTDEVICEMEM *psExportDeviceMemIN, + PVRSRV_BRIDGE_OUT_EXPORTDEVICEMEM *psExportDeviceMemOUT, + PVRSRV_PER_PROCESS_DATA *psPerProc) +{ + IMG_HANDLE hDevCookieInt; + PVRSRV_KERNEL_MEM_INFO *psKernelMemInfo; + + PVRSRV_BRIDGE_ASSERT_CMD(ui32BridgeID, PVRSRV_BRIDGE_EXPORT_DEVICEMEM); + + + psExportDeviceMemOUT->eError = + PVRSRVLookupHandle(psPerProc->psHandleBase, &hDevCookieInt, + psExportDeviceMemIN->hDevCookie, + PVRSRV_HANDLE_TYPE_DEV_NODE); + + if(psExportDeviceMemOUT->eError != PVRSRV_OK) + { + PVR_DPF((PVR_DBG_ERROR, "PVRSRVExportDeviceMemBW: can't find devcookie")); + return 0; + } + + + psExportDeviceMemOUT->eError = + PVRSRVLookupHandle(psPerProc->psHandleBase, (IMG_PVOID *)&psKernelMemInfo, + psExportDeviceMemIN->psKernelMemInfo, + PVRSRV_HANDLE_TYPE_MEM_INFO); + + if(psExportDeviceMemOUT->eError != PVRSRV_OK) + { + PVR_DPF((PVR_DBG_ERROR, "PVRSRVExportDeviceMemBW: can't find kernel meminfo")); + return 0; + } + + + psExportDeviceMemOUT->eError = + PVRSRVFindHandle(KERNEL_HANDLE_BASE, + &psExportDeviceMemOUT->hMemInfo, + psKernelMemInfo, + PVRSRV_HANDLE_TYPE_MEM_INFO); + if(psExportDeviceMemOUT->eError == PVRSRV_OK) + { + + PVR_DPF((PVR_DBG_MESSAGE, "PVRSRVExportDeviceMemBW: allocation is already exported")); + return 0; + } + + + psExportDeviceMemOUT->eError = PVRSRVAllocHandle(KERNEL_HANDLE_BASE, + &psExportDeviceMemOUT->hMemInfo, + psKernelMemInfo, + PVRSRV_HANDLE_TYPE_MEM_INFO, + PVRSRV_HANDLE_ALLOC_FLAG_NONE); + if (psExportDeviceMemOUT->eError != PVRSRV_OK) + { + PVR_DPF((PVR_DBG_ERROR, "PVRSRVExportDeviceMemBW: failed to allocate handle from global handle list")); + return 0; + } + + + psKernelMemInfo->ui32Flags |= PVRSRV_MEM_EXPORTED; + + return 0; +} + + +static IMG_INT +PVRSRVMapDeviceMemoryBW(IMG_UINT32 ui32BridgeID, + PVRSRV_BRIDGE_IN_MAP_DEV_MEMORY *psMapDevMemIN, + PVRSRV_BRIDGE_OUT_MAP_DEV_MEMORY *psMapDevMemOUT, + PVRSRV_PER_PROCESS_DATA *psPerProc) +{ + PVRSRV_KERNEL_MEM_INFO *psSrcKernelMemInfo = IMG_NULL; + PVRSRV_KERNEL_MEM_INFO *psDstKernelMemInfo = IMG_NULL; + IMG_HANDLE hDstDevMemHeap = IMG_NULL; + + PVRSRV_BRIDGE_ASSERT_CMD(ui32BridgeID, PVRSRV_BRIDGE_MAP_DEV_MEMORY); + + NEW_HANDLE_BATCH_OR_ERROR(psMapDevMemOUT->eError, psPerProc, 2); + + + psMapDevMemOUT->eError = PVRSRVLookupHandle(KERNEL_HANDLE_BASE, + (IMG_VOID**)&psSrcKernelMemInfo, + psMapDevMemIN->hKernelMemInfo, + PVRSRV_HANDLE_TYPE_MEM_INFO); + if(psMapDevMemOUT->eError != PVRSRV_OK) + { + return 0; + } + + + psMapDevMemOUT->eError = PVRSRVLookupHandle(psPerProc->psHandleBase, + &hDstDevMemHeap, + psMapDevMemIN->hDstDevMemHeap, + PVRSRV_HANDLE_TYPE_DEV_MEM_HEAP); + if(psMapDevMemOUT->eError != PVRSRV_OK) + { + return 0; + } + + + psMapDevMemOUT->eError = PVRSRVMapDeviceMemoryKM(psPerProc, + psSrcKernelMemInfo, + hDstDevMemHeap, + &psDstKernelMemInfo); + if(psMapDevMemOUT->eError != PVRSRV_OK) + { + return 0; + } + + OSMemSet(&psMapDevMemOUT->sDstClientMemInfo, + 0, + sizeof(psMapDevMemOUT->sDstClientMemInfo)); + OSMemSet(&psMapDevMemOUT->sDstClientSyncInfo, + 0, + sizeof(psMapDevMemOUT->sDstClientSyncInfo)); + + psMapDevMemOUT->sDstClientMemInfo.pvLinAddrKM = + psDstKernelMemInfo->pvLinAddrKM; + + psMapDevMemOUT->sDstClientMemInfo.pvLinAddr = 0; + psMapDevMemOUT->sDstClientMemInfo.sDevVAddr = psDstKernelMemInfo->sDevVAddr; + psMapDevMemOUT->sDstClientMemInfo.ui32Flags = psDstKernelMemInfo->ui32Flags; + psMapDevMemOUT->sDstClientMemInfo.ui32AllocSize = psDstKernelMemInfo->ui32AllocSize; + psMapDevMemOUT->sDstClientMemInfo.hMappingInfo = psDstKernelMemInfo->sMemBlk.hOSMemHandle; + + + PVRSRVAllocHandleNR(psPerProc->psHandleBase, + &psMapDevMemOUT->sDstClientMemInfo.hKernelMemInfo, + psDstKernelMemInfo, + PVRSRV_HANDLE_TYPE_MEM_INFO, + PVRSRV_HANDLE_ALLOC_FLAG_NONE); + psMapDevMemOUT->sDstClientSyncInfo.hKernelSyncInfo = IMG_NULL; + psMapDevMemOUT->psDstKernelSyncInfo = IMG_NULL; + + + if(psDstKernelMemInfo->psKernelSyncInfo) + { + psMapDevMemOUT->psDstKernelSyncInfo = psDstKernelMemInfo->psKernelSyncInfo; + + psMapDevMemOUT->sDstClientSyncInfo.psSyncData = + psDstKernelMemInfo->psKernelSyncInfo->psSyncData; + psMapDevMemOUT->sDstClientSyncInfo.sWriteOpsCompleteDevVAddr = + psDstKernelMemInfo->psKernelSyncInfo->sWriteOpsCompleteDevVAddr; + psMapDevMemOUT->sDstClientSyncInfo.sReadOpsCompleteDevVAddr = + psDstKernelMemInfo->psKernelSyncInfo->sReadOpsCompleteDevVAddr; + + psMapDevMemOUT->sDstClientSyncInfo.hMappingInfo = + psDstKernelMemInfo->psKernelSyncInfo->psSyncDataMemInfoKM->sMemBlk.hOSMemHandle; + + psMapDevMemOUT->sDstClientMemInfo.psClientSyncInfo = &psMapDevMemOUT->sDstClientSyncInfo; + + PVRSRVAllocSubHandleNR(psPerProc->psHandleBase, + &psMapDevMemOUT->sDstClientSyncInfo.hKernelSyncInfo, + psDstKernelMemInfo->psKernelSyncInfo, + PVRSRV_HANDLE_TYPE_SYNC_INFO, + PVRSRV_HANDLE_ALLOC_FLAG_MULTI, + psMapDevMemOUT->sDstClientMemInfo.hKernelMemInfo); + } + + COMMIT_HANDLE_BATCH_OR_ERROR(psMapDevMemOUT->eError, psPerProc); + + return 0; +} + + +static IMG_INT +PVRSRVUnmapDeviceMemoryBW(IMG_UINT32 ui32BridgeID, + PVRSRV_BRIDGE_IN_UNMAP_DEV_MEMORY *psUnmapDevMemIN, + PVRSRV_BRIDGE_RETURN *psRetOUT, + PVRSRV_PER_PROCESS_DATA *psPerProc) +{ + PVRSRV_KERNEL_MEM_INFO *psKernelMemInfo = IMG_NULL; + + PVRSRV_BRIDGE_ASSERT_CMD(ui32BridgeID, PVRSRV_BRIDGE_UNMAP_DEV_MEMORY); + + psRetOUT->eError = PVRSRVLookupHandle(psPerProc->psHandleBase, + (IMG_VOID**)&psKernelMemInfo, + psUnmapDevMemIN->psKernelMemInfo, + PVRSRV_HANDLE_TYPE_MEM_INFO); + if(psRetOUT->eError != PVRSRV_OK) + { + return 0; + } + + psRetOUT->eError = PVRSRVUnmapDeviceMemoryKM(psKernelMemInfo); + if(psRetOUT->eError != PVRSRV_OK) + { + return 0; + } + + psRetOUT->eError = PVRSRVReleaseHandle(psPerProc->psHandleBase, + psUnmapDevMemIN->psKernelMemInfo, + PVRSRV_HANDLE_TYPE_MEM_INFO); + + return 0; +} + + + +static IMG_INT +PVRSRVMapDeviceClassMemoryBW(IMG_UINT32 ui32BridgeID, + PVRSRV_BRIDGE_IN_MAP_DEVICECLASS_MEMORY *psMapDevClassMemIN, + PVRSRV_BRIDGE_OUT_MAP_DEVICECLASS_MEMORY *psMapDevClassMemOUT, + PVRSRV_PER_PROCESS_DATA *psPerProc) +{ + PVRSRV_KERNEL_MEM_INFO *psMemInfo; + IMG_HANDLE hOSMapInfo; + IMG_HANDLE hDeviceClassBufferInt; + IMG_HANDLE hDevMemContextInt; + PVRSRV_HANDLE_TYPE eHandleType; + + PVRSRV_BRIDGE_ASSERT_CMD(ui32BridgeID, PVRSRV_BRIDGE_MAP_DEVICECLASS_MEMORY); + + NEW_HANDLE_BATCH_OR_ERROR(psMapDevClassMemOUT->eError, psPerProc, 2); + + + psMapDevClassMemOUT->eError = + PVRSRVLookupHandleAnyType(psPerProc->psHandleBase, &hDeviceClassBufferInt, + &eHandleType, + psMapDevClassMemIN->hDeviceClassBuffer); + + if(psMapDevClassMemOUT->eError != PVRSRV_OK) + { + return 0; + } + + + psMapDevClassMemOUT->eError = + PVRSRVLookupHandle(psPerProc->psHandleBase, &hDevMemContextInt, + psMapDevClassMemIN->hDevMemContext, + PVRSRV_HANDLE_TYPE_DEV_MEM_CONTEXT); + + if(psMapDevClassMemOUT->eError != PVRSRV_OK) + { + return 0; + } + + + switch(eHandleType) + { +#if defined(PVR_SECURE_HANDLES) + case PVRSRV_HANDLE_TYPE_DISP_BUFFER: + case PVRSRV_HANDLE_TYPE_BUF_BUFFER: +#else + case PVRSRV_HANDLE_TYPE_NONE: +#endif + break; + default: + psMapDevClassMemOUT->eError = PVRSRV_ERROR_GENERIC; + return 0; + } + + psMapDevClassMemOUT->eError = + PVRSRVMapDeviceClassMemoryKM(psPerProc, + hDevMemContextInt, + hDeviceClassBufferInt, + &psMemInfo, + &hOSMapInfo); + if(psMapDevClassMemOUT->eError != PVRSRV_OK) + { + return 0; + } + + OSMemSet(&psMapDevClassMemOUT->sClientMemInfo, + 0, + sizeof(psMapDevClassMemOUT->sClientMemInfo)); + OSMemSet(&psMapDevClassMemOUT->sClientSyncInfo, + 0, + sizeof(psMapDevClassMemOUT->sClientSyncInfo)); + + psMapDevClassMemOUT->sClientMemInfo.pvLinAddrKM = + psMemInfo->pvLinAddrKM; + + psMapDevClassMemOUT->sClientMemInfo.pvLinAddr = 0; + psMapDevClassMemOUT->sClientMemInfo.sDevVAddr = psMemInfo->sDevVAddr; + psMapDevClassMemOUT->sClientMemInfo.ui32Flags = psMemInfo->ui32Flags; + psMapDevClassMemOUT->sClientMemInfo.ui32AllocSize = psMemInfo->ui32AllocSize; + psMapDevClassMemOUT->sClientMemInfo.hMappingInfo = psMemInfo->sMemBlk.hOSMemHandle; + + PVRSRVAllocSubHandleNR(psPerProc->psHandleBase, + &psMapDevClassMemOUT->sClientMemInfo.hKernelMemInfo, + psMemInfo, + PVRSRV_HANDLE_TYPE_MEM_INFO, + PVRSRV_HANDLE_ALLOC_FLAG_NONE, + psMapDevClassMemIN->hDeviceClassBuffer); + + psMapDevClassMemOUT->sClientSyncInfo.hKernelSyncInfo = IMG_NULL; + psMapDevClassMemOUT->psKernelSyncInfo = IMG_NULL; + + + if(psMemInfo->psKernelSyncInfo) + { + psMapDevClassMemOUT->psKernelSyncInfo = psMemInfo->psKernelSyncInfo; + + psMapDevClassMemOUT->sClientSyncInfo.psSyncData = + psMemInfo->psKernelSyncInfo->psSyncData; + psMapDevClassMemOUT->sClientSyncInfo.sWriteOpsCompleteDevVAddr = + psMemInfo->psKernelSyncInfo->sWriteOpsCompleteDevVAddr; + psMapDevClassMemOUT->sClientSyncInfo.sReadOpsCompleteDevVAddr = + psMemInfo->psKernelSyncInfo->sReadOpsCompleteDevVAddr; + + psMapDevClassMemOUT->sClientSyncInfo.hMappingInfo = + psMemInfo->psKernelSyncInfo->psSyncDataMemInfoKM->sMemBlk.hOSMemHandle; + + psMapDevClassMemOUT->sClientMemInfo.psClientSyncInfo = &psMapDevClassMemOUT->sClientSyncInfo; + + PVRSRVAllocSubHandleNR(psPerProc->psHandleBase, + &psMapDevClassMemOUT->sClientSyncInfo.hKernelSyncInfo, + psMemInfo->psKernelSyncInfo, + PVRSRV_HANDLE_TYPE_SYNC_INFO, + PVRSRV_HANDLE_ALLOC_FLAG_MULTI, + psMapDevClassMemOUT->sClientMemInfo.hKernelMemInfo); + } + + COMMIT_HANDLE_BATCH_OR_ERROR(psMapDevClassMemOUT->eError, psPerProc); + + return 0; +} + +static IMG_INT +PVRSRVUnmapDeviceClassMemoryBW(IMG_UINT32 ui32BridgeID, + PVRSRV_BRIDGE_IN_UNMAP_DEVICECLASS_MEMORY *psUnmapDevClassMemIN, + PVRSRV_BRIDGE_RETURN *psRetOUT, + PVRSRV_PER_PROCESS_DATA *psPerProc) +{ + IMG_VOID *pvKernelMemInfo; + + PVRSRV_BRIDGE_ASSERT_CMD(ui32BridgeID, PVRSRV_BRIDGE_UNMAP_DEVICECLASS_MEMORY); + + psRetOUT->eError = + PVRSRVLookupHandle(psPerProc->psHandleBase, &pvKernelMemInfo, + psUnmapDevClassMemIN->psKernelMemInfo, + PVRSRV_HANDLE_TYPE_MEM_INFO); + if(psRetOUT->eError != PVRSRV_OK) + { + return 0; + } + + psRetOUT->eError = PVRSRVUnmapDeviceClassMemoryKM(pvKernelMemInfo); + + if(psRetOUT->eError != PVRSRV_OK) + { + return 0; + } + + psRetOUT->eError = + PVRSRVReleaseHandle(psPerProc->psHandleBase, + psUnmapDevClassMemIN->psKernelMemInfo, + PVRSRV_HANDLE_TYPE_MEM_INFO); + + return 0; +} + + +#if defined(OS_PVRSRV_WRAP_EXT_MEM_BW) +IMG_INT +PVRSRVWrapExtMemoryBW(IMG_UINT32 ui32BridgeID, + PVRSRV_BRIDGE_IN_WRAP_EXT_MEMORY *psWrapExtMemIN, + PVRSRV_BRIDGE_OUT_WRAP_EXT_MEMORY *psWrapExtMemOUT, + PVRSRV_PER_PROCESS_DATA *psPerProc); +#else +static IMG_INT +PVRSRVWrapExtMemoryBW(IMG_UINT32 ui32BridgeID, + PVRSRV_BRIDGE_IN_WRAP_EXT_MEMORY *psWrapExtMemIN, + PVRSRV_BRIDGE_OUT_WRAP_EXT_MEMORY *psWrapExtMemOUT, + PVRSRV_PER_PROCESS_DATA *psPerProc) +{ + IMG_HANDLE hDevCookieInt; + IMG_HANDLE hDevMemContextInt; + PVRSRV_KERNEL_MEM_INFO *psMemInfo; + IMG_UINT32 ui32PageTableSize = 0; + IMG_SYS_PHYADDR *psSysPAddr = IMG_NULL; + + PVRSRV_BRIDGE_ASSERT_CMD(ui32BridgeID, PVRSRV_BRIDGE_WRAP_EXT_MEMORY); + + NEW_HANDLE_BATCH_OR_ERROR(psWrapExtMemOUT->eError, psPerProc, 2); + + + psWrapExtMemOUT->eError = + PVRSRVLookupHandle(psPerProc->psHandleBase, &hDevCookieInt, + psWrapExtMemIN->hDevCookie, + PVRSRV_HANDLE_TYPE_DEV_NODE); + if(psWrapExtMemOUT->eError != PVRSRV_OK) + { + return 0; + } + + + psWrapExtMemOUT->eError = + PVRSRVLookupHandle(psPerProc->psHandleBase, &hDevMemContextInt, + psWrapExtMemIN->hDevMemContext, + PVRSRV_HANDLE_TYPE_DEV_MEM_CONTEXT); + + if(psWrapExtMemOUT->eError != PVRSRV_OK) + { + return 0; + } + + if(psWrapExtMemIN->ui32NumPageTableEntries) + { + ui32PageTableSize = psWrapExtMemIN->ui32NumPageTableEntries + * sizeof(IMG_SYS_PHYADDR); + + ASSIGN_AND_EXIT_ON_ERROR(psWrapExtMemOUT->eError, + OSAllocMem(PVRSRV_OS_PAGEABLE_HEAP, + ui32PageTableSize, + (IMG_VOID **)&psSysPAddr, 0)); + + if(CopyFromUserWrapper(psPerProc, + ui32BridgeID, + psSysPAddr, + psWrapExtMemIN->psSysPAddr, + ui32PageTableSize) != PVRSRV_OK) + { + OSFreeMem(PVRSRV_OS_PAGEABLE_HEAP, ui32PageTableSize, (IMG_VOID *)psSysPAddr, 0); + return -EFAULT; + } + } + + psWrapExtMemOUT->eError = + PVRSRVWrapExtMemoryKM(hDevCookieInt, + psPerProc, + hDevMemContextInt, + psWrapExtMemIN->ui32ByteSize, + psWrapExtMemIN->ui32PageOffset, + psWrapExtMemIN->bPhysContig, + psSysPAddr, + psWrapExtMemIN->pvLinAddr, + &psMemInfo); + if(psWrapExtMemIN->ui32NumPageTableEntries) + { + OSFreeMem(PVRSRV_OS_PAGEABLE_HEAP, + ui32PageTableSize, + (IMG_VOID *)psSysPAddr, 0); + } + if(psWrapExtMemOUT->eError != PVRSRV_OK) + { + return 0; + } + + psWrapExtMemOUT->sClientMemInfo.pvLinAddrKM = + psMemInfo->pvLinAddrKM; + + + psWrapExtMemOUT->sClientMemInfo.pvLinAddr = 0; + psWrapExtMemOUT->sClientMemInfo.sDevVAddr = psMemInfo->sDevVAddr; + psWrapExtMemOUT->sClientMemInfo.ui32Flags = psMemInfo->ui32Flags; + psWrapExtMemOUT->sClientMemInfo.ui32AllocSize = psMemInfo->ui32AllocSize; + psWrapExtMemOUT->sClientMemInfo.hMappingInfo = psMemInfo->sMemBlk.hOSMemHandle; + + PVRSRVAllocHandleNR(psPerProc->psHandleBase, + &psWrapExtMemOUT->sClientMemInfo.hKernelMemInfo, + psMemInfo, + PVRSRV_HANDLE_TYPE_MEM_INFO, + PVRSRV_HANDLE_ALLOC_FLAG_NONE); + + + psWrapExtMemOUT->sClientSyncInfo.psSyncData = + psMemInfo->psKernelSyncInfo->psSyncData; + psWrapExtMemOUT->sClientSyncInfo.sWriteOpsCompleteDevVAddr = + psMemInfo->psKernelSyncInfo->sWriteOpsCompleteDevVAddr; + psWrapExtMemOUT->sClientSyncInfo.sReadOpsCompleteDevVAddr = + psMemInfo->psKernelSyncInfo->sReadOpsCompleteDevVAddr; + + psWrapExtMemOUT->sClientSyncInfo.hMappingInfo = + psMemInfo->psKernelSyncInfo->psSyncDataMemInfoKM->sMemBlk.hOSMemHandle; + + psWrapExtMemOUT->sClientMemInfo.psClientSyncInfo = &psWrapExtMemOUT->sClientSyncInfo; + + PVRSRVAllocSubHandleNR(psPerProc->psHandleBase, + &psWrapExtMemOUT->sClientSyncInfo.hKernelSyncInfo, + (IMG_HANDLE)psMemInfo->psKernelSyncInfo, + PVRSRV_HANDLE_TYPE_SYNC_INFO, + PVRSRV_HANDLE_ALLOC_FLAG_NONE, + psWrapExtMemOUT->sClientMemInfo.hKernelMemInfo); + + COMMIT_HANDLE_BATCH_OR_ERROR(psWrapExtMemOUT->eError, psPerProc); + + return 0; +} +#endif + +static IMG_INT +PVRSRVUnwrapExtMemoryBW(IMG_UINT32 ui32BridgeID, + PVRSRV_BRIDGE_IN_UNWRAP_EXT_MEMORY *psUnwrapExtMemIN, + PVRSRV_BRIDGE_RETURN *psRetOUT, + PVRSRV_PER_PROCESS_DATA *psPerProc) +{ + IMG_VOID *pvMemInfo; + + PVRSRV_BRIDGE_ASSERT_CMD(ui32BridgeID, PVRSRV_BRIDGE_UNWRAP_EXT_MEMORY); + + psRetOUT->eError = + PVRSRVLookupHandle(psPerProc->psHandleBase, + &pvMemInfo, + psUnwrapExtMemIN->hKernelMemInfo, + PVRSRV_HANDLE_TYPE_MEM_INFO); + if(psRetOUT->eError != PVRSRV_OK) + { + return 0; + } + + psRetOUT->eError = + PVRSRVUnwrapExtMemoryKM((PVRSRV_KERNEL_MEM_INFO *)pvMemInfo); + if(psRetOUT->eError != PVRSRV_OK) + { + return 0; + } + + psRetOUT->eError = + PVRSRVReleaseHandle(psPerProc->psHandleBase, + psUnwrapExtMemIN->hKernelMemInfo, + PVRSRV_HANDLE_TYPE_MEM_INFO); + + return 0; +} + +static IMG_INT +PVRSRVGetFreeDeviceMemBW(IMG_UINT32 ui32BridgeID, + PVRSRV_BRIDGE_IN_GETFREEDEVICEMEM *psGetFreeDeviceMemIN, + PVRSRV_BRIDGE_OUT_GETFREEDEVICEMEM *psGetFreeDeviceMemOUT, + PVRSRV_PER_PROCESS_DATA *psPerProc) +{ + PVRSRV_BRIDGE_ASSERT_CMD(ui32BridgeID, PVRSRV_BRIDGE_GETFREE_DEVICEMEM); + + PVR_UNREFERENCED_PARAMETER(psPerProc); + + psGetFreeDeviceMemOUT->eError = + PVRSRVGetFreeDeviceMemKM(psGetFreeDeviceMemIN->ui32Flags, + &psGetFreeDeviceMemOUT->ui32Total, + &psGetFreeDeviceMemOUT->ui32Free, + &psGetFreeDeviceMemOUT->ui32LargestBlock); + + return 0; +} + +static IMG_INT +PVRMMapOSMemHandleToMMapDataBW(IMG_UINT32 ui32BridgeID, + PVRSRV_BRIDGE_IN_MHANDLE_TO_MMAP_DATA *psMMapDataIN, + PVRSRV_BRIDGE_OUT_MHANDLE_TO_MMAP_DATA *psMMapDataOUT, + PVRSRV_PER_PROCESS_DATA *psPerProc) +{ + PVRSRV_BRIDGE_ASSERT_CMD(ui32BridgeID, PVRSRV_BRIDGE_MHANDLE_TO_MMAP_DATA); + +#if defined (__linux__) + psMMapDataOUT->eError = + PVRMMapOSMemHandleToMMapData(psPerProc, + psMMapDataIN->hMHandle, + &psMMapDataOUT->ui32MMapOffset, + &psMMapDataOUT->ui32ByteOffset, + &psMMapDataOUT->ui32RealByteSize, + &psMMapDataOUT->ui32UserVAddr); +#else + PVR_UNREFERENCED_PARAMETER(psPerProc); + PVR_UNREFERENCED_PARAMETER(psMMapDataIN); + + psMMapDataOUT->eError = PVRSRV_ERROR_NOT_SUPPORTED; +#endif + return 0; +} + + +static IMG_INT +PVRMMapReleaseMMapDataBW(IMG_UINT32 ui32BridgeID, + PVRSRV_BRIDGE_IN_RELEASE_MMAP_DATA *psMMapDataIN, + PVRSRV_BRIDGE_OUT_RELEASE_MMAP_DATA *psMMapDataOUT, + PVRSRV_PER_PROCESS_DATA *psPerProc) +{ + PVRSRV_BRIDGE_ASSERT_CMD(ui32BridgeID, PVRSRV_BRIDGE_RELEASE_MMAP_DATA); + +#if defined (__linux__) + psMMapDataOUT->eError = + PVRMMapReleaseMMapData(psPerProc, + psMMapDataIN->hMHandle, + &psMMapDataOUT->bMUnmap, + &psMMapDataOUT->ui32RealByteSize, + &psMMapDataOUT->ui32UserVAddr); +#else + PVR_UNREFERENCED_PARAMETER(psPerProc); + PVR_UNREFERENCED_PARAMETER(psMMapDataIN); + + psMMapDataOUT->eError = PVRSRV_ERROR_NOT_SUPPORTED; +#endif + return 0; +} + + +#ifdef PDUMP +static IMG_INT +PDumpIsCaptureFrameBW(IMG_UINT32 ui32BridgeID, + IMG_VOID *psBridgeIn, + PVRSRV_BRIDGE_OUT_PDUMP_ISCAPTURING *psPDumpIsCapturingOUT, + PVRSRV_PER_PROCESS_DATA *psPerProc) +{ + PVRSRV_BRIDGE_ASSERT_CMD(ui32BridgeID, PVRSRV_BRIDGE_PDUMP_ISCAPTURING); + PVR_UNREFERENCED_PARAMETER(psBridgeIn); + PVR_UNREFERENCED_PARAMETER(psPerProc); + + psPDumpIsCapturingOUT->bIsCapturing = PDumpIsCaptureFrameKM(); + psPDumpIsCapturingOUT->eError = PVRSRV_OK; + + return 0; +} + +static IMG_INT +PDumpCommentBW(IMG_UINT32 ui32BridgeID, + PVRSRV_BRIDGE_IN_PDUMP_COMMENT *psPDumpCommentIN, + PVRSRV_BRIDGE_RETURN *psRetOUT, + PVRSRV_PER_PROCESS_DATA *psPerProc) +{ + PVRSRV_BRIDGE_ASSERT_CMD(ui32BridgeID, PVRSRV_BRIDGE_PDUMP_COMMENT); + PVR_UNREFERENCED_PARAMETER(psPerProc); + + psRetOUT->eError = PDumpCommentKM(&psPDumpCommentIN->szComment[0], + psPDumpCommentIN->ui32Flags); + return 0; +} + +static IMG_INT +PDumpSetFrameBW(IMG_UINT32 ui32BridgeID, + PVRSRV_BRIDGE_IN_PDUMP_SETFRAME *psPDumpSetFrameIN, + PVRSRV_BRIDGE_RETURN *psRetOUT, + PVRSRV_PER_PROCESS_DATA *psPerProc) +{ + PVRSRV_BRIDGE_ASSERT_CMD(ui32BridgeID, PVRSRV_BRIDGE_PDUMP_SETFRAME); + PVR_UNREFERENCED_PARAMETER(psPerProc); + + psRetOUT->eError = PDumpSetFrameKM(psPDumpSetFrameIN->ui32Frame); + + return 0; +} + +static IMG_INT +PDumpRegWithFlagsBW(IMG_UINT32 ui32BridgeID, + PVRSRV_BRIDGE_IN_PDUMP_DUMPREG *psPDumpRegDumpIN, + PVRSRV_BRIDGE_RETURN *psRetOUT, + PVRSRV_PER_PROCESS_DATA *psPerProc) +{ + PVRSRV_BRIDGE_ASSERT_CMD(ui32BridgeID, PVRSRV_BRIDGE_PDUMP_REG); + PVR_UNREFERENCED_PARAMETER(psPerProc); + + psRetOUT->eError = + PDumpRegWithFlagsKM(psPDumpRegDumpIN->sHWReg.ui32RegAddr, + psPDumpRegDumpIN->sHWReg.ui32RegVal, + psPDumpRegDumpIN->ui32Flags); + + return 0; +} + +static IMG_INT +PDumpRegPolBW(IMG_UINT32 ui32BridgeID, + PVRSRV_BRIDGE_IN_PDUMP_REGPOL *psPDumpRegPolIN, + PVRSRV_BRIDGE_RETURN *psRetOUT, + PVRSRV_PER_PROCESS_DATA *psPerProc) +{ + PVRSRV_BRIDGE_ASSERT_CMD(ui32BridgeID, PVRSRV_BRIDGE_PDUMP_REGPOL); + PVR_UNREFERENCED_PARAMETER(psPerProc); + + psRetOUT->eError = + PDumpRegPolWithFlagsKM(psPDumpRegPolIN->sHWReg.ui32RegAddr, + psPDumpRegPolIN->sHWReg.ui32RegVal, + psPDumpRegPolIN->ui32Mask, + psPDumpRegPolIN->ui32Flags); + + return 0; +} + +static IMG_INT +PDumpMemPolBW(IMG_UINT32 ui32BridgeID, + PVRSRV_BRIDGE_IN_PDUMP_MEMPOL *psPDumpMemPolIN, + PVRSRV_BRIDGE_RETURN *psRetOUT, + PVRSRV_PER_PROCESS_DATA *psPerProc) +{ + IMG_VOID *pvMemInfo; + + PVRSRV_BRIDGE_ASSERT_CMD(ui32BridgeID, PVRSRV_BRIDGE_PDUMP_MEMPOL); + + psRetOUT->eError = + PVRSRVLookupHandle(psPerProc->psHandleBase, + &pvMemInfo, + psPDumpMemPolIN->psKernelMemInfo, + PVRSRV_HANDLE_TYPE_MEM_INFO); + if(psRetOUT->eError != PVRSRV_OK) + { + return 0; + } + + psRetOUT->eError = + PDumpMemPolKM(((PVRSRV_KERNEL_MEM_INFO *)pvMemInfo), + psPDumpMemPolIN->ui32Offset, + psPDumpMemPolIN->ui32Value, + psPDumpMemPolIN->ui32Mask, + PDUMP_POLL_OPERATOR_EQUAL, + psPDumpMemPolIN->bLastFrame, + psPDumpMemPolIN->bOverwrite, + MAKEUNIQUETAG(pvMemInfo)); + + return 0; +} + +static IMG_INT +PDumpMemBW(IMG_UINT32 ui32BridgeID, + PVRSRV_BRIDGE_IN_PDUMP_DUMPMEM *psPDumpMemDumpIN, + PVRSRV_BRIDGE_RETURN *psRetOUT, + PVRSRV_PER_PROCESS_DATA *psPerProc) +{ + IMG_VOID *pvMemInfo; + + PVRSRV_BRIDGE_ASSERT_CMD(ui32BridgeID, PVRSRV_BRIDGE_PDUMP_DUMPMEM); + + psRetOUT->eError = + PVRSRVLookupHandle(psPerProc->psHandleBase, + &pvMemInfo, + psPDumpMemDumpIN->psKernelMemInfo, + PVRSRV_HANDLE_TYPE_MEM_INFO); + if(psRetOUT->eError != PVRSRV_OK) + { + return 0; + } + + psRetOUT->eError = + PDumpMemUM(psPerProc, + psPDumpMemDumpIN->pvAltLinAddr, + psPDumpMemDumpIN->pvLinAddr, + pvMemInfo, + psPDumpMemDumpIN->ui32Offset, + psPDumpMemDumpIN->ui32Bytes, + psPDumpMemDumpIN->ui32Flags, + MAKEUNIQUETAG(pvMemInfo)); + + return 0; +} + +static IMG_INT +PDumpBitmapBW(IMG_UINT32 ui32BridgeID, + PVRSRV_BRIDGE_IN_PDUMP_BITMAP *psPDumpBitmapIN, + PVRSRV_BRIDGE_RETURN *psRetOUT, + PVRSRV_PER_PROCESS_DATA *psPerProc) +{ + PVR_UNREFERENCED_PARAMETER(psPerProc); + PVR_UNREFERENCED_PARAMETER(ui32BridgeID); + + psRetOUT->eError = + PDumpBitmapKM(&psPDumpBitmapIN->szFileName[0], + psPDumpBitmapIN->ui32FileOffset, + psPDumpBitmapIN->ui32Width, + psPDumpBitmapIN->ui32Height, + psPDumpBitmapIN->ui32StrideInBytes, + psPDumpBitmapIN->sDevBaseAddr, + psPDumpBitmapIN->ui32Size, + psPDumpBitmapIN->ePixelFormat, + psPDumpBitmapIN->eMemFormat, + psPDumpBitmapIN->ui32Flags); + + return 0; +} + +static IMG_INT +PDumpReadRegBW(IMG_UINT32 ui32BridgeID, + PVRSRV_BRIDGE_IN_PDUMP_READREG *psPDumpReadRegIN, + PVRSRV_BRIDGE_RETURN *psRetOUT, + PVRSRV_PER_PROCESS_DATA *psPerProc) +{ + PVRSRV_BRIDGE_ASSERT_CMD(ui32BridgeID, PVRSRV_BRIDGE_PDUMP_DUMPREADREG); + PVR_UNREFERENCED_PARAMETER(psPerProc); + + psRetOUT->eError = + PDumpReadRegKM(&psPDumpReadRegIN->szFileName[0], + psPDumpReadRegIN->ui32FileOffset, + psPDumpReadRegIN->ui32Address, + psPDumpReadRegIN->ui32Size, + psPDumpReadRegIN->ui32Flags); + + return 0; +} + +static IMG_INT +PDumpDriverInfoBW(IMG_UINT32 ui32BridgeID, + PVRSRV_BRIDGE_IN_PDUMP_DRIVERINFO *psPDumpDriverInfoIN, + PVRSRV_BRIDGE_RETURN *psRetOUT, + PVRSRV_PER_PROCESS_DATA *psPerProc) +{ + IMG_UINT32 ui32PDumpFlags; + + PVRSRV_BRIDGE_ASSERT_CMD(ui32BridgeID, PVRSRV_BRIDGE_PDUMP_DRIVERINFO); + PVR_UNREFERENCED_PARAMETER(psPerProc); + + ui32PDumpFlags = 0; + if(psPDumpDriverInfoIN->bContinuous) + { + ui32PDumpFlags |= PDUMP_FLAGS_CONTINUOUS; + } + psRetOUT->eError = + PDumpDriverInfoKM(&psPDumpDriverInfoIN->szString[0], + ui32PDumpFlags); + + return 0; +} + +static IMG_INT +PDumpSyncDumpBW(IMG_UINT32 ui32BridgeID, + PVRSRV_BRIDGE_IN_PDUMP_DUMPSYNC *psPDumpSyncDumpIN, + PVRSRV_BRIDGE_RETURN *psRetOUT, + PVRSRV_PER_PROCESS_DATA *psPerProc) +{ + IMG_UINT32 ui32Bytes = psPDumpSyncDumpIN->ui32Bytes; + IMG_VOID *pvSyncInfo; + + PVRSRV_BRIDGE_ASSERT_CMD(ui32BridgeID, PVRSRV_BRIDGE_PDUMP_DUMPSYNC); + + psRetOUT->eError = + PVRSRVLookupHandle(psPerProc->psHandleBase, &pvSyncInfo, + psPDumpSyncDumpIN->psKernelSyncInfo, + PVRSRV_HANDLE_TYPE_SYNC_INFO); + if(psRetOUT->eError != PVRSRV_OK) + { + return 0; + } + + psRetOUT->eError = + PDumpMemUM(psPerProc, + psPDumpSyncDumpIN->pvAltLinAddr, + IMG_NULL, + ((PVRSRV_KERNEL_SYNC_INFO *)pvSyncInfo)->psSyncDataMemInfoKM, + psPDumpSyncDumpIN->ui32Offset, + ui32Bytes, + 0, + MAKEUNIQUETAG(((PVRSRV_KERNEL_SYNC_INFO *)pvSyncInfo)->psSyncDataMemInfoKM)); + + return 0; +} + +static IMG_INT +PDumpSyncPolBW(IMG_UINT32 ui32BridgeID, + PVRSRV_BRIDGE_IN_PDUMP_SYNCPOL *psPDumpSyncPolIN, + PVRSRV_BRIDGE_RETURN *psRetOUT, + PVRSRV_PER_PROCESS_DATA *psPerProc) +{ + IMG_UINT32 ui32Offset; + IMG_VOID *pvSyncInfo; + + PVRSRV_BRIDGE_ASSERT_CMD(ui32BridgeID, PVRSRV_BRIDGE_PDUMP_SYNCPOL); + + psRetOUT->eError = + PVRSRVLookupHandle(psPerProc->psHandleBase, &pvSyncInfo, + psPDumpSyncPolIN->psKernelSyncInfo, + PVRSRV_HANDLE_TYPE_SYNC_INFO); + if(psRetOUT->eError != PVRSRV_OK) + { + return 0; + } + + if(psPDumpSyncPolIN->bIsRead) + { + ui32Offset = offsetof(PVRSRV_SYNC_DATA, ui32ReadOpsComplete); + } + else + { + ui32Offset = offsetof(PVRSRV_SYNC_DATA, ui32WriteOpsComplete); + } + + psRetOUT->eError = + PDumpMemPolKM(((PVRSRV_KERNEL_SYNC_INFO *)pvSyncInfo)->psSyncDataMemInfoKM, + ui32Offset, + psPDumpSyncPolIN->ui32Value, + psPDumpSyncPolIN->ui32Mask, + PDUMP_POLL_OPERATOR_EQUAL, + IMG_FALSE, + IMG_FALSE, + MAKEUNIQUETAG(((PVRSRV_KERNEL_SYNC_INFO *)pvSyncInfo)->psSyncDataMemInfoKM)); + + return 0; +} + +static IMG_INT +PDumpPDRegBW(IMG_UINT32 ui32BridgeID, + PVRSRV_BRIDGE_IN_PDUMP_DUMPPDREG *psPDumpPDRegDumpIN, + PVRSRV_BRIDGE_RETURN *psRetOUT, + PVRSRV_PER_PROCESS_DATA *psPerProc) +{ + PVRSRV_BRIDGE_ASSERT_CMD(ui32BridgeID, PVRSRV_BRIDGE_PDUMP_PDREG); + PVR_UNREFERENCED_PARAMETER(psPerProc); + + PDumpPDReg(psPDumpPDRegDumpIN->sHWReg.ui32RegAddr, + psPDumpPDRegDumpIN->sHWReg.ui32RegVal, + PDUMP_PD_UNIQUETAG); + + psRetOUT->eError = PVRSRV_OK; + return 0; +} + +static IMG_INT +PDumpCycleCountRegReadBW(IMG_UINT32 ui32BridgeID, + PVRSRV_BRIDGE_IN_PDUMP_CYCLE_COUNT_REG_READ *psPDumpCycleCountRegReadIN, + PVRSRV_BRIDGE_RETURN *psRetOUT, + PVRSRV_PER_PROCESS_DATA *psPerProc) +{ + PVRSRV_BRIDGE_ASSERT_CMD(ui32BridgeID, PVRSRV_BRIDGE_PDUMP_CYCLE_COUNT_REG_READ); + PVR_UNREFERENCED_PARAMETER(psPerProc); + + PDumpCycleCountRegRead(psPDumpCycleCountRegReadIN->ui32RegOffset, + psPDumpCycleCountRegReadIN->bLastFrame); + + psRetOUT->eError = PVRSRV_OK; + + return 0; +} + +static IMG_INT +PDumpPDDevPAddrBW(IMG_UINT32 ui32BridgeID, + PVRSRV_BRIDGE_IN_PDUMP_DUMPPDDEVPADDR *psPDumpPDDevPAddrIN, + PVRSRV_BRIDGE_RETURN *psRetOUT, + PVRSRV_PER_PROCESS_DATA *psPerProc) +{ + IMG_VOID *pvMemInfo; + + PVRSRV_BRIDGE_ASSERT_CMD(ui32BridgeID, PVRSRV_BRIDGE_PDUMP_DUMPPDDEVPADDR); + + psRetOUT->eError = + PVRSRVLookupHandle(psPerProc->psHandleBase, &pvMemInfo, + psPDumpPDDevPAddrIN->hKernelMemInfo, + PVRSRV_HANDLE_TYPE_MEM_INFO); + if(psRetOUT->eError != PVRSRV_OK) + { + return 0; + } + + psRetOUT->eError = + PDumpPDDevPAddrKM((PVRSRV_KERNEL_MEM_INFO *)pvMemInfo, + psPDumpPDDevPAddrIN->ui32Offset, + psPDumpPDDevPAddrIN->sPDDevPAddr, + MAKEUNIQUETAG(pvMemInfo), + PDUMP_PD_UNIQUETAG); + return 0; +} + +static IMG_INT +PDumpStartInitPhaseBW(IMG_UINT32 ui32BridgeID, + IMG_VOID *psBridgeIn, + PVRSRV_BRIDGE_RETURN *psRetOUT, + PVRSRV_PER_PROCESS_DATA *psPerProc) +{ + PVRSRV_BRIDGE_ASSERT_CMD(ui32BridgeID, PVRSRV_BRIDGE_PDUMP_STARTINITPHASE); + PVR_UNREFERENCED_PARAMETER(psBridgeIn); + PVR_UNREFERENCED_PARAMETER(psPerProc); + + psRetOUT->eError = PDumpStartInitPhaseKM(); + + return 0; +} + +static IMG_INT +PDumpStopInitPhaseBW(IMG_UINT32 ui32BridgeID, + IMG_VOID *psBridgeIn, + PVRSRV_BRIDGE_RETURN *psRetOUT, + PVRSRV_PER_PROCESS_DATA *psPerProc) +{ + PVRSRV_BRIDGE_ASSERT_CMD(ui32BridgeID, PVRSRV_BRIDGE_PDUMP_STOPINITPHASE); + PVR_UNREFERENCED_PARAMETER(psBridgeIn); + PVR_UNREFERENCED_PARAMETER(psPerProc); + + psRetOUT->eError = PDumpStopInitPhaseKM(); + + return 0; +} + +#endif + + +static IMG_INT +PVRSRVGetMiscInfoBW(IMG_UINT32 ui32BridgeID, + PVRSRV_BRIDGE_IN_GET_MISC_INFO *psGetMiscInfoIN, + PVRSRV_BRIDGE_OUT_GET_MISC_INFO *psGetMiscInfoOUT, + PVRSRV_PER_PROCESS_DATA *psPerProc) +{ + PVRSRV_ERROR eError; + + PVRSRV_BRIDGE_ASSERT_CMD(ui32BridgeID, PVRSRV_BRIDGE_GET_MISC_INFO); + + OSMemCopy(&psGetMiscInfoOUT->sMiscInfo, + &psGetMiscInfoIN->sMiscInfo, + sizeof(PVRSRV_MISC_INFO)); + + if (((psGetMiscInfoIN->sMiscInfo.ui32StateRequest & PVRSRV_MISC_INFO_MEMSTATS_PRESENT) != 0) && + ((psGetMiscInfoIN->sMiscInfo.ui32StateRequest & PVRSRV_MISC_INFO_DDKVERSION_PRESENT) != 0)) + { + + psGetMiscInfoOUT->eError = PVRSRV_ERROR_INVALID_PARAMS; + return 0; + } + + if (((psGetMiscInfoIN->sMiscInfo.ui32StateRequest & PVRSRV_MISC_INFO_MEMSTATS_PRESENT) != 0) || + ((psGetMiscInfoIN->sMiscInfo.ui32StateRequest & PVRSRV_MISC_INFO_DDKVERSION_PRESENT) != 0)) + { + + ASSIGN_AND_EXIT_ON_ERROR(psGetMiscInfoOUT->eError, + OSAllocMem(PVRSRV_OS_PAGEABLE_HEAP, + psGetMiscInfoOUT->sMiscInfo.ui32MemoryStrLen, + (IMG_VOID **)&psGetMiscInfoOUT->sMiscInfo.pszMemoryStr, 0)); + + psGetMiscInfoOUT->eError = PVRSRVGetMiscInfoKM(&psGetMiscInfoOUT->sMiscInfo); + + + eError = CopyToUserWrapper(psPerProc, ui32BridgeID, + psGetMiscInfoIN->sMiscInfo.pszMemoryStr, + psGetMiscInfoOUT->sMiscInfo.pszMemoryStr, + psGetMiscInfoOUT->sMiscInfo.ui32MemoryStrLen); + + + OSFreeMem(PVRSRV_OS_PAGEABLE_HEAP, + psGetMiscInfoOUT->sMiscInfo.ui32MemoryStrLen, + (IMG_VOID *)psGetMiscInfoOUT->sMiscInfo.pszMemoryStr, 0); + + + psGetMiscInfoOUT->sMiscInfo.pszMemoryStr = psGetMiscInfoIN->sMiscInfo.pszMemoryStr; + + if(eError != PVRSRV_OK) + { + + PVR_DPF((PVR_DBG_ERROR, "PVRSRVGetMiscInfoBW Error copy to user")); + return -EFAULT; + } + } + else + { + psGetMiscInfoOUT->eError = PVRSRVGetMiscInfoKM(&psGetMiscInfoOUT->sMiscInfo); + } + + + if (psGetMiscInfoOUT->eError != PVRSRV_OK) + { + return 0; + } + + + if (psGetMiscInfoIN->sMiscInfo.ui32StateRequest & PVRSRV_MISC_INFO_GLOBALEVENTOBJECT_PRESENT) + { + psGetMiscInfoOUT->eError = PVRSRVAllocHandle(psPerProc->psHandleBase, + &psGetMiscInfoOUT->sMiscInfo.sGlobalEventObject.hOSEventKM, + psGetMiscInfoOUT->sMiscInfo.sGlobalEventObject.hOSEventKM, + PVRSRV_HANDLE_TYPE_SHARED_EVENT_OBJECT, + PVRSRV_HANDLE_ALLOC_FLAG_SHARED); + + if (psGetMiscInfoOUT->eError != PVRSRV_OK) + { + return 0; + } + } + + if (psGetMiscInfoOUT->sMiscInfo.hSOCTimerRegisterOSMemHandle) + { + + psGetMiscInfoOUT->eError = PVRSRVAllocHandle(psPerProc->psHandleBase, + &psGetMiscInfoOUT->sMiscInfo.hSOCTimerRegisterOSMemHandle, + psGetMiscInfoOUT->sMiscInfo.hSOCTimerRegisterOSMemHandle, + PVRSRV_HANDLE_TYPE_SOC_TIMER, + PVRSRV_HANDLE_ALLOC_FLAG_SHARED); + + if (psGetMiscInfoOUT->eError != PVRSRV_OK) + { + return 0; + } + } + + return 0; +} + +static IMG_INT +PVRSRVConnectBW(IMG_UINT32 ui32BridgeID, + IMG_VOID *psBridgeIn, + PVRSRV_BRIDGE_OUT_CONNECT_SERVICES *psConnectServicesOUT, + PVRSRV_PER_PROCESS_DATA *psPerProc) +{ + PVR_UNREFERENCED_PARAMETER(psBridgeIn); + + PVRSRV_BRIDGE_ASSERT_CMD(ui32BridgeID, PVRSRV_BRIDGE_CONNECT_SERVICES); + + psConnectServicesOUT->hKernelServices = psPerProc->hPerProcData; + psConnectServicesOUT->eError = PVRSRV_OK; + +#if defined(PDUMP) + + { + SYS_DATA *psSysData; + SysAcquireData(&psSysData); + psSysData->bPowerUpPDumped = IMG_FALSE; + } +#endif + + return 0; +} + +static IMG_INT +PVRSRVDisconnectBW(IMG_UINT32 ui32BridgeID, + IMG_VOID *psBridgeIn, + PVRSRV_BRIDGE_RETURN *psRetOUT, + PVRSRV_PER_PROCESS_DATA *psPerProc) +{ + PVR_UNREFERENCED_PARAMETER(psPerProc); + PVR_UNREFERENCED_PARAMETER(psBridgeIn); + + PVRSRV_BRIDGE_ASSERT_CMD(ui32BridgeID, PVRSRV_BRIDGE_DISCONNECT_SERVICES); + + + psRetOUT->eError = PVRSRV_OK; + + return 0; +} + +static IMG_INT +PVRSRVEnumerateDCBW(IMG_UINT32 ui32BridgeID, + PVRSRV_BRIDGE_IN_ENUMCLASS *psEnumDispClassIN, + PVRSRV_BRIDGE_OUT_ENUMCLASS *psEnumDispClassOUT, + PVRSRV_PER_PROCESS_DATA *psPerProc) +{ + PVR_UNREFERENCED_PARAMETER(psPerProc); + + PVRSRV_BRIDGE_ASSERT_CMD(ui32BridgeID, PVRSRV_BRIDGE_ENUM_CLASS); + + psEnumDispClassOUT->eError = + PVRSRVEnumerateDCKM(psEnumDispClassIN->sDeviceClass, + &psEnumDispClassOUT->ui32NumDevices, + &psEnumDispClassOUT->ui32DevID[0]); + + return 0; +} + +static IMG_INT +PVRSRVOpenDCDeviceBW(IMG_UINT32 ui32BridgeID, + PVRSRV_BRIDGE_IN_OPEN_DISPCLASS_DEVICE *psOpenDispClassDeviceIN, + PVRSRV_BRIDGE_OUT_OPEN_DISPCLASS_DEVICE *psOpenDispClassDeviceOUT, + PVRSRV_PER_PROCESS_DATA *psPerProc) +{ + IMG_HANDLE hDevCookieInt; + IMG_HANDLE hDispClassInfoInt; + + PVRSRV_BRIDGE_ASSERT_CMD(ui32BridgeID, PVRSRV_BRIDGE_OPEN_DISPCLASS_DEVICE); + + NEW_HANDLE_BATCH_OR_ERROR(psOpenDispClassDeviceOUT->eError, psPerProc, 1); + + psOpenDispClassDeviceOUT->eError = + PVRSRVLookupHandle(psPerProc->psHandleBase, + &hDevCookieInt, + psOpenDispClassDeviceIN->hDevCookie, + PVRSRV_HANDLE_TYPE_DEV_NODE); + if(psOpenDispClassDeviceOUT->eError != PVRSRV_OK) + { + return 0; + } + + psOpenDispClassDeviceOUT->eError = + PVRSRVOpenDCDeviceKM(psPerProc, + psOpenDispClassDeviceIN->ui32DeviceID, + hDevCookieInt, + &hDispClassInfoInt); + + if(psOpenDispClassDeviceOUT->eError != PVRSRV_OK) + { + return 0; + } + + PVRSRVAllocHandleNR(psPerProc->psHandleBase, + &psOpenDispClassDeviceOUT->hDeviceKM, + hDispClassInfoInt, + PVRSRV_HANDLE_TYPE_DISP_INFO, + PVRSRV_HANDLE_ALLOC_FLAG_NONE); + COMMIT_HANDLE_BATCH_OR_ERROR(psOpenDispClassDeviceOUT->eError, psPerProc); + + return 0; +} + +static IMG_INT +PVRSRVCloseDCDeviceBW(IMG_UINT32 ui32BridgeID, + PVRSRV_BRIDGE_IN_CLOSE_DISPCLASS_DEVICE *psCloseDispClassDeviceIN, + PVRSRV_BRIDGE_RETURN *psRetOUT, + PVRSRV_PER_PROCESS_DATA *psPerProc) +{ + IMG_VOID *pvDispClassInfoInt; + + PVRSRV_BRIDGE_ASSERT_CMD(ui32BridgeID, PVRSRV_BRIDGE_CLOSE_DISPCLASS_DEVICE); + + psRetOUT->eError = + PVRSRVLookupHandle(psPerProc->psHandleBase, + &pvDispClassInfoInt, + psCloseDispClassDeviceIN->hDeviceKM, + PVRSRV_HANDLE_TYPE_DISP_INFO); + + if(psRetOUT->eError != PVRSRV_OK) + { + return 0; + } + + psRetOUT->eError = PVRSRVCloseDCDeviceKM(pvDispClassInfoInt, IMG_FALSE); + if(psRetOUT->eError != PVRSRV_OK) + { + return 0; + } + + psRetOUT->eError = + PVRSRVReleaseHandle(psPerProc->psHandleBase, + psCloseDispClassDeviceIN->hDeviceKM, + PVRSRV_HANDLE_TYPE_DISP_INFO); + return 0; +} + +static IMG_INT +PVRSRVEnumDCFormatsBW(IMG_UINT32 ui32BridgeID, + PVRSRV_BRIDGE_IN_ENUM_DISPCLASS_FORMATS *psEnumDispClassFormatsIN, + PVRSRV_BRIDGE_OUT_ENUM_DISPCLASS_FORMATS *psEnumDispClassFormatsOUT, + PVRSRV_PER_PROCESS_DATA *psPerProc) +{ + IMG_VOID *pvDispClassInfoInt; + + PVRSRV_BRIDGE_ASSERT_CMD(ui32BridgeID, PVRSRV_BRIDGE_ENUM_DISPCLASS_FORMATS); + + psEnumDispClassFormatsOUT->eError = + PVRSRVLookupHandle(psPerProc->psHandleBase, + &pvDispClassInfoInt, + psEnumDispClassFormatsIN->hDeviceKM, + PVRSRV_HANDLE_TYPE_DISP_INFO); + if(psEnumDispClassFormatsOUT->eError != PVRSRV_OK) + { + return 0; + } + + psEnumDispClassFormatsOUT->eError = + PVRSRVEnumDCFormatsKM(pvDispClassInfoInt, + &psEnumDispClassFormatsOUT->ui32Count, + psEnumDispClassFormatsOUT->asFormat); + + return 0; +} + +static IMG_INT +PVRSRVEnumDCDimsBW(IMG_UINT32 ui32BridgeID, + PVRSRV_BRIDGE_IN_ENUM_DISPCLASS_DIMS *psEnumDispClassDimsIN, + PVRSRV_BRIDGE_OUT_ENUM_DISPCLASS_DIMS *psEnumDispClassDimsOUT, + PVRSRV_PER_PROCESS_DATA *psPerProc) +{ + IMG_VOID *pvDispClassInfoInt; + + PVRSRV_BRIDGE_ASSERT_CMD(ui32BridgeID, PVRSRV_BRIDGE_ENUM_DISPCLASS_DIMS); + + psEnumDispClassDimsOUT->eError = + PVRSRVLookupHandle(psPerProc->psHandleBase, + &pvDispClassInfoInt, + psEnumDispClassDimsIN->hDeviceKM, + PVRSRV_HANDLE_TYPE_DISP_INFO); + + if(psEnumDispClassDimsOUT->eError != PVRSRV_OK) + { + return 0; + } + + psEnumDispClassDimsOUT->eError = + PVRSRVEnumDCDimsKM(pvDispClassInfoInt, + &psEnumDispClassDimsIN->sFormat, + &psEnumDispClassDimsOUT->ui32Count, + psEnumDispClassDimsOUT->asDim); + + return 0; +} + +static IMG_INT +PVRSRVGetDCSystemBufferBW(IMG_UINT32 ui32BridgeID, + PVRSRV_BRIDGE_IN_GET_DISPCLASS_SYSBUFFER *psGetDispClassSysBufferIN, + PVRSRV_BRIDGE_OUT_GET_DISPCLASS_SYSBUFFER *psGetDispClassSysBufferOUT, + PVRSRV_PER_PROCESS_DATA *psPerProc) +{ + IMG_HANDLE hBufferInt; + IMG_VOID *pvDispClassInfoInt; + + PVRSRV_BRIDGE_ASSERT_CMD(ui32BridgeID, PVRSRV_BRIDGE_GET_DISPCLASS_SYSBUFFER); + + NEW_HANDLE_BATCH_OR_ERROR(psGetDispClassSysBufferOUT->eError, psPerProc, 1); + + psGetDispClassSysBufferOUT->eError = + PVRSRVLookupHandle(psPerProc->psHandleBase, + &pvDispClassInfoInt, + psGetDispClassSysBufferIN->hDeviceKM, + PVRSRV_HANDLE_TYPE_DISP_INFO); + if(psGetDispClassSysBufferOUT->eError != PVRSRV_OK) + { + return 0; + } + + psGetDispClassSysBufferOUT->eError = + PVRSRVGetDCSystemBufferKM(pvDispClassInfoInt, + &hBufferInt); + + if(psGetDispClassSysBufferOUT->eError != PVRSRV_OK) + { + return 0; + } + + PVRSRVAllocSubHandleNR(psPerProc->psHandleBase, + &psGetDispClassSysBufferOUT->hBuffer, + hBufferInt, + PVRSRV_HANDLE_TYPE_DISP_BUFFER, + (PVRSRV_HANDLE_ALLOC_FLAG)(PVRSRV_HANDLE_ALLOC_FLAG_PRIVATE | PVRSRV_HANDLE_ALLOC_FLAG_SHARED), + psGetDispClassSysBufferIN->hDeviceKM); + + COMMIT_HANDLE_BATCH_OR_ERROR(psGetDispClassSysBufferOUT->eError, psPerProc); + + return 0; +} + +static IMG_INT +PVRSRVGetDCInfoBW(IMG_UINT32 ui32BridgeID, + PVRSRV_BRIDGE_IN_GET_DISPCLASS_INFO *psGetDispClassInfoIN, + PVRSRV_BRIDGE_OUT_GET_DISPCLASS_INFO *psGetDispClassInfoOUT, + PVRSRV_PER_PROCESS_DATA *psPerProc) +{ + IMG_VOID *pvDispClassInfo; + + PVRSRV_BRIDGE_ASSERT_CMD(ui32BridgeID, PVRSRV_BRIDGE_GET_DISPCLASS_INFO); + + psGetDispClassInfoOUT->eError = + PVRSRVLookupHandle(psPerProc->psHandleBase, + &pvDispClassInfo, + psGetDispClassInfoIN->hDeviceKM, + PVRSRV_HANDLE_TYPE_DISP_INFO); + if(psGetDispClassInfoOUT->eError != PVRSRV_OK) + { + return 0; + } + + psGetDispClassInfoOUT->eError = + PVRSRVGetDCInfoKM(pvDispClassInfo, + &psGetDispClassInfoOUT->sDisplayInfo); + + return 0; +} + +static IMG_INT +PVRSRVCreateDCSwapChainBW(IMG_UINT32 ui32BridgeID, + PVRSRV_BRIDGE_IN_CREATE_DISPCLASS_SWAPCHAIN *psCreateDispClassSwapChainIN, + PVRSRV_BRIDGE_OUT_CREATE_DISPCLASS_SWAPCHAIN *psCreateDispClassSwapChainOUT, + PVRSRV_PER_PROCESS_DATA *psPerProc) +{ + IMG_VOID *pvDispClassInfo; + IMG_HANDLE hSwapChainInt; + + PVRSRV_BRIDGE_ASSERT_CMD(ui32BridgeID, PVRSRV_BRIDGE_CREATE_DISPCLASS_SWAPCHAIN); + + NEW_HANDLE_BATCH_OR_ERROR(psCreateDispClassSwapChainOUT->eError, psPerProc, 1); + + psCreateDispClassSwapChainOUT->eError = + PVRSRVLookupHandle(psPerProc->psHandleBase, + &pvDispClassInfo, + psCreateDispClassSwapChainIN->hDeviceKM, + PVRSRV_HANDLE_TYPE_DISP_INFO); + + if(psCreateDispClassSwapChainOUT->eError != PVRSRV_OK) + { + return 0; + } + + psCreateDispClassSwapChainOUT->eError = + PVRSRVCreateDCSwapChainKM(psPerProc, pvDispClassInfo, + psCreateDispClassSwapChainIN->ui32Flags, + &psCreateDispClassSwapChainIN->sDstSurfAttrib, + &psCreateDispClassSwapChainIN->sSrcSurfAttrib, + psCreateDispClassSwapChainIN->ui32BufferCount, + psCreateDispClassSwapChainIN->ui32OEMFlags, + &hSwapChainInt, + &psCreateDispClassSwapChainOUT->ui32SwapChainID); + + if(psCreateDispClassSwapChainOUT->eError != PVRSRV_OK) + { + return 0; + } + + PVRSRVAllocSubHandleNR(psPerProc->psHandleBase, + &psCreateDispClassSwapChainOUT->hSwapChain, + hSwapChainInt, + PVRSRV_HANDLE_TYPE_DISP_SWAP_CHAIN, + PVRSRV_HANDLE_ALLOC_FLAG_NONE, + psCreateDispClassSwapChainIN->hDeviceKM); + + COMMIT_HANDLE_BATCH_OR_ERROR(psCreateDispClassSwapChainOUT->eError, psPerProc); + + return 0; +} + +static IMG_INT +PVRSRVDestroyDCSwapChainBW(IMG_UINT32 ui32BridgeID, + PVRSRV_BRIDGE_IN_DESTROY_DISPCLASS_SWAPCHAIN *psDestroyDispClassSwapChainIN, + PVRSRV_BRIDGE_RETURN *psRetOUT, + PVRSRV_PER_PROCESS_DATA *psPerProc) +{ + IMG_VOID *pvSwapChain; + + PVRSRV_BRIDGE_ASSERT_CMD(ui32BridgeID, PVRSRV_BRIDGE_DESTROY_DISPCLASS_SWAPCHAIN); + + psRetOUT->eError = + PVRSRVLookupHandle(psPerProc->psHandleBase, &pvSwapChain, + psDestroyDispClassSwapChainIN->hSwapChain, + PVRSRV_HANDLE_TYPE_DISP_SWAP_CHAIN); + if(psRetOUT->eError != PVRSRV_OK) + { + return 0; + } + + psRetOUT->eError = + PVRSRVDestroyDCSwapChainKM(pvSwapChain); + + if(psRetOUT->eError != PVRSRV_OK) + { + return 0; + } + + psRetOUT->eError = + PVRSRVReleaseHandle(psPerProc->psHandleBase, + psDestroyDispClassSwapChainIN->hSwapChain, + PVRSRV_HANDLE_TYPE_DISP_SWAP_CHAIN); + + return 0; +} + +static IMG_INT +PVRSRVSetDCDstRectBW(IMG_UINT32 ui32BridgeID, + PVRSRV_BRIDGE_IN_SET_DISPCLASS_RECT *psSetDispClassDstRectIN, + PVRSRV_BRIDGE_RETURN *psRetOUT, + PVRSRV_PER_PROCESS_DATA *psPerProc) +{ + IMG_VOID *pvDispClassInfo; + IMG_VOID *pvSwapChain; + + PVRSRV_BRIDGE_ASSERT_CMD(ui32BridgeID, PVRSRV_BRIDGE_SET_DISPCLASS_DSTRECT); + + psRetOUT->eError = + PVRSRVLookupHandle(psPerProc->psHandleBase, + &pvDispClassInfo, + psSetDispClassDstRectIN->hDeviceKM, + PVRSRV_HANDLE_TYPE_DISP_INFO); + if(psRetOUT->eError != PVRSRV_OK) + { + return 0; + } + + psRetOUT->eError = + PVRSRVLookupHandle(psPerProc->psHandleBase, + &pvSwapChain, + psSetDispClassDstRectIN->hSwapChain, + PVRSRV_HANDLE_TYPE_DISP_SWAP_CHAIN); + + if(psRetOUT->eError != PVRSRV_OK) + { + return 0; + } + + psRetOUT->eError = + PVRSRVSetDCDstRectKM(pvDispClassInfo, + pvSwapChain, + &psSetDispClassDstRectIN->sRect); + + return 0; +} + +static IMG_INT +PVRSRVSetDCSrcRectBW(IMG_UINT32 ui32BridgeID, + PVRSRV_BRIDGE_IN_SET_DISPCLASS_RECT *psSetDispClassSrcRectIN, + PVRSRV_BRIDGE_RETURN *psRetOUT, + PVRSRV_PER_PROCESS_DATA *psPerProc) +{ + IMG_VOID *pvDispClassInfo; + IMG_VOID *pvSwapChain; + + PVRSRV_BRIDGE_ASSERT_CMD(ui32BridgeID, PVRSRV_BRIDGE_SET_DISPCLASS_SRCRECT); + + psRetOUT->eError = + PVRSRVLookupHandle(psPerProc->psHandleBase, + &pvDispClassInfo, + psSetDispClassSrcRectIN->hDeviceKM, + PVRSRV_HANDLE_TYPE_DISP_INFO); + if(psRetOUT->eError != PVRSRV_OK) + { + return 0; + } + + psRetOUT->eError = + PVRSRVLookupHandle(psPerProc->psHandleBase, + &pvSwapChain, + psSetDispClassSrcRectIN->hSwapChain, + PVRSRV_HANDLE_TYPE_DISP_SWAP_CHAIN); + if(psRetOUT->eError != PVRSRV_OK) + { + return 0; + } + + psRetOUT->eError = + PVRSRVSetDCSrcRectKM(pvDispClassInfo, + pvSwapChain, + &psSetDispClassSrcRectIN->sRect); + + return 0; +} + +static IMG_INT +PVRSRVSetDCDstColourKeyBW(IMG_UINT32 ui32BridgeID, + PVRSRV_BRIDGE_IN_SET_DISPCLASS_COLOURKEY *psSetDispClassColKeyIN, + PVRSRV_BRIDGE_RETURN *psRetOUT, + PVRSRV_PER_PROCESS_DATA *psPerProc) +{ + IMG_VOID *pvDispClassInfo; + IMG_VOID *pvSwapChain; + + PVRSRV_BRIDGE_ASSERT_CMD(ui32BridgeID, PVRSRV_BRIDGE_SET_DISPCLASS_DSTCOLOURKEY); + + psRetOUT->eError = + PVRSRVLookupHandle(psPerProc->psHandleBase, + &pvDispClassInfo, + psSetDispClassColKeyIN->hDeviceKM, + PVRSRV_HANDLE_TYPE_DISP_INFO); + if(psRetOUT->eError != PVRSRV_OK) + { + return 0; + } + + psRetOUT->eError = + PVRSRVLookupHandle(psPerProc->psHandleBase, + &pvSwapChain, + psSetDispClassColKeyIN->hSwapChain, + PVRSRV_HANDLE_TYPE_DISP_SWAP_CHAIN); + if(psRetOUT->eError != PVRSRV_OK) + { + return 0; + } + + psRetOUT->eError = + PVRSRVSetDCDstColourKeyKM(pvDispClassInfo, + pvSwapChain, + psSetDispClassColKeyIN->ui32CKColour); + + return 0; +} + +static IMG_INT +PVRSRVSetDCSrcColourKeyBW(IMG_UINT32 ui32BridgeID, + PVRSRV_BRIDGE_IN_SET_DISPCLASS_COLOURKEY *psSetDispClassColKeyIN, + PVRSRV_BRIDGE_RETURN *psRetOUT, + PVRSRV_PER_PROCESS_DATA *psPerProc) +{ + IMG_VOID *pvDispClassInfo; + IMG_VOID *pvSwapChain; + + PVRSRV_BRIDGE_ASSERT_CMD(ui32BridgeID, PVRSRV_BRIDGE_SET_DISPCLASS_SRCCOLOURKEY); + + psRetOUT->eError = + PVRSRVLookupHandle(psPerProc->psHandleBase, + &pvDispClassInfo, + psSetDispClassColKeyIN->hDeviceKM, + PVRSRV_HANDLE_TYPE_DISP_INFO); + if(psRetOUT->eError != PVRSRV_OK) + { + return 0; + } + + psRetOUT->eError = + PVRSRVLookupHandle(psPerProc->psHandleBase, + &pvSwapChain, + psSetDispClassColKeyIN->hSwapChain, + PVRSRV_HANDLE_TYPE_DISP_SWAP_CHAIN); + if(psRetOUT->eError != PVRSRV_OK) + { + return 0; + } + + psRetOUT->eError = + PVRSRVSetDCSrcColourKeyKM(pvDispClassInfo, + pvSwapChain, + psSetDispClassColKeyIN->ui32CKColour); + + return 0; +} + +static IMG_INT +PVRSRVGetDCBuffersBW(IMG_UINT32 ui32BridgeID, + PVRSRV_BRIDGE_IN_GET_DISPCLASS_BUFFERS *psGetDispClassBuffersIN, + PVRSRV_BRIDGE_OUT_GET_DISPCLASS_BUFFERS *psGetDispClassBuffersOUT, + PVRSRV_PER_PROCESS_DATA *psPerProc) +{ + IMG_VOID *pvDispClassInfo; + IMG_VOID *pvSwapChain; + IMG_UINT32 i; + + PVRSRV_BRIDGE_ASSERT_CMD(ui32BridgeID, PVRSRV_BRIDGE_GET_DISPCLASS_BUFFERS); + + NEW_HANDLE_BATCH_OR_ERROR(psGetDispClassBuffersOUT->eError, psPerProc, PVRSRV_MAX_DC_SWAPCHAIN_BUFFERS); + + psGetDispClassBuffersOUT->eError = + PVRSRVLookupHandle(psPerProc->psHandleBase, + &pvDispClassInfo, + psGetDispClassBuffersIN->hDeviceKM, + PVRSRV_HANDLE_TYPE_DISP_INFO); + if(psGetDispClassBuffersOUT->eError != PVRSRV_OK) + { + return 0; + } + + psGetDispClassBuffersOUT->eError = + PVRSRVLookupHandle(psPerProc->psHandleBase, + &pvSwapChain, + psGetDispClassBuffersIN->hSwapChain, + PVRSRV_HANDLE_TYPE_DISP_SWAP_CHAIN); + if(psGetDispClassBuffersOUT->eError != PVRSRV_OK) + { + return 0; + } + + psGetDispClassBuffersOUT->eError = + PVRSRVGetDCBuffersKM(pvDispClassInfo, + pvSwapChain, + &psGetDispClassBuffersOUT->ui32BufferCount, + psGetDispClassBuffersOUT->ahBuffer); + if (psGetDispClassBuffersOUT->eError != PVRSRV_OK) + { + return 0; + } + + PVR_ASSERT(psGetDispClassBuffersOUT->ui32BufferCount <= PVRSRV_MAX_DC_SWAPCHAIN_BUFFERS); + + for(i = 0; i < psGetDispClassBuffersOUT->ui32BufferCount; i++) + { + IMG_HANDLE hBufferExt; + + PVRSRVAllocSubHandleNR(psPerProc->psHandleBase, + &hBufferExt, + psGetDispClassBuffersOUT->ahBuffer[i], + PVRSRV_HANDLE_TYPE_DISP_BUFFER, + (PVRSRV_HANDLE_ALLOC_FLAG)(PVRSRV_HANDLE_ALLOC_FLAG_PRIVATE | PVRSRV_HANDLE_ALLOC_FLAG_SHARED), + psGetDispClassBuffersIN->hSwapChain); + + psGetDispClassBuffersOUT->ahBuffer[i] = hBufferExt; + } + + COMMIT_HANDLE_BATCH_OR_ERROR(psGetDispClassBuffersOUT->eError, psPerProc); + + return 0; +} + +static IMG_INT +PVRSRVSwapToDCBufferBW(IMG_UINT32 ui32BridgeID, + PVRSRV_BRIDGE_IN_SWAP_DISPCLASS_TO_BUFFER *psSwapDispClassBufferIN, + PVRSRV_BRIDGE_RETURN *psRetOUT, + PVRSRV_PER_PROCESS_DATA *psPerProc) +{ + IMG_VOID *pvDispClassInfo; + IMG_VOID *pvSwapChainBuf; + + PVRSRV_BRIDGE_ASSERT_CMD(ui32BridgeID, PVRSRV_BRIDGE_SWAP_DISPCLASS_TO_BUFFER); + + psRetOUT->eError = + PVRSRVLookupHandle(psPerProc->psHandleBase, + &pvDispClassInfo, + psSwapDispClassBufferIN->hDeviceKM, + PVRSRV_HANDLE_TYPE_DISP_INFO); + if(psRetOUT->eError != PVRSRV_OK) + { + return 0; + } + + psRetOUT->eError = + PVRSRVLookupSubHandle(psPerProc->psHandleBase, + &pvSwapChainBuf, + psSwapDispClassBufferIN->hBuffer, + PVRSRV_HANDLE_TYPE_DISP_BUFFER, + psSwapDispClassBufferIN->hDeviceKM); + if(psRetOUT->eError != PVRSRV_OK) + { + return 0; + } + + psRetOUT->eError = + PVRSRVSwapToDCBufferKM(pvDispClassInfo, + pvSwapChainBuf, + psSwapDispClassBufferIN->ui32SwapInterval, + psSwapDispClassBufferIN->hPrivateTag, + psSwapDispClassBufferIN->ui32ClipRectCount, + psSwapDispClassBufferIN->sClipRect); + + return 0; +} + +static IMG_INT +PVRSRVSwapToDCSystemBW(IMG_UINT32 ui32BridgeID, + PVRSRV_BRIDGE_IN_SWAP_DISPCLASS_TO_SYSTEM *psSwapDispClassSystemIN, + PVRSRV_BRIDGE_RETURN *psRetOUT, + PVRSRV_PER_PROCESS_DATA *psPerProc) +{ + IMG_VOID *pvDispClassInfo; + IMG_VOID *pvSwapChain; + + PVRSRV_BRIDGE_ASSERT_CMD(ui32BridgeID, PVRSRV_BRIDGE_SWAP_DISPCLASS_TO_SYSTEM); + + psRetOUT->eError = + PVRSRVLookupHandle(psPerProc->psHandleBase, + &pvDispClassInfo, + psSwapDispClassSystemIN->hDeviceKM, + PVRSRV_HANDLE_TYPE_DISP_INFO); + if(psRetOUT->eError != PVRSRV_OK) + { + return 0; + } + + psRetOUT->eError = + PVRSRVLookupSubHandle(psPerProc->psHandleBase, + &pvSwapChain, + psSwapDispClassSystemIN->hSwapChain, + PVRSRV_HANDLE_TYPE_DISP_SWAP_CHAIN, + psSwapDispClassSystemIN->hDeviceKM); + if(psRetOUT->eError != PVRSRV_OK) + { + return 0; + } + psRetOUT->eError = + PVRSRVSwapToDCSystemKM(pvDispClassInfo, + pvSwapChain); + + return 0; +} + +static IMG_INT +PVRSRVOpenBCDeviceBW(IMG_UINT32 ui32BridgeID, + PVRSRV_BRIDGE_IN_OPEN_BUFFERCLASS_DEVICE *psOpenBufferClassDeviceIN, + PVRSRV_BRIDGE_OUT_OPEN_BUFFERCLASS_DEVICE *psOpenBufferClassDeviceOUT, + PVRSRV_PER_PROCESS_DATA *psPerProc) +{ + IMG_HANDLE hDevCookieInt; + IMG_HANDLE hBufClassInfo; + + PVRSRV_BRIDGE_ASSERT_CMD(ui32BridgeID, PVRSRV_BRIDGE_OPEN_BUFFERCLASS_DEVICE); + + NEW_HANDLE_BATCH_OR_ERROR(psOpenBufferClassDeviceOUT->eError, psPerProc, 1); + + psOpenBufferClassDeviceOUT->eError = + PVRSRVLookupHandle(psPerProc->psHandleBase, + &hDevCookieInt, + psOpenBufferClassDeviceIN->hDevCookie, + PVRSRV_HANDLE_TYPE_DEV_NODE); + if(psOpenBufferClassDeviceOUT->eError != PVRSRV_OK) + { + return 0; + } + + psOpenBufferClassDeviceOUT->eError = + PVRSRVOpenBCDeviceKM(psPerProc, + psOpenBufferClassDeviceIN->ui32DeviceID, + hDevCookieInt, + &hBufClassInfo); + if(psOpenBufferClassDeviceOUT->eError != PVRSRV_OK) + { + return 0; + } + + PVRSRVAllocHandleNR(psPerProc->psHandleBase, + &psOpenBufferClassDeviceOUT->hDeviceKM, + hBufClassInfo, + PVRSRV_HANDLE_TYPE_BUF_INFO, + PVRSRV_HANDLE_ALLOC_FLAG_NONE); + + COMMIT_HANDLE_BATCH_OR_ERROR(psOpenBufferClassDeviceOUT->eError, psPerProc); + + return 0; +} + +static IMG_INT +PVRSRVCloseBCDeviceBW(IMG_UINT32 ui32BridgeID, + PVRSRV_BRIDGE_IN_CLOSE_BUFFERCLASS_DEVICE *psCloseBufferClassDeviceIN, + PVRSRV_BRIDGE_RETURN *psRetOUT, + PVRSRV_PER_PROCESS_DATA *psPerProc) +{ + IMG_VOID *pvBufClassInfo; + + PVRSRV_BRIDGE_ASSERT_CMD(ui32BridgeID, PVRSRV_BRIDGE_CLOSE_BUFFERCLASS_DEVICE); + + psRetOUT->eError = + PVRSRVLookupHandle(psPerProc->psHandleBase, + &pvBufClassInfo, + psCloseBufferClassDeviceIN->hDeviceKM, + PVRSRV_HANDLE_TYPE_BUF_INFO); + if(psRetOUT->eError != PVRSRV_OK) + { + return 0; + } + + psRetOUT->eError = + PVRSRVCloseBCDeviceKM(pvBufClassInfo, IMG_FALSE); + + if(psRetOUT->eError != PVRSRV_OK) + { + return 0; + } + + psRetOUT->eError = PVRSRVReleaseHandle(psPerProc->psHandleBase, + psCloseBufferClassDeviceIN->hDeviceKM, + PVRSRV_HANDLE_TYPE_BUF_INFO); + + return 0; +} + +static IMG_INT +PVRSRVGetBCInfoBW(IMG_UINT32 ui32BridgeID, + PVRSRV_BRIDGE_IN_GET_BUFFERCLASS_INFO *psGetBufferClassInfoIN, + PVRSRV_BRIDGE_OUT_GET_BUFFERCLASS_INFO *psGetBufferClassInfoOUT, + PVRSRV_PER_PROCESS_DATA *psPerProc) +{ + IMG_VOID *pvBufClassInfo; + + PVRSRV_BRIDGE_ASSERT_CMD(ui32BridgeID, PVRSRV_BRIDGE_GET_BUFFERCLASS_INFO); + + psGetBufferClassInfoOUT->eError = + PVRSRVLookupHandle(psPerProc->psHandleBase, + &pvBufClassInfo, + psGetBufferClassInfoIN->hDeviceKM, + PVRSRV_HANDLE_TYPE_BUF_INFO); + if(psGetBufferClassInfoOUT->eError != PVRSRV_OK) + { + return 0; + } + + psGetBufferClassInfoOUT->eError = + PVRSRVGetBCInfoKM(pvBufClassInfo, + &psGetBufferClassInfoOUT->sBufferInfo); + return 0; +} + +static IMG_INT +PVRSRVGetBCBufferBW(IMG_UINT32 ui32BridgeID, + PVRSRV_BRIDGE_IN_GET_BUFFERCLASS_BUFFER *psGetBufferClassBufferIN, + PVRSRV_BRIDGE_OUT_GET_BUFFERCLASS_BUFFER *psGetBufferClassBufferOUT, + PVRSRV_PER_PROCESS_DATA *psPerProc) +{ + IMG_VOID *pvBufClassInfo; + IMG_HANDLE hBufferInt; + + PVRSRV_BRIDGE_ASSERT_CMD(ui32BridgeID, PVRSRV_BRIDGE_GET_BUFFERCLASS_BUFFER); + + NEW_HANDLE_BATCH_OR_ERROR(psGetBufferClassBufferOUT->eError, psPerProc, 1); + + psGetBufferClassBufferOUT->eError = + PVRSRVLookupHandle(psPerProc->psHandleBase, + &pvBufClassInfo, + psGetBufferClassBufferIN->hDeviceKM, + PVRSRV_HANDLE_TYPE_BUF_INFO); + if(psGetBufferClassBufferOUT->eError != PVRSRV_OK) + { + return 0; + } + + psGetBufferClassBufferOUT->eError = + PVRSRVGetBCBufferKM(pvBufClassInfo, + psGetBufferClassBufferIN->ui32BufferIndex, + &hBufferInt); + + if(psGetBufferClassBufferOUT->eError != PVRSRV_OK) + { + return 0; + } + + PVRSRVAllocSubHandleNR(psPerProc->psHandleBase, + &psGetBufferClassBufferOUT->hBuffer, + hBufferInt, + PVRSRV_HANDLE_TYPE_BUF_BUFFER, + (PVRSRV_HANDLE_ALLOC_FLAG)(PVRSRV_HANDLE_ALLOC_FLAG_PRIVATE | PVRSRV_HANDLE_ALLOC_FLAG_SHARED), + psGetBufferClassBufferIN->hDeviceKM); + + COMMIT_HANDLE_BATCH_OR_ERROR(psGetBufferClassBufferOUT->eError, psPerProc); + + return 0; +} + + +static IMG_INT +PVRSRVAllocSharedSysMemoryBW(IMG_UINT32 ui32BridgeID, + PVRSRV_BRIDGE_IN_ALLOC_SHARED_SYS_MEM *psAllocSharedSysMemIN, + PVRSRV_BRIDGE_OUT_ALLOC_SHARED_SYS_MEM *psAllocSharedSysMemOUT, + PVRSRV_PER_PROCESS_DATA *psPerProc) +{ + PVRSRV_KERNEL_MEM_INFO *psKernelMemInfo; + + PVRSRV_BRIDGE_ASSERT_CMD(ui32BridgeID, PVRSRV_BRIDGE_ALLOC_SHARED_SYS_MEM); + + NEW_HANDLE_BATCH_OR_ERROR(psAllocSharedSysMemOUT->eError, psPerProc, 1); + + psAllocSharedSysMemOUT->eError = + PVRSRVAllocSharedSysMemoryKM(psPerProc, + psAllocSharedSysMemIN->ui32Flags, + psAllocSharedSysMemIN->ui32Size, + &psKernelMemInfo); + if(psAllocSharedSysMemOUT->eError != PVRSRV_OK) + { + return 0; + } + + OSMemSet(&psAllocSharedSysMemOUT->sClientMemInfo, + 0, + sizeof(psAllocSharedSysMemOUT->sClientMemInfo)); + + psAllocSharedSysMemOUT->sClientMemInfo.pvLinAddrKM = + psKernelMemInfo->pvLinAddrKM; + + psAllocSharedSysMemOUT->sClientMemInfo.pvLinAddr = 0; + psAllocSharedSysMemOUT->sClientMemInfo.ui32Flags = + psKernelMemInfo->ui32Flags; + psAllocSharedSysMemOUT->sClientMemInfo.ui32AllocSize = + psKernelMemInfo->ui32AllocSize; + psAllocSharedSysMemOUT->sClientMemInfo.hMappingInfo = psKernelMemInfo->sMemBlk.hOSMemHandle; + + PVRSRVAllocHandleNR(psPerProc->psHandleBase, + &psAllocSharedSysMemOUT->sClientMemInfo.hKernelMemInfo, + psKernelMemInfo, + PVRSRV_HANDLE_TYPE_SHARED_SYS_MEM_INFO, + PVRSRV_HANDLE_ALLOC_FLAG_NONE); + + COMMIT_HANDLE_BATCH_OR_ERROR(psAllocSharedSysMemOUT->eError, psPerProc); + + return 0; +} + +static IMG_INT +PVRSRVFreeSharedSysMemoryBW(IMG_UINT32 ui32BridgeID, + PVRSRV_BRIDGE_IN_FREE_SHARED_SYS_MEM *psFreeSharedSysMemIN, + PVRSRV_BRIDGE_OUT_FREE_SHARED_SYS_MEM *psFreeSharedSysMemOUT, + PVRSRV_PER_PROCESS_DATA *psPerProc) +{ + PVRSRV_KERNEL_MEM_INFO *psKernelMemInfo; + + PVRSRV_BRIDGE_ASSERT_CMD(ui32BridgeID, PVRSRV_BRIDGE_FREE_SHARED_SYS_MEM); + + psFreeSharedSysMemOUT->eError = + PVRSRVLookupHandle(psPerProc->psHandleBase, + (IMG_VOID **)&psKernelMemInfo, + psFreeSharedSysMemIN->psKernelMemInfo, + PVRSRV_HANDLE_TYPE_SHARED_SYS_MEM_INFO); + + if(psFreeSharedSysMemOUT->eError != PVRSRV_OK) + return 0; + + psFreeSharedSysMemOUT->eError = + PVRSRVFreeSharedSysMemoryKM(psKernelMemInfo); + if(psFreeSharedSysMemOUT->eError != PVRSRV_OK) + return 0; + + psFreeSharedSysMemOUT->eError = + PVRSRVReleaseHandle(psPerProc->psHandleBase, + psFreeSharedSysMemIN->psKernelMemInfo, + PVRSRV_HANDLE_TYPE_SHARED_SYS_MEM_INFO); + return 0; +} + +static IMG_INT +PVRSRVMapMemInfoMemBW(IMG_UINT32 ui32BridgeID, + PVRSRV_BRIDGE_IN_MAP_MEMINFO_MEM *psMapMemInfoMemIN, + PVRSRV_BRIDGE_OUT_MAP_MEMINFO_MEM *psMapMemInfoMemOUT, + PVRSRV_PER_PROCESS_DATA *psPerProc) +{ + PVRSRV_KERNEL_MEM_INFO *psKernelMemInfo; + PVRSRV_HANDLE_TYPE eHandleType; + IMG_HANDLE hParent; + PVRSRV_BRIDGE_ASSERT_CMD(ui32BridgeID, PVRSRV_BRIDGE_MAP_MEMINFO_MEM); + + NEW_HANDLE_BATCH_OR_ERROR(psMapMemInfoMemOUT->eError, psPerProc, 2); + + psMapMemInfoMemOUT->eError = + PVRSRVLookupHandleAnyType(psPerProc->psHandleBase, + (IMG_VOID **)&psKernelMemInfo, + &eHandleType, + psMapMemInfoMemIN->hKernelMemInfo); + if(psMapMemInfoMemOUT->eError != PVRSRV_OK) + { + return 0; + } + + switch (eHandleType) + { +#if defined(PVR_SECURE_HANDLES) + case PVRSRV_HANDLE_TYPE_MEM_INFO: + case PVRSRV_HANDLE_TYPE_MEM_INFO_REF: + case PVRSRV_HANDLE_TYPE_SHARED_SYS_MEM_INFO: +#else + case PVRSRV_HANDLE_TYPE_NONE: +#endif + break; + default: + psMapMemInfoMemOUT->eError = PVRSRV_ERROR_GENERIC; + return 0; + } + + + psMapMemInfoMemOUT->eError = + PVRSRVGetParentHandle(psPerProc->psHandleBase, + &hParent, + psMapMemInfoMemIN->hKernelMemInfo, + eHandleType); + if (psMapMemInfoMemOUT->eError != PVRSRV_OK) + { + return 0; + } + if (hParent == IMG_NULL) + { + hParent = psMapMemInfoMemIN->hKernelMemInfo; + } + + OSMemSet(&psMapMemInfoMemOUT->sClientMemInfo, + 0, + sizeof(psMapMemInfoMemOUT->sClientMemInfo)); + + psMapMemInfoMemOUT->sClientMemInfo.pvLinAddrKM = + psKernelMemInfo->pvLinAddrKM; + + psMapMemInfoMemOUT->sClientMemInfo.pvLinAddr = 0; + psMapMemInfoMemOUT->sClientMemInfo.sDevVAddr = + psKernelMemInfo->sDevVAddr; + psMapMemInfoMemOUT->sClientMemInfo.ui32Flags = + psKernelMemInfo->ui32Flags; + psMapMemInfoMemOUT->sClientMemInfo.ui32AllocSize = + psKernelMemInfo->ui32AllocSize; + psMapMemInfoMemOUT->sClientMemInfo.hMappingInfo = psKernelMemInfo->sMemBlk.hOSMemHandle; + + PVRSRVAllocSubHandleNR(psPerProc->psHandleBase, + &psMapMemInfoMemOUT->sClientMemInfo.hKernelMemInfo, + psKernelMemInfo, + PVRSRV_HANDLE_TYPE_MEM_INFO_REF, + PVRSRV_HANDLE_ALLOC_FLAG_MULTI, + hParent); + + if(psKernelMemInfo->ui32Flags & PVRSRV_MEM_NO_SYNCOBJ) + { + + OSMemSet(&psMapMemInfoMemOUT->sClientSyncInfo, + 0, + sizeof (PVRSRV_CLIENT_SYNC_INFO)); + psMapMemInfoMemOUT->psKernelSyncInfo = IMG_NULL; + } + else + { + + psMapMemInfoMemOUT->sClientSyncInfo.psSyncData = + psKernelMemInfo->psKernelSyncInfo->psSyncData; + psMapMemInfoMemOUT->sClientSyncInfo.sWriteOpsCompleteDevVAddr = + psKernelMemInfo->psKernelSyncInfo->sWriteOpsCompleteDevVAddr; + psMapMemInfoMemOUT->sClientSyncInfo.sReadOpsCompleteDevVAddr = + psKernelMemInfo->psKernelSyncInfo->sReadOpsCompleteDevVAddr; + + psMapMemInfoMemOUT->sClientSyncInfo.hMappingInfo = + psKernelMemInfo->psKernelSyncInfo->psSyncDataMemInfoKM->sMemBlk.hOSMemHandle; + + psMapMemInfoMemOUT->sClientMemInfo.psClientSyncInfo = &psMapMemInfoMemOUT->sClientSyncInfo; + + PVRSRVAllocSubHandleNR(psPerProc->psHandleBase, + &psMapMemInfoMemOUT->sClientSyncInfo.hKernelSyncInfo, + psKernelMemInfo->psKernelSyncInfo, + PVRSRV_HANDLE_TYPE_SYNC_INFO, + PVRSRV_HANDLE_ALLOC_FLAG_MULTI, + psMapMemInfoMemOUT->sClientMemInfo.hKernelMemInfo); + } + + COMMIT_HANDLE_BATCH_OR_ERROR(psMapMemInfoMemOUT->eError, psPerProc); + + return 0; +} + + +static IMG_INT +PVRSRVModifySyncOpsBW(IMG_UINT32 ui32BridgeID, + PVRSRV_BRIDGE_IN_MODIFY_SYNC_OPS *psModifySyncOpsIN, + PVRSRV_BRIDGE_OUT_MODIFY_SYNC_OPS *psModifySyncOpsOUT, + PVRSRV_PER_PROCESS_DATA *psPerProc) +{ + IMG_HANDLE hKernelSyncInfo; + PVRSRV_KERNEL_SYNC_INFO *psKernelSyncInfo; + + PVRSRV_BRIDGE_ASSERT_CMD(ui32BridgeID, PVRSRV_BRIDGE_MODIFY_SYNC_OPS); + + psModifySyncOpsOUT->eError = PVRSRVLookupHandle(psPerProc->psHandleBase, + &hKernelSyncInfo, + psModifySyncOpsIN->hKernelSyncInfo, + PVRSRV_HANDLE_TYPE_SYNC_INFO); + if (psModifySyncOpsOUT->eError != PVRSRV_OK) + { + return 0; + } + + psKernelSyncInfo = (PVRSRV_KERNEL_SYNC_INFO *)hKernelSyncInfo; + + + + psModifySyncOpsOUT->ui32ReadOpsPending = + psKernelSyncInfo->psSyncData->ui32ReadOpsPending; + + psModifySyncOpsOUT->ui32WriteOpsPending = + psKernelSyncInfo->psSyncData->ui32WriteOpsPending; + + psModifySyncOpsOUT->ui32ReadOpsComplete = + psKernelSyncInfo->psSyncData->ui32ReadOpsComplete; + + psModifySyncOpsOUT->ui32WriteOpsComplete = + psKernelSyncInfo->psSyncData->ui32WriteOpsComplete; + + if(psModifySyncOpsIN->ui32ModifyFlags & PVRSRV_MODIFYSYNCOPS_FLAGS_WOP_INC) + { + psKernelSyncInfo->psSyncData->ui32WriteOpsPending++; + } + + if(psModifySyncOpsIN->ui32ModifyFlags & PVRSRV_MODIFYSYNCOPS_FLAGS_ROP_INC) + { + psKernelSyncInfo->psSyncData->ui32ReadOpsPending++; + } + + if(psModifySyncOpsIN->ui32ModifyFlags & PVRSRV_MODIFYSYNCOPS_FLAGS_WOC_INC) + { + psKernelSyncInfo->psSyncData->ui32WriteOpsComplete++; + } + + if(psModifySyncOpsIN->ui32ModifyFlags & PVRSRV_MODIFYSYNCOPS_FLAGS_ROC_INC) + { + psKernelSyncInfo->psSyncData->ui32ReadOpsComplete++; + } + + return 0; +} + + +static IMG_INT +MMU_GetPDDevPAddrBW(IMG_UINT32 ui32BridgeID, + PVRSRV_BRIDGE_IN_GETMMU_PD_DEVPADDR *psGetMmuPDDevPAddrIN, + PVRSRV_BRIDGE_OUT_GETMMU_PD_DEVPADDR *psGetMmuPDDevPAddrOUT, + PVRSRV_PER_PROCESS_DATA *psPerProc) +{ + IMG_HANDLE hDevMemContextInt; + + PVRSRV_BRIDGE_ASSERT_CMD(ui32BridgeID, PVRSRV_BRIDGE_GETMMU_PD_DEVPADDR); + + psGetMmuPDDevPAddrOUT->eError = + PVRSRVLookupHandle(psPerProc->psHandleBase, &hDevMemContextInt, + psGetMmuPDDevPAddrIN->hDevMemContext, + PVRSRV_HANDLE_TYPE_DEV_MEM_CONTEXT); + if(psGetMmuPDDevPAddrOUT->eError != PVRSRV_OK) + { + return 0; + } + + psGetMmuPDDevPAddrOUT->sPDDevPAddr = + BM_GetDeviceNode(hDevMemContextInt)->pfnMMUGetPDDevPAddr(BM_GetMMUContextFromMemContext(hDevMemContextInt)); + if(psGetMmuPDDevPAddrOUT->sPDDevPAddr.uiAddr) + { + psGetMmuPDDevPAddrOUT->eError = PVRSRV_OK; + } + else + { + psGetMmuPDDevPAddrOUT->eError = PVRSRV_ERROR_GENERIC; + } + return 0; +} + + + +IMG_INT +DummyBW(IMG_UINT32 ui32BridgeID, + IMG_VOID *psBridgeIn, + IMG_VOID *psBridgeOut, + PVRSRV_PER_PROCESS_DATA *psPerProc) +{ +#if !defined(DEBUG) + PVR_UNREFERENCED_PARAMETER(ui32BridgeID); +#endif + PVR_UNREFERENCED_PARAMETER(psBridgeIn); + PVR_UNREFERENCED_PARAMETER(psBridgeOut); + PVR_UNREFERENCED_PARAMETER(psPerProc); + +#if defined(DEBUG_BRIDGE_KM) + PVR_DPF((PVR_DBG_ERROR, "%s: BRIDGE ERROR: BridgeID %lu (%s) mapped to " + "Dummy Wrapper (probably not what you want!)", + __FUNCTION__, ui32BridgeID, g_BridgeDispatchTable[ui32BridgeID].pszIOCName)); +#else + PVR_DPF((PVR_DBG_ERROR, "%s: BRIDGE ERROR: BridgeID %lu mapped to " + "Dummy Wrapper (probably not what you want!)", + __FUNCTION__, ui32BridgeID)); +#endif + return -ENOTTY; +} + + +IMG_VOID +_SetDispatchTableEntry(IMG_UINT32 ui32Index, + const IMG_CHAR *pszIOCName, + BridgeWrapperFunction pfFunction, + const IMG_CHAR *pszFunctionName) +{ + static IMG_UINT32 ui32PrevIndex = ~0UL; +#if !defined(DEBUG) + PVR_UNREFERENCED_PARAMETER(pszIOCName); +#endif +#if !defined(DEBUG_BRIDGE_KM_DISPATCH_TABLE) && !defined(DEBUG_BRIDGE_KM) + PVR_UNREFERENCED_PARAMETER(pszFunctionName); +#endif + +#if defined(DEBUG_BRIDGE_KM_DISPATCH_TABLE) + + PVR_DPF((PVR_DBG_WARNING, "%s: %d %s %s", __FUNCTION__, ui32Index, pszIOCName, pszFunctionName)); +#endif + + + if(g_BridgeDispatchTable[ui32Index].pfFunction) + { +#if defined(DEBUG_BRIDGE_KM) + PVR_DPF((PVR_DBG_ERROR, + "%s: BUG!: Adding dispatch table entry for %s clobbers an existing entry for %s", + __FUNCTION__, pszIOCName, g_BridgeDispatchTable[ui32Index].pszIOCName)); +#else + PVR_DPF((PVR_DBG_ERROR, + "%s: BUG!: Adding dispatch table entry for %s clobbers an existing entry (index=%lu)", + __FUNCTION__, pszIOCName, ui32Index)); +#endif + PVR_DPF((PVR_DBG_ERROR, "NOTE: Enabling DEBUG_BRIDGE_KM_DISPATCH_TABLE may help debug this issue.", + __FUNCTION__)); + } + + + if((ui32PrevIndex != ~0UL) && + ((ui32Index >= ui32PrevIndex + DISPATCH_TABLE_GAP_THRESHOLD) || + (ui32Index <= ui32PrevIndex))) + { +#if defined(DEBUG_BRIDGE_KM) + PVR_DPF((PVR_DBG_WARNING, + "%s: There is a gap in the dispatch table between indices %lu (%s) and %lu (%s)", + __FUNCTION__, ui32PrevIndex, g_BridgeDispatchTable[ui32PrevIndex].pszIOCName, + ui32Index, pszIOCName)); +#else + PVR_DPF((PVR_DBG_WARNING, + "%s: There is a gap in the dispatch table between indices %u and %u (%s)", + __FUNCTION__, (IMG_UINT)ui32PrevIndex, (IMG_UINT)ui32Index, pszIOCName)); +#endif + PVR_DPF((PVR_DBG_ERROR, "NOTE: Enabling DEBUG_BRIDGE_KM_DISPATCH_TABLE may help debug this issue.", + __FUNCTION__)); + } + + g_BridgeDispatchTable[ui32Index].pfFunction = pfFunction; +#if defined(DEBUG_BRIDGE_KM) + g_BridgeDispatchTable[ui32Index].pszIOCName = pszIOCName; + g_BridgeDispatchTable[ui32Index].pszFunctionName = pszFunctionName; + g_BridgeDispatchTable[ui32Index].ui32CallCount = 0; + g_BridgeDispatchTable[ui32Index].ui32CopyFromUserTotalBytes = 0; +#endif + + ui32PrevIndex = ui32Index; +} + +static IMG_INT +PVRSRVInitSrvConnectBW(IMG_UINT32 ui32BridgeID, + IMG_VOID *psBridgeIn, + PVRSRV_BRIDGE_RETURN *psRetOUT, + PVRSRV_PER_PROCESS_DATA *psPerProc) +{ + PVR_UNREFERENCED_PARAMETER(psBridgeIn); + + PVRSRV_BRIDGE_ASSERT_CMD(ui32BridgeID, PVRSRV_BRIDGE_INITSRV_CONNECT); + PVR_UNREFERENCED_PARAMETER(psBridgeIn); + + if(!OSProcHasPrivSrvInit() || PVRSRVGetInitServerState(PVRSRV_INIT_SERVER_RUNNING) || PVRSRVGetInitServerState(PVRSRV_INIT_SERVER_RAN)) + { + psRetOUT->eError = PVRSRV_ERROR_GENERIC; + return 0; + } + +#if defined (__linux__) + PVRSRVSetInitServerState(PVRSRV_INIT_SERVER_RUNNING, IMG_TRUE); +#endif + psPerProc->bInitProcess = IMG_TRUE; + + psRetOUT->eError = PVRSRV_OK; + + return 0; +} + + +static IMG_INT +PVRSRVInitSrvDisconnectBW(IMG_UINT32 ui32BridgeID, + PVRSRV_BRIDGE_IN_INITSRV_DISCONNECT *psInitSrvDisconnectIN, + PVRSRV_BRIDGE_RETURN *psRetOUT, + PVRSRV_PER_PROCESS_DATA *psPerProc) +{ + PVRSRV_BRIDGE_ASSERT_CMD(ui32BridgeID, PVRSRV_BRIDGE_INITSRV_DISCONNECT); + + if(!psPerProc->bInitProcess) + { + psRetOUT->eError = PVRSRV_ERROR_GENERIC; + return 0; + } + + psPerProc->bInitProcess = IMG_FALSE; + + PVRSRVSetInitServerState(PVRSRV_INIT_SERVER_RUNNING, IMG_FALSE); + PVRSRVSetInitServerState(PVRSRV_INIT_SERVER_RAN, IMG_TRUE); + + psRetOUT->eError = PVRSRVFinaliseSystem(psInitSrvDisconnectIN->bInitSuccesful); + + PVRSRVSetInitServerState( PVRSRV_INIT_SERVER_SUCCESSFUL ,(IMG_BOOL)(((psRetOUT->eError == PVRSRV_OK) && (psInitSrvDisconnectIN->bInitSuccesful)))); + return 0; +} + + +static IMG_INT +PVRSRVEventObjectWaitBW(IMG_UINT32 ui32BridgeID, + PVRSRV_BRIDGE_IN_EVENT_OBJECT_WAIT *psEventObjectWaitIN, + PVRSRV_BRIDGE_RETURN *psRetOUT, + PVRSRV_PER_PROCESS_DATA *psPerProc) +{ + IMG_HANDLE hOSEventKM; + + PVRSRV_BRIDGE_ASSERT_CMD(ui32BridgeID, PVRSRV_BRIDGE_EVENT_OBJECT_WAIT); + + psRetOUT->eError = PVRSRVLookupHandle(psPerProc->psHandleBase, + &hOSEventKM, + psEventObjectWaitIN->hOSEventKM, + PVRSRV_HANDLE_TYPE_EVENT_OBJECT_CONNECT); + + if(psRetOUT->eError != PVRSRV_OK) + { + return 0; + } + + psRetOUT->eError = OSEventObjectWait(hOSEventKM); + + return 0; +} + + +static IMG_INT +PVRSRVEventObjectOpenBW(IMG_UINT32 ui32BridgeID, + PVRSRV_BRIDGE_IN_EVENT_OBJECT_OPEN *psEventObjectOpenIN, + PVRSRV_BRIDGE_OUT_EVENT_OBJECT_OPEN *psEventObjectOpenOUT, + PVRSRV_PER_PROCESS_DATA *psPerProc) +{ + + PVRSRV_BRIDGE_ASSERT_CMD(ui32BridgeID, PVRSRV_BRIDGE_EVENT_OBJECT_OPEN); + + NEW_HANDLE_BATCH_OR_ERROR(psEventObjectOpenOUT->eError, psPerProc, 1); + + psEventObjectOpenOUT->eError = + PVRSRVLookupHandle(psPerProc->psHandleBase, + &psEventObjectOpenIN->sEventObject.hOSEventKM, + psEventObjectOpenIN->sEventObject.hOSEventKM, + PVRSRV_HANDLE_TYPE_SHARED_EVENT_OBJECT); + + if(psEventObjectOpenOUT->eError != PVRSRV_OK) + { + return 0; + } + + psEventObjectOpenOUT->eError = OSEventObjectOpen(&psEventObjectOpenIN->sEventObject, &psEventObjectOpenOUT->hOSEvent); + + if(psEventObjectOpenOUT->eError != PVRSRV_OK) + { + return 0; + } + + PVRSRVAllocHandleNR(psPerProc->psHandleBase, + &psEventObjectOpenOUT->hOSEvent, + psEventObjectOpenOUT->hOSEvent, + PVRSRV_HANDLE_TYPE_EVENT_OBJECT_CONNECT, + PVRSRV_HANDLE_ALLOC_FLAG_MULTI); + + COMMIT_HANDLE_BATCH_OR_ERROR(psEventObjectOpenOUT->eError, psPerProc); + + return 0; +} + + +static IMG_INT +PVRSRVEventObjectCloseBW(IMG_UINT32 ui32BridgeID, + PVRSRV_BRIDGE_IN_EVENT_OBJECT_CLOSE *psEventObjectCloseIN, + PVRSRV_BRIDGE_RETURN *psRetOUT, + PVRSRV_PER_PROCESS_DATA *psPerProc) +{ + IMG_HANDLE hOSEventKM; + + PVRSRV_BRIDGE_ASSERT_CMD(ui32BridgeID, PVRSRV_BRIDGE_EVENT_OBJECT_CLOSE); + + psRetOUT->eError = + PVRSRVLookupHandle(psPerProc->psHandleBase, + &psEventObjectCloseIN->sEventObject.hOSEventKM, + psEventObjectCloseIN->sEventObject.hOSEventKM, + PVRSRV_HANDLE_TYPE_SHARED_EVENT_OBJECT); + if(psRetOUT->eError != PVRSRV_OK) + { + return 0; + } + + psRetOUT->eError = PVRSRVLookupAndReleaseHandle(psPerProc->psHandleBase, + &hOSEventKM, + psEventObjectCloseIN->hOSEventKM, + PVRSRV_HANDLE_TYPE_EVENT_OBJECT_CONNECT); + + if(psRetOUT->eError != PVRSRV_OK) + { + return 0; + } + + psRetOUT->eError = OSEventObjectClose(&psEventObjectCloseIN->sEventObject, hOSEventKM); + + return 0; +} + + +PVRSRV_ERROR +CommonBridgeInit(IMG_VOID) +{ + IMG_UINT32 i; + + SetDispatchTableEntry(PVRSRV_BRIDGE_ENUM_DEVICES, PVRSRVEnumerateDevicesBW); + SetDispatchTableEntry(PVRSRV_BRIDGE_ACQUIRE_DEVICEINFO, PVRSRVAcquireDeviceDataBW); + SetDispatchTableEntry(PVRSRV_BRIDGE_RELEASE_DEVICEINFO, DummyBW); + SetDispatchTableEntry(PVRSRV_BRIDGE_CREATE_DEVMEMCONTEXT, PVRSRVCreateDeviceMemContextBW); + SetDispatchTableEntry(PVRSRV_BRIDGE_DESTROY_DEVMEMCONTEXT, PVRSRVDestroyDeviceMemContextBW); + SetDispatchTableEntry(PVRSRV_BRIDGE_GET_DEVMEM_HEAPINFO, PVRSRVGetDeviceMemHeapInfoBW); + SetDispatchTableEntry(PVRSRV_BRIDGE_ALLOC_DEVICEMEM, PVRSRVAllocDeviceMemBW); + SetDispatchTableEntry(PVRSRV_BRIDGE_FREE_DEVICEMEM, PVRSRVFreeDeviceMemBW); + SetDispatchTableEntry(PVRSRV_BRIDGE_GETFREE_DEVICEMEM, PVRSRVGetFreeDeviceMemBW); + SetDispatchTableEntry(PVRSRV_BRIDGE_CREATE_COMMANDQUEUE, DummyBW); + SetDispatchTableEntry(PVRSRV_BRIDGE_DESTROY_COMMANDQUEUE, DummyBW); + SetDispatchTableEntry(PVRSRV_BRIDGE_MHANDLE_TO_MMAP_DATA, PVRMMapOSMemHandleToMMapDataBW); + SetDispatchTableEntry(PVRSRV_BRIDGE_CONNECT_SERVICES, PVRSRVConnectBW); + SetDispatchTableEntry(PVRSRV_BRIDGE_DISCONNECT_SERVICES, PVRSRVDisconnectBW); + SetDispatchTableEntry(PVRSRV_BRIDGE_WRAP_DEVICE_MEM, DummyBW); + SetDispatchTableEntry(PVRSRV_BRIDGE_GET_DEVICEMEMINFO, DummyBW); + SetDispatchTableEntry(PVRSRV_BRIDGE_RESERVE_DEV_VIRTMEM , DummyBW); + SetDispatchTableEntry(PVRSRV_BRIDGE_FREE_DEV_VIRTMEM, DummyBW); + SetDispatchTableEntry(PVRSRV_BRIDGE_MAP_EXT_MEMORY, DummyBW); + SetDispatchTableEntry(PVRSRV_BRIDGE_UNMAP_EXT_MEMORY, DummyBW); + SetDispatchTableEntry(PVRSRV_BRIDGE_MAP_DEV_MEMORY, PVRSRVMapDeviceMemoryBW); + SetDispatchTableEntry(PVRSRV_BRIDGE_UNMAP_DEV_MEMORY, PVRSRVUnmapDeviceMemoryBW); + SetDispatchTableEntry(PVRSRV_BRIDGE_MAP_DEVICECLASS_MEMORY, PVRSRVMapDeviceClassMemoryBW); + SetDispatchTableEntry(PVRSRV_BRIDGE_UNMAP_DEVICECLASS_MEMORY, PVRSRVUnmapDeviceClassMemoryBW); + SetDispatchTableEntry(PVRSRV_BRIDGE_MAP_MEM_INFO_TO_USER, DummyBW); + SetDispatchTableEntry(PVRSRV_BRIDGE_UNMAP_MEM_INFO_FROM_USER, DummyBW); + SetDispatchTableEntry(PVRSRV_BRIDGE_EXPORT_DEVICEMEM, PVRSRVExportDeviceMemBW); + SetDispatchTableEntry(PVRSRV_BRIDGE_RELEASE_MMAP_DATA, PVRMMapReleaseMMapDataBW); + + + SetDispatchTableEntry(PVRSRV_BRIDGE_PROCESS_SIMISR_EVENT, DummyBW); + SetDispatchTableEntry(PVRSRV_BRIDGE_REGISTER_SIM_PROCESS, DummyBW); + SetDispatchTableEntry(PVRSRV_BRIDGE_UNREGISTER_SIM_PROCESS, DummyBW); + + + SetDispatchTableEntry(PVRSRV_BRIDGE_MAPPHYSTOUSERSPACE, DummyBW); + SetDispatchTableEntry(PVRSRV_BRIDGE_UNMAPPHYSTOUSERSPACE, DummyBW); + SetDispatchTableEntry(PVRSRV_BRIDGE_GETPHYSTOUSERSPACEMAP, DummyBW); + + SetDispatchTableEntry(PVRSRV_BRIDGE_GET_FB_STATS, DummyBW); + + + SetDispatchTableEntry(PVRSRV_BRIDGE_GET_MISC_INFO, PVRSRVGetMiscInfoBW); + SetDispatchTableEntry(PVRSRV_BRIDGE_RELEASE_MISC_INFO, DummyBW); + + +#if defined (SUPPORT_OVERLAY_ROTATE_BLIT) + SetDispatchTableEntry(PVRSRV_BRIDGE_INIT_3D_OVL_BLT_RES, DummyBW); + SetDispatchTableEntry(PVRSRV_BRIDGE_DEINIT_3D_OVL_BLT_RES, DummyBW); +#endif + + + +#if defined(PDUMP) + SetDispatchTableEntry(PVRSRV_BRIDGE_PDUMP_INIT, DummyBW); + SetDispatchTableEntry(PVRSRV_BRIDGE_PDUMP_MEMPOL, PDumpMemPolBW); + SetDispatchTableEntry(PVRSRV_BRIDGE_PDUMP_DUMPMEM, PDumpMemBW); + SetDispatchTableEntry(PVRSRV_BRIDGE_PDUMP_REG, PDumpRegWithFlagsBW); + SetDispatchTableEntry(PVRSRV_BRIDGE_PDUMP_REGPOL, PDumpRegPolBW); + SetDispatchTableEntry(PVRSRV_BRIDGE_PDUMP_COMMENT, PDumpCommentBW); + SetDispatchTableEntry(PVRSRV_BRIDGE_PDUMP_SETFRAME, PDumpSetFrameBW); + SetDispatchTableEntry(PVRSRV_BRIDGE_PDUMP_ISCAPTURING, PDumpIsCaptureFrameBW); + SetDispatchTableEntry(PVRSRV_BRIDGE_PDUMP_DUMPBITMAP, PDumpBitmapBW); + SetDispatchTableEntry(PVRSRV_BRIDGE_PDUMP_DUMPREADREG, PDumpReadRegBW); + SetDispatchTableEntry(PVRSRV_BRIDGE_PDUMP_SYNCPOL, PDumpSyncPolBW); + SetDispatchTableEntry(PVRSRV_BRIDGE_PDUMP_DUMPSYNC, PDumpSyncDumpBW); + SetDispatchTableEntry(PVRSRV_BRIDGE_PDUMP_DRIVERINFO, PDumpDriverInfoBW); + SetDispatchTableEntry(PVRSRV_BRIDGE_PDUMP_PDREG, PDumpPDRegBW); + SetDispatchTableEntry(PVRSRV_BRIDGE_PDUMP_DUMPPDDEVPADDR, PDumpPDDevPAddrBW); + SetDispatchTableEntry(PVRSRV_BRIDGE_PDUMP_CYCLE_COUNT_REG_READ, PDumpCycleCountRegReadBW); + SetDispatchTableEntry(PVRSRV_BRIDGE_PDUMP_STARTINITPHASE, PDumpStartInitPhaseBW); + SetDispatchTableEntry(PVRSRV_BRIDGE_PDUMP_STOPINITPHASE, PDumpStopInitPhaseBW); +#endif + + + SetDispatchTableEntry(PVRSRV_BRIDGE_GET_OEMJTABLE, DummyBW); + + + SetDispatchTableEntry(PVRSRV_BRIDGE_ENUM_CLASS, PVRSRVEnumerateDCBW); + + + SetDispatchTableEntry(PVRSRV_BRIDGE_OPEN_DISPCLASS_DEVICE, PVRSRVOpenDCDeviceBW); + SetDispatchTableEntry(PVRSRV_BRIDGE_CLOSE_DISPCLASS_DEVICE, PVRSRVCloseDCDeviceBW); + SetDispatchTableEntry(PVRSRV_BRIDGE_ENUM_DISPCLASS_FORMATS, PVRSRVEnumDCFormatsBW); + SetDispatchTableEntry(PVRSRV_BRIDGE_ENUM_DISPCLASS_DIMS, PVRSRVEnumDCDimsBW); + SetDispatchTableEntry(PVRSRV_BRIDGE_GET_DISPCLASS_SYSBUFFER, PVRSRVGetDCSystemBufferBW); + SetDispatchTableEntry(PVRSRV_BRIDGE_GET_DISPCLASS_INFO, PVRSRVGetDCInfoBW); + SetDispatchTableEntry(PVRSRV_BRIDGE_CREATE_DISPCLASS_SWAPCHAIN, PVRSRVCreateDCSwapChainBW); + SetDispatchTableEntry(PVRSRV_BRIDGE_DESTROY_DISPCLASS_SWAPCHAIN, PVRSRVDestroyDCSwapChainBW); + SetDispatchTableEntry(PVRSRV_BRIDGE_SET_DISPCLASS_DSTRECT, PVRSRVSetDCDstRectBW); + SetDispatchTableEntry(PVRSRV_BRIDGE_SET_DISPCLASS_SRCRECT, PVRSRVSetDCSrcRectBW); + SetDispatchTableEntry(PVRSRV_BRIDGE_SET_DISPCLASS_DSTCOLOURKEY, PVRSRVSetDCDstColourKeyBW); + SetDispatchTableEntry(PVRSRV_BRIDGE_SET_DISPCLASS_SRCCOLOURKEY, PVRSRVSetDCSrcColourKeyBW); + SetDispatchTableEntry(PVRSRV_BRIDGE_GET_DISPCLASS_BUFFERS, PVRSRVGetDCBuffersBW); + SetDispatchTableEntry(PVRSRV_BRIDGE_SWAP_DISPCLASS_TO_BUFFER, PVRSRVSwapToDCBufferBW); + SetDispatchTableEntry(PVRSRV_BRIDGE_SWAP_DISPCLASS_TO_SYSTEM, PVRSRVSwapToDCSystemBW); + + + SetDispatchTableEntry(PVRSRV_BRIDGE_OPEN_BUFFERCLASS_DEVICE, PVRSRVOpenBCDeviceBW); + SetDispatchTableEntry(PVRSRV_BRIDGE_CLOSE_BUFFERCLASS_DEVICE, PVRSRVCloseBCDeviceBW); + SetDispatchTableEntry(PVRSRV_BRIDGE_GET_BUFFERCLASS_INFO, PVRSRVGetBCInfoBW); + SetDispatchTableEntry(PVRSRV_BRIDGE_GET_BUFFERCLASS_BUFFER, PVRSRVGetBCBufferBW); + + + SetDispatchTableEntry(PVRSRV_BRIDGE_WRAP_EXT_MEMORY, PVRSRVWrapExtMemoryBW); + SetDispatchTableEntry(PVRSRV_BRIDGE_UNWRAP_EXT_MEMORY, PVRSRVUnwrapExtMemoryBW); + + + SetDispatchTableEntry(PVRSRV_BRIDGE_ALLOC_SHARED_SYS_MEM, PVRSRVAllocSharedSysMemoryBW); + SetDispatchTableEntry(PVRSRV_BRIDGE_FREE_SHARED_SYS_MEM, PVRSRVFreeSharedSysMemoryBW); + SetDispatchTableEntry(PVRSRV_BRIDGE_MAP_MEMINFO_MEM, PVRSRVMapMemInfoMemBW); + + + SetDispatchTableEntry(PVRSRV_BRIDGE_GETMMU_PD_DEVPADDR, MMU_GetPDDevPAddrBW); + + + SetDispatchTableEntry(PVRSRV_BRIDGE_INITSRV_CONNECT, PVRSRVInitSrvConnectBW); + SetDispatchTableEntry(PVRSRV_BRIDGE_INITSRV_DISCONNECT, PVRSRVInitSrvDisconnectBW); + + + SetDispatchTableEntry(PVRSRV_BRIDGE_EVENT_OBJECT_WAIT, PVRSRVEventObjectWaitBW); + SetDispatchTableEntry(PVRSRV_BRIDGE_EVENT_OBJECT_OPEN, PVRSRVEventObjectOpenBW); + SetDispatchTableEntry(PVRSRV_BRIDGE_EVENT_OBJECT_CLOSE, PVRSRVEventObjectCloseBW); + + + SetDispatchTableEntry(PVRSRV_BRIDGE_MODIFY_SYNC_OPS, PVRSRVModifySyncOpsBW); + +#if defined (SUPPORT_SGX) + SetSGXDispatchTableEntry(); +#endif +#if defined (SUPPORT_VGX) + SetVGXDispatchTableEntry(); +#endif + + + + for(i=0;iui32BridgeID; + IMG_INT err = -EFAULT; + +#if defined(DEBUG_TRACE_BRIDGE_KM) + PVR_DPF((PVR_DBG_ERROR, "%s: %s", + __FUNCTION__, + g_BridgeDispatchTable[ui32BridgeID].pszIOCName)); +#endif + +#if defined(DEBUG_BRIDGE_KM) + g_BridgeDispatchTable[ui32BridgeID].ui32CallCount++; + g_BridgeGlobalStats.ui32IOCTLCount++; +#endif + + if(!psPerProc->bInitProcess) + { + if(PVRSRVGetInitServerState(PVRSRV_INIT_SERVER_RAN)) + { + if(!PVRSRVGetInitServerState(PVRSRV_INIT_SERVER_SUCCESSFUL)) + { + PVR_DPF((PVR_DBG_ERROR, "%s: Initialisation failed. Driver unusable.", + __FUNCTION__)); + goto return_fault; + } + } + else + { + if(PVRSRVGetInitServerState(PVRSRV_INIT_SERVER_RUNNING)) + { + PVR_DPF((PVR_DBG_ERROR, "%s: Initialisation is in progress", + __FUNCTION__)); + goto return_fault; + } + else + { + + switch(ui32BridgeID) + { + case PVRSRV_GET_BRIDGE_ID(PVRSRV_BRIDGE_CONNECT_SERVICES): + case PVRSRV_GET_BRIDGE_ID(PVRSRV_BRIDGE_DISCONNECT_SERVICES): + case PVRSRV_GET_BRIDGE_ID(PVRSRV_BRIDGE_INITSRV_CONNECT): + case PVRSRV_GET_BRIDGE_ID(PVRSRV_BRIDGE_INITSRV_DISCONNECT): + break; + default: + PVR_DPF((PVR_DBG_ERROR, "%s: Driver initialisation not completed yet.", + __FUNCTION__)); + goto return_fault; + } + } + } + } + + + +#if defined(__linux__) + { + + SYS_DATA *psSysData; + + if(SysAcquireData(&psSysData) != PVRSRV_OK) + { + goto return_fault; + } + + + psBridgeIn = ((ENV_DATA *)psSysData->pvEnvSpecificData)->pvBridgeData; + psBridgeOut = (IMG_PVOID)((IMG_PBYTE)psBridgeIn + PVRSRV_MAX_BRIDGE_IN_SIZE); + + if(psBridgePackageKM->ui32InBufferSize > 0) + { + if(!OSAccessOK(PVR_VERIFY_READ, + psBridgePackageKM->pvParamIn, + psBridgePackageKM->ui32InBufferSize)) + { + PVR_DPF((PVR_DBG_ERROR, "%s: Invalid pvParamIn pointer", __FUNCTION__)); + } + + if(CopyFromUserWrapper(psPerProc, + ui32BridgeID, + psBridgeIn, + psBridgePackageKM->pvParamIn, + psBridgePackageKM->ui32InBufferSize) + != PVRSRV_OK) + { + goto return_fault; + } + } + } +#else + psBridgeIn = psBridgePackageKM->pvParamIn; + psBridgeOut = psBridgePackageKM->pvParamOut; +#endif + + if(ui32BridgeID >= (BRIDGE_DISPATCH_TABLE_ENTRY_COUNT)) + { + PVR_DPF((PVR_DBG_ERROR, "%s: ui32BridgeID = %d is out if range!", + __FUNCTION__, ui32BridgeID)); + goto return_fault; + } + pfBridgeHandler = + (BridgeWrapperFunction)g_BridgeDispatchTable[ui32BridgeID].pfFunction; + err = pfBridgeHandler(ui32BridgeID, + psBridgeIn, + psBridgeOut, + psPerProc); + if(err < 0) + { + goto return_fault; + } + + +#if defined(__linux__) + + if(CopyToUserWrapper(psPerProc, + ui32BridgeID, + psBridgePackageKM->pvParamOut, + psBridgeOut, + psBridgePackageKM->ui32OutBufferSize) + != PVRSRV_OK) + { + goto return_fault; + } +#endif + + err = 0; +return_fault: + ReleaseHandleBatch(psPerProc); + return err; +} + diff --git a/services4/srvkm/bridged/bridged_pvr_bridge.h b/services4/srvkm/bridged/bridged_pvr_bridge.h new file mode 100644 index 0000000..cb71f25 --- /dev/null +++ b/services4/srvkm/bridged/bridged_pvr_bridge.h @@ -0,0 +1,228 @@ +/********************************************************************** + * + * Copyright(c) 2008 Imagination Technologies Ltd. All rights reserved. + * + * This program is free software; you can redistribute it and/or modify it + * under the terms and conditions of the GNU General Public License, + * version 2, as published by the Free Software Foundation. + * + * This program is distributed in the hope it will be useful but, except + * as otherwise stated in writing, without any warranty; without even the + * implied warranty of merchantability or fitness for a particular purpose. + * See the GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License along with + * this program; if not, write to the Free Software Foundation, Inc., + * 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA. + * + * The full GNU General Public License is included in this distribution in + * the file called "COPYING". + * + * Contact Information: + * Imagination Technologies Ltd. + * Home Park Estate, Kings Langley, Herts, WD4 8LZ, UK + * + ******************************************************************************/ + +#ifndef __BRIDGED_PVR_BRIDGE_H__ +#define __BRIDGED_PVR_BRIDGE_H__ + +#include "pvr_bridge.h" + +#if defined(__cplusplus) +extern "C" { +#endif + +#if defined(__linux__) +#define PVRSRV_GET_BRIDGE_ID(X) _IOC_NR(X) +#else +#define PVRSRV_GET_BRIDGE_ID(X) (X - PVRSRV_IOWR(PVRSRV_BRIDGE_CORE_CMD_FIRST)) +#endif + +#ifndef ENOMEM +#define ENOMEM 12 +#endif +#ifndef EFAULT +#define EFAULT 14 +#endif +#ifndef ENOTTY +#define ENOTTY 25 +#endif + +#if defined(DEBUG_BRIDGE_KM) +PVRSRV_ERROR +CopyFromUserWrapper(PVRSRV_PER_PROCESS_DATA *pProcData, + IMG_UINT32 ui32BridgeID, + IMG_VOID *pvDest, + IMG_VOID *pvSrc, + IMG_UINT32 ui32Size); +PVRSRV_ERROR +CopyToUserWrapper(PVRSRV_PER_PROCESS_DATA *pProcData, + IMG_UINT32 ui32BridgeID, + IMG_VOID *pvDest, + IMG_VOID *pvSrc, + IMG_UINT32 ui32Size); +#else +#define CopyFromUserWrapper(pProcData, ui32BridgeID, pvDest, pvSrc, ui32Size) \ + OSCopyFromUser(pProcData, pvDest, pvSrc, ui32Size) +#define CopyToUserWrapper(pProcData, ui32BridgeID, pvDest, pvSrc, ui32Size) \ + OSCopyToUser(pProcData, pvDest, pvSrc, ui32Size) +#endif + + +#define ASSIGN_AND_RETURN_ON_ERROR(error, src, res) \ + do \ + { \ + (error) = (src); \ + if ((error) != PVRSRV_OK) \ + { \ + return (res); \ + } \ + } while (error != PVRSRV_OK) + +#define ASSIGN_AND_EXIT_ON_ERROR(error, src) \ + ASSIGN_AND_RETURN_ON_ERROR(error, src, 0) + +#if defined (PVR_SECURE_HANDLES) +#ifdef INLINE_IS_PRAGMA +#pragma inline(NewHandleBatch) +#endif +static INLINE PVRSRV_ERROR +NewHandleBatch(PVRSRV_PER_PROCESS_DATA *psPerProc, + IMG_UINT32 ui32BatchSize) +{ + PVRSRV_ERROR eError; + + PVR_ASSERT(!psPerProc->bHandlesBatched); + + eError = PVRSRVNewHandleBatch(psPerProc->psHandleBase, ui32BatchSize); + + if (eError == PVRSRV_OK) + { + psPerProc->bHandlesBatched = IMG_TRUE; + } + + return eError; +} + +#define NEW_HANDLE_BATCH_OR_ERROR(error, psPerProc, ui32BatchSize) \ + ASSIGN_AND_EXIT_ON_ERROR(error, NewHandleBatch(psPerProc, ui32BatchSize)) + +#ifdef INLINE_IS_PRAGMA +#pragma inline(CommitHandleBatch) +#endif +static INLINE PVRSRV_ERROR +CommitHandleBatch(PVRSRV_PER_PROCESS_DATA *psPerProc) +{ + PVR_ASSERT(psPerProc->bHandlesBatched); + + psPerProc->bHandlesBatched = IMG_FALSE; + + return PVRSRVCommitHandleBatch(psPerProc->psHandleBase); +} + + +#define COMMIT_HANDLE_BATCH_OR_ERROR(error, psPerProc) \ + ASSIGN_AND_EXIT_ON_ERROR(error, CommitHandleBatch(psPerProc)) + +#ifdef INLINE_IS_PRAGMA +#pragma inline(ReleaseHandleBatch) +#endif +static INLINE IMG_VOID +ReleaseHandleBatch(PVRSRV_PER_PROCESS_DATA *psPerProc) +{ + if (psPerProc->bHandlesBatched) + { + psPerProc->bHandlesBatched = IMG_FALSE; + + PVRSRVReleaseHandleBatch(psPerProc->psHandleBase); + } +} +#else +#define NEW_HANDLE_BATCH_OR_ERROR(error, psPerProc, ui32BatchSize) +#define COMMIT_HANDLE_BATCH_OR_ERROR(error, psPerProc) +#define ReleaseHandleBatch(psPerProc) +#endif + +IMG_INT +DummyBW(IMG_UINT32 ui32BridgeID, + IMG_VOID *psBridgeIn, + IMG_VOID *psBridgeOut, + PVRSRV_PER_PROCESS_DATA *psPerProc); + +typedef IMG_INT (*BridgeWrapperFunction)(IMG_UINT32 ui32BridgeID, + IMG_VOID *psBridgeIn, + IMG_VOID *psBridgeOut, + PVRSRV_PER_PROCESS_DATA *psPerProc); + +typedef struct _PVRSRV_BRIDGE_DISPATCH_TABLE_ENTRY +{ + BridgeWrapperFunction pfFunction; +#if defined(DEBUG_BRIDGE_KM) + const IMG_CHAR *pszIOCName; + const IMG_CHAR *pszFunctionName; + IMG_UINT32 ui32CallCount; + IMG_UINT32 ui32CopyFromUserTotalBytes; + IMG_UINT32 ui32CopyToUserTotalBytes; +#endif +}PVRSRV_BRIDGE_DISPATCH_TABLE_ENTRY; + +#if defined(SUPPORT_VGX) +#define BRIDGE_DISPATCH_TABLE_ENTRY_COUNT (PVRSRV_BRIDGE_LAST_VGX_CMD+1) +#define PVRSRV_BRIDGE_LAST_DEVICE_CMD PVRSRV_BRIDGE_LAST_VGX_CMD +#else + +#if defined(SUPPORT_SGX) +#define BRIDGE_DISPATCH_TABLE_ENTRY_COUNT (PVRSRV_BRIDGE_LAST_SGX_CMD+1) +#define PVRSRV_BRIDGE_LAST_DEVICE_CMD PVRSRV_BRIDGE_LAST_SGX_CMD +#else +#define BRIDGE_DISPATCH_TABLE_ENTRY_COUNT (PVRSRV_BRIDGE_LAST_NON_DEVICE_CMD+1) +#define PVRSRV_BRIDGE_LAST_DEVICE_CMD PVRSRV_BRIDGE_LAST_NON_DEVICE_CMD +#endif + +#endif + +extern PVRSRV_BRIDGE_DISPATCH_TABLE_ENTRY g_BridgeDispatchTable[BRIDGE_DISPATCH_TABLE_ENTRY_COUNT]; + +IMG_VOID +_SetDispatchTableEntry(IMG_UINT32 ui32Index, + const IMG_CHAR *pszIOCName, + BridgeWrapperFunction pfFunction, + const IMG_CHAR *pszFunctionName); + + +#define SetDispatchTableEntry(ui32Index, pfFunction) \ + _SetDispatchTableEntry(PVRSRV_GET_BRIDGE_ID(ui32Index), #ui32Index, (BridgeWrapperFunction)pfFunction, #pfFunction) + +#define DISPATCH_TABLE_GAP_THRESHOLD 5 + +#if defined(DEBUG) +#define PVRSRV_BRIDGE_ASSERT_CMD(X, Y) PVR_ASSERT(X == PVRSRV_GET_BRIDGE_ID(Y)) +#else +#define PVRSRV_BRIDGE_ASSERT_CMD(X, Y) PVR_UNREFERENCED_PARAMETER(X) +#endif + + +#if defined(DEBUG_BRIDGE_KM) +typedef struct _PVRSRV_BRIDGE_GLOBAL_STATS +{ + IMG_UINT32 ui32IOCTLCount; + IMG_UINT32 ui32TotalCopyFromUserBytes; + IMG_UINT32 ui32TotalCopyToUserBytes; +}PVRSRV_BRIDGE_GLOBAL_STATS; + +extern PVRSRV_BRIDGE_GLOBAL_STATS g_BridgeGlobalStats; +#endif + + +PVRSRV_ERROR CommonBridgeInit(IMG_VOID); + +IMG_INT BridgedDispatchKM(PVRSRV_PER_PROCESS_DATA * psPerProc, + PVRSRV_BRIDGE_PACKAGE * psBridgePackageKM); + +#if defined (__cplusplus) +} +#endif + +#endif + diff --git a/services4/srvkm/bridged/bridged_support.c b/services4/srvkm/bridged/bridged_support.c new file mode 100644 index 0000000..d8a9eee --- /dev/null +++ b/services4/srvkm/bridged/bridged_support.c @@ -0,0 +1,85 @@ +/********************************************************************** + * + * Copyright(c) 2008 Imagination Technologies Ltd. All rights reserved. + * + * This program is free software; you can redistribute it and/or modify it + * under the terms and conditions of the GNU General Public License, + * version 2, as published by the Free Software Foundation. + * + * This program is distributed in the hope it will be useful but, except + * as otherwise stated in writing, without any warranty; without even the + * implied warranty of merchantability or fitness for a particular purpose. + * See the GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License along with + * this program; if not, write to the Free Software Foundation, Inc., + * 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA. + * + * The full GNU General Public License is included in this distribution in + * the file called "COPYING". + * + * Contact Information: + * Imagination Technologies Ltd. + * Home Park Estate, Kings Langley, Herts, WD4 8LZ, UK + * + ******************************************************************************/ + +#include "img_defs.h" +#include "servicesint.h" +#include "bridged_support.h" + + +PVRSRV_ERROR +PVRSRVLookupOSMemHandle(PVRSRV_HANDLE_BASE *psHandleBase, IMG_HANDLE *phOSMemHandle, IMG_HANDLE hMHandle) +{ + IMG_HANDLE hMHandleInt; + PVRSRV_HANDLE_TYPE eHandleType; + PVRSRV_ERROR eError; + + + eError = PVRSRVLookupHandleAnyType(psHandleBase, &hMHandleInt, + &eHandleType, + hMHandle); + if(eError != PVRSRV_OK) + { + return eError; + } + + switch(eHandleType) + { +#if defined(PVR_SECURE_HANDLES) + case PVRSRV_HANDLE_TYPE_MEM_INFO: + case PVRSRV_HANDLE_TYPE_MEM_INFO_REF: + case PVRSRV_HANDLE_TYPE_SHARED_SYS_MEM_INFO: + { + PVRSRV_KERNEL_MEM_INFO *psMemInfo = (PVRSRV_KERNEL_MEM_INFO *)hMHandleInt; + + *phOSMemHandle = psMemInfo->sMemBlk.hOSMemHandle; + + break; + } + case PVRSRV_HANDLE_TYPE_SYNC_INFO: + { + PVRSRV_KERNEL_SYNC_INFO *psSyncInfo = (PVRSRV_KERNEL_SYNC_INFO *)hMHandleInt; + PVRSRV_KERNEL_MEM_INFO *psMemInfo = psSyncInfo->psSyncDataMemInfoKM; + + *phOSMemHandle = psMemInfo->sMemBlk.hOSMemHandle; + + break; + } + case PVRSRV_HANDLE_TYPE_SOC_TIMER: + { + *phOSMemHandle = (IMG_VOID *)hMHandleInt; + break; + } +#else + case PVRSRV_HANDLE_TYPE_NONE: + *phOSMemHandle = (IMG_VOID *)hMHandleInt; + break; +#endif + default: + return PVRSRV_ERROR_BAD_MAPPING; + } + + return PVRSRV_OK;; +} diff --git a/services4/srvkm/bridged/bridged_support.h b/services4/srvkm/bridged/bridged_support.h new file mode 100644 index 0000000..371715d --- /dev/null +++ b/services4/srvkm/bridged/bridged_support.h @@ -0,0 +1,43 @@ +/********************************************************************** + * + * Copyright(c) 2008 Imagination Technologies Ltd. All rights reserved. + * + * This program is free software; you can redistribute it and/or modify it + * under the terms and conditions of the GNU General Public License, + * version 2, as published by the Free Software Foundation. + * + * This program is distributed in the hope it will be useful but, except + * as otherwise stated in writing, without any warranty; without even the + * implied warranty of merchantability or fitness for a particular purpose. + * See the GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License along with + * this program; if not, write to the Free Software Foundation, Inc., + * 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA. + * + * The full GNU General Public License is included in this distribution in + * the file called "COPYING". + * + * Contact Information: + * Imagination Technologies Ltd. + * Home Park Estate, Kings Langley, Herts, WD4 8LZ, UK + * + ******************************************************************************/ + +#ifndef __BRIDGED_SUPPORT_H__ +#define __BRIDGED_SUPPORT_H__ + +#include "handle.h" + +#if defined(__cplusplus) +extern "C" { +#endif + +PVRSRV_ERROR PVRSRVLookupOSMemHandle(PVRSRV_HANDLE_BASE *psBase, IMG_HANDLE *phOSMemHandle, IMG_HANDLE hMHandle); + +#if defined (__cplusplus) +} +#endif + +#endif + diff --git a/services4/srvkm/bridged/sgx/bridged_sgx_bridge.c b/services4/srvkm/bridged/sgx/bridged_sgx_bridge.c new file mode 100644 index 0000000..ff78232 --- /dev/null +++ b/services4/srvkm/bridged/sgx/bridged_sgx_bridge.c @@ -0,0 +1,2253 @@ +/********************************************************************** + * + * Copyright(c) 2008 Imagination Technologies Ltd. All rights reserved. + * + * This program is free software; you can redistribute it and/or modify it + * under the terms and conditions of the GNU General Public License, + * version 2, as published by the Free Software Foundation. + * + * This program is distributed in the hope it will be useful but, except + * as otherwise stated in writing, without any warranty; without even the + * implied warranty of merchantability or fitness for a particular purpose. + * See the GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License along with + * this program; if not, write to the Free Software Foundation, Inc., + * 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA. + * + * The full GNU General Public License is included in this distribution in + * the file called "COPYING". + * + * Contact Information: + * Imagination Technologies Ltd. + * Home Park Estate, Kings Langley, Herts, WD4 8LZ, UK + * + ******************************************************************************/ + + + +#include + +#include "img_defs.h" + +#if defined(SUPPORT_SGX) + +#include "services.h" +#include "pvr_debug.h" +#include "pvr_bridge.h" +#include "sgx_bridge.h" +#include "perproc.h" +#include "power.h" +#include "pvr_bridge_km.h" +#include "sgx_bridge_km.h" +#include "bridged_pvr_bridge.h" +#include "bridged_sgx_bridge.h" +#include "sgxutils.h" +#include "pdump_km.h" + +static IMG_INT +SGXGetClientInfoBW(IMG_UINT32 ui32BridgeID, + PVRSRV_BRIDGE_IN_GETCLIENTINFO *psGetClientInfoIN, + PVRSRV_BRIDGE_OUT_GETCLIENTINFO *psGetClientInfoOUT, + PVRSRV_PER_PROCESS_DATA *psPerProc) +{ + IMG_HANDLE hDevCookieInt; + + PVRSRV_BRIDGE_ASSERT_CMD(ui32BridgeID, PVRSRV_BRIDGE_SGX_GETCLIENTINFO); + + psGetClientInfoOUT->eError = + PVRSRVLookupHandle(psPerProc->psHandleBase, &hDevCookieInt, + psGetClientInfoIN->hDevCookie, + PVRSRV_HANDLE_TYPE_DEV_NODE); + if(psGetClientInfoOUT->eError != PVRSRV_OK) + { + return 0; + } + + psGetClientInfoOUT->eError = + SGXGetClientInfoKM(hDevCookieInt, + &psGetClientInfoOUT->sClientInfo); + return 0; +} + +static IMG_INT +SGXReleaseClientInfoBW(IMG_UINT32 ui32BridgeID, + PVRSRV_BRIDGE_IN_RELEASECLIENTINFO *psReleaseClientInfoIN, + PVRSRV_BRIDGE_RETURN *psRetOUT, + PVRSRV_PER_PROCESS_DATA *psPerProc) +{ + PVRSRV_SGXDEV_INFO *psDevInfo; + IMG_HANDLE hDevCookieInt; + + PVRSRV_BRIDGE_ASSERT_CMD(ui32BridgeID, PVRSRV_BRIDGE_SGX_RELEASECLIENTINFO); + + psRetOUT->eError = + PVRSRVLookupHandle(psPerProc->psHandleBase, &hDevCookieInt, + psReleaseClientInfoIN->hDevCookie, + PVRSRV_HANDLE_TYPE_DEV_NODE); + if(psRetOUT->eError != PVRSRV_OK) + { + return 0; + } + + psDevInfo = (PVRSRV_SGXDEV_INFO *)((PVRSRV_DEVICE_NODE *)hDevCookieInt)->pvDevice; + + PVR_ASSERT(psDevInfo->ui32ClientRefCount > 0); + + psDevInfo->ui32ClientRefCount--; + + psRetOUT->eError = PVRSRV_OK; + + return 0; +} + + +static IMG_INT +SGXGetInternalDevInfoBW(IMG_UINT32 ui32BridgeID, + PVRSRV_BRIDGE_IN_GETINTERNALDEVINFO *psSGXGetInternalDevInfoIN, + PVRSRV_BRIDGE_OUT_GETINTERNALDEVINFO *psSGXGetInternalDevInfoOUT, + PVRSRV_PER_PROCESS_DATA *psPerProc) +{ + IMG_HANDLE hDevCookieInt; + + PVRSRV_BRIDGE_ASSERT_CMD(ui32BridgeID, PVRSRV_BRIDGE_SGX_GETINTERNALDEVINFO); + + psSGXGetInternalDevInfoOUT->eError = + PVRSRVLookupHandle(psPerProc->psHandleBase, &hDevCookieInt, + psSGXGetInternalDevInfoIN->hDevCookie, + PVRSRV_HANDLE_TYPE_DEV_NODE); + if(psSGXGetInternalDevInfoOUT->eError != PVRSRV_OK) + { + return 0; + } + + psSGXGetInternalDevInfoOUT->eError = + SGXGetInternalDevInfoKM(hDevCookieInt, + &psSGXGetInternalDevInfoOUT->sSGXInternalDevInfo); + + + psSGXGetInternalDevInfoOUT->eError = + PVRSRVAllocHandle(psPerProc->psHandleBase, + &psSGXGetInternalDevInfoOUT->sSGXInternalDevInfo.hHostCtlKernelMemInfoHandle, + psSGXGetInternalDevInfoOUT->sSGXInternalDevInfo.hHostCtlKernelMemInfoHandle, + PVRSRV_HANDLE_TYPE_MEM_INFO, + PVRSRV_HANDLE_ALLOC_FLAG_SHARED); + + return 0; +} + + +static IMG_INT +SGXDoKickBW(IMG_UINT32 ui32BridgeID, + PVRSRV_BRIDGE_IN_DOKICK *psDoKickIN, + PVRSRV_BRIDGE_RETURN *psRetOUT, + PVRSRV_PER_PROCESS_DATA *psPerProc) +{ + IMG_HANDLE hDevCookieInt; + IMG_UINT32 i; + + PVRSRV_BRIDGE_ASSERT_CMD(ui32BridgeID, PVRSRV_BRIDGE_SGX_DOKICK); + + psRetOUT->eError = + PVRSRVLookupHandle(psPerProc->psHandleBase, + &hDevCookieInt, + psDoKickIN->hDevCookie, + PVRSRV_HANDLE_TYPE_DEV_NODE); + + if(psRetOUT->eError != PVRSRV_OK) + { + return 0; + } + + psRetOUT->eError = + PVRSRVLookupHandle(psPerProc->psHandleBase, + &psDoKickIN->sCCBKick.hCCBKernelMemInfo, + psDoKickIN->sCCBKick.hCCBKernelMemInfo, + PVRSRV_HANDLE_TYPE_MEM_INFO); + + if(psRetOUT->eError != PVRSRV_OK) + { + return 0; + } + + if(psDoKickIN->sCCBKick.hTA3DSyncInfo != IMG_NULL) + { + psRetOUT->eError = + PVRSRVLookupHandle(psPerProc->psHandleBase, + &psDoKickIN->sCCBKick.hTA3DSyncInfo, + psDoKickIN->sCCBKick.hTA3DSyncInfo, + PVRSRV_HANDLE_TYPE_SYNC_INFO); + + if(psRetOUT->eError != PVRSRV_OK) + { + return 0; + } + } + + if(psDoKickIN->sCCBKick.hTASyncInfo != IMG_NULL) + { + psRetOUT->eError = + PVRSRVLookupHandle(psPerProc->psHandleBase, + &psDoKickIN->sCCBKick.hTASyncInfo, + psDoKickIN->sCCBKick.hTASyncInfo, + PVRSRV_HANDLE_TYPE_SYNC_INFO); + + if(psRetOUT->eError != PVRSRV_OK) + { + return 0; + } + } + + if(psDoKickIN->sCCBKick.h3DSyncInfo != IMG_NULL) + { + psRetOUT->eError = + PVRSRVLookupHandle(psPerProc->psHandleBase, + &psDoKickIN->sCCBKick.h3DSyncInfo, + psDoKickIN->sCCBKick.h3DSyncInfo, + PVRSRV_HANDLE_TYPE_SYNC_INFO); + + if(psRetOUT->eError != PVRSRV_OK) + { + return 0; + } + } + + + if (psDoKickIN->sCCBKick.ui32NumSrcSyncs > SGX_MAX_SRC_SYNCS) + { + psRetOUT->eError = PVRSRV_ERROR_INVALID_PARAMS; + return 0; + } + for(i=0; isCCBKick.ui32NumSrcSyncs; i++) + { + psRetOUT->eError = + PVRSRVLookupHandle(psPerProc->psHandleBase, + &psDoKickIN->sCCBKick.ahSrcKernelSyncInfo[i], + psDoKickIN->sCCBKick.ahSrcKernelSyncInfo[i], + PVRSRV_HANDLE_TYPE_SYNC_INFO); + + if(psRetOUT->eError != PVRSRV_OK) + { + return 0; + } + } + + if (psDoKickIN->sCCBKick.ui32NumTAStatusVals > SGX_MAX_TA_STATUS_VALS) + { + psRetOUT->eError = PVRSRV_ERROR_INVALID_PARAMS; + return 0; + } + for (i = 0; i < psDoKickIN->sCCBKick.ui32NumTAStatusVals; i++) + { + psRetOUT->eError = +#if defined(SUPPORT_SGX_NEW_STATUS_VALS) + PVRSRVLookupHandle(psPerProc->psHandleBase, + &psDoKickIN->sCCBKick.asTAStatusUpdate[i].hKernelMemInfo, + psDoKickIN->sCCBKick.asTAStatusUpdate[i].hKernelMemInfo, + PVRSRV_HANDLE_TYPE_MEM_INFO); +#else + PVRSRVLookupHandle(psPerProc->psHandleBase, + &psDoKickIN->sCCBKick.ahTAStatusSyncInfo[i], + psDoKickIN->sCCBKick.ahTAStatusSyncInfo[i], + PVRSRV_HANDLE_TYPE_SYNC_INFO); +#endif + if(psRetOUT->eError != PVRSRV_OK) + { + return 0; + } + } + + if (psDoKickIN->sCCBKick.ui32Num3DStatusVals > SGX_MAX_3D_STATUS_VALS) + { + psRetOUT->eError = PVRSRV_ERROR_INVALID_PARAMS; + return 0; + } + for(i = 0; i < psDoKickIN->sCCBKick.ui32Num3DStatusVals; i++) + { + psRetOUT->eError = +#if defined(SUPPORT_SGX_NEW_STATUS_VALS) + PVRSRVLookupHandle(psPerProc->psHandleBase, + &psDoKickIN->sCCBKick.as3DStatusUpdate[i].hKernelMemInfo, + psDoKickIN->sCCBKick.as3DStatusUpdate[i].hKernelMemInfo, + PVRSRV_HANDLE_TYPE_MEM_INFO); +#else + PVRSRVLookupHandle(psPerProc->psHandleBase, + &psDoKickIN->sCCBKick.ah3DStatusSyncInfo[i], + psDoKickIN->sCCBKick.ah3DStatusSyncInfo[i], + PVRSRV_HANDLE_TYPE_SYNC_INFO); +#endif + + if(psRetOUT->eError != PVRSRV_OK) + { + return 0; + } + } + + if(psDoKickIN->sCCBKick.ui32NumDstSyncObjects > 0) + { + psRetOUT->eError = + PVRSRVLookupHandle(psPerProc->psHandleBase, + &psDoKickIN->sCCBKick.hKernelHWSyncListMemInfo, + psDoKickIN->sCCBKick.hKernelHWSyncListMemInfo, + PVRSRV_HANDLE_TYPE_MEM_INFO); + + if(psRetOUT->eError != PVRSRV_OK) + { + return 0; + } + +#if defined(SGX_FEATURE_RENDER_TARGET_ARRAYS) + for( i = 0; i < psDoKickIN->sCCBKick.ui32NumDstSyncObjects; i++) + { + + if (psDoKickIN->sCCBKick.pasDstSyncHandles[i] != IMG_NULL) + { + psRetOUT->eError = + PVRSRVLookupHandle(psPerProc->psHandleBase, + &psDoKickIN->sCCBKick.pasDstSyncHandles[i], + psDoKickIN->sCCBKick.pasDstSyncHandles[i], + PVRSRV_HANDLE_TYPE_SYNC_INFO); + + if(psRetOUT->eError != PVRSRV_OK) + { + return 0; + } + } + } +#else + psRetOUT->eError = PVRSRVLookupHandle(psPerProc->psHandleBase, + &psDoKickIN->sCCBKick.sDstSyncHandle, + psDoKickIN->sCCBKick.sDstSyncHandle, + PVRSRV_HANDLE_TYPE_SYNC_INFO); + + if(psRetOUT->eError != PVRSRV_OK) + { + return 0; + } +#endif + } + + psRetOUT->eError = + SGXDoKickKM(hDevCookieInt, + &psDoKickIN->sCCBKick); + + return 0; +} + + +static IMG_INT +SGXScheduleProcessQueuesBW(IMG_UINT32 ui32BridgeID, + PVRSRV_BRIDGE_IN_SGX_SCHEDULE_PROCESS_QUEUES *psScheduleProcQIN, + PVRSRV_BRIDGE_RETURN *psRetOUT, + PVRSRV_PER_PROCESS_DATA *psPerProc) +{ + IMG_HANDLE hDevCookieInt; + + PVRSRV_BRIDGE_ASSERT_CMD(ui32BridgeID, PVRSRV_BRIDGE_SGX_SCHEDULE_PROCESS_QUEUES); + + psRetOUT->eError = + PVRSRVLookupHandle(psPerProc->psHandleBase, + &hDevCookieInt, + psScheduleProcQIN->hDevCookie, + PVRSRV_HANDLE_TYPE_DEV_NODE); + + if(psRetOUT->eError != PVRSRV_OK) + { + return 0; + } + + psRetOUT->eError = SGXScheduleProcessQueuesKM(hDevCookieInt); + + return 0; +} + + +#if defined(TRANSFER_QUEUE) +static IMG_INT +SGXSubmitTransferBW(IMG_UINT32 ui32BridgeID, + PVRSRV_BRIDGE_IN_SUBMITTRANSFER *psSubmitTransferIN, + PVRSRV_BRIDGE_RETURN *psRetOUT, + PVRSRV_PER_PROCESS_DATA *psPerProc) +{ + IMG_HANDLE hDevCookieInt; + PVRSRV_TRANSFER_SGX_KICK *psKick; + IMG_UINT32 i; + + PVRSRV_BRIDGE_ASSERT_CMD(ui32BridgeID, PVRSRV_BRIDGE_SGX_SUBMITTRANSFER); + PVR_UNREFERENCED_PARAMETER(ui32BridgeID); + + psKick = &psSubmitTransferIN->sKick; + + psRetOUT->eError = + PVRSRVLookupHandle(psPerProc->psHandleBase, + &hDevCookieInt, + psSubmitTransferIN->hDevCookie, + PVRSRV_HANDLE_TYPE_DEV_NODE); + if(psRetOUT->eError != PVRSRV_OK) + { + return 0; + } + + psRetOUT->eError = + PVRSRVLookupHandle(psPerProc->psHandleBase, + &psKick->hCCBMemInfo, + psKick->hCCBMemInfo, + PVRSRV_HANDLE_TYPE_MEM_INFO); + if(psRetOUT->eError != PVRSRV_OK) + { + return 0; + } + + if (psKick->hTASyncInfo != IMG_NULL) + { + psRetOUT->eError = + PVRSRVLookupHandle(psPerProc->psHandleBase, + &psKick->hTASyncInfo, + psKick->hTASyncInfo, + PVRSRV_HANDLE_TYPE_SYNC_INFO); + if(psRetOUT->eError != PVRSRV_OK) + { + return 0; + } + } + + if (psKick->h3DSyncInfo != IMG_NULL) + { + psRetOUT->eError = + PVRSRVLookupHandle(psPerProc->psHandleBase, + &psKick->h3DSyncInfo, + psKick->h3DSyncInfo, + PVRSRV_HANDLE_TYPE_SYNC_INFO); + if(psRetOUT->eError != PVRSRV_OK) + { + return 0; + } + } + + if (psKick->ui32NumSrcSync > SGX_MAX_TRANSFER_SYNC_OPS) + { + psRetOUT->eError = PVRSRV_ERROR_INVALID_PARAMS; + return 0; + } + for (i = 0; i < psKick->ui32NumSrcSync; i++) + { + psRetOUT->eError = + PVRSRVLookupHandle(psPerProc->psHandleBase, + &psKick->ahSrcSyncInfo[i], + psKick->ahSrcSyncInfo[i], + PVRSRV_HANDLE_TYPE_SYNC_INFO); + if(psRetOUT->eError != PVRSRV_OK) + { + return 0; + } + } + + if (psKick->ui32NumDstSync > SGX_MAX_TRANSFER_SYNC_OPS) + { + psRetOUT->eError = PVRSRV_ERROR_INVALID_PARAMS; + return 0; + } + for (i = 0; i < psKick->ui32NumDstSync; i++) + { + psRetOUT->eError = + PVRSRVLookupHandle(psPerProc->psHandleBase, + &psKick->ahDstSyncInfo[i], + psKick->ahDstSyncInfo[i], + PVRSRV_HANDLE_TYPE_SYNC_INFO); + if(psRetOUT->eError != PVRSRV_OK) + { + return 0; + } + } + + psRetOUT->eError = SGXSubmitTransferKM(hDevCookieInt, psKick); + + return 0; +} + + +#if defined(SGX_FEATURE_2D_HARDWARE) +static IMG_INT +SGXSubmit2DBW(IMG_UINT32 ui32BridgeID, + PVRSRV_BRIDGE_IN_SUBMIT2D *psSubmit2DIN, + PVRSRV_BRIDGE_RETURN *psRetOUT, + PVRSRV_PER_PROCESS_DATA *psPerProc) +{ + IMG_HANDLE hDevCookieInt; + PVRSRV_2D_SGX_KICK *psKick; + IMG_UINT32 i; + + PVRSRV_BRIDGE_ASSERT_CMD(ui32BridgeID, PVRSRV_BRIDGE_SGX_SUBMIT2D); + PVR_UNREFERENCED_PARAMETER(ui32BridgeID); + + psRetOUT->eError = + PVRSRVLookupHandle(psPerProc->psHandleBase, + &hDevCookieInt, + psSubmit2DIN->hDevCookie, + PVRSRV_HANDLE_TYPE_DEV_NODE); + + if(psRetOUT->eError != PVRSRV_OK) + { + return 0; + } + + psKick = &psSubmit2DIN->sKick; + + psRetOUT->eError = + PVRSRVLookupHandle(psPerProc->psHandleBase, + &psKick->hCCBMemInfo, + psKick->hCCBMemInfo, + PVRSRV_HANDLE_TYPE_MEM_INFO); + if(psRetOUT->eError != PVRSRV_OK) + { + return 0; + } + + if (psKick->hTASyncInfo != IMG_NULL) + { + psRetOUT->eError = + PVRSRVLookupHandle(psPerProc->psHandleBase, + &psKick->hTASyncInfo, + psKick->hTASyncInfo, + PVRSRV_HANDLE_TYPE_SYNC_INFO); + if(psRetOUT->eError != PVRSRV_OK) + { + return 0; + } + } + + if (psKick->h3DSyncInfo != IMG_NULL) + { + psRetOUT->eError = + PVRSRVLookupHandle(psPerProc->psHandleBase, + &psKick->h3DSyncInfo, + psKick->h3DSyncInfo, + PVRSRV_HANDLE_TYPE_SYNC_INFO); + if(psRetOUT->eError != PVRSRV_OK) + { + return 0; + } + } + + if (psKick->ui32NumSrcSync > SGX_MAX_2D_SRC_SYNC_OPS) + { + psRetOUT->eError = PVRSRV_ERROR_INVALID_PARAMS; + return 0; + } + for (i = 0; i < psKick->ui32NumSrcSync; i++) + { + psRetOUT->eError = + PVRSRVLookupHandle(psPerProc->psHandleBase, + &psKick->ahSrcSyncInfo[i], + psKick->ahSrcSyncInfo[i], + PVRSRV_HANDLE_TYPE_SYNC_INFO); + if(psRetOUT->eError != PVRSRV_OK) + { + return 0; + } + } + + if (psKick->hDstSyncInfo != IMG_NULL) + { + psRetOUT->eError = + PVRSRVLookupHandle(psPerProc->psHandleBase, + &psKick->hDstSyncInfo, + psKick->hDstSyncInfo, + PVRSRV_HANDLE_TYPE_SYNC_INFO); + if(psRetOUT->eError != PVRSRV_OK) + { + return 0; + } + } + + psRetOUT->eError = + SGXSubmit2DKM(hDevCookieInt, psKick); + + return 0; +} +#endif +#endif + + +static IMG_INT +SGXGetMiscInfoBW(IMG_UINT32 ui32BridgeID, + PVRSRV_BRIDGE_IN_SGXGETMISCINFO *psSGXGetMiscInfoIN, + PVRSRV_BRIDGE_RETURN *psRetOUT, + PVRSRV_PER_PROCESS_DATA *psPerProc) +{ + IMG_HANDLE hDevCookieInt; + PVRSRV_SGXDEV_INFO *psDevInfo; + SGX_MISC_INFO sMiscInfo; + PVRSRV_DEVICE_NODE *psDeviceNode; + + PVRSRV_BRIDGE_ASSERT_CMD(ui32BridgeID, + PVRSRV_BRIDGE_SGX_GETMISCINFO); + + psRetOUT->eError = PVRSRVLookupHandle(psPerProc->psHandleBase, + &hDevCookieInt, + psSGXGetMiscInfoIN->hDevCookie, + PVRSRV_HANDLE_TYPE_DEV_NODE); + + if(psRetOUT->eError != PVRSRV_OK) + { + return 0; + } + + + psDeviceNode = hDevCookieInt; + PVR_ASSERT(psDeviceNode != IMG_NULL); + if (psDeviceNode == IMG_NULL) + { + return -EFAULT; + } + + psDevInfo = psDeviceNode->pvDevice; + + + psRetOUT->eError = CopyFromUserWrapper(psPerProc, + ui32BridgeID, + &sMiscInfo, + psSGXGetMiscInfoIN->psMiscInfo, + sizeof(SGX_MISC_INFO)); + if (psRetOUT->eError != PVRSRV_OK) + { + return -EFAULT; + } + +#ifdef SUPPORT_SGX_HWPERF + if (sMiscInfo.eRequest == SGX_MISC_INFO_REQUEST_HWPERF_RETRIEVE_CB) + { + + IMG_VOID * pAllocated; + IMG_HANDLE hAllocatedHandle; + IMG_VOID * psTmpUserData; + IMG_UINT32 allocatedSize; + + allocatedSize = (IMG_UINT32)(sMiscInfo.uData.sRetrieveCB.ui32ArraySize * sizeof(PVRSRV_SGX_HWPERF_CBDATA)); + + ASSIGN_AND_EXIT_ON_ERROR(psRetOUT->eError, + OSAllocMem(PVRSRV_OS_PAGEABLE_HEAP, + allocatedSize, + &pAllocated, + &hAllocatedHandle)); + + + psTmpUserData = sMiscInfo.uData.sRetrieveCB.psHWPerfData; + sMiscInfo.uData.sRetrieveCB.psHWPerfData = pAllocated; + + psRetOUT->eError = SGXGetMiscInfoKM(psDevInfo, &sMiscInfo, psDeviceNode); + if (psRetOUT->eError != PVRSRV_OK) + { + OSFreeMem(PVRSRV_OS_PAGEABLE_HEAP, + allocatedSize, + pAllocated, + hAllocatedHandle); + return 0; + } + + + psRetOUT->eError = CopyToUserWrapper(psPerProc, + ui32BridgeID, + psTmpUserData, + sMiscInfo.uData.sRetrieveCB.psHWPerfData, + allocatedSize); + + sMiscInfo.uData.sRetrieveCB.psHWPerfData = psTmpUserData; + + OSFreeMem(PVRSRV_OS_PAGEABLE_HEAP, + allocatedSize, + pAllocated, + hAllocatedHandle); + + if (psRetOUT->eError != PVRSRV_OK) + { + return -EFAULT; + } + } + else +#endif + { + psRetOUT->eError = SGXGetMiscInfoKM(psDevInfo, &sMiscInfo, psDeviceNode); + + if (psRetOUT->eError != PVRSRV_OK) + { + return 0; + } + } + + + psRetOUT->eError = CopyToUserWrapper(psPerProc, + ui32BridgeID, + psSGXGetMiscInfoIN->psMiscInfo, + &sMiscInfo, + sizeof(SGX_MISC_INFO)); + if (psRetOUT->eError != PVRSRV_OK) + { + return -EFAULT; + } + return 0; +} + + +#if defined(SUPPORT_SGX_HWPERF) +static IMG_INT +SGXReadDiffCountersBW(IMG_UINT32 ui32BridgeID, + PVRSRV_BRIDGE_IN_SGX_READ_DIFF_COUNTERS *psSGXReadDiffCountersIN, + PVRSRV_BRIDGE_OUT_SGX_READ_DIFF_COUNTERS *psSGXReadDiffCountersOUT, + PVRSRV_PER_PROCESS_DATA *psPerProc) +{ + IMG_HANDLE hDevCookieInt; + + PVRSRV_BRIDGE_ASSERT_CMD(ui32BridgeID, PVRSRV_BRIDGE_SGX_READ_DIFF_COUNTERS); + + psSGXReadDiffCountersOUT->eError = PVRSRVLookupHandle(psPerProc->psHandleBase, + &hDevCookieInt, + psSGXReadDiffCountersIN->hDevCookie, + PVRSRV_HANDLE_TYPE_DEV_NODE); + + if(psSGXReadDiffCountersOUT->eError != PVRSRV_OK) + { + return 0; + } + + psSGXReadDiffCountersOUT->eError = SGXReadDiffCountersKM(hDevCookieInt, + psSGXReadDiffCountersIN->ui32Reg, + &psSGXReadDiffCountersOUT->ui32Old, + psSGXReadDiffCountersIN->bNew, + psSGXReadDiffCountersIN->ui32New, + psSGXReadDiffCountersIN->ui32NewReset, + psSGXReadDiffCountersIN->ui32CountersReg, + &psSGXReadDiffCountersOUT->ui32Time, + &psSGXReadDiffCountersOUT->bActive, + &psSGXReadDiffCountersOUT->sDiffs); + + return 0; +} + + +static IMG_INT +SGXReadHWPerfCBBW(IMG_UINT32 ui32BridgeID, + PVRSRV_BRIDGE_IN_SGX_READ_HWPERF_CB *psSGXReadHWPerfCBIN, + PVRSRV_BRIDGE_OUT_SGX_READ_HWPERF_CB *psSGXReadHWPerfCBOUT, + PVRSRV_PER_PROCESS_DATA *psPerProc) +{ + IMG_HANDLE hDevCookieInt; + PVRSRV_SGX_HWPERF_CB_ENTRY *psAllocated; + IMG_HANDLE hAllocatedHandle; + IMG_UINT32 ui32AllocatedSize; + + PVRSRV_BRIDGE_ASSERT_CMD(ui32BridgeID, PVRSRV_BRIDGE_SGX_READ_HWPERF_CB); + + psSGXReadHWPerfCBOUT->eError = PVRSRVLookupHandle(psPerProc->psHandleBase, + &hDevCookieInt, + psSGXReadHWPerfCBIN->hDevCookie, + PVRSRV_HANDLE_TYPE_DEV_NODE); + + if(psSGXReadHWPerfCBOUT->eError != PVRSRV_OK) + { + return 0; + } + + ui32AllocatedSize = psSGXReadHWPerfCBIN->ui32ArraySize * + sizeof(psSGXReadHWPerfCBIN->psHWPerfCBData[0]); + ASSIGN_AND_EXIT_ON_ERROR(psSGXReadHWPerfCBOUT->eError, + OSAllocMem(PVRSRV_OS_PAGEABLE_HEAP, + ui32AllocatedSize, + (IMG_VOID **)&psAllocated, + &hAllocatedHandle)); + + psSGXReadHWPerfCBOUT->eError = SGXReadHWPerfCBKM(hDevCookieInt, + psSGXReadHWPerfCBIN->ui32ArraySize, + psAllocated, + &psSGXReadHWPerfCBOUT->ui32DataCount, + &psSGXReadHWPerfCBOUT->ui32ClockSpeed, + &psSGXReadHWPerfCBOUT->ui32HostTimeStamp); + if (psSGXReadHWPerfCBOUT->eError == PVRSRV_OK) + { + psSGXReadHWPerfCBOUT->eError = CopyToUserWrapper(psPerProc, + ui32BridgeID, + psSGXReadHWPerfCBIN->psHWPerfCBData, + psAllocated, + ui32AllocatedSize); + } + + OSFreeMem(PVRSRV_OS_PAGEABLE_HEAP, + ui32AllocatedSize, + psAllocated, + hAllocatedHandle); + + return 0; +} +#endif + + +static IMG_INT +SGXDevInitPart2BW(IMG_UINT32 ui32BridgeID, + PVRSRV_BRIDGE_IN_SGXDEVINITPART2 *psSGXDevInitPart2IN, + PVRSRV_BRIDGE_RETURN *psRetOUT, + PVRSRV_PER_PROCESS_DATA *psPerProc) +{ + IMG_HANDLE hDevCookieInt; + PVRSRV_ERROR eError; + IMG_BOOL bDissociateFailed = IMG_FALSE; + IMG_BOOL bLookupFailed = IMG_FALSE; + IMG_BOOL bReleaseFailed = IMG_FALSE; + IMG_HANDLE hDummy; + IMG_UINT32 i; + + PVRSRV_BRIDGE_ASSERT_CMD(ui32BridgeID, PVRSRV_BRIDGE_SGX_DEVINITPART2); + + if(!psPerProc->bInitProcess) + { + psRetOUT->eError = PVRSRV_ERROR_GENERIC; + return 0; + } + + psRetOUT->eError = + PVRSRVLookupHandle(psPerProc->psHandleBase, + &hDevCookieInt, + psSGXDevInitPart2IN->hDevCookie, + PVRSRV_HANDLE_TYPE_DEV_NODE); + if(psRetOUT->eError != PVRSRV_OK) + { + return 0; + } + + + eError = PVRSRVLookupHandle(psPerProc->psHandleBase, + &hDummy, + psSGXDevInitPart2IN->sInitInfo.hKernelCCBMemInfo, + PVRSRV_HANDLE_TYPE_MEM_INFO); + bLookupFailed |= (IMG_BOOL)(eError != PVRSRV_OK); + + eError = PVRSRVLookupHandle(psPerProc->psHandleBase, + &hDummy, + psSGXDevInitPart2IN->sInitInfo.hKernelCCBCtlMemInfo, + PVRSRV_HANDLE_TYPE_MEM_INFO); + bLookupFailed |= (IMG_BOOL)(eError != PVRSRV_OK); + + eError = PVRSRVLookupHandle(psPerProc->psHandleBase, + &hDummy, + psSGXDevInitPart2IN->sInitInfo.hKernelCCBEventKickerMemInfo, + PVRSRV_HANDLE_TYPE_MEM_INFO); + bLookupFailed |= (IMG_BOOL)(eError != PVRSRV_OK); + + eError = PVRSRVLookupHandle(psPerProc->psHandleBase, + &hDummy, + psSGXDevInitPart2IN->sInitInfo.hKernelSGXHostCtlMemInfo, + PVRSRV_HANDLE_TYPE_MEM_INFO); + bLookupFailed |= (IMG_BOOL)(eError != PVRSRV_OK); + + eError = PVRSRVLookupHandle(psPerProc->psHandleBase, + &hDummy, + psSGXDevInitPart2IN->sInitInfo.hKernelSGXTA3DCtlMemInfo, + PVRSRV_HANDLE_TYPE_MEM_INFO); + bLookupFailed |= (IMG_BOOL)(eError != PVRSRV_OK); + + + eError = PVRSRVLookupHandle(psPerProc->psHandleBase, + &hDummy, + psSGXDevInitPart2IN->sInitInfo.hKernelSGXMiscMemInfo, + PVRSRV_HANDLE_TYPE_MEM_INFO); + bLookupFailed |= (IMG_BOOL)(eError != PVRSRV_OK); + +#if defined(SGX_SUPPORT_HWPROFILING) + eError = PVRSRVLookupHandle(psPerProc->psHandleBase, + &hDummy, + psSGXDevInitPart2IN->sInitInfo.hKernelHWProfilingMemInfo, + PVRSRV_HANDLE_TYPE_MEM_INFO); + bLookupFailed |= (IMG_BOOL)(eError != PVRSRV_OK); +#endif + +#if defined(SUPPORT_SGX_HWPERF) + eError = PVRSRVLookupHandle(psPerProc->psHandleBase, + &hDummy, + psSGXDevInitPart2IN->sInitInfo.hKernelHWPerfCBMemInfo, + PVRSRV_HANDLE_TYPE_MEM_INFO); + bLookupFailed |= (IMG_BOOL)(eError != PVRSRV_OK); +#endif + +#if defined(PVRSRV_USSE_EDM_STATUS_DEBUG) + eError = PVRSRVLookupHandle(psPerProc->psHandleBase, + &hDummy, + psSGXDevInitPart2IN->sInitInfo.hKernelEDMStatusBufferMemInfo, + PVRSRV_HANDLE_TYPE_MEM_INFO); + bLookupFailed |= (IMG_BOOL)(eError != PVRSRV_OK); +#endif + + for (i = 0; i < SGX_MAX_INIT_MEM_HANDLES; i++) + { + IMG_HANDLE hHandle = psSGXDevInitPart2IN->sInitInfo.asInitMemHandles[i]; + + if (hHandle == IMG_NULL) + { + continue; + } + + eError = PVRSRVLookupHandle(psPerProc->psHandleBase, + &hDummy, + hHandle, + PVRSRV_HANDLE_TYPE_MEM_INFO); + bLookupFailed |= (IMG_BOOL)(eError != PVRSRV_OK); + } + + if (bLookupFailed) + { + PVR_DPF((PVR_DBG_ERROR, "DevInitSGXPart2BW: A handle lookup failed")); + psRetOUT->eError = PVRSRV_ERROR_GENERIC; + return 0; + } + + + eError = PVRSRVLookupAndReleaseHandle(psPerProc->psHandleBase, + &psSGXDevInitPart2IN->sInitInfo.hKernelCCBMemInfo, + psSGXDevInitPart2IN->sInitInfo.hKernelCCBMemInfo, + PVRSRV_HANDLE_TYPE_MEM_INFO); + bReleaseFailed |= (IMG_BOOL)(eError != PVRSRV_OK); + + eError = PVRSRVLookupAndReleaseHandle(psPerProc->psHandleBase, + &psSGXDevInitPart2IN->sInitInfo.hKernelCCBCtlMemInfo, + psSGXDevInitPart2IN->sInitInfo.hKernelCCBCtlMemInfo, + PVRSRV_HANDLE_TYPE_MEM_INFO); + bReleaseFailed |= (IMG_BOOL)(eError != PVRSRV_OK); + + eError = PVRSRVLookupAndReleaseHandle(psPerProc->psHandleBase, + &psSGXDevInitPart2IN->sInitInfo.hKernelCCBEventKickerMemInfo, + psSGXDevInitPart2IN->sInitInfo.hKernelCCBEventKickerMemInfo, + PVRSRV_HANDLE_TYPE_MEM_INFO); + bReleaseFailed |= (IMG_BOOL)(eError != PVRSRV_OK); + + + eError = PVRSRVLookupAndReleaseHandle(psPerProc->psHandleBase, + &psSGXDevInitPart2IN->sInitInfo.hKernelSGXHostCtlMemInfo, + psSGXDevInitPart2IN->sInitInfo.hKernelSGXHostCtlMemInfo, + PVRSRV_HANDLE_TYPE_MEM_INFO); + bReleaseFailed |= (IMG_BOOL)(eError != PVRSRV_OK); + + eError = PVRSRVLookupAndReleaseHandle(psPerProc->psHandleBase, + &psSGXDevInitPart2IN->sInitInfo.hKernelSGXTA3DCtlMemInfo, + psSGXDevInitPart2IN->sInitInfo.hKernelSGXTA3DCtlMemInfo, + PVRSRV_HANDLE_TYPE_MEM_INFO); + bReleaseFailed |= (IMG_BOOL)(eError != PVRSRV_OK); + + eError = PVRSRVLookupAndReleaseHandle(psPerProc->psHandleBase, + &psSGXDevInitPart2IN->sInitInfo.hKernelSGXMiscMemInfo, + psSGXDevInitPart2IN->sInitInfo.hKernelSGXMiscMemInfo, + PVRSRV_HANDLE_TYPE_MEM_INFO); + bReleaseFailed |= (IMG_BOOL)(eError != PVRSRV_OK); + + + #if defined(SGX_SUPPORT_HWPROFILING) + eError = PVRSRVLookupAndReleaseHandle(psPerProc->psHandleBase, + &psSGXDevInitPart2IN->sInitInfo.hKernelHWProfilingMemInfo, + psSGXDevInitPart2IN->sInitInfo.hKernelHWProfilingMemInfo, + PVRSRV_HANDLE_TYPE_MEM_INFO); + bReleaseFailed |= (IMG_BOOL)(eError != PVRSRV_OK); +#endif + +#if defined(SUPPORT_SGX_HWPERF) + eError = PVRSRVLookupAndReleaseHandle(psPerProc->psHandleBase, + &psSGXDevInitPart2IN->sInitInfo.hKernelHWPerfCBMemInfo, + psSGXDevInitPart2IN->sInitInfo.hKernelHWPerfCBMemInfo, + PVRSRV_HANDLE_TYPE_MEM_INFO); + bReleaseFailed |= (IMG_BOOL)(eError != PVRSRV_OK); +#endif + +#if defined(PVRSRV_USSE_EDM_STATUS_DEBUG) + eError = PVRSRVLookupAndReleaseHandle(psPerProc->psHandleBase, + &psSGXDevInitPart2IN->sInitInfo.hKernelEDMStatusBufferMemInfo, + psSGXDevInitPart2IN->sInitInfo.hKernelEDMStatusBufferMemInfo, + PVRSRV_HANDLE_TYPE_MEM_INFO); + bReleaseFailed |= (IMG_BOOL)(eError != PVRSRV_OK); +#endif + + for (i = 0; i < SGX_MAX_INIT_MEM_HANDLES; i++) + { + IMG_HANDLE *phHandle = &psSGXDevInitPart2IN->sInitInfo.asInitMemHandles[i]; + + if (*phHandle == IMG_NULL) + continue; + + eError = PVRSRVLookupAndReleaseHandle(psPerProc->psHandleBase, + phHandle, + *phHandle, + PVRSRV_HANDLE_TYPE_MEM_INFO); + bReleaseFailed |= (IMG_BOOL)(eError != PVRSRV_OK); + } + + if (bReleaseFailed) + { + PVR_DPF((PVR_DBG_ERROR, "DevInitSGXPart2BW: A handle release failed")); + psRetOUT->eError = PVRSRV_ERROR_GENERIC; + + PVR_DBG_BREAK; + return 0; + } + + + eError = PVRSRVDissociateDeviceMemKM(hDevCookieInt, psSGXDevInitPart2IN->sInitInfo.hKernelCCBMemInfo); + bDissociateFailed |= (IMG_BOOL)(eError != PVRSRV_OK); + + eError = PVRSRVDissociateDeviceMemKM(hDevCookieInt, psSGXDevInitPart2IN->sInitInfo.hKernelCCBCtlMemInfo); + bDissociateFailed |= (IMG_BOOL)(eError != PVRSRV_OK); + + eError = PVRSRVDissociateDeviceMemKM(hDevCookieInt, psSGXDevInitPart2IN->sInitInfo.hKernelCCBEventKickerMemInfo); + bDissociateFailed |= (IMG_BOOL)(eError != PVRSRV_OK); + + eError = PVRSRVDissociateDeviceMemKM(hDevCookieInt, psSGXDevInitPart2IN->sInitInfo.hKernelSGXHostCtlMemInfo); + bDissociateFailed |= (IMG_BOOL)(eError != PVRSRV_OK); + + eError = PVRSRVDissociateDeviceMemKM(hDevCookieInt, psSGXDevInitPart2IN->sInitInfo.hKernelSGXTA3DCtlMemInfo); + bDissociateFailed |= (IMG_BOOL)(eError != PVRSRV_OK); + + + eError = PVRSRVDissociateDeviceMemKM(hDevCookieInt, psSGXDevInitPart2IN->sInitInfo.hKernelSGXMiscMemInfo); + bDissociateFailed |= (IMG_BOOL)(eError != PVRSRV_OK); + + +#if defined(SGX_SUPPORT_HWPROFILING) + eError = PVRSRVDissociateDeviceMemKM(hDevCookieInt, psSGXDevInitPart2IN->sInitInfo.hKernelHWProfilingMemInfo); + bDissociateFailed |= (IMG_BOOL)(eError != PVRSRV_OK); +#endif + +#if defined(SUPPORT_SGX_HWPERF) + eError = PVRSRVDissociateDeviceMemKM(hDevCookieInt, psSGXDevInitPart2IN->sInitInfo.hKernelHWPerfCBMemInfo); + bDissociateFailed |= (IMG_BOOL)(eError != PVRSRV_OK); +#endif + +#if defined(PVRSRV_USSE_EDM_STATUS_DEBUG) + eError = PVRSRVDissociateDeviceMemKM(hDevCookieInt, psSGXDevInitPart2IN->sInitInfo.hKernelEDMStatusBufferMemInfo); + bDissociateFailed |= (IMG_BOOL)(eError != PVRSRV_OK); +#endif + + for (i = 0; i < SGX_MAX_INIT_MEM_HANDLES; i++) + { + IMG_HANDLE hHandle = psSGXDevInitPart2IN->sInitInfo.asInitMemHandles[i]; + + if (hHandle == IMG_NULL) + continue; + + eError = PVRSRVDissociateDeviceMemKM(hDevCookieInt, hHandle); + bDissociateFailed |= (IMG_BOOL)(eError != PVRSRV_OK); + } + + + if(bDissociateFailed) + { + PVRSRVFreeDeviceMemKM(hDevCookieInt, psSGXDevInitPart2IN->sInitInfo.hKernelCCBMemInfo); + PVRSRVFreeDeviceMemKM(hDevCookieInt, psSGXDevInitPart2IN->sInitInfo.hKernelCCBCtlMemInfo); + PVRSRVFreeDeviceMemKM(hDevCookieInt, psSGXDevInitPart2IN->sInitInfo.hKernelSGXHostCtlMemInfo); + PVRSRVFreeDeviceMemKM(hDevCookieInt, psSGXDevInitPart2IN->sInitInfo.hKernelSGXTA3DCtlMemInfo); + PVRSRVFreeDeviceMemKM(hDevCookieInt, psSGXDevInitPart2IN->sInitInfo.hKernelSGXMiscMemInfo); + + for (i = 0; i < SGX_MAX_INIT_MEM_HANDLES; i++) + { + IMG_HANDLE hHandle = psSGXDevInitPart2IN->sInitInfo.asInitMemHandles[i]; + + if (hHandle == IMG_NULL) + continue; + + PVRSRVFreeDeviceMemKM(hDevCookieInt, (PVRSRV_KERNEL_MEM_INFO *)hHandle); + + } + + PVR_DPF((PVR_DBG_ERROR, "DevInitSGXPart2BW: A dissociate failed")); + + psRetOUT->eError = PVRSRV_ERROR_GENERIC; + + + PVR_DBG_BREAK; + return 0; + } + + psRetOUT->eError = + DevInitSGXPart2KM(psPerProc, + hDevCookieInt, + &psSGXDevInitPart2IN->sInitInfo); + + return 0; +} + + +static IMG_INT +SGXRegisterHWRenderContextBW(IMG_UINT32 ui32BridgeID, + PVRSRV_BRIDGE_IN_SGX_REGISTER_HW_RENDER_CONTEXT *psSGXRegHWRenderContextIN, + PVRSRV_BRIDGE_OUT_SGX_REGISTER_HW_RENDER_CONTEXT *psSGXRegHWRenderContextOUT, + PVRSRV_PER_PROCESS_DATA *psPerProc) +{ + IMG_HANDLE hDevCookieInt; + IMG_HANDLE hHWRenderContextInt; + + PVRSRV_BRIDGE_ASSERT_CMD(ui32BridgeID, PVRSRV_BRIDGE_SGX_REGISTER_HW_RENDER_CONTEXT); + + NEW_HANDLE_BATCH_OR_ERROR(psSGXRegHWRenderContextOUT->eError, psPerProc, 1); + + psSGXRegHWRenderContextOUT->eError = + PVRSRVLookupHandle(psPerProc->psHandleBase, + &hDevCookieInt, + psSGXRegHWRenderContextIN->hDevCookie, + PVRSRV_HANDLE_TYPE_DEV_NODE); + if(psSGXRegHWRenderContextOUT->eError != PVRSRV_OK) + { + return 0; + } + + hHWRenderContextInt = + SGXRegisterHWRenderContextKM(hDevCookieInt, + &psSGXRegHWRenderContextIN->sHWRenderContextDevVAddr, + psPerProc); + + if (hHWRenderContextInt == IMG_NULL) + { + psSGXRegHWRenderContextOUT->eError = PVRSRV_ERROR_GENERIC; + return 0; + } + + PVRSRVAllocHandleNR(psPerProc->psHandleBase, + &psSGXRegHWRenderContextOUT->hHWRenderContext, + hHWRenderContextInt, + PVRSRV_HANDLE_TYPE_SGX_HW_RENDER_CONTEXT, + PVRSRV_HANDLE_ALLOC_FLAG_NONE); + + COMMIT_HANDLE_BATCH_OR_ERROR(psSGXRegHWRenderContextOUT->eError, psPerProc); + + return 0; +} + + +static IMG_INT +SGXUnregisterHWRenderContextBW(IMG_UINT32 ui32BridgeID, + PVRSRV_BRIDGE_IN_SGX_UNREGISTER_HW_RENDER_CONTEXT *psSGXUnregHWRenderContextIN, + PVRSRV_BRIDGE_RETURN *psRetOUT, + PVRSRV_PER_PROCESS_DATA *psPerProc) +{ + IMG_HANDLE hHWRenderContextInt; + + PVRSRV_BRIDGE_ASSERT_CMD(ui32BridgeID, PVRSRV_BRIDGE_SGX_UNREGISTER_HW_RENDER_CONTEXT); + + psRetOUT->eError = + PVRSRVLookupHandle(psPerProc->psHandleBase, + &hHWRenderContextInt, + psSGXUnregHWRenderContextIN->hHWRenderContext, + PVRSRV_HANDLE_TYPE_SGX_HW_RENDER_CONTEXT); + if(psRetOUT->eError != PVRSRV_OK) + { + return 0; + } + + psRetOUT->eError = SGXUnregisterHWRenderContextKM(hHWRenderContextInt); + if(psRetOUT->eError != PVRSRV_OK) + { + return 0; + } + + psRetOUT->eError = + PVRSRVReleaseHandle(psPerProc->psHandleBase, + psSGXUnregHWRenderContextIN->hHWRenderContext, + PVRSRV_HANDLE_TYPE_SGX_HW_RENDER_CONTEXT); + + return 0; +} + + +static IMG_INT +SGXRegisterHWTransferContextBW(IMG_UINT32 ui32BridgeID, + PVRSRV_BRIDGE_IN_SGX_REGISTER_HW_TRANSFER_CONTEXT *psSGXRegHWTransferContextIN, + PVRSRV_BRIDGE_OUT_SGX_REGISTER_HW_TRANSFER_CONTEXT *psSGXRegHWTransferContextOUT, + PVRSRV_PER_PROCESS_DATA *psPerProc) +{ + IMG_HANDLE hDevCookieInt; + IMG_HANDLE hHWTransferContextInt; + + PVRSRV_BRIDGE_ASSERT_CMD(ui32BridgeID, PVRSRV_BRIDGE_SGX_REGISTER_HW_TRANSFER_CONTEXT); + + NEW_HANDLE_BATCH_OR_ERROR(psSGXRegHWTransferContextOUT->eError, psPerProc, 1); + + psSGXRegHWTransferContextOUT->eError = + PVRSRVLookupHandle(psPerProc->psHandleBase, + &hDevCookieInt, + psSGXRegHWTransferContextIN->hDevCookie, + PVRSRV_HANDLE_TYPE_DEV_NODE); + if(psSGXRegHWTransferContextOUT->eError != PVRSRV_OK) + { + return 0; + } + + hHWTransferContextInt = + SGXRegisterHWTransferContextKM(hDevCookieInt, + &psSGXRegHWTransferContextIN->sHWTransferContextDevVAddr, + psPerProc); + + if (hHWTransferContextInt == IMG_NULL) + { + psSGXRegHWTransferContextOUT->eError = PVRSRV_ERROR_GENERIC; + return 0; + } + + PVRSRVAllocHandleNR(psPerProc->psHandleBase, + &psSGXRegHWTransferContextOUT->hHWTransferContext, + hHWTransferContextInt, + PVRSRV_HANDLE_TYPE_SGX_HW_TRANSFER_CONTEXT, + PVRSRV_HANDLE_ALLOC_FLAG_NONE); + + COMMIT_HANDLE_BATCH_OR_ERROR(psSGXRegHWTransferContextOUT->eError, psPerProc); + + return 0; +} + + +static IMG_INT +SGXUnregisterHWTransferContextBW(IMG_UINT32 ui32BridgeID, + PVRSRV_BRIDGE_IN_SGX_UNREGISTER_HW_TRANSFER_CONTEXT *psSGXUnregHWTransferContextIN, + PVRSRV_BRIDGE_RETURN *psRetOUT, + PVRSRV_PER_PROCESS_DATA *psPerProc) +{ + IMG_HANDLE hHWTransferContextInt; + + PVRSRV_BRIDGE_ASSERT_CMD(ui32BridgeID, PVRSRV_BRIDGE_SGX_UNREGISTER_HW_TRANSFER_CONTEXT); + + psRetOUT->eError = + PVRSRVLookupHandle(psPerProc->psHandleBase, + &hHWTransferContextInt, + psSGXUnregHWTransferContextIN->hHWTransferContext, + PVRSRV_HANDLE_TYPE_SGX_HW_TRANSFER_CONTEXT); + if(psRetOUT->eError != PVRSRV_OK) + { + return 0; + } + + psRetOUT->eError = SGXUnregisterHWTransferContextKM(hHWTransferContextInt); + if(psRetOUT->eError != PVRSRV_OK) + { + return 0; + } + + psRetOUT->eError = + PVRSRVReleaseHandle(psPerProc->psHandleBase, + psSGXUnregHWTransferContextIN->hHWTransferContext, + PVRSRV_HANDLE_TYPE_SGX_HW_TRANSFER_CONTEXT); + + return 0; +} + + +#if defined(SGX_FEATURE_2D_HARDWARE) +static IMG_INT +SGXRegisterHW2DContextBW(IMG_UINT32 ui32BridgeID, + PVRSRV_BRIDGE_IN_SGX_REGISTER_HW_2D_CONTEXT *psSGXRegHW2DContextIN, + PVRSRV_BRIDGE_OUT_SGX_REGISTER_HW_2D_CONTEXT *psSGXRegHW2DContextOUT, + PVRSRV_PER_PROCESS_DATA *psPerProc) +{ + IMG_HANDLE hDevCookieInt; + IMG_HANDLE hHW2DContextInt; + + PVRSRV_BRIDGE_ASSERT_CMD(ui32BridgeID, PVRSRV_BRIDGE_SGX_REGISTER_HW_2D_CONTEXT); + + NEW_HANDLE_BATCH_OR_ERROR(psSGXRegHW2DContextOUT->eError, psPerProc, 1); + + psSGXRegHW2DContextOUT->eError = + PVRSRVLookupHandle(psPerProc->psHandleBase, + &hDevCookieInt, + psSGXRegHW2DContextIN->hDevCookie, + PVRSRV_HANDLE_TYPE_DEV_NODE); + if(psSGXRegHW2DContextOUT->eError != PVRSRV_OK) + { + return 0; + } + + hHW2DContextInt = + SGXRegisterHW2DContextKM(hDevCookieInt, + &psSGXRegHW2DContextIN->sHW2DContextDevVAddr, + psPerProc); + + if (hHW2DContextInt == IMG_NULL) + { + psSGXRegHW2DContextOUT->eError = PVRSRV_ERROR_GENERIC; + return 0; + } + + PVRSRVAllocHandleNR(psPerProc->psHandleBase, + &psSGXRegHW2DContextOUT->hHW2DContext, + hHW2DContextInt, + PVRSRV_HANDLE_TYPE_SGX_HW_2D_CONTEXT, + PVRSRV_HANDLE_ALLOC_FLAG_NONE); + + COMMIT_HANDLE_BATCH_OR_ERROR(psSGXRegHW2DContextOUT->eError, psPerProc); + + return 0; +} + + +static IMG_INT +SGXUnregisterHW2DContextBW(IMG_UINT32 ui32BridgeID, + PVRSRV_BRIDGE_IN_SGX_UNREGISTER_HW_2D_CONTEXT *psSGXUnregHW2DContextIN, + PVRSRV_BRIDGE_RETURN *psRetOUT, + PVRSRV_PER_PROCESS_DATA *psPerProc) +{ + IMG_HANDLE hHW2DContextInt; + + PVRSRV_BRIDGE_ASSERT_CMD(ui32BridgeID, PVRSRV_BRIDGE_SGX_UNREGISTER_HW_2D_CONTEXT); + + psRetOUT->eError = + PVRSRVLookupHandle(psPerProc->psHandleBase, + &hHW2DContextInt, + psSGXUnregHW2DContextIN->hHW2DContext, + PVRSRV_HANDLE_TYPE_SGX_HW_2D_CONTEXT); + if(psRetOUT->eError != PVRSRV_OK) + { + return 0; + } + + psRetOUT->eError = SGXUnregisterHW2DContextKM(hHW2DContextInt); + if(psRetOUT->eError != PVRSRV_OK) + { + return 0; + } + + psRetOUT->eError = + PVRSRVReleaseHandle(psPerProc->psHandleBase, + psSGXUnregHW2DContextIN->hHW2DContext, + PVRSRV_HANDLE_TYPE_SGX_HW_2D_CONTEXT); + + return 0; +} +#endif + +static IMG_INT +SGXFlushHWRenderTargetBW(IMG_UINT32 ui32BridgeID, + PVRSRV_BRIDGE_IN_SGX_FLUSH_HW_RENDER_TARGET *psSGXFlushHWRenderTargetIN, + PVRSRV_BRIDGE_RETURN *psRetOUT, + PVRSRV_PER_PROCESS_DATA *psPerProc) +{ + IMG_HANDLE hDevCookieInt; + PVRSRV_BRIDGE_ASSERT_CMD(ui32BridgeID, PVRSRV_BRIDGE_SGX_FLUSH_HW_RENDER_TARGET); + + psRetOUT->eError = + PVRSRVLookupHandle(psPerProc->psHandleBase, + &hDevCookieInt, + psSGXFlushHWRenderTargetIN->hDevCookie, + PVRSRV_HANDLE_TYPE_DEV_NODE); + if(psRetOUT->eError != PVRSRV_OK) + { + return 0; + } + + SGXFlushHWRenderTargetKM(hDevCookieInt, psSGXFlushHWRenderTargetIN->sHWRTDataSetDevVAddr); + + return 0; +} + + +static IMG_INT +SGX2DQueryBlitsCompleteBW(IMG_UINT32 ui32BridgeID, + PVRSRV_BRIDGE_IN_2DQUERYBLTSCOMPLETE *ps2DQueryBltsCompleteIN, + PVRSRV_BRIDGE_RETURN *psRetOUT, + PVRSRV_PER_PROCESS_DATA *psPerProc) +{ + IMG_HANDLE hDevCookieInt; + IMG_VOID *pvSyncInfo; + PVRSRV_SGXDEV_INFO *psDevInfo; + + PVRSRV_BRIDGE_ASSERT_CMD(ui32BridgeID, PVRSRV_BRIDGE_SGX_2DQUERYBLTSCOMPLETE); + + psRetOUT->eError = + PVRSRVLookupHandle(psPerProc->psHandleBase, &hDevCookieInt, + ps2DQueryBltsCompleteIN->hDevCookie, + PVRSRV_HANDLE_TYPE_DEV_NODE); + if(psRetOUT->eError != PVRSRV_OK) + { + return 0; + } + + psRetOUT->eError = + PVRSRVLookupHandle(psPerProc->psHandleBase, &pvSyncInfo, + ps2DQueryBltsCompleteIN->hKernSyncInfo, + PVRSRV_HANDLE_TYPE_SYNC_INFO); + if(psRetOUT->eError != PVRSRV_OK) + { + return 0; + } + + psDevInfo = (PVRSRV_SGXDEV_INFO *)((PVRSRV_DEVICE_NODE *)hDevCookieInt)->pvDevice; + + psRetOUT->eError = + SGX2DQueryBlitsCompleteKM(psDevInfo, + (PVRSRV_KERNEL_SYNC_INFO *)pvSyncInfo, + ps2DQueryBltsCompleteIN->bWaitForComplete); + + return 0; +} + + +static IMG_INT +SGXFindSharedPBDescBW(IMG_UINT32 ui32BridgeID, + PVRSRV_BRIDGE_IN_SGXFINDSHAREDPBDESC *psSGXFindSharedPBDescIN, + PVRSRV_BRIDGE_OUT_SGXFINDSHAREDPBDESC *psSGXFindSharedPBDescOUT, + PVRSRV_PER_PROCESS_DATA *psPerProc) +{ + IMG_HANDLE hDevCookieInt; + PVRSRV_KERNEL_MEM_INFO *psSharedPBDescKernelMemInfo; + PVRSRV_KERNEL_MEM_INFO *psHWPBDescKernelMemInfo; + PVRSRV_KERNEL_MEM_INFO *psBlockKernelMemInfo; + PVRSRV_KERNEL_MEM_INFO **ppsSharedPBDescSubKernelMemInfos = IMG_NULL; + IMG_UINT32 ui32SharedPBDescSubKernelMemInfosCount = 0; + IMG_UINT32 i; + IMG_HANDLE hSharedPBDesc = IMG_NULL; + + PVRSRV_BRIDGE_ASSERT_CMD(ui32BridgeID, PVRSRV_BRIDGE_SGX_FINDSHAREDPBDESC); + + NEW_HANDLE_BATCH_OR_ERROR(psSGXFindSharedPBDescOUT->eError, psPerProc, PVRSRV_BRIDGE_SGX_SHAREDPBDESC_MAX_SUBMEMINFOS + 4); + + psSGXFindSharedPBDescOUT->hSharedPBDesc = IMG_NULL; + + psSGXFindSharedPBDescOUT->eError = + PVRSRVLookupHandle(psPerProc->psHandleBase, + &hDevCookieInt, + psSGXFindSharedPBDescIN->hDevCookie, + PVRSRV_HANDLE_TYPE_DEV_NODE); + if(psSGXFindSharedPBDescOUT->eError != PVRSRV_OK) + goto PVRSRV_BRIDGE_SGX_FINDSHAREDPBDESC_EXIT; + + psSGXFindSharedPBDescOUT->eError = + SGXFindSharedPBDescKM(psPerProc, hDevCookieInt, + psSGXFindSharedPBDescIN->bLockOnFailure, + psSGXFindSharedPBDescIN->ui32TotalPBSize, + &hSharedPBDesc, + &psSharedPBDescKernelMemInfo, + &psHWPBDescKernelMemInfo, + &psBlockKernelMemInfo, + &ppsSharedPBDescSubKernelMemInfos, + &ui32SharedPBDescSubKernelMemInfosCount); + if(psSGXFindSharedPBDescOUT->eError != PVRSRV_OK) + goto PVRSRV_BRIDGE_SGX_FINDSHAREDPBDESC_EXIT; + + PVR_ASSERT(ui32SharedPBDescSubKernelMemInfosCount + <= PVRSRV_BRIDGE_SGX_SHAREDPBDESC_MAX_SUBMEMINFOS); + + psSGXFindSharedPBDescOUT->ui32SharedPBDescSubKernelMemInfoHandlesCount = + ui32SharedPBDescSubKernelMemInfosCount; + + if(hSharedPBDesc == IMG_NULL) + { + psSGXFindSharedPBDescOUT->hSharedPBDescKernelMemInfoHandle = 0; + + goto PVRSRV_BRIDGE_SGX_FINDSHAREDPBDESC_EXIT; + } + + PVRSRVAllocHandleNR(psPerProc->psHandleBase, + &psSGXFindSharedPBDescOUT->hSharedPBDesc, + hSharedPBDesc, + PVRSRV_HANDLE_TYPE_SHARED_PB_DESC, + PVRSRV_HANDLE_ALLOC_FLAG_NONE); + + + PVRSRVAllocSubHandleNR(psPerProc->psHandleBase, + &psSGXFindSharedPBDescOUT->hSharedPBDescKernelMemInfoHandle, + psSharedPBDescKernelMemInfo, + PVRSRV_HANDLE_TYPE_MEM_INFO_REF, + PVRSRV_HANDLE_ALLOC_FLAG_MULTI, + psSGXFindSharedPBDescOUT->hSharedPBDesc); + + PVRSRVAllocSubHandleNR(psPerProc->psHandleBase, + &psSGXFindSharedPBDescOUT->hHWPBDescKernelMemInfoHandle, + psHWPBDescKernelMemInfo, + PVRSRV_HANDLE_TYPE_MEM_INFO_REF, + PVRSRV_HANDLE_ALLOC_FLAG_MULTI, + psSGXFindSharedPBDescOUT->hSharedPBDesc); + + PVRSRVAllocSubHandleNR(psPerProc->psHandleBase, + &psSGXFindSharedPBDescOUT->hBlockKernelMemInfoHandle, + psBlockKernelMemInfo, + PVRSRV_HANDLE_TYPE_MEM_INFO_REF, + PVRSRV_HANDLE_ALLOC_FLAG_MULTI, + psSGXFindSharedPBDescOUT->hSharedPBDesc); + + + for(i=0; ipsHandleBase, + &psSGXFindSharedPBDescOut->ahSharedPBDescSubKernelMemInfoHandles[i], + ppsSharedPBDescSubKernelMemInfos[i], + PVRSRV_HANDLE_TYPE_MEM_INFO_REF, + PVRSRV_HANDLE_ALLOC_FLAG_MULTI, + psSGXFindSharedPBDescOUT->hSharedPBDescKernelMemInfoHandle); + } + +PVRSRV_BRIDGE_SGX_FINDSHAREDPBDESC_EXIT: + if (ppsSharedPBDescSubKernelMemInfos != IMG_NULL) + { + OSFreeMem(PVRSRV_OS_PAGEABLE_HEAP, + sizeof(PVRSRV_KERNEL_MEM_INFO *) + * ui32SharedPBDescSubKernelMemInfosCount, + ppsSharedPBDescSubKernelMemInfos, + IMG_NULL); + } + + if(psSGXFindSharedPBDescOUT->eError != PVRSRV_OK) + { + if(hSharedPBDesc != IMG_NULL) + { + SGXUnrefSharedPBDescKM(hSharedPBDesc); + } + } + else + { + COMMIT_HANDLE_BATCH_OR_ERROR(psSGXFindSharedPBDescOUT->eError, psPerProc); + } + + return 0; +} + + +static IMG_INT +SGXUnrefSharedPBDescBW(IMG_UINT32 ui32BridgeID, + PVRSRV_BRIDGE_IN_SGXUNREFSHAREDPBDESC *psSGXUnrefSharedPBDescIN, + PVRSRV_BRIDGE_OUT_SGXUNREFSHAREDPBDESC *psSGXUnrefSharedPBDescOUT, + PVRSRV_PER_PROCESS_DATA *psPerProc) +{ + IMG_HANDLE hSharedPBDesc; + + PVRSRV_BRIDGE_ASSERT_CMD(ui32BridgeID, PVRSRV_BRIDGE_SGX_UNREFSHAREDPBDESC); + + psSGXUnrefSharedPBDescOUT->eError = + PVRSRVLookupHandle(psPerProc->psHandleBase, + &hSharedPBDesc, + psSGXUnrefSharedPBDescIN->hSharedPBDesc, + PVRSRV_HANDLE_TYPE_SHARED_PB_DESC); + if(psSGXUnrefSharedPBDescOUT->eError != PVRSRV_OK) + { + return 0; + } + + psSGXUnrefSharedPBDescOUT->eError = + SGXUnrefSharedPBDescKM(hSharedPBDesc); + + if(psSGXUnrefSharedPBDescOUT->eError != PVRSRV_OK) + { + return 0; + } + + psSGXUnrefSharedPBDescOUT->eError = + PVRSRVReleaseHandle(psPerProc->psHandleBase, + psSGXUnrefSharedPBDescIN->hSharedPBDesc, + PVRSRV_HANDLE_TYPE_SHARED_PB_DESC); + + return 0; +} + + +static IMG_INT +SGXAddSharedPBDescBW(IMG_UINT32 ui32BridgeID, + PVRSRV_BRIDGE_IN_SGXADDSHAREDPBDESC *psSGXAddSharedPBDescIN, + PVRSRV_BRIDGE_OUT_SGXADDSHAREDPBDESC *psSGXAddSharedPBDescOUT, + PVRSRV_PER_PROCESS_DATA *psPerProc) +{ + IMG_HANDLE hDevCookieInt; + PVRSRV_KERNEL_MEM_INFO *psSharedPBDescKernelMemInfo; + PVRSRV_KERNEL_MEM_INFO *psHWPBDescKernelMemInfo; + PVRSRV_KERNEL_MEM_INFO *psBlockKernelMemInfo; + IMG_UINT32 ui32KernelMemInfoHandlesCount = + psSGXAddSharedPBDescIN->ui32KernelMemInfoHandlesCount; + IMG_INT ret = 0; + IMG_HANDLE *phKernelMemInfoHandles = IMG_NULL; + PVRSRV_KERNEL_MEM_INFO **ppsKernelMemInfos = IMG_NULL; + IMG_UINT32 i; + PVRSRV_ERROR eError; + IMG_HANDLE hSharedPBDesc = IMG_NULL; + + PVRSRV_BRIDGE_ASSERT_CMD(ui32BridgeID, PVRSRV_BRIDGE_SGX_ADDSHAREDPBDESC); + + NEW_HANDLE_BATCH_OR_ERROR(psSGXAddSharedPBDescOUT->eError, psPerProc, 1); + + psSGXAddSharedPBDescOUT->hSharedPBDesc = IMG_NULL; + + PVR_ASSERT(ui32KernelMemInfoHandlesCount + <= PVRSRV_BRIDGE_SGX_SHAREDPBDESC_MAX_SUBMEMINFOS); + + eError = PVRSRVLookupHandle(psPerProc->psHandleBase, + &hDevCookieInt, + psSGXAddSharedPBDescIN->hDevCookie, + PVRSRV_HANDLE_TYPE_DEV_NODE); + if(eError != PVRSRV_OK) + { + goto PVRSRV_BRIDGE_SGX_ADDSHAREDPBDESC_RETURN_RESULT; + } + + eError = PVRSRVLookupHandle(psPerProc->psHandleBase, + (IMG_VOID **)&psSharedPBDescKernelMemInfo, + psSGXAddSharedPBDescIN->hSharedPBDescKernelMemInfo, + PVRSRV_HANDLE_TYPE_SHARED_SYS_MEM_INFO); + if(eError != PVRSRV_OK) + { + goto PVRSRV_BRIDGE_SGX_ADDSHAREDPBDESC_RETURN_RESULT; + } + + eError = PVRSRVLookupHandle(psPerProc->psHandleBase, + (IMG_VOID **)&psHWPBDescKernelMemInfo, + psSGXAddSharedPBDescIN->hHWPBDescKernelMemInfo, + PVRSRV_HANDLE_TYPE_MEM_INFO); + if(eError != PVRSRV_OK) + { + goto PVRSRV_BRIDGE_SGX_ADDSHAREDPBDESC_RETURN_RESULT; + } + + eError = PVRSRVLookupHandle(psPerProc->psHandleBase, + (IMG_VOID **)&psBlockKernelMemInfo, + psSGXAddSharedPBDescIN->hBlockKernelMemInfo, + PVRSRV_HANDLE_TYPE_SHARED_SYS_MEM_INFO); + if(eError != PVRSRV_OK) + { + goto PVRSRV_BRIDGE_SGX_ADDSHAREDPBDESC_RETURN_RESULT; + } + + if(!OSAccessOK(PVR_VERIFY_READ, + psSGXAddSharedPBDescIN->phKernelMemInfoHandles, + ui32KernelMemInfoHandlesCount * sizeof(IMG_HANDLE))) + { + PVR_DPF((PVR_DBG_ERROR, "%s: PVRSRV_BRIDGE_SGX_ADDSHAREDPBDESC:" + " Invalid phKernelMemInfos pointer", __FUNCTION__)); + ret = -EFAULT; + goto PVRSRV_BRIDGE_SGX_ADDSHAREDPBDESC_RETURN_RESULT; + } + + eError = OSAllocMem(PVRSRV_OS_PAGEABLE_HEAP, + ui32KernelMemInfoHandlesCount * sizeof(IMG_HANDLE), + (IMG_VOID **)&phKernelMemInfoHandles, + 0); + if (eError != PVRSRV_OK) + { + goto PVRSRV_BRIDGE_SGX_ADDSHAREDPBDESC_RETURN_RESULT; + } + + if(CopyFromUserWrapper(psPerProc, + ui32BridgeID, + phKernelMemInfoHandles, + psSGXAddSharedPBDescIN->phKernelMemInfoHandles, + ui32KernelMemInfoHandlesCount * sizeof(IMG_HANDLE)) + != PVRSRV_OK) + { + ret = -EFAULT; + goto PVRSRV_BRIDGE_SGX_ADDSHAREDPBDESC_RETURN_RESULT; + } + + eError = OSAllocMem(PVRSRV_OS_PAGEABLE_HEAP, + ui32KernelMemInfoHandlesCount * sizeof(PVRSRV_KERNEL_MEM_INFO *), + (IMG_VOID **)&ppsKernelMemInfos, + 0); + if (eError != PVRSRV_OK) + { + goto PVRSRV_BRIDGE_SGX_ADDSHAREDPBDESC_RETURN_RESULT; + } + + for(i=0; ipsHandleBase, + (IMG_VOID **)&ppsKernelMemInfos[i], + phKernelMemInfoHandles[i], + PVRSRV_HANDLE_TYPE_MEM_INFO); + if(eError != PVRSRV_OK) + { + goto PVRSRV_BRIDGE_SGX_ADDSHAREDPBDESC_RETURN_RESULT; + } + } + + + eError = PVRSRVReleaseHandle(psPerProc->psHandleBase, + psSGXAddSharedPBDescIN->hSharedPBDescKernelMemInfo, + PVRSRV_HANDLE_TYPE_SHARED_SYS_MEM_INFO); + PVR_ASSERT(eError == PVRSRV_OK); + + eError = PVRSRVReleaseHandle(psPerProc->psHandleBase, + psSGXAddSharedPBDescIN->hHWPBDescKernelMemInfo, + PVRSRV_HANDLE_TYPE_MEM_INFO); + PVR_ASSERT(eError == PVRSRV_OK); + + eError = PVRSRVReleaseHandle(psPerProc->psHandleBase, + psSGXAddSharedPBDescIN->hBlockKernelMemInfo, + PVRSRV_HANDLE_TYPE_SHARED_SYS_MEM_INFO); + PVR_ASSERT(eError == PVRSRV_OK); + + for(i=0; ipsHandleBase, + phKernelMemInfoHandles[i], + PVRSRV_HANDLE_TYPE_MEM_INFO); + PVR_ASSERT(eError == PVRSRV_OK); + } + + eError = SGXAddSharedPBDescKM(psPerProc, hDevCookieInt, + psSharedPBDescKernelMemInfo, + psHWPBDescKernelMemInfo, + psBlockKernelMemInfo, + psSGXAddSharedPBDescIN->ui32TotalPBSize, + &hSharedPBDesc, + ppsKernelMemInfos, + ui32KernelMemInfoHandlesCount); + + + if (eError != PVRSRV_OK) + { + goto PVRSRV_BRIDGE_SGX_ADDSHAREDPBDESC_RETURN_RESULT; + } + + PVRSRVAllocHandleNR(psPerProc->psHandleBase, + &psSGXAddSharedPBDescOUT->hSharedPBDesc, + hSharedPBDesc, + PVRSRV_HANDLE_TYPE_SHARED_PB_DESC, + PVRSRV_HANDLE_ALLOC_FLAG_NONE); + +PVRSRV_BRIDGE_SGX_ADDSHAREDPBDESC_RETURN_RESULT: + + if(phKernelMemInfoHandles) + { + OSFreeMem(PVRSRV_OS_PAGEABLE_HEAP, + psSGXAddSharedPBDescIN->ui32KernelMemInfoHandlesCount + * sizeof(IMG_HANDLE), + (IMG_VOID *)phKernelMemInfoHandles, 0); + } + if(ppsKernelMemInfos) + { + OSFreeMem(PVRSRV_OS_PAGEABLE_HEAP, + psSGXAddSharedPBDescIN->ui32KernelMemInfoHandlesCount + * sizeof(PVRSRV_KERNEL_MEM_INFO *), + (IMG_VOID *)ppsKernelMemInfos, 0); + } + + if(ret == 0 && eError == PVRSRV_OK) + { + COMMIT_HANDLE_BATCH_OR_ERROR(psSGXAddSharedPBDescOUT->eError, psPerProc); + } + + psSGXAddSharedPBDescOUT->eError = eError; + + return ret; +} + +static IMG_INT +SGXGetInfoForSrvinitBW(IMG_UINT32 ui32BridgeID, + PVRSRV_BRIDGE_IN_SGXINFO_FOR_SRVINIT *psSGXInfoForSrvinitIN, + PVRSRV_BRIDGE_OUT_SGXINFO_FOR_SRVINIT *psSGXInfoForSrvinitOUT, + PVRSRV_PER_PROCESS_DATA *psPerProc) +{ + IMG_HANDLE hDevCookieInt; + IMG_UINT32 i; + PVRSRV_BRIDGE_ASSERT_CMD(ui32BridgeID, PVRSRV_BRIDGE_SGXINFO_FOR_SRVINIT); + + NEW_HANDLE_BATCH_OR_ERROR(psSGXInfoForSrvinitOUT->eError, psPerProc, PVRSRV_MAX_CLIENT_HEAPS); + + if(!psPerProc->bInitProcess) + { + psSGXInfoForSrvinitOUT->eError = PVRSRV_ERROR_GENERIC; + return 0; + } + + psSGXInfoForSrvinitOUT->eError = + PVRSRVLookupHandle(psPerProc->psHandleBase, &hDevCookieInt, + psSGXInfoForSrvinitIN->hDevCookie, + PVRSRV_HANDLE_TYPE_DEV_NODE); + + if(psSGXInfoForSrvinitOUT->eError != PVRSRV_OK) + { + return 0; + } + + psSGXInfoForSrvinitOUT->eError = + SGXGetInfoForSrvinitKM(hDevCookieInt, + &psSGXInfoForSrvinitOUT->sInitInfo); + + if(psSGXInfoForSrvinitOUT->eError != PVRSRV_OK) + { + return 0; + } + + for(i = 0; i < PVRSRV_MAX_CLIENT_HEAPS; i++) + { + PVRSRV_HEAP_INFO *psHeapInfo; + + psHeapInfo = &psSGXInfoForSrvinitOUT->sInitInfo.asHeapInfo[i]; + + if (psHeapInfo->ui32HeapID != (IMG_UINT32)SGX_UNDEFINED_HEAP_ID) + { + IMG_HANDLE hDevMemHeapExt; + + if (psHeapInfo->hDevMemHeap != IMG_NULL) + { + + PVRSRVAllocHandleNR(psPerProc->psHandleBase, + &hDevMemHeapExt, + psHeapInfo->hDevMemHeap, + PVRSRV_HANDLE_TYPE_DEV_MEM_HEAP, + PVRSRV_HANDLE_ALLOC_FLAG_SHARED); + psHeapInfo->hDevMemHeap = hDevMemHeapExt; + } + } + } + + COMMIT_HANDLE_BATCH_OR_ERROR(psSGXInfoForSrvinitOUT->eError, psPerProc); + + return 0; +} + +#if defined(PDUMP) +static IMG_VOID +DumpBufferArray(PVRSRV_PER_PROCESS_DATA *psPerProc, + PSGX_KICKTA_DUMP_BUFFER psBufferArray, + IMG_UINT32 ui32BufferArrayLength, + IMG_BOOL bDumpPolls) +{ + IMG_UINT32 i; + + for (i=0; ipszName; + if (!pszName) + { + pszName = "Nameless buffer"; + } + + hUniqueTag = MAKEUNIQUETAG((PVRSRV_KERNEL_MEM_INFO *)psBuffer->hKernelMemInfo); + + #if defined(SUPPORT_SGX_NEW_STATUS_VALS) + psCtrlMemInfoKM = ((PVRSRV_KERNEL_MEM_INFO *)psBuffer->hCtrlKernelMemInfo); + ui32Offset = psBuffer->sCtrlDevVAddr.uiAddr - psCtrlMemInfoKM->sDevVAddr.uiAddr; + #else + psCtrlMemInfoKM = ((PVRSRV_KERNEL_MEM_INFO *)psBuffer->hKernelMemInfo)->psKernelSyncInfo->psSyncDataMemInfoKM; + ui32Offset = offsetof(PVRSRV_SYNC_DATA, ui32ReadOpsComplete); + #endif + + if (psBuffer->ui32Start <= psBuffer->ui32End) + { + if (bDumpPolls) + { + PDUMPCOMMENTWITHFLAGS(0, "Wait for %s space\r\n", pszName); + PDUMPCBP(psCtrlMemInfoKM, + ui32Offset, + psBuffer->ui32Start, + psBuffer->ui32SpaceUsed, + psBuffer->ui32BufferSize, + 0, + MAKEUNIQUETAG(psCtrlMemInfoKM)); + } + + PDUMPCOMMENTWITHFLAGS(0, "%s\r\n", pszName); + PDUMPMEMUM(psPerProc, + IMG_NULL, + psBuffer->pvLinAddr, + (PVRSRV_KERNEL_MEM_INFO*)psBuffer->hKernelMemInfo, + psBuffer->ui32Start, + psBuffer->ui32End - psBuffer->ui32Start, + 0, + hUniqueTag); + } + else + { + + + if (bDumpPolls) + { + PDUMPCOMMENTWITHFLAGS(0, "Wait for %s space\r\n", pszName); + PDUMPCBP(psCtrlMemInfoKM, + ui32Offset, + psBuffer->ui32Start, + psBuffer->ui32BackEndLength, + psBuffer->ui32BufferSize, + 0, + MAKEUNIQUETAG(psCtrlMemInfoKM)); + } + PDUMPCOMMENTWITHFLAGS(0, "%s (part 1)\r\n", pszName); + PDUMPMEMUM(psPerProc, + IMG_NULL, + psBuffer->pvLinAddr, + (PVRSRV_KERNEL_MEM_INFO*)psBuffer->hKernelMemInfo, + psBuffer->ui32Start, + psBuffer->ui32BackEndLength, + 0, + hUniqueTag); + + if (bDumpPolls) + { + PDUMPMEMPOL(psCtrlMemInfoKM, + ui32Offset, + 0, + 0xFFFFFFFF, + PDUMP_POLL_OPERATOR_NOTEQUAL, + IMG_FALSE, + IMG_FALSE, + MAKEUNIQUETAG(psCtrlMemInfoKM)); + + PDUMPCOMMENTWITHFLAGS(0, "Wait for %s space\r\n", pszName); + PDUMPCBP(psCtrlMemInfoKM, + ui32Offset, + 0, + psBuffer->ui32End, + psBuffer->ui32BufferSize, + 0, + MAKEUNIQUETAG(psCtrlMemInfoKM)); + } + PDUMPCOMMENTWITHFLAGS(0, "%s (part 2)\r\n", pszName); + PDUMPMEMUM(psPerProc, + IMG_NULL, + psBuffer->pvLinAddr, + (PVRSRV_KERNEL_MEM_INFO*)psBuffer->hKernelMemInfo, + 0, + psBuffer->ui32End, + 0, + hUniqueTag); + } + } +} +static IMG_INT +SGXPDumpBufferArrayBW(IMG_UINT32 ui32BridgeID, + PVRSRV_BRIDGE_IN_PDUMP_BUFFER_ARRAY *psPDumpBufferArrayIN, + IMG_VOID *psBridgeOut, + PVRSRV_PER_PROCESS_DATA *psPerProc) +{ + IMG_UINT32 i; + SGX_KICKTA_DUMP_BUFFER *psKickTADumpBuffer; + IMG_UINT32 ui32BufferArrayLength = + psPDumpBufferArrayIN->ui32BufferArrayLength; + IMG_UINT32 ui32BufferArraySize = + ui32BufferArrayLength * sizeof(SGX_KICKTA_DUMP_BUFFER); + PVRSRV_ERROR eError = PVRSRV_ERROR_GENERIC; + + PVR_UNREFERENCED_PARAMETER(psBridgeOut); + + PVRSRV_BRIDGE_ASSERT_CMD(ui32BridgeID, PVRSRV_BRIDGE_SGX_PDUMP_BUFFER_ARRAY); + + if(OSAllocMem(PVRSRV_OS_PAGEABLE_HEAP, + ui32BufferArraySize, + (IMG_PVOID *)&psKickTADumpBuffer, 0) != PVRSRV_OK) + { + return -ENOMEM; + } + + if(CopyFromUserWrapper(psPerProc, + ui32BridgeID, + psKickTADumpBuffer, + psPDumpBufferArrayIN->psBufferArray, + ui32BufferArraySize) != PVRSRV_OK) + { + OSFreeMem(PVRSRV_OS_PAGEABLE_HEAP, ui32BufferArraySize, psKickTADumpBuffer, 0); + return -EFAULT; + } + + for(i = 0; i < ui32BufferArrayLength; i++) + { + IMG_VOID *pvMemInfo; + + eError = PVRSRVLookupHandle(psPerProc->psHandleBase, + &pvMemInfo, + psKickTADumpBuffer[i].hKernelMemInfo, + PVRSRV_HANDLE_TYPE_MEM_INFO); + + if(eError != PVRSRV_OK) + { + PVR_DPF((PVR_DBG_ERROR, "PVRSRV_BRIDGE_SGX_PDUMP_BUFFER_ARRAY: " + "PVRSRVLookupHandle failed (%d)", eError)); + break; + } + psKickTADumpBuffer[i].hKernelMemInfo = pvMemInfo; + +#if defined(SUPPORT_SGX_NEW_STATUS_VALS) + eError = PVRSRVLookupHandle(psPerProc->psHandleBase, + &pvMemInfo, + psKickTADumpBuffer[i].hCtrlKernelMemInfo, + PVRSRV_HANDLE_TYPE_MEM_INFO); + + if(eError != PVRSRV_OK) + { + PVR_DPF((PVR_DBG_ERROR, "PVRSRV_BRIDGE_SGX_PDUMP_BUFFER_ARRAY: " + "PVRSRVLookupHandle failed (%d)", eError)); + break; + } + psKickTADumpBuffer[i].hCtrlKernelMemInfo = pvMemInfo; +#endif + } + + if(eError == PVRSRV_OK) + { + DumpBufferArray(psPerProc, + psKickTADumpBuffer, + ui32BufferArrayLength, + psPDumpBufferArrayIN->bDumpPolls); + } + + OSFreeMem(PVRSRV_OS_PAGEABLE_HEAP, ui32BufferArraySize, psKickTADumpBuffer, 0); + + return 0; +} + +static IMG_INT +SGXPDump3DSignatureRegistersBW(IMG_UINT32 ui32BridgeID, + PVRSRV_BRIDGE_IN_PDUMP_3D_SIGNATURE_REGISTERS *psPDump3DSignatureRegistersIN, + IMG_VOID *psBridgeOut, + PVRSRV_PER_PROCESS_DATA *psPerProc) +{ + IMG_UINT32 ui32RegisterArraySize = psPDump3DSignatureRegistersIN->ui32NumRegisters * sizeof(IMG_UINT32); + IMG_UINT32 *pui32Registers = IMG_NULL; + IMG_INT ret = -EFAULT; + + PVR_UNREFERENCED_PARAMETER(psBridgeOut); + + PVRSRV_BRIDGE_ASSERT_CMD(ui32BridgeID, PVRSRV_BRIDGE_SGX_PDUMP_3D_SIGNATURE_REGISTERS); + + if (ui32RegisterArraySize == 0) + { + goto ExitNoError; + } + + if(OSAllocMem(PVRSRV_OS_PAGEABLE_HEAP, + ui32RegisterArraySize, + (IMG_PVOID *)&pui32Registers, 0) != PVRSRV_OK) + { + PVR_DPF((PVR_DBG_ERROR, "PDump3DSignatureRegistersBW: OSAllocMem failed")); + goto Exit; + } + + if(CopyFromUserWrapper(psPerProc, + ui32BridgeID, + pui32Registers, + psPDump3DSignatureRegistersIN->pui32Registers, + ui32RegisterArraySize) != PVRSRV_OK) + { + PVR_DPF((PVR_DBG_ERROR, "PDump3DSignatureRegistersBW: CopyFromUserWrapper failed")); + goto Exit; + } + + PDump3DSignatureRegisters(psPDump3DSignatureRegistersIN->ui32DumpFrameNum, + psPDump3DSignatureRegistersIN->bLastFrame, + pui32Registers, + psPDump3DSignatureRegistersIN->ui32NumRegisters); + +ExitNoError: + ret = 0; +Exit: + if (pui32Registers != IMG_NULL) + { + OSFreeMem(PVRSRV_OS_PAGEABLE_HEAP, ui32RegisterArraySize, pui32Registers, 0); + } + + return ret; +} + +static IMG_INT +SGXPDumpCounterRegistersBW(IMG_UINT32 ui32BridgeID, + PVRSRV_BRIDGE_IN_PDUMP_COUNTER_REGISTERS *psPDumpCounterRegistersIN, + IMG_VOID *psBridgeOut, + PVRSRV_PER_PROCESS_DATA *psPerProc) +{ + IMG_UINT32 ui32RegisterArraySize = psPDumpCounterRegistersIN->ui32NumRegisters * sizeof(IMG_UINT32); + IMG_UINT32 *pui32Registers = IMG_NULL; + IMG_INT ret = -EFAULT; + + PVR_UNREFERENCED_PARAMETER(psBridgeOut); + + PVRSRV_BRIDGE_ASSERT_CMD(ui32BridgeID, PVRSRV_BRIDGE_SGX_PDUMP_COUNTER_REGISTERS); + + if (ui32RegisterArraySize == 0) + { + goto ExitNoError; + } + + if(OSAllocMem(PVRSRV_OS_PAGEABLE_HEAP, + ui32RegisterArraySize, + (IMG_PVOID *)&pui32Registers, 0) != PVRSRV_OK) + { + PVR_DPF((PVR_DBG_ERROR, "PDumpCounterRegistersBW: OSAllocMem failed")); + ret = -ENOMEM; + goto Exit; + } + + if(CopyFromUserWrapper(psPerProc, + ui32BridgeID, + pui32Registers, + psPDumpCounterRegistersIN->pui32Registers, + ui32RegisterArraySize) != PVRSRV_OK) + { + PVR_DPF((PVR_DBG_ERROR, "PDumpCounterRegistersBW: CopyFromUserWrapper failed")); + goto Exit; + } + + PDumpCounterRegisters(psPDumpCounterRegistersIN->ui32DumpFrameNum, + psPDumpCounterRegistersIN->bLastFrame, + pui32Registers, + psPDumpCounterRegistersIN->ui32NumRegisters); + +ExitNoError: + ret = 0; +Exit: + if (pui32Registers != IMG_NULL) + { + OSFreeMem(PVRSRV_OS_PAGEABLE_HEAP, ui32RegisterArraySize, pui32Registers, 0); + } + + return ret; +} + +static IMG_INT +SGXPDumpTASignatureRegistersBW(IMG_UINT32 ui32BridgeID, + PVRSRV_BRIDGE_IN_PDUMP_TA_SIGNATURE_REGISTERS *psPDumpTASignatureRegistersIN, + IMG_VOID *psBridgeOut, + PVRSRV_PER_PROCESS_DATA *psPerProc) +{ + IMG_UINT32 ui32RegisterArraySize = psPDumpTASignatureRegistersIN->ui32NumRegisters * sizeof(IMG_UINT32); + IMG_UINT32 *pui32Registers = IMG_NULL; + IMG_INT ret = -EFAULT; + + PVR_UNREFERENCED_PARAMETER(psBridgeOut); + + PVRSRV_BRIDGE_ASSERT_CMD(ui32BridgeID, PVRSRV_BRIDGE_SGX_PDUMP_TA_SIGNATURE_REGISTERS); + + if (ui32RegisterArraySize == 0) + { + goto ExitNoError; + } + + if(OSAllocMem(PVRSRV_OS_PAGEABLE_HEAP, + ui32RegisterArraySize, + (IMG_PVOID *)&pui32Registers, 0) != PVRSRV_OK) + { + PVR_DPF((PVR_DBG_ERROR, "PDumpTASignatureRegistersBW: OSAllocMem failed")); + ret = -ENOMEM; + goto Exit; + } + + if(CopyFromUserWrapper(psPerProc, + ui32BridgeID, + pui32Registers, + psPDumpTASignatureRegistersIN->pui32Registers, + ui32RegisterArraySize) != PVRSRV_OK) + { + PVR_DPF((PVR_DBG_ERROR, "PDumpTASignatureRegistersBW: CopyFromUserWrapper failed")); + goto Exit; + } + + PDumpTASignatureRegisters(psPDumpTASignatureRegistersIN->ui32DumpFrameNum, + psPDumpTASignatureRegistersIN->ui32TAKickCount, + psPDumpTASignatureRegistersIN->bLastFrame, + pui32Registers, + psPDumpTASignatureRegistersIN->ui32NumRegisters); + +ExitNoError: + ret = 0; +Exit: + if (pui32Registers != IMG_NULL) + { + OSFreeMem(PVRSRV_OS_PAGEABLE_HEAP, ui32RegisterArraySize, pui32Registers, 0); + } + + return ret; +} +static IMG_INT +SGXPDumpHWPerfCBBW(IMG_UINT32 ui32BridgeID, + PVRSRV_BRIDGE_IN_PDUMP_HWPERFCB *psPDumpHWPerfCBIN, + PVRSRV_BRIDGE_RETURN *psRetOUT, + PVRSRV_PER_PROCESS_DATA *psPerProc) +{ +#if defined(SUPPORT_SGX_HWPERF) +#if defined(__linux__) + PVRSRV_SGXDEV_INFO *psDevInfo; + IMG_HANDLE hDevCookieInt; + + PVRSRV_BRIDGE_ASSERT_CMD(ui32BridgeID, PVRSRV_BRIDGE_SGX_PDUMP_HWPERFCB); + + psRetOUT->eError = + PVRSRVLookupHandle(psPerProc->psHandleBase, &hDevCookieInt, + psPDumpHWPerfCBIN->hDevCookie, + PVRSRV_HANDLE_TYPE_DEV_NODE); + if(psRetOUT->eError != PVRSRV_OK) + { + return 0; + } + + psDevInfo = ((PVRSRV_DEVICE_NODE *)hDevCookieInt)->pvDevice; + + PDumpHWPerfCBKM(&psPDumpHWPerfCBIN->szFileName[0], + psPDumpHWPerfCBIN->ui32FileOffset, + psDevInfo->psKernelHWPerfCBMemInfo->sDevVAddr, + psDevInfo->psKernelHWPerfCBMemInfo->ui32AllocSize, + psPDumpHWPerfCBIN->ui32PDumpFlags); + + return 0; +#else + PVR_UNREFERENCED_PARAMETER(ui32BridgeID); + PVR_UNREFERENCED_PARAMETER(psPDumpHWPerfCBIN); + PVR_UNREFERENCED_PARAMETER(psRetOUT); + PVR_UNREFERENCED_PARAMETER(psPerProc); + return 0; +#endif +#else + PVR_UNREFERENCED_PARAMETER(ui32BridgeID); + PVR_UNREFERENCED_PARAMETER(psPDumpHWPerfCBIN); + PVR_UNREFERENCED_PARAMETER(psRetOUT); + PVR_UNREFERENCED_PARAMETER(psPerProc); + return -EFAULT; +#endif +} + +#endif + + +IMG_VOID SetSGXDispatchTableEntry(IMG_VOID) +{ + + SetDispatchTableEntry(PVRSRV_BRIDGE_SGX_GETCLIENTINFO, SGXGetClientInfoBW); + SetDispatchTableEntry(PVRSRV_BRIDGE_SGX_RELEASECLIENTINFO, SGXReleaseClientInfoBW); + SetDispatchTableEntry(PVRSRV_BRIDGE_SGX_GETINTERNALDEVINFO, SGXGetInternalDevInfoBW); + SetDispatchTableEntry(PVRSRV_BRIDGE_SGX_DOKICK, SGXDoKickBW); + SetDispatchTableEntry(PVRSRV_BRIDGE_SGX_GETPHYSPAGEADDR, DummyBW); + SetDispatchTableEntry(PVRSRV_BRIDGE_SGX_READREGISTRYDWORD, DummyBW); + SetDispatchTableEntry(PVRSRV_BRIDGE_SGX_SCHEDULECOMMAND, DummyBW); + + SetDispatchTableEntry(PVRSRV_BRIDGE_SGX_2DQUERYBLTSCOMPLETE, SGX2DQueryBlitsCompleteBW); + + SetDispatchTableEntry(PVRSRV_BRIDGE_SGX_GETMMUPDADDR, DummyBW); + +#if defined(TRANSFER_QUEUE) + SetDispatchTableEntry(PVRSRV_BRIDGE_SGX_SUBMITTRANSFER, SGXSubmitTransferBW); +#endif + SetDispatchTableEntry(PVRSRV_BRIDGE_SGX_GETMISCINFO, SGXGetMiscInfoBW); + SetDispatchTableEntry(PVRSRV_BRIDGE_SGXINFO_FOR_SRVINIT , SGXGetInfoForSrvinitBW); + SetDispatchTableEntry(PVRSRV_BRIDGE_SGX_DEVINITPART2, SGXDevInitPart2BW); + + SetDispatchTableEntry(PVRSRV_BRIDGE_SGX_FINDSHAREDPBDESC, SGXFindSharedPBDescBW); + SetDispatchTableEntry(PVRSRV_BRIDGE_SGX_UNREFSHAREDPBDESC, SGXUnrefSharedPBDescBW); + SetDispatchTableEntry(PVRSRV_BRIDGE_SGX_ADDSHAREDPBDESC, SGXAddSharedPBDescBW); + SetDispatchTableEntry(PVRSRV_BRIDGE_SGX_REGISTER_HW_RENDER_CONTEXT, SGXRegisterHWRenderContextBW); + SetDispatchTableEntry(PVRSRV_BRIDGE_SGX_FLUSH_HW_RENDER_TARGET, SGXFlushHWRenderTargetBW); + SetDispatchTableEntry(PVRSRV_BRIDGE_SGX_UNREGISTER_HW_RENDER_CONTEXT, SGXUnregisterHWRenderContextBW); +#if defined(SGX_FEATURE_2D_HARDWARE) + SetDispatchTableEntry(PVRSRV_BRIDGE_SGX_SUBMIT2D, SGXSubmit2DBW); + SetDispatchTableEntry(PVRSRV_BRIDGE_SGX_REGISTER_HW_2D_CONTEXT, SGXRegisterHW2DContextBW); + SetDispatchTableEntry(PVRSRV_BRIDGE_SGX_UNREGISTER_HW_2D_CONTEXT, SGXUnregisterHW2DContextBW); +#endif + SetDispatchTableEntry(PVRSRV_BRIDGE_SGX_REGISTER_HW_TRANSFER_CONTEXT, SGXRegisterHWTransferContextBW); + SetDispatchTableEntry(PVRSRV_BRIDGE_SGX_UNREGISTER_HW_TRANSFER_CONTEXT, SGXUnregisterHWTransferContextBW); + +#if defined(SUPPORT_SGX_HWPERF) + SetDispatchTableEntry(PVRSRV_BRIDGE_SGX_READ_DIFF_COUNTERS, SGXReadDiffCountersBW); + SetDispatchTableEntry(PVRSRV_BRIDGE_SGX_READ_HWPERF_CB, SGXReadHWPerfCBBW); +#endif + + SetDispatchTableEntry(PVRSRV_BRIDGE_SGX_SCHEDULE_PROCESS_QUEUES, SGXScheduleProcessQueuesBW); + +#if defined(PDUMP) + SetDispatchTableEntry(PVRSRV_BRIDGE_SGX_PDUMP_BUFFER_ARRAY, SGXPDumpBufferArrayBW); + SetDispatchTableEntry(PVRSRV_BRIDGE_SGX_PDUMP_3D_SIGNATURE_REGISTERS, SGXPDump3DSignatureRegistersBW); + SetDispatchTableEntry(PVRSRV_BRIDGE_SGX_PDUMP_COUNTER_REGISTERS, SGXPDumpCounterRegistersBW); + SetDispatchTableEntry(PVRSRV_BRIDGE_SGX_PDUMP_TA_SIGNATURE_REGISTERS, SGXPDumpTASignatureRegistersBW); + SetDispatchTableEntry(PVRSRV_BRIDGE_SGX_PDUMP_HWPERFCB, SGXPDumpHWPerfCBBW); +#endif +} + +#endif diff --git a/services4/srvkm/bridged/sgx/bridged_sgx_bridge.h b/services4/srvkm/bridged/sgx/bridged_sgx_bridge.h new file mode 100644 index 0000000..de6cfd1 --- /dev/null +++ b/services4/srvkm/bridged/sgx/bridged_sgx_bridge.h @@ -0,0 +1,42 @@ +/********************************************************************** + * + * Copyright(c) 2008 Imagination Technologies Ltd. All rights reserved. + * + * This program is free software; you can redistribute it and/or modify it + * under the terms and conditions of the GNU General Public License, + * version 2, as published by the Free Software Foundation. + * + * This program is distributed in the hope it will be useful but, except + * as otherwise stated in writing, without any warranty; without even the + * implied warranty of merchantability or fitness for a particular purpose. + * See the GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License along with + * this program; if not, write to the Free Software Foundation, Inc., + * 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA. + * + * The full GNU General Public License is included in this distribution in + * the file called "COPYING". + * + * Contact Information: + * Imagination Technologies Ltd. + * Home Park Estate, Kings Langley, Herts, WD4 8LZ, UK + * + ******************************************************************************/ + +#ifndef __BRIDGED_SGX_BRIDGE_H__ +#define __BRIDGED_SGX_BRIDGE_H__ + +#if defined (__cplusplus) +extern "C" { +#endif + + +IMG_VOID SetSGXDispatchTableEntry(IMG_VOID); + +#if defined (__cplusplus) +} +#endif + +#endif + diff --git a/services4/srvkm/common/buffer_manager.c b/services4/srvkm/common/buffer_manager.c new file mode 100644 index 0000000..0ac347a --- /dev/null +++ b/services4/srvkm/common/buffer_manager.c @@ -0,0 +1,1962 @@ +/********************************************************************** + * + * Copyright(c) 2008 Imagination Technologies Ltd. All rights reserved. + * + * This program is free software; you can redistribute it and/or modify it + * under the terms and conditions of the GNU General Public License, + * version 2, as published by the Free Software Foundation. + * + * This program is distributed in the hope it will be useful but, except + * as otherwise stated in writing, without any warranty; without even the + * implied warranty of merchantability or fitness for a particular purpose. + * See the GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License along with + * this program; if not, write to the Free Software Foundation, Inc., + * 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA. + * + * The full GNU General Public License is included in this distribution in + * the file called "COPYING". + * + * Contact Information: + * Imagination Technologies Ltd. + * Home Park Estate, Kings Langley, Herts, WD4 8LZ, UK + * + ******************************************************************************/ + +#include "services_headers.h" + +#include "sysconfig.h" +#include "hash.h" +#include "ra.h" +#include "pdump_km.h" + +#define MIN(a,b) (a > b ? b : a) + +static IMG_BOOL +ZeroBuf(BM_BUF *pBuf, BM_MAPPING *pMapping, IMG_UINT32 ui32Bytes, IMG_UINT32 ui32Flags); +static IMG_VOID +BM_FreeMemory (IMG_VOID *pH, IMG_UINTPTR_T base, BM_MAPPING *psMapping); +static IMG_BOOL +BM_ImportMemory(IMG_VOID *pH, IMG_SIZE_T uSize, + IMG_SIZE_T *pActualSize, BM_MAPPING **ppsMapping, + IMG_UINT32 uFlags, IMG_UINTPTR_T *pBase); + +static IMG_BOOL +DevMemoryAlloc (BM_CONTEXT *pBMContext, + BM_MAPPING *pMapping, + IMG_SIZE_T *pActualSize, + IMG_UINT32 uFlags, + IMG_UINT32 dev_vaddr_alignment, + IMG_DEV_VIRTADDR *pDevVAddr); +static IMG_VOID +DevMemoryFree (BM_MAPPING *pMapping); + +static IMG_BOOL +AllocMemory (BM_CONTEXT *pBMContext, + BM_HEAP *psBMHeap, + IMG_DEV_VIRTADDR *psDevVAddr, + IMG_SIZE_T uSize, + IMG_UINT32 uFlags, + IMG_UINT32 uDevVAddrAlignment, + BM_BUF *pBuf) +{ + BM_MAPPING *pMapping; + IMG_UINTPTR_T uOffset; + RA_ARENA *pArena = IMG_NULL; + + PVR_DPF ((PVR_DBG_MESSAGE, + "AllocMemory (pBMContext=%08X, uSize=0x%x, uFlags=0x%x, align=0x%x, pBuf=%08X)", + pBMContext, uSize, uFlags, uDevVAddrAlignment, pBuf)); + + + + + if(uFlags & PVRSRV_MEM_RAM_BACKED_ALLOCATION) + { + if(uFlags & PVRSRV_MEM_USER_SUPPLIED_DEVVADDR) + { + + PVR_DPF ((PVR_DBG_ERROR, "AllocMemory: combination of DevVAddr management and RAM backing mode unsupported")); + return IMG_FALSE; + } + + + + + if(psBMHeap->ui32Attribs + & (PVRSRV_BACKINGSTORE_SYSMEM_NONCONTIG + |PVRSRV_BACKINGSTORE_LOCALMEM_CONTIG)) + { + + pArena = psBMHeap->pImportArena; + } + else + { + PVR_DPF ((PVR_DBG_ERROR, "AllocMemory: backing store type doesn't match heap")); + return IMG_FALSE; + } + + + if (!RA_Alloc(pArena, + uSize, + IMG_NULL, + (IMG_VOID*) &pMapping, + uFlags, + uDevVAddrAlignment, + 0, + (IMG_UINTPTR_T *)&(pBuf->DevVAddr.uiAddr))) + { + PVR_DPF((PVR_DBG_ERROR, "AllocMemory: RA_Alloc(0x%x) FAILED", uSize)); + return IMG_FALSE; + } + + uOffset = pBuf->DevVAddr.uiAddr - pMapping->DevVAddr.uiAddr; + if(pMapping->CpuVAddr) + { + pBuf->CpuVAddr = (IMG_VOID*) ((IMG_UINTPTR_T)pMapping->CpuVAddr + uOffset); + } + else + { + pBuf->CpuVAddr = IMG_NULL; + } + + if(uSize == pMapping->uSize) + { + pBuf->hOSMemHandle = pMapping->hOSMemHandle; + } + else + { + if(OSGetSubMemHandle(pMapping->hOSMemHandle, + uOffset, + uSize, + psBMHeap->ui32Attribs, + &pBuf->hOSMemHandle)!=PVRSRV_OK) + { + PVR_DPF((PVR_DBG_ERROR, "AllocMemory: OSGetSubMemHandle FAILED")); + return IMG_FALSE; + } + } + + + pBuf->CpuPAddr.uiAddr = pMapping->CpuPAddr.uiAddr + uOffset; + + if(uFlags & PVRSRV_MEM_ZERO) + { + if(!ZeroBuf(pBuf, pMapping, uSize, psBMHeap->ui32Attribs | uFlags)) + { + return IMG_FALSE; + } + } + } + else + { + if(uFlags & PVRSRV_MEM_USER_SUPPLIED_DEVVADDR) + { + + PVR_ASSERT(psDevVAddr != IMG_NULL); + + if (psDevVAddr == IMG_NULL) + { + PVR_DPF((PVR_DBG_ERROR, "AllocMemory: invalid parameter - psDevVAddr")); + return IMG_FALSE; + } + + + pBMContext->psDeviceNode->pfnMMUAlloc (psBMHeap->pMMUHeap, + uSize, + IMG_NULL, + PVRSRV_MEM_USER_SUPPLIED_DEVVADDR, + uDevVAddrAlignment, + psDevVAddr); + + + pBuf->DevVAddr = *psDevVAddr; + } + else + { + + + + pBMContext->psDeviceNode->pfnMMUAlloc (psBMHeap->pMMUHeap, + uSize, + IMG_NULL, + 0, + uDevVAddrAlignment, + &pBuf->DevVAddr); + } + + + if (OSAllocMem(PVRSRV_OS_PAGEABLE_HEAP, + sizeof (struct _BM_MAPPING_), + (IMG_PVOID *)&pMapping, IMG_NULL) != PVRSRV_OK) + { + PVR_DPF((PVR_DBG_ERROR, "AllocMemory: OSAllocMem(0x%x) FAILED")); + return IMG_FALSE; + } + + + pBuf->CpuVAddr = IMG_NULL; + pBuf->hOSMemHandle = 0; + pBuf->CpuPAddr.uiAddr = 0; + + + pMapping->CpuVAddr = IMG_NULL; + pMapping->CpuPAddr.uiAddr = 0; + pMapping->DevVAddr = pBuf->DevVAddr; + pMapping->psSysAddr = IMG_NULL; + pMapping->uSize = uSize; + pMapping->hOSMemHandle = 0; + } + + + pMapping->pArena = pArena; + + + pMapping->pBMHeap = psBMHeap; + pBuf->pMapping = pMapping; + + + PVR_DPF ((PVR_DBG_MESSAGE, + "AllocMemory: pMapping=%08X: DevV=%08X CpuV=%08X CpuP=%08X uSize=0x%x", + pMapping, + pMapping->DevVAddr.uiAddr, + pMapping->CpuVAddr, + pMapping->CpuPAddr.uiAddr, + pMapping->uSize)); + + PVR_DPF ((PVR_DBG_MESSAGE, + "AllocMemory: pBuf=%08X: DevV=%08X CpuV=%08X CpuP=%08X uSize=0x%x", + pBuf, + pBuf->DevVAddr.uiAddr, + pBuf->CpuVAddr, + pBuf->CpuPAddr.uiAddr, + uSize)); + + + PVR_ASSERT(((pBuf->DevVAddr.uiAddr) & (uDevVAddrAlignment - 1)) == 0); + + return IMG_TRUE; +} + + +static IMG_BOOL +WrapMemory (BM_HEAP *psBMHeap, + IMG_SIZE_T uSize, + IMG_UINT32 ui32BaseOffset, + IMG_BOOL bPhysContig, + IMG_SYS_PHYADDR *psAddr, + IMG_VOID *pvCPUVAddr, + IMG_UINT32 uFlags, + BM_BUF *pBuf) +{ + IMG_DEV_VIRTADDR DevVAddr = {0}; + BM_MAPPING *pMapping; + IMG_BOOL bResult; + IMG_UINT32 const ui32PageSize = HOST_PAGESIZE(); + + PVR_DPF ((PVR_DBG_MESSAGE, + "WrapMemory(psBMHeap=%08X, size=0x%x, offset=0x%x, bPhysContig=0x%x, pvCPUVAddr = 0x%x, flags=0x%x, pBuf=%08X)", + psBMHeap, uSize, ui32BaseOffset, bPhysContig, pvCPUVAddr, uFlags, pBuf)); + + PVR_ASSERT((psAddr->uiAddr & (ui32PageSize - 1)) == 0); + + PVR_ASSERT(((IMG_UINT32)pvCPUVAddr & (ui32PageSize - 1)) == 0); + + uSize += ui32BaseOffset; + uSize = HOST_PAGEALIGN (uSize); + + + if (OSAllocMem(PVRSRV_OS_PAGEABLE_HEAP, + sizeof(*pMapping), + (IMG_PVOID *)&pMapping, IMG_NULL) != PVRSRV_OK) + { + PVR_DPF((PVR_DBG_ERROR, "WrapMemory: OSAllocMem(0x%x) FAILED",sizeof(*pMapping))); + return IMG_FALSE; + } + + OSMemSet(pMapping, 0, sizeof (*pMapping)); + + pMapping->uSize = uSize; + pMapping->pBMHeap = psBMHeap; + + if(pvCPUVAddr) + { + pMapping->CpuVAddr = pvCPUVAddr; + + if (bPhysContig) + { + pMapping->eCpuMemoryOrigin = hm_wrapped_virtaddr; + pMapping->CpuPAddr = SysSysPAddrToCpuPAddr(psAddr[0]); + + if(OSRegisterMem(pMapping->CpuPAddr, + pMapping->CpuVAddr, + pMapping->uSize, + uFlags, + &pMapping->hOSMemHandle) != PVRSRV_OK) + { + PVR_DPF((PVR_DBG_ERROR, "WrapMemory: OSRegisterMem Phys=0x%08X, CpuVAddr = 0x%08X, Size=%d) failed", + pMapping->CpuPAddr, pMapping->CpuVAddr, pMapping->uSize)); + goto fail_cleanup; + } + } + else + { + pMapping->eCpuMemoryOrigin = hm_wrapped_scatter_virtaddr; + pMapping->psSysAddr = psAddr; + + if(OSRegisterDiscontigMem(pMapping->psSysAddr, + pMapping->CpuVAddr, + pMapping->uSize, + uFlags, + &pMapping->hOSMemHandle) != PVRSRV_OK) + { + PVR_DPF((PVR_DBG_ERROR, "WrapMemory: OSRegisterDiscontigMem CpuVAddr = 0x%08X, Size=%d) failed", + pMapping->CpuVAddr, pMapping->uSize)); + goto fail_cleanup; + } + } + } + else + { + if (bPhysContig) + { + pMapping->eCpuMemoryOrigin = hm_wrapped; + pMapping->CpuPAddr = SysSysPAddrToCpuPAddr(psAddr[0]); + + if(OSReservePhys(pMapping->CpuPAddr, + pMapping->uSize, + uFlags, + &pMapping->CpuVAddr, + &pMapping->hOSMemHandle) != PVRSRV_OK) + { + PVR_DPF((PVR_DBG_ERROR, "WrapMemory: OSReservePhys Phys=0x%08X, Size=%d) failed", + pMapping->CpuPAddr, pMapping->uSize)); + goto fail_cleanup; + } + } + else + { + pMapping->eCpuMemoryOrigin = hm_wrapped_scatter; + pMapping->psSysAddr = psAddr; + + if(OSReserveDiscontigPhys(pMapping->psSysAddr, + pMapping->uSize, + uFlags, + &pMapping->CpuVAddr, + &pMapping->hOSMemHandle) != PVRSRV_OK) + { + PVR_DPF((PVR_DBG_ERROR, "WrapMemory: OSReserveDiscontigPhys Size=%d) failed", + pMapping->uSize)); + goto fail_cleanup; + } + } + } + + + bResult = DevMemoryAlloc(psBMHeap->pBMContext, + pMapping, + IMG_NULL, + uFlags | PVRSRV_MEM_READ | PVRSRV_MEM_WRITE, + ui32PageSize, + &DevVAddr); + if (!bResult) + { + PVR_DPF((PVR_DBG_ERROR, + "WrapMemory: DevMemoryAlloc(0x%x) failed", + pMapping->uSize)); + goto fail_cleanup; + } + + + pBuf->CpuPAddr.uiAddr = pMapping->CpuPAddr.uiAddr + ui32BaseOffset; + if(!ui32BaseOffset) + { + pBuf->hOSMemHandle = pMapping->hOSMemHandle; + } + else + { + if(OSGetSubMemHandle(pMapping->hOSMemHandle, + ui32BaseOffset, + (pMapping->uSize-ui32BaseOffset), + uFlags, + &pBuf->hOSMemHandle)!=PVRSRV_OK) + { + PVR_DPF((PVR_DBG_ERROR, "WrapMemory: OSGetSubMemHandle failed")); + goto fail_cleanup; + } + } + if(pMapping->CpuVAddr) + { + pBuf->CpuVAddr = (IMG_VOID*) ((IMG_UINTPTR_T)pMapping->CpuVAddr + ui32BaseOffset); + } + pBuf->DevVAddr.uiAddr = pMapping->DevVAddr.uiAddr + ui32BaseOffset; + + if(uFlags & PVRSRV_MEM_ZERO) + { + if(!ZeroBuf(pBuf, pMapping, uSize, uFlags)) + { + return IMG_FALSE; + } + } + + PVR_DPF ((PVR_DBG_MESSAGE, "DevVaddr.uiAddr=%08X", DevVAddr.uiAddr)); + PVR_DPF ((PVR_DBG_MESSAGE, + "WrapMemory: pMapping=%08X: DevV=%08X CpuV=%08X CpuP=%08X uSize=0x%x", + pMapping, pMapping->DevVAddr.uiAddr, + pMapping->CpuVAddr, pMapping->CpuPAddr.uiAddr, pMapping->uSize)); + PVR_DPF ((PVR_DBG_MESSAGE, + "WrapMemory: pBuf=%08X: DevV=%08X CpuV=%08X CpuP=%08X uSize=0x%x", + pBuf, pBuf->DevVAddr.uiAddr, + pBuf->CpuVAddr, pBuf->CpuPAddr.uiAddr, uSize)); + + pBuf->pMapping = pMapping; + return IMG_TRUE; + +fail_cleanup: + if(ui32BaseOffset && pBuf->hOSMemHandle) + { + OSReleaseSubMemHandle(pBuf->hOSMemHandle, uFlags); + } + + if(pMapping && (pMapping->CpuVAddr || pMapping->hOSMemHandle)) + { + switch(pMapping->eCpuMemoryOrigin) + { + case hm_wrapped: + OSUnReservePhys(pMapping->CpuVAddr, pMapping->uSize, uFlags, pMapping->hOSMemHandle); + break; + case hm_wrapped_virtaddr: + OSUnRegisterMem(pMapping->CpuVAddr, pMapping->uSize, uFlags, pMapping->hOSMemHandle); + break; + case hm_wrapped_scatter: + OSUnReserveDiscontigPhys(pMapping->CpuVAddr, pMapping->uSize, uFlags, pMapping->hOSMemHandle); + break; + case hm_wrapped_scatter_virtaddr: + OSUnRegisterDiscontigMem(pMapping->CpuVAddr, pMapping->uSize, uFlags, pMapping->hOSMemHandle); + break; + default: + break; + } + + } + + OSFreeMem(PVRSRV_OS_PAGEABLE_HEAP, sizeof(BM_MAPPING), pMapping, IMG_NULL); + + return IMG_FALSE; +} + + +static IMG_BOOL +ZeroBuf(BM_BUF *pBuf, BM_MAPPING *pMapping, IMG_UINT32 ui32Bytes, IMG_UINT32 ui32Flags) +{ + IMG_VOID *pvCpuVAddr; + + if(pBuf->CpuVAddr) + { + OSMemSet(pBuf->CpuVAddr, 0, ui32Bytes); + } + else if(pMapping->eCpuMemoryOrigin == hm_contiguous + || pMapping->eCpuMemoryOrigin == hm_wrapped) + { + pvCpuVAddr = OSMapPhysToLin(pBuf->CpuPAddr, + ui32Bytes, + PVRSRV_HAP_KERNEL_ONLY + | (ui32Flags & PVRSRV_HAP_CACHETYPE_MASK), + IMG_NULL); + if(!pvCpuVAddr) + { + PVR_DPF((PVR_DBG_ERROR, "ZeroBuf: OSMapPhysToLin for contiguous buffer failed")); + return IMG_FALSE; + } + OSMemSet(pvCpuVAddr, 0, ui32Bytes); + OSUnMapPhysToLin(pvCpuVAddr, + ui32Bytes, + PVRSRV_HAP_KERNEL_ONLY + | (ui32Flags & PVRSRV_HAP_CACHETYPE_MASK), + IMG_NULL); + } + else + { + IMG_UINT32 ui32BytesRemaining = ui32Bytes; + IMG_UINT32 ui32CurrentOffset = 0; + IMG_CPU_PHYADDR CpuPAddr; + + + PVR_ASSERT(pBuf->hOSMemHandle); + + while(ui32BytesRemaining > 0) + { + IMG_UINT32 ui32BlockBytes = MIN(ui32BytesRemaining, HOST_PAGESIZE()); + CpuPAddr = OSMemHandleToCpuPAddr(pBuf->hOSMemHandle, ui32CurrentOffset); + + if(CpuPAddr.uiAddr & (HOST_PAGESIZE() -1)) + { + ui32BlockBytes = + MIN(ui32BytesRemaining, HOST_PAGEALIGN(CpuPAddr.uiAddr) - CpuPAddr.uiAddr); + } + + pvCpuVAddr = OSMapPhysToLin(CpuPAddr, + ui32BlockBytes, + PVRSRV_HAP_KERNEL_ONLY + | (ui32Flags & PVRSRV_HAP_CACHETYPE_MASK), + IMG_NULL); + if(!pvCpuVAddr) + { + PVR_DPF((PVR_DBG_ERROR, "ZeroBuf: OSMapPhysToLin while zeroing non-contiguous memory FAILED")); + return IMG_FALSE; + } + OSMemSet(pvCpuVAddr, 0, ui32BlockBytes); + OSUnMapPhysToLin(pvCpuVAddr, + ui32BlockBytes, + PVRSRV_HAP_KERNEL_ONLY + | (ui32Flags & PVRSRV_HAP_CACHETYPE_MASK), + IMG_NULL); + + ui32BytesRemaining -= ui32BlockBytes; + ui32CurrentOffset += ui32BlockBytes; + } + } + + return IMG_TRUE; +} + +static IMG_VOID +FreeBuf (BM_BUF *pBuf, IMG_UINT32 ui32Flags) +{ + BM_MAPPING *pMapping; + + PVR_DPF ((PVR_DBG_MESSAGE, + "FreeBuf: pBuf=%08X: DevVAddr=%08X CpuVAddr=%08X CpuPAddr=%08X", + pBuf, pBuf->DevVAddr.uiAddr, pBuf->CpuVAddr, pBuf->CpuPAddr.uiAddr)); + + + pMapping = pBuf->pMapping; + + if(ui32Flags & PVRSRV_MEM_USER_SUPPLIED_DEVVADDR) + { + + if(ui32Flags & PVRSRV_MEM_RAM_BACKED_ALLOCATION) + { + + PVR_DPF ((PVR_DBG_ERROR, "FreeBuf: combination of DevVAddr management and RAM backing mode unsupported")); + } + else + { + + OSFreeMem(PVRSRV_OS_PAGEABLE_HEAP, sizeof(BM_MAPPING), pMapping, IMG_NULL); + } + } + else + { + + if(pBuf->hOSMemHandle != pMapping->hOSMemHandle) + { + OSReleaseSubMemHandle(pBuf->hOSMemHandle, ui32Flags); + } + if(ui32Flags & PVRSRV_MEM_RAM_BACKED_ALLOCATION) + { + + + + RA_Free (pBuf->pMapping->pArena, pBuf->DevVAddr.uiAddr, IMG_FALSE); + } + else + { + switch (pMapping->eCpuMemoryOrigin) + { + case hm_wrapped: + OSUnReservePhys(pMapping->CpuVAddr, pMapping->uSize, ui32Flags, pMapping->hOSMemHandle); + break; + case hm_wrapped_virtaddr: + OSUnRegisterMem(pMapping->CpuVAddr, pMapping->uSize, ui32Flags, pMapping->hOSMemHandle); + break; + case hm_wrapped_scatter: + OSUnReserveDiscontigPhys(pMapping->CpuVAddr, pMapping->uSize, ui32Flags, pMapping->hOSMemHandle); + break; + case hm_wrapped_scatter_virtaddr: + OSUnRegisterDiscontigMem(pMapping->CpuVAddr, pMapping->uSize, ui32Flags, pMapping->hOSMemHandle); + break; + default: + break; + } + + DevMemoryFree (pMapping); + + + OSFreeMem(PVRSRV_OS_PAGEABLE_HEAP, sizeof(BM_MAPPING), pMapping, IMG_NULL); + } + } + + OSFreeMem(PVRSRV_OS_PAGEABLE_HEAP, sizeof(BM_BUF), pBuf, IMG_NULL); +} + + + +PVRSRV_ERROR +BM_DestroyContext(IMG_HANDLE hBMContext, + IMG_BOOL *pbDestroyed) +{ + PVRSRV_ERROR eError; + BM_CONTEXT *pBMContext = (BM_CONTEXT*)hBMContext; + BM_HEAP *psBMHeap; + + PVR_DPF ((PVR_DBG_MESSAGE, "BM_DestroyContext")); + + if (pbDestroyed != IMG_NULL) + { + *pbDestroyed = IMG_FALSE; + } + + + + if (pBMContext == IMG_NULL) + { + PVR_DPF ((PVR_DBG_ERROR, "BM_DestroyContext: Invalid handle")); + return PVRSRV_ERROR_INVALID_PARAMS; + } + + pBMContext->ui32RefCount--; + + if (pBMContext->ui32RefCount > 0) + { + + return PVRSRV_OK; + } + + + + + for (psBMHeap = pBMContext->psBMHeap; + psBMHeap != IMG_NULL; + psBMHeap = psBMHeap->psNext) + { + if(psBMHeap->ui32Attribs + & (PVRSRV_BACKINGSTORE_SYSMEM_NONCONTIG + |PVRSRV_BACKINGSTORE_LOCALMEM_CONTIG)) + { + if (psBMHeap->pImportArena) + { + IMG_BOOL bTestDelete = RA_TestDelete(psBMHeap->pImportArena); + PVR_ASSERT(bTestDelete); + if (!bTestDelete) + { + return PVRSRV_ERROR_GENERIC; + } + } + } + } + + eError = ResManFreeResByPtr(pBMContext->hResItem); + + if (eError != PVRSRV_OK) + { + PVR_DPF ((PVR_DBG_ERROR, "BM_DestroyContext: ResManFreeResByPtr failed %d",eError)); + return eError; + } + + if (pbDestroyed != IMG_NULL) + { + *pbDestroyed = IMG_TRUE; + } + + return PVRSRV_OK; +} + + +static PVRSRV_ERROR BM_DestroyContextCallBack(IMG_PVOID pvParam, + IMG_UINT32 ui32Param) +{ + BM_CONTEXT *pBMContext = pvParam; + BM_CONTEXT **ppBMContext; + BM_HEAP *psBMHeap, *psTmpBMHeap; + PVRSRV_DEVICE_NODE *psDeviceNode; + + PVR_UNREFERENCED_PARAMETER(ui32Param); + + + + psDeviceNode = pBMContext->psDeviceNode; + + + + psBMHeap = pBMContext->psBMHeap; + while(psBMHeap) + { + + if(psBMHeap->ui32Attribs + & (PVRSRV_BACKINGSTORE_SYSMEM_NONCONTIG + |PVRSRV_BACKINGSTORE_LOCALMEM_CONTIG)) + { + if (psBMHeap->pImportArena) + { + RA_Delete (psBMHeap->pImportArena); + } + } + else + { + PVR_DPF((PVR_DBG_ERROR, "BM_DestroyContext: backing store type unsupported")); + return PVRSRV_ERROR_GENERIC; + } + + + psDeviceNode->pfnMMUDelete(psBMHeap->pMMUHeap); + + + psTmpBMHeap = psBMHeap; + + + psBMHeap = psBMHeap->psNext; + + + OSFreeMem(PVRSRV_OS_PAGEABLE_HEAP, 0, psTmpBMHeap, IMG_NULL); + } + + + + if (pBMContext->psMMUContext) + { + psDeviceNode->pfnMMUFinalise(pBMContext->psMMUContext); + } + + + + if (pBMContext->pBufferHash) + { + HASH_Delete(pBMContext->pBufferHash); + } + + if (pBMContext == psDeviceNode->sDevMemoryInfo.pBMKernelContext) + { + + psDeviceNode->sDevMemoryInfo.pBMKernelContext = IMG_NULL; + } + else + { + + for (ppBMContext = &psDeviceNode->sDevMemoryInfo.pBMContext; + *ppBMContext; + ppBMContext = &((*ppBMContext)->psNext)) + { + if(*ppBMContext == pBMContext) + { + + *ppBMContext = pBMContext->psNext; + + break; + } + } + } + + OSFreeMem(PVRSRV_OS_PAGEABLE_HEAP, 0, pBMContext, IMG_NULL); + + return PVRSRV_OK; +} + + +IMG_HANDLE +BM_CreateContext(PVRSRV_DEVICE_NODE *psDeviceNode, + IMG_DEV_PHYADDR *psPDDevPAddr, + PVRSRV_PER_PROCESS_DATA *psPerProc, + IMG_BOOL *pbCreated) +{ + BM_CONTEXT *pBMContext; + BM_HEAP *psBMHeap; + DEVICE_MEMORY_INFO *psDevMemoryInfo; + IMG_BOOL bKernelContext; + PRESMAN_CONTEXT hResManContext; + + PVR_DPF((PVR_DBG_MESSAGE, "BM_CreateContext")); + + if (psPerProc == IMG_NULL) + { + bKernelContext = IMG_TRUE; + hResManContext = psDeviceNode->hResManContext; + } + else + { + bKernelContext = IMG_FALSE; + hResManContext = psPerProc->hResManContext; + } + + if (pbCreated != IMG_NULL) + { + *pbCreated = IMG_FALSE; + } + + + psDevMemoryInfo = &psDeviceNode->sDevMemoryInfo; + + if (bKernelContext == IMG_FALSE) + { + for (pBMContext = psDevMemoryInfo->pBMContext; + pBMContext != IMG_NULL; + pBMContext = pBMContext->psNext) + { + if(ResManFindResourceByPtr(hResManContext, pBMContext->hResItem) == PVRSRV_OK) + { + + pBMContext->ui32RefCount++; + + return (IMG_HANDLE)pBMContext; + } + } + } + + + if (OSAllocMem(PVRSRV_OS_PAGEABLE_HEAP, + sizeof (struct _BM_CONTEXT_), + (IMG_PVOID *)&pBMContext, IMG_NULL) != PVRSRV_OK) + { + PVR_DPF ((PVR_DBG_ERROR, "BM_CreateContext: Alloc failed")); + return IMG_NULL; + } + OSMemSet(pBMContext, 0, sizeof (BM_CONTEXT)); + + + pBMContext->psDeviceNode = psDeviceNode; + + + + pBMContext->pBufferHash = HASH_Create(32); + if (pBMContext->pBufferHash==IMG_NULL) + { + PVR_DPF ((PVR_DBG_ERROR, "BM_CreateContext: HASH_Create failed")); + goto cleanup; + } + + if(psDeviceNode->pfnMMUInitialise(psDeviceNode, + &pBMContext->psMMUContext, + psPDDevPAddr) != PVRSRV_OK) + { + PVR_DPF((PVR_DBG_ERROR, "BM_CreateContext: MMUInitialise failed")); + goto cleanup; + } + + if(bKernelContext) + { + + PVR_ASSERT(psDevMemoryInfo->pBMKernelContext == IMG_NULL); + psDevMemoryInfo->pBMKernelContext = pBMContext; + } + else + { + + + + + + PVR_ASSERT(psDevMemoryInfo->pBMKernelContext); + + if (psDevMemoryInfo->pBMKernelContext == IMG_NULL) + { + PVR_DPF((PVR_DBG_ERROR, "BM_CreateContext: psDevMemoryInfo->pBMKernelContext invalid")); + goto cleanup; + } + + PVR_ASSERT(psDevMemoryInfo->pBMKernelContext->psBMHeap); + + + + + + pBMContext->psBMSharedHeap = psDevMemoryInfo->pBMKernelContext->psBMHeap; + + + + + psBMHeap = pBMContext->psBMSharedHeap; + while(psBMHeap) + { + switch(psBMHeap->sDevArena.DevMemHeapType) + { + case DEVICE_MEMORY_HEAP_SHARED: + case DEVICE_MEMORY_HEAP_SHARED_EXPORTED: + { + + psDeviceNode->pfnMMUInsertHeap(pBMContext->psMMUContext, psBMHeap->pMMUHeap); + break; + } + } + + psBMHeap = psBMHeap->psNext; + } + + + pBMContext->psNext = psDevMemoryInfo->pBMContext; + psDevMemoryInfo->pBMContext = pBMContext; + } + + + pBMContext->ui32RefCount++; + + + pBMContext->hResItem = ResManRegisterRes(hResManContext, + RESMAN_TYPE_DEVICEMEM_CONTEXT, + pBMContext, + 0, + BM_DestroyContextCallBack); + if (pBMContext->hResItem == IMG_NULL) + { + PVR_DPF ((PVR_DBG_ERROR, "BM_CreateContext: ResManRegisterRes failed")); + goto cleanup; + } + + if (pbCreated != IMG_NULL) + { + *pbCreated = IMG_TRUE; + } + return (IMG_HANDLE)pBMContext; + +cleanup: + BM_DestroyContextCallBack(pBMContext, 0); + + return IMG_NULL; +} + + +IMG_HANDLE +BM_CreateHeap (IMG_HANDLE hBMContext, + DEVICE_MEMORY_HEAP_INFO *psDevMemHeapInfo) +{ + BM_CONTEXT *pBMContext = (BM_CONTEXT*)hBMContext; + PVRSRV_DEVICE_NODE *psDeviceNode = pBMContext->psDeviceNode; + BM_HEAP *psBMHeap; + + PVR_DPF((PVR_DBG_MESSAGE, "BM_CreateHeap")); + + if(!pBMContext) + { + return IMG_NULL; + } + + + + + + + if(pBMContext->ui32RefCount > 0) + { + psBMHeap = pBMContext->psBMHeap; + + while(psBMHeap) + { + if(psBMHeap->sDevArena.ui32HeapID == psDevMemHeapInfo->ui32HeapID) + + { + + return psBMHeap; + } + psBMHeap = psBMHeap->psNext; + } + } + + + if (OSAllocMem(PVRSRV_OS_PAGEABLE_HEAP, + sizeof (BM_HEAP), + (IMG_PVOID *)&psBMHeap, IMG_NULL) != PVRSRV_OK) + { + PVR_DPF((PVR_DBG_ERROR, "BM_CreateHeap: Alloc failed")); + return IMG_NULL; + } + + OSMemSet (psBMHeap, 0, sizeof (BM_HEAP)); + + psBMHeap->sDevArena.ui32HeapID = psDevMemHeapInfo->ui32HeapID; + psBMHeap->sDevArena.pszName = psDevMemHeapInfo->pszName; + psBMHeap->sDevArena.BaseDevVAddr = psDevMemHeapInfo->sDevVAddrBase; + psBMHeap->sDevArena.ui32Size = psDevMemHeapInfo->ui32HeapSize; + psBMHeap->sDevArena.DevMemHeapType = psDevMemHeapInfo->DevMemHeapType; + psBMHeap->sDevArena.ui32DataPageSize = psDevMemHeapInfo->ui32DataPageSize; + psBMHeap->sDevArena.psDeviceMemoryHeapInfo = psDevMemHeapInfo; + psBMHeap->ui32Attribs = psDevMemHeapInfo->ui32Attribs; + + + psBMHeap->pBMContext = pBMContext; + + psBMHeap->pMMUHeap = psDeviceNode->pfnMMUCreate (pBMContext->psMMUContext, + &psBMHeap->sDevArena, + &psBMHeap->pVMArena); + if (!psBMHeap->pMMUHeap) + { + PVR_DPF((PVR_DBG_ERROR, "BM_CreateHeap: MMUCreate failed")); + goto ErrorExit; + } + + + psBMHeap->pImportArena = RA_Create (psDevMemHeapInfo->pszBSName, + 0, 0, IMG_NULL, + psBMHeap->sDevArena.ui32DataPageSize, + BM_ImportMemory, + BM_FreeMemory, + IMG_NULL, + psBMHeap); + if(psBMHeap->pImportArena == IMG_NULL) + { + PVR_DPF((PVR_DBG_ERROR, "BM_CreateHeap: RA_Create failed")); + goto ErrorExit; + } + + if(psBMHeap->ui32Attribs & PVRSRV_BACKINGSTORE_LOCALMEM_CONTIG) + { + + + + + psBMHeap->pLocalDevMemArena = psDevMemHeapInfo->psLocalDevMemArena; + if(psBMHeap->pLocalDevMemArena == IMG_NULL) + { + PVR_DPF((PVR_DBG_ERROR, "BM_CreateHeap: LocalDevMemArena null")); + goto ErrorExit; + } + } + + + psBMHeap->psNext = pBMContext->psBMHeap; + pBMContext->psBMHeap = psBMHeap; + + return (IMG_HANDLE)psBMHeap; + + +ErrorExit: + + + if (psBMHeap->pMMUHeap != IMG_NULL) + { + psDeviceNode->pfnMMUDelete (psBMHeap->pMMUHeap); + psDeviceNode->pfnMMUFinalise (pBMContext->psMMUContext); + } + + + OSFreeMem(PVRSRV_OS_PAGEABLE_HEAP, 0, psBMHeap, IMG_NULL); + + return IMG_NULL; +} + +IMG_VOID +BM_DestroyHeap (IMG_HANDLE hDevMemHeap) +{ + BM_HEAP* psBMHeap = (BM_HEAP*)hDevMemHeap; + PVRSRV_DEVICE_NODE *psDeviceNode = psBMHeap->pBMContext->psDeviceNode; + + PVR_DPF((PVR_DBG_MESSAGE, "BM_DestroyHeap")); + + if(psBMHeap) + { + BM_HEAP **ppsBMHeap; + + + if(psBMHeap->ui32Attribs + & (PVRSRV_BACKINGSTORE_SYSMEM_NONCONTIG + |PVRSRV_BACKINGSTORE_LOCALMEM_CONTIG)) + { + if (psBMHeap->pImportArena) + { + RA_Delete (psBMHeap->pImportArena); + } + } + else + { + PVR_DPF((PVR_DBG_ERROR, "BM_DestroyHeap: backing store type unsupported")); + return; + } + + + psDeviceNode->pfnMMUDelete (psBMHeap->pMMUHeap); + + + ppsBMHeap = &psBMHeap->pBMContext->psBMHeap; + while(*ppsBMHeap) + { + if(*ppsBMHeap == psBMHeap) + { + + *ppsBMHeap = psBMHeap->psNext; + OSFreeMem(PVRSRV_OS_PAGEABLE_HEAP, 0, psBMHeap, IMG_NULL); + break; + } + ppsBMHeap = &((*ppsBMHeap)->psNext); + } + } + else + { + PVR_DPF ((PVR_DBG_ERROR, "BM_DestroyHeap: invalid heap handle")); + } +} + + +IMG_BOOL +BM_Reinitialise (PVRSRV_DEVICE_NODE *psDeviceNode) +{ + + PVR_DPF((PVR_DBG_MESSAGE, "BM_Reinitialise")); + PVR_UNREFERENCED_PARAMETER(psDeviceNode); + + + return IMG_TRUE; +} + +IMG_BOOL +BM_Alloc ( IMG_HANDLE hDevMemHeap, + IMG_DEV_VIRTADDR *psDevVAddr, + IMG_SIZE_T uSize, + IMG_UINT32 *pui32Flags, + IMG_UINT32 uDevVAddrAlignment, + BM_HANDLE *phBuf) +{ + BM_BUF *pBuf; + BM_CONTEXT *pBMContext; + BM_HEAP *psBMHeap; + SYS_DATA *psSysData; + IMG_UINT32 uFlags; + + if (pui32Flags == IMG_NULL) + { + PVR_DPF((PVR_DBG_ERROR, "BM_Alloc: invalid parameter")); + PVR_DBG_BREAK; + return IMG_FALSE; + } + + uFlags = *pui32Flags; + + PVR_DPF ((PVR_DBG_MESSAGE, + "BM_Alloc (uSize=0x%x, uFlags=0x%x, uDevVAddrAlignment=0x%x)", + uSize, uFlags, uDevVAddrAlignment)); + + if (SysAcquireData(&psSysData) != PVRSRV_OK) + { + return IMG_FALSE; + } + + psBMHeap = (BM_HEAP*)hDevMemHeap; + pBMContext = psBMHeap->pBMContext; + + if(uDevVAddrAlignment == 0) + { + uDevVAddrAlignment = 1; + } + + + if (OSAllocMem(PVRSRV_OS_PAGEABLE_HEAP, + sizeof (BM_BUF), + (IMG_PVOID *)&pBuf, IMG_NULL) != PVRSRV_OK) + { + PVR_DPF((PVR_DBG_ERROR, "BM_Alloc: BM_Buf alloc FAILED")); + return IMG_FALSE; + } + OSMemSet(pBuf, 0, sizeof (BM_BUF)); + + + if (AllocMemory(pBMContext, + psBMHeap, + psDevVAddr, + uSize, + uFlags, + uDevVAddrAlignment, + pBuf) != IMG_TRUE) + { + OSFreeMem(PVRSRV_OS_PAGEABLE_HEAP, sizeof (BM_BUF), pBuf, IMG_NULL); + PVR_DPF((PVR_DBG_ERROR, "BM_Alloc: AllocMemory FAILED")); + return IMG_FALSE; + } + + PVR_DPF ((PVR_DBG_MESSAGE, + "BM_Alloc (uSize=0x%x, uFlags=0x%x)=%08X", + uSize, uFlags, pBuf)); + + + pBuf->ui32RefCount = 1; + *phBuf = (BM_HANDLE)pBuf; + *pui32Flags = uFlags | psBMHeap->ui32Attribs; + + return IMG_TRUE; +} + + + +#if defined(PVR_LMA) +static IMG_BOOL +ValidSysPAddrArrayForDev(PVRSRV_DEVICE_NODE *psDeviceNode, IMG_SYS_PHYADDR *psSysPAddr, IMG_UINT32 ui32PageCount, IMG_UINT32 ui32PageSize) +{ + IMG_UINT32 i; + + for (i = 0; i < ui32PageCount; i++) + { + IMG_SYS_PHYADDR sStartSysPAddr = psSysPAddr[i]; + IMG_SYS_PHYADDR sEndSysPAddr; + + if (!SysVerifySysPAddrToDevPAddr(psDeviceNode->sDevId.eDeviceType, sStartSysPAddr)) + { + return IMG_FALSE; + } + + sEndSysPAddr.uiAddr = sStartSysPAddr.uiAddr + ui32PageSize; + + if (!SysVerifySysPAddrToDevPAddr(psDeviceNode->sDevId.eDeviceType, sEndSysPAddr)) + { + return IMG_FALSE; + } + } + + return IMG_TRUE; +} + +static IMG_BOOL +ValidSysPAddrRangeForDev(PVRSRV_DEVICE_NODE *psDeviceNode, IMG_SYS_PHYADDR sStartSysPAddr, IMG_UINT32 ui32Range) +{ + IMG_SYS_PHYADDR sEndSysPAddr; + + if (!SysVerifySysPAddrToDevPAddr(psDeviceNode->sDevId.eDeviceType, sStartSysPAddr)) + { + return IMG_FALSE; + } + + sEndSysPAddr.uiAddr = sStartSysPAddr.uiAddr + ui32Range; + + if (!SysVerifySysPAddrToDevPAddr(psDeviceNode->sDevId.eDeviceType, sEndSysPAddr)) + { + return IMG_FALSE; + } + + return IMG_TRUE; +} + +#define WRAP_MAPPING_SIZE(ui32ByteSize, ui32PageOffset) HOST_PAGEALIGN((ui32ByteSize) + (ui32PageOffset)) + +#define WRAP_PAGE_COUNT(ui32ByteSize, ui32PageOffset, ui32HostPageSize) (WRAP_MAPPING_SIZE(ui32ByteSize, ui32PageOffset) / (ui32HostPageSize)) + +#endif + + +IMG_BOOL +BM_Wrap ( IMG_HANDLE hDevMemHeap, + IMG_UINT32 ui32Size, + IMG_UINT32 ui32Offset, + IMG_BOOL bPhysContig, + IMG_SYS_PHYADDR *psSysAddr, + IMG_VOID *pvCPUVAddr, + IMG_UINT32 *pui32Flags, + BM_HANDLE *phBuf) +{ + BM_BUF *pBuf; + BM_CONTEXT *psBMContext; + BM_HEAP *psBMHeap; + SYS_DATA *psSysData; + IMG_SYS_PHYADDR sHashAddress; + IMG_UINT32 uFlags; + + psBMHeap = (BM_HEAP*)hDevMemHeap; + psBMContext = psBMHeap->pBMContext; + + uFlags = psBMHeap->ui32Attribs & (PVRSRV_HAP_CACHETYPE_MASK | PVRSRV_HAP_MAPTYPE_MASK); + + if(pui32Flags) + uFlags |= *pui32Flags; + + PVR_DPF ((PVR_DBG_MESSAGE, + "BM_Wrap (uSize=0x%x, uOffset=0x%x, bPhysContig=0x%x, pvCPUVAddr=0x%x, uFlags=0x%x)", + ui32Size, ui32Offset, bPhysContig, pvCPUVAddr, uFlags)); + + if(SysAcquireData (&psSysData) != PVRSRV_OK) + return IMG_FALSE; + +#if defined(PVR_LMA) + if (bPhysContig) + { + if (!ValidSysPAddrRangeForDev(psBMContext->psDeviceNode, *psSysAddr, WRAP_MAPPING_SIZE(ui32Size, ui32Offset))) + { + PVR_DPF((PVR_DBG_ERROR, "BM_Wrap: System address range invalid for device")); + return IMG_FALSE; + } + } + else + { + IMG_UINT32 ui32HostPageSize = HOST_PAGESIZE(); + + if (!ValidSysPAddrArrayForDev(psBMContext->psDeviceNode, psSysAddr, WRAP_PAGE_COUNT(ui32Size, ui32Offset, ui32HostPageSize), ui32HostPageSize)) + { + PVR_DPF((PVR_DBG_ERROR, "BM_Wrap: Array of system addresses invalid for device")); + return IMG_FALSE; + } + } +#endif + + sHashAddress = psSysAddr[0]; + + + sHashAddress.uiAddr += ui32Offset; + + + pBuf = (BM_BUF *)HASH_Retrieve(psBMContext->pBufferHash, (IMG_UINTPTR_T) sHashAddress.uiAddr); + + if(pBuf) + { + IMG_UINT32 ui32MappingSize = HOST_PAGEALIGN (ui32Size + ui32Offset); + + + if(pBuf->pMapping->uSize == ui32MappingSize && (pBuf->pMapping->eCpuMemoryOrigin == hm_wrapped || + pBuf->pMapping->eCpuMemoryOrigin == hm_wrapped_virtaddr)) + { + PVR_DPF((PVR_DBG_MESSAGE, + "BM_Wrap (Matched previous Wrap! uSize=0x%x, uOffset=0x%x, SysAddr=%08X)", + ui32Size, ui32Offset, sHashAddress.uiAddr)); + + pBuf->ui32RefCount++; + *phBuf = (BM_HANDLE)pBuf; + if(pui32Flags) + *pui32Flags = uFlags; + + return IMG_TRUE; + } + } + + + if (OSAllocMem(PVRSRV_OS_PAGEABLE_HEAP, + sizeof (BM_BUF), + (IMG_PVOID *)&pBuf, IMG_NULL) != PVRSRV_OK) + { + PVR_DPF((PVR_DBG_ERROR, "BM_Wrap: BM_Buf alloc FAILED")); + return IMG_FALSE; + } + OSMemSet(pBuf, 0, sizeof (BM_BUF)); + + + if (WrapMemory (psBMHeap, ui32Size, ui32Offset, bPhysContig, psSysAddr, pvCPUVAddr, uFlags, pBuf) != IMG_TRUE) + { + PVR_DPF((PVR_DBG_ERROR, "BM_Wrap: WrapMemory FAILED")); + OSFreeMem(PVRSRV_OS_PAGEABLE_HEAP, sizeof (BM_BUF), pBuf, IMG_NULL); + return IMG_FALSE; + } + + + if(pBuf->pMapping->eCpuMemoryOrigin == hm_wrapped || pBuf->pMapping->eCpuMemoryOrigin == hm_wrapped_virtaddr) + { + + PVR_ASSERT(SysSysPAddrToCpuPAddr(sHashAddress).uiAddr == pBuf->CpuPAddr.uiAddr); + + if (!HASH_Insert (psBMContext->pBufferHash, (IMG_UINTPTR_T) sHashAddress.uiAddr, (IMG_UINTPTR_T)pBuf)) + { + FreeBuf (pBuf, uFlags); + OSFreeMem(PVRSRV_OS_PAGEABLE_HEAP, sizeof (BM_BUF), pBuf, IMG_NULL); + PVR_DPF((PVR_DBG_ERROR, "BM_Wrap: HASH_Insert FAILED")); + return IMG_FALSE; + } + } + + PVR_DPF ((PVR_DBG_MESSAGE, + "BM_Wrap (uSize=0x%x, uFlags=0x%x)=%08X(devVAddr=%08X)", + ui32Size, uFlags, pBuf, pBuf->DevVAddr.uiAddr)); + + + pBuf->ui32RefCount = 1; + *phBuf = (BM_HANDLE)pBuf; + if(pui32Flags) + { + + *pui32Flags = (uFlags & ~PVRSRV_HAP_MAPTYPE_MASK) | PVRSRV_HAP_MULTI_PROCESS; + } + + return IMG_TRUE; +} + + +IMG_VOID +BM_Free (BM_HANDLE hBuf, + IMG_UINT32 ui32Flags) +{ + BM_BUF *pBuf = (BM_BUF *)hBuf; + SYS_DATA *psSysData; + IMG_SYS_PHYADDR sHashAddr; + + PVR_DPF ((PVR_DBG_MESSAGE, "BM_Free (h=%08X)", hBuf)); + PVR_ASSERT (pBuf!=IMG_NULL); + + if (pBuf == IMG_NULL) + { + PVR_DPF((PVR_DBG_ERROR, "BM_Free: invalid parameter")); + return; + } + + if(SysAcquireData (&psSysData) != PVRSRV_OK) + return; + + pBuf->ui32RefCount--; + + if(pBuf->ui32RefCount == 0) + { + if(pBuf->pMapping->eCpuMemoryOrigin == hm_wrapped || pBuf->pMapping->eCpuMemoryOrigin == hm_wrapped_virtaddr) + { + sHashAddr = SysCpuPAddrToSysPAddr(pBuf->CpuPAddr); + + HASH_Remove (pBuf->pMapping->pBMHeap->pBMContext->pBufferHash, (IMG_UINTPTR_T)sHashAddr.uiAddr); + } + FreeBuf (pBuf, ui32Flags); + } +} + + +IMG_CPU_VIRTADDR +BM_HandleToCpuVaddr (BM_HANDLE hBuf) +{ + BM_BUF *pBuf = (BM_BUF *)hBuf; + + PVR_ASSERT (pBuf != IMG_NULL); + if (pBuf == IMG_NULL) + { + PVR_DPF((PVR_DBG_ERROR, "BM_HandleToCpuVaddr: invalid parameter")); + return IMG_NULL; + } + + PVR_DPF ((PVR_DBG_MESSAGE, + "BM_HandleToCpuVaddr(h=%08X)=%08X", + hBuf, pBuf->CpuVAddr)); + return pBuf->CpuVAddr; +} + + +IMG_DEV_VIRTADDR +BM_HandleToDevVaddr (BM_HANDLE hBuf) +{ + BM_BUF *pBuf = (BM_BUF *)hBuf; + + PVR_ASSERT (pBuf != IMG_NULL); + if (pBuf == IMG_NULL) + { + IMG_DEV_VIRTADDR DevVAddr = {0}; + PVR_DPF((PVR_DBG_ERROR, "BM_HandleToDevVaddr: invalid parameter")); + return DevVAddr; + } + + PVR_DPF ((PVR_DBG_MESSAGE, "BM_HandleToDevVaddr(h=%08X)=%08X", hBuf, pBuf->DevVAddr)); + return pBuf->DevVAddr; +} + + +IMG_SYS_PHYADDR +BM_HandleToSysPaddr (BM_HANDLE hBuf) +{ + BM_BUF *pBuf = (BM_BUF *)hBuf; + + PVR_ASSERT (pBuf != IMG_NULL); + + if (pBuf == IMG_NULL) + { + IMG_SYS_PHYADDR PhysAddr = {0}; + PVR_DPF((PVR_DBG_ERROR, "BM_HandleToSysPaddr: invalid parameter")); + return PhysAddr; + } + + PVR_DPF ((PVR_DBG_MESSAGE, "BM_HandleToSysPaddr(h=%08X)=%08X", hBuf, pBuf->CpuPAddr.uiAddr)); + return SysCpuPAddrToSysPAddr (pBuf->CpuPAddr); +} + +IMG_HANDLE +BM_HandleToOSMemHandle(BM_HANDLE hBuf) +{ + BM_BUF *pBuf = (BM_BUF *)hBuf; + + PVR_ASSERT (pBuf != IMG_NULL); + + if (pBuf == IMG_NULL) + { + PVR_DPF((PVR_DBG_ERROR, "BM_HandleToOSMemHandle: invalid parameter")); + return IMG_NULL; + } + + PVR_DPF ((PVR_DBG_MESSAGE, + "BM_HandleToOSMemHandle(h=%08X)=%08X", + hBuf, pBuf->hOSMemHandle)); + return pBuf->hOSMemHandle; +} + +IMG_BOOL +BM_ContiguousStatistics (IMG_UINT32 uFlags, + IMG_UINT32 *pTotalBytes, + IMG_UINT32 *pAvailableBytes) +{ + if (pAvailableBytes || pTotalBytes || uFlags); + return IMG_FALSE; +} + + +static IMG_BOOL +DevMemoryAlloc (BM_CONTEXT *pBMContext, + BM_MAPPING *pMapping, + IMG_SIZE_T *pActualSize, + IMG_UINT32 uFlags, + IMG_UINT32 dev_vaddr_alignment, + IMG_DEV_VIRTADDR *pDevVAddr) +{ + PVRSRV_DEVICE_NODE *psDeviceNode; +#ifdef PDUMP + IMG_UINT32 ui32PDumpSize = pMapping->uSize; +#endif + + psDeviceNode = pBMContext->psDeviceNode; + + if(uFlags & PVRSRV_MEM_INTERLEAVED) + { + + pMapping->uSize *= 2; + } + +#ifdef PDUMP + if(uFlags & PVRSRV_MEM_DUMMY) + { + + ui32PDumpSize = pMapping->pBMHeap->sDevArena.ui32DataPageSize; + } +#endif + + + if (!psDeviceNode->pfnMMUAlloc (pMapping->pBMHeap->pMMUHeap, + pMapping->uSize, + pActualSize, + 0, + dev_vaddr_alignment, + &(pMapping->DevVAddr))) + { + PVR_DPF((PVR_DBG_ERROR, "DevMemoryAlloc ERROR MMU_Alloc")); + return IMG_FALSE; + } + +#ifdef SUPPORT_SGX_MMU_BYPASS + EnableHostAccess(pBMContext->psMMUContext); +#endif + + + + PDUMPMALLOCPAGES(psDeviceNode->sDevId.eDeviceType, pMapping->DevVAddr.uiAddr, pMapping->CpuVAddr, pMapping->hOSMemHandle, ui32PDumpSize, pMapping->pBMHeap->sDevArena.ui32DataPageSize, (IMG_HANDLE)pMapping); + + switch (pMapping->eCpuMemoryOrigin) + { + case hm_wrapped: + case hm_wrapped_virtaddr: + case hm_contiguous: + { + psDeviceNode->pfnMMUMapPages ( pMapping->pBMHeap->pMMUHeap, + pMapping->DevVAddr, + SysCpuPAddrToSysPAddr (pMapping->CpuPAddr), + pMapping->uSize, + uFlags, + (IMG_HANDLE)pMapping); + + *pDevVAddr = pMapping->DevVAddr; + break; + } + case hm_env: + { + psDeviceNode->pfnMMUMapShadow ( pMapping->pBMHeap->pMMUHeap, + pMapping->DevVAddr, + pMapping->uSize, + pMapping->CpuVAddr, + pMapping->hOSMemHandle, + pDevVAddr, + uFlags, + (IMG_HANDLE)pMapping); + break; + } + case hm_wrapped_scatter: + case hm_wrapped_scatter_virtaddr: + { + psDeviceNode->pfnMMUMapScatter (pMapping->pBMHeap->pMMUHeap, + pMapping->DevVAddr, + pMapping->psSysAddr, + pMapping->uSize, + uFlags, + (IMG_HANDLE)pMapping); + + *pDevVAddr = pMapping->DevVAddr; + break; + } + default: + PVR_DPF((PVR_DBG_ERROR, + "Illegal value %d for pMapping->eCpuMemoryOrigin", + pMapping->eCpuMemoryOrigin)); + return IMG_FALSE; + } + +#ifdef SUPPORT_SGX_MMU_BYPASS + DisableHostAccess(pBMContext->psMMUContext); +#endif + + return IMG_TRUE; +} + +static IMG_VOID +DevMemoryFree (BM_MAPPING *pMapping) +{ + PVRSRV_DEVICE_NODE *psDeviceNode; +#ifdef PDUMP + IMG_UINT32 ui32PSize; +#endif + +#ifdef PDUMP + + if(pMapping->ui32Flags & PVRSRV_MEM_DUMMY) + { + + ui32PSize = pMapping->pBMHeap->sDevArena.ui32DataPageSize; + } + else + { + ui32PSize = pMapping->uSize; + } + + PDUMPFREEPAGES(pMapping->pBMHeap, + pMapping->DevVAddr, + ui32PSize, + pMapping->pBMHeap->sDevArena.ui32DataPageSize, + (IMG_HANDLE)pMapping, + (IMG_BOOL)(pMapping->ui32Flags & PVRSRV_MEM_INTERLEAVED)); +#endif + + psDeviceNode = pMapping->pBMHeap->pBMContext->psDeviceNode; + + psDeviceNode->pfnMMUFree (pMapping->pBMHeap->pMMUHeap, pMapping->DevVAddr, pMapping->uSize); +} + +static IMG_BOOL +BM_ImportMemory (IMG_VOID *pH, + IMG_SIZE_T uRequestSize, + IMG_SIZE_T *pActualSize, + BM_MAPPING **ppsMapping, + IMG_UINT32 uFlags, + IMG_UINTPTR_T *pBase) +{ + BM_MAPPING *pMapping; + BM_HEAP *pBMHeap = pH; + BM_CONTEXT *pBMContext = pBMHeap->pBMContext; + IMG_BOOL bResult; + IMG_SIZE_T uSize; + IMG_SIZE_T uPSize; + IMG_UINT32 uDevVAddrAlignment = 0; + + PVR_DPF ((PVR_DBG_MESSAGE, + "BM_ImportMemory (pBMContext=%08X, uRequestSize=0x%x, uFlags=0x%x, uAlign=0x%x)", + pBMContext, uRequestSize, uFlags, uDevVAddrAlignment)); + + PVR_ASSERT (ppsMapping != IMG_NULL); + PVR_ASSERT (pBMContext != IMG_NULL); + + if (ppsMapping == IMG_NULL) + { + PVR_DPF((PVR_DBG_ERROR, "BM_ImportMemory: invalid parameter")); + goto fail_exit; + } + + uSize = HOST_PAGEALIGN (uRequestSize); + PVR_ASSERT (uSize >= uRequestSize); + + if (OSAllocMem(PVRSRV_OS_PAGEABLE_HEAP, + sizeof (BM_MAPPING), + (IMG_PVOID *)&pMapping, IMG_NULL) != PVRSRV_OK) + { + PVR_DPF ((PVR_DBG_ERROR, "BM_ImportMemory: failed BM_MAPPING alloc")); + goto fail_exit; + } + + pMapping->hOSMemHandle = 0; + pMapping->CpuVAddr = 0; + pMapping->DevVAddr.uiAddr = 0; + pMapping->CpuPAddr.uiAddr = 0; + pMapping->uSize = uSize; + pMapping->pBMHeap = pBMHeap; + pMapping->ui32Flags = uFlags; + + + if (pActualSize) + { + *pActualSize = uSize; + } + + + if(pMapping->ui32Flags & PVRSRV_MEM_DUMMY) + { + uPSize = pBMHeap->sDevArena.ui32DataPageSize; + } + else + { + uPSize = pMapping->uSize; + } + + + + if(pBMHeap->ui32Attribs & PVRSRV_BACKINGSTORE_SYSMEM_NONCONTIG) + { + + if (OSAllocPages(pBMHeap->ui32Attribs, + uPSize, + pBMHeap->sDevArena.ui32DataPageSize, + (IMG_VOID **)&pMapping->CpuVAddr, + &pMapping->hOSMemHandle) != PVRSRV_OK) + { + PVR_DPF((PVR_DBG_ERROR, + "BM_ImportMemory: OSAllocPages(0x%x) failed", + uPSize)); + goto fail_mapping_alloc; + } + + + pMapping->eCpuMemoryOrigin = hm_env; + } + else if(pBMHeap->ui32Attribs & PVRSRV_BACKINGSTORE_LOCALMEM_CONTIG) + { + IMG_SYS_PHYADDR sSysPAddr; + + + PVR_ASSERT(pBMHeap->pLocalDevMemArena != IMG_NULL); + + if (!RA_Alloc (pBMHeap->pLocalDevMemArena, + uPSize, + IMG_NULL, + IMG_NULL, + 0, + pBMHeap->sDevArena.ui32DataPageSize, + 0, + (IMG_UINTPTR_T *)&sSysPAddr.uiAddr)) + { + PVR_DPF((PVR_DBG_ERROR, "BM_ImportMemory: RA_Alloc(0x%x) FAILED", uPSize)); + goto fail_mapping_alloc; + } + + + pMapping->CpuPAddr = SysSysPAddrToCpuPAddr(sSysPAddr); + if(OSReservePhys(pMapping->CpuPAddr, + uPSize, + pBMHeap->ui32Attribs, + &pMapping->CpuVAddr, + &pMapping->hOSMemHandle) != PVRSRV_OK) + { + PVR_DPF((PVR_DBG_ERROR, "BM_ImportMemory: OSReservePhys failed")); + goto fail_dev_mem_alloc; + } + + + pMapping->eCpuMemoryOrigin = hm_contiguous; + } + else + { + PVR_DPF((PVR_DBG_ERROR, "BM_ImportMemory: Invalid backing store type")); + goto fail_mapping_alloc; + } + + + bResult = DevMemoryAlloc (pBMContext, + pMapping, + IMG_NULL, + uFlags, + uDevVAddrAlignment, + &pMapping->DevVAddr); + if (!bResult) + { + PVR_DPF((PVR_DBG_ERROR, + "BM_ImportMemory: DevMemoryAlloc(0x%x) failed", + pMapping->uSize)); + goto fail_dev_mem_alloc; + } + + + + PVR_ASSERT (uDevVAddrAlignment>1?(pMapping->DevVAddr.uiAddr%uDevVAddrAlignment)==0:1); + + *pBase = pMapping->DevVAddr.uiAddr; + *ppsMapping = pMapping; + + PVR_DPF ((PVR_DBG_MESSAGE, "BM_ImportMemory: IMG_TRUE")); + return IMG_TRUE; + +fail_dev_mem_alloc: + if (pMapping && (pMapping->CpuVAddr || pMapping->hOSMemHandle)) + { + + if(pMapping->ui32Flags & PVRSRV_MEM_INTERLEAVED) + { + pMapping->uSize /= 2; + } + + if(pMapping->ui32Flags & PVRSRV_MEM_DUMMY) + { + uPSize = pBMHeap->sDevArena.ui32DataPageSize; + } + else + { + uPSize = pMapping->uSize; + } + + if(pBMHeap->ui32Attribs & PVRSRV_BACKINGSTORE_SYSMEM_NONCONTIG) + { + OSFreePages(pBMHeap->ui32Attribs, + uPSize, + (IMG_VOID *)pMapping->CpuVAddr, + pMapping->hOSMemHandle); + } + else + { + IMG_SYS_PHYADDR sSysPAddr; + + if(pMapping->CpuVAddr) + { + OSUnReservePhys(pMapping->CpuVAddr, + uPSize, + pBMHeap->ui32Attribs, + pMapping->hOSMemHandle); + } + sSysPAddr = SysCpuPAddrToSysPAddr(pMapping->CpuPAddr); + RA_Free (pBMHeap->pLocalDevMemArena, sSysPAddr.uiAddr, IMG_FALSE); + } + } +fail_mapping_alloc: + OSFreeMem(PVRSRV_OS_PAGEABLE_HEAP, sizeof(BM_MAPPING), pMapping, IMG_NULL); +fail_exit: + return IMG_FALSE; +} + + +static IMG_VOID +BM_FreeMemory (IMG_VOID *h, IMG_UINTPTR_T _base, BM_MAPPING *psMapping) +{ + BM_HEAP *pBMHeap = h; + IMG_SIZE_T uPSize; + + PVR_UNREFERENCED_PARAMETER (_base); + + PVR_DPF ((PVR_DBG_MESSAGE, + "BM_FreeMemory (h=%08X, base=0x%x, psMapping=0x%x)", h, _base, psMapping)); + + PVR_ASSERT (psMapping != IMG_NULL); + + if (psMapping == IMG_NULL) + { + PVR_DPF((PVR_DBG_ERROR, "BM_FreeMemory: invalid parameter")); + return; + } + + DevMemoryFree (psMapping); + + + if((psMapping->ui32Flags & PVRSRV_MEM_INTERLEAVED) != 0) + { + psMapping->uSize /= 2; + } + + if(psMapping->ui32Flags & PVRSRV_MEM_DUMMY) + { + uPSize = psMapping->pBMHeap->sDevArena.ui32DataPageSize; + } + else + { + uPSize = psMapping->uSize; + } + + if(pBMHeap->ui32Attribs & PVRSRV_BACKINGSTORE_SYSMEM_NONCONTIG) + { + OSFreePages(pBMHeap->ui32Attribs, + uPSize, + (IMG_VOID *) psMapping->CpuVAddr, + psMapping->hOSMemHandle); + } + else if(pBMHeap->ui32Attribs & PVRSRV_BACKINGSTORE_LOCALMEM_CONTIG) + { + IMG_SYS_PHYADDR sSysPAddr; + + OSUnReservePhys(psMapping->CpuVAddr, uPSize, pBMHeap->ui32Attribs, psMapping->hOSMemHandle); + + sSysPAddr = SysCpuPAddrToSysPAddr(psMapping->CpuPAddr); + + RA_Free (pBMHeap->pLocalDevMemArena, sSysPAddr.uiAddr, IMG_FALSE); + } + else + { + PVR_DPF((PVR_DBG_ERROR, "BM_FreeMemory: Invalid backing store type")); + } + + OSFreeMem(PVRSRV_OS_PAGEABLE_HEAP, sizeof(BM_MAPPING), psMapping, IMG_NULL); + + PVR_DPF((PVR_DBG_MESSAGE, + "..BM_FreeMemory (h=%08X, base=0x%x, psMapping=0x%x)", + h, _base, psMapping)); +} + +PVRSRV_ERROR BM_GetPhysPageAddr(PVRSRV_KERNEL_MEM_INFO *psMemInfo, + IMG_DEV_VIRTADDR sDevVPageAddr, + IMG_DEV_PHYADDR *psDevPAddr) +{ + PVRSRV_DEVICE_NODE *psDeviceNode; + + PVR_DPF((PVR_DBG_MESSAGE, "BM_GetPhysPageAddr")); + + if(!psMemInfo || !psDevPAddr) + { + PVR_DPF((PVR_DBG_ERROR, "BM_GetPhysPageAddr: Invalid params")); + return PVRSRV_ERROR_INVALID_PARAMS; + } + + + PVR_ASSERT((sDevVPageAddr.uiAddr & 0xFFF) == 0); + + psDeviceNode = ((BM_BUF*)psMemInfo->sMemBlk.hBuffer)->pMapping->pBMHeap->pBMContext->psDeviceNode; + + *psDevPAddr = psDeviceNode->pfnMMUGetPhysPageAddr(((BM_BUF*)psMemInfo->sMemBlk.hBuffer)->pMapping->pBMHeap->pMMUHeap, + sDevVPageAddr); + + return PVRSRV_OK; +} + + +PVRSRV_ERROR BM_GetHeapInfo(IMG_HANDLE hDevMemHeap, PVRSRV_HEAP_INFO *psHeapInfo) +{ + BM_HEAP *psBMHeap = (BM_HEAP *)hDevMemHeap; + + PVR_DPF((PVR_DBG_VERBOSE, "BM_GetHeapInfo")); + + psHeapInfo->hDevMemHeap = hDevMemHeap; + psHeapInfo->sDevVAddrBase = psBMHeap->sDevArena.BaseDevVAddr; + psHeapInfo->ui32HeapByteSize = psBMHeap->sDevArena.ui32Size; + psHeapInfo->ui32Attribs = psBMHeap->ui32Attribs; + + return PVRSRV_OK; +} + + +MMU_CONTEXT* BM_GetMMUContext(IMG_HANDLE hDevMemHeap) +{ + BM_HEAP *pBMHeap = (BM_HEAP*)hDevMemHeap; + + PVR_DPF((PVR_DBG_VERBOSE, "BM_GetMMUContext")); + + return pBMHeap->pBMContext->psMMUContext; +} + +MMU_CONTEXT* BM_GetMMUContextFromMemContext(IMG_HANDLE hDevMemContext) +{ + BM_CONTEXT *pBMContext = (BM_CONTEXT*)hDevMemContext; + + PVR_DPF ((PVR_DBG_VERBOSE, "BM_GetMMUContextFromMemContext")); + + return pBMContext->psMMUContext; +} + +IMG_HANDLE BM_GetMMUHeap(IMG_HANDLE hDevMemHeap) +{ + PVR_DPF((PVR_DBG_VERBOSE, "BM_GetMMUHeap")); + + return (IMG_HANDLE)((BM_HEAP*)hDevMemHeap)->pMMUHeap; +} + + +PVRSRV_DEVICE_NODE* BM_GetDeviceNode(IMG_HANDLE hDevMemContext) +{ + PVR_DPF((PVR_DBG_VERBOSE, "BM_GetDeviceNode")); + + return ((BM_CONTEXT*)hDevMemContext)->psDeviceNode; +} + + +IMG_HANDLE BM_GetMappingHandle(PVRSRV_KERNEL_MEM_INFO *psMemInfo) +{ + PVR_DPF((PVR_DBG_VERBOSE, "BM_GetMappingHandle")); + + return ((BM_BUF*)psMemInfo->sMemBlk.hBuffer)->pMapping->hOSMemHandle; +} + diff --git a/services4/srvkm/common/deviceclass.c b/services4/srvkm/common/deviceclass.c new file mode 100644 index 0000000..4ba18b7 --- /dev/null +++ b/services4/srvkm/common/deviceclass.c @@ -0,0 +1,1761 @@ +/********************************************************************** + * + * Copyright(c) 2008 Imagination Technologies Ltd. All rights reserved. + * + * This program is free software; you can redistribute it and/or modify it + * under the terms and conditions of the GNU General Public License, + * version 2, as published by the Free Software Foundation. + * + * This program is distributed in the hope it will be useful but, except + * as otherwise stated in writing, without any warranty; without even the + * implied warranty of merchantability or fitness for a particular purpose. + * See the GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License along with + * this program; if not, write to the Free Software Foundation, Inc., + * 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA. + * + * The full GNU General Public License is included in this distribution in + * the file called "COPYING". + * + * Contact Information: + * Imagination Technologies Ltd. + * Home Park Estate, Kings Langley, Herts, WD4 8LZ, UK + * + ******************************************************************************/ + +#include "services_headers.h" +#include "buffer_manager.h" +#include "kernelbuffer.h" +#include "pvr_bridge_km.h" + + +PVRSRV_ERROR AllocateDeviceID(SYS_DATA *psSysData, IMG_UINT32 *pui32DevID); +PVRSRV_ERROR FreeDeviceID(SYS_DATA *psSysData, IMG_UINT32 ui32DevID); + +typedef struct PVRSRV_DC_SRV2DISP_KMJTABLE_TAG *PPVRSRV_DC_SRV2DISP_KMJTABLE; + +typedef struct PVRSRV_DC_BUFFER_TAG +{ + + PVRSRV_DEVICECLASS_BUFFER sDeviceClassBuffer; + + struct PVRSRV_DISPLAYCLASS_INFO_TAG *psDCInfo; + struct PVRSRV_DC_SWAPCHAIN_TAG *psSwapChain; +} PVRSRV_DC_BUFFER; + +typedef struct PVRSRV_DC_SWAPCHAIN_TAG +{ + IMG_HANDLE hExtSwapChain; + PVRSRV_QUEUE_INFO *psQueue; + PVRSRV_DC_BUFFER asBuffer[PVRSRV_MAX_DC_SWAPCHAIN_BUFFERS]; + IMG_UINT32 ui32BufferCount; + PVRSRV_DC_BUFFER *psLastFlipBuffer; + struct PVRSRV_DISPLAYCLASS_INFO_TAG *psDCInfo; + IMG_HANDLE hResItem; +} PVRSRV_DC_SWAPCHAIN; + +typedef struct PVRSRV_DISPLAYCLASS_INFO_TAG +{ + IMG_UINT32 ui32RefCount; + IMG_UINT32 ui32DeviceID; + IMG_HANDLE hExtDevice; + PPVRSRV_DC_SRV2DISP_KMJTABLE psFuncTable; + IMG_HANDLE hDevMemContext; + PVRSRV_DC_BUFFER sSystemBuffer; +} PVRSRV_DISPLAYCLASS_INFO; + + +typedef struct PVRSRV_DISPLAYCLASS_PERCONTEXT_INFO_TAG +{ + PVRSRV_DISPLAYCLASS_INFO *psDCInfo; + PRESMAN_ITEM hResItem; +} PVRSRV_DISPLAYCLASS_PERCONTEXT_INFO; + + +typedef struct PVRSRV_BC_SRV2BUFFER_KMJTABLE_TAG *PPVRSRV_BC_SRV2BUFFER_KMJTABLE; + +typedef struct PVRSRV_BC_BUFFER_TAG +{ + + PVRSRV_DEVICECLASS_BUFFER sDeviceClassBuffer; + + struct PVRSRV_BUFFERCLASS_INFO_TAG *psBCInfo; +} PVRSRV_BC_BUFFER; + + +typedef struct PVRSRV_BUFFERCLASS_INFO_TAG +{ + IMG_UINT32 ui32RefCount; + IMG_UINT32 ui32DeviceID; + IMG_HANDLE hExtDevice; + PPVRSRV_BC_SRV2BUFFER_KMJTABLE psFuncTable; + IMG_HANDLE hDevMemContext; + + IMG_UINT32 ui32BufferCount; + PVRSRV_BC_BUFFER *psBuffer; + +} PVRSRV_BUFFERCLASS_INFO; + + +typedef struct PVRSRV_BUFFERCLASS_PERCONTEXT_INFO_TAG +{ + PVRSRV_BUFFERCLASS_INFO *psBCInfo; + IMG_HANDLE hResItem; +} PVRSRV_BUFFERCLASS_PERCONTEXT_INFO; + + +static PVRSRV_DISPLAYCLASS_INFO* DCDeviceHandleToDCInfo (IMG_HANDLE hDeviceKM) +{ + PVRSRV_DISPLAYCLASS_PERCONTEXT_INFO *psDCPerContextInfo; + + psDCPerContextInfo = (PVRSRV_DISPLAYCLASS_PERCONTEXT_INFO *)hDeviceKM; + + return psDCPerContextInfo->psDCInfo; +} + + +static PVRSRV_BUFFERCLASS_INFO* BCDeviceHandleToBCInfo (IMG_HANDLE hDeviceKM) +{ + PVRSRV_BUFFERCLASS_PERCONTEXT_INFO *psBCPerContextInfo; + + psBCPerContextInfo = (PVRSRV_BUFFERCLASS_PERCONTEXT_INFO *)hDeviceKM; + + return psBCPerContextInfo->psBCInfo; +} + + +IMG_EXPORT +PVRSRV_ERROR PVRSRVEnumerateDCKM (PVRSRV_DEVICE_CLASS DeviceClass, + IMG_UINT32 *pui32DevCount, + IMG_UINT32 *pui32DevID ) +{ + PVRSRV_DEVICE_NODE *psDeviceNode; + IMG_UINT ui32DevCount = 0; + SYS_DATA *psSysData; + + if (SysAcquireData(&psSysData) != PVRSRV_OK) + { + PVR_DPF((PVR_DBG_ERROR,"PVRSRVEnumerateDCKM: Failed to get SysData")); + return PVRSRV_ERROR_GENERIC; + } + + + + psDeviceNode = psSysData->psDeviceNodeList; + while(psDeviceNode) + { + if ((psDeviceNode->sDevId.eDeviceClass == DeviceClass) + && (psDeviceNode->sDevId.eDeviceType == PVRSRV_DEVICE_TYPE_EXT)) + { + ui32DevCount++; + if(pui32DevID) + { + *pui32DevID++ = psDeviceNode->sDevId.ui32DeviceIndex; + } + } + psDeviceNode = psDeviceNode->psNext; + } + + if(pui32DevCount) + { + *pui32DevCount = ui32DevCount; + } + else if(pui32DevID == IMG_NULL) + { + PVR_DPF((PVR_DBG_ERROR,"PVRSRVEnumerateDCKM: Invalid parameters")); + return (PVRSRV_ERROR_INVALID_PARAMS); + } + + return PVRSRV_OK; +} + + +PVRSRV_ERROR PVRSRVRegisterDCDeviceKM (PVRSRV_DC_SRV2DISP_KMJTABLE *psFuncTable, + IMG_UINT32 *pui32DeviceID) +{ + PVRSRV_DISPLAYCLASS_INFO *psDCInfo = IMG_NULL; + PVRSRV_DEVICE_NODE *psDeviceNode; + SYS_DATA *psSysData; + + + + + + + + + + + + + + + + + if (SysAcquireData(&psSysData) != PVRSRV_OK) + { + PVR_DPF((PVR_DBG_ERROR,"PVRSRVRegisterDCDeviceKM: Failed to get SysData")); + return PVRSRV_ERROR_GENERIC; + } + + + + + + + if(OSAllocMem( PVRSRV_OS_PAGEABLE_HEAP, + sizeof(*psDCInfo), + (IMG_VOID **)&psDCInfo, IMG_NULL) != PVRSRV_OK) + { + PVR_DPF((PVR_DBG_ERROR,"PVRSRVRegisterDCDeviceKM: Failed psDCInfo alloc")); + return PVRSRV_ERROR_OUT_OF_MEMORY; + } + OSMemSet (psDCInfo, 0, sizeof(*psDCInfo)); + + + if(OSAllocMem( PVRSRV_OS_PAGEABLE_HEAP, + sizeof(PVRSRV_DC_SRV2DISP_KMJTABLE), + (IMG_VOID **)&psDCInfo->psFuncTable, IMG_NULL) != PVRSRV_OK) + { + PVR_DPF((PVR_DBG_ERROR,"PVRSRVRegisterDCDeviceKM: Failed psFuncTable alloc")); + goto ErrorExit; + } + OSMemSet (psDCInfo->psFuncTable, 0, sizeof(PVRSRV_DC_SRV2DISP_KMJTABLE)); + + + *psDCInfo->psFuncTable = *psFuncTable; + + + if(OSAllocMem( PVRSRV_OS_PAGEABLE_HEAP, + sizeof(PVRSRV_DEVICE_NODE), + (IMG_VOID **)&psDeviceNode, IMG_NULL) != PVRSRV_OK) + { + PVR_DPF((PVR_DBG_ERROR,"PVRSRVRegisterDCDeviceKM: Failed psDeviceNode alloc")); + goto ErrorExit; + } + OSMemSet (psDeviceNode, 0, sizeof(PVRSRV_DEVICE_NODE)); + + psDeviceNode->pvDevice = (IMG_VOID*)psDCInfo; + psDeviceNode->ui32pvDeviceSize = sizeof(*psDCInfo); + psDeviceNode->ui32RefCount = 1; + psDeviceNode->sDevId.eDeviceType = PVRSRV_DEVICE_TYPE_EXT; + psDeviceNode->sDevId.eDeviceClass = PVRSRV_DEVICE_CLASS_DISPLAY; + psDeviceNode->psSysData = psSysData; + + + AllocateDeviceID(psSysData, &psDeviceNode->sDevId.ui32DeviceIndex); + psDCInfo->ui32DeviceID = psDeviceNode->sDevId.ui32DeviceIndex; + if (pui32DeviceID) + { + *pui32DeviceID = psDeviceNode->sDevId.ui32DeviceIndex; + } + + + SysRegisterExternalDevice(psDeviceNode); + + + psDeviceNode->psNext = psSysData->psDeviceNodeList; + psSysData->psDeviceNodeList = psDeviceNode; + + return PVRSRV_OK; + +ErrorExit: + + if(psDCInfo->psFuncTable) + { + OSFreeMem(PVRSRV_OS_PAGEABLE_HEAP, sizeof(PVRSRV_DC_SRV2DISP_KMJTABLE), psDCInfo->psFuncTable, IMG_NULL); + } + + OSFreeMem(PVRSRV_OS_PAGEABLE_HEAP, sizeof(PVRSRV_DISPLAYCLASS_INFO), psDCInfo, IMG_NULL); + + return PVRSRV_ERROR_OUT_OF_MEMORY; +} + + +PVRSRV_ERROR PVRSRVRemoveDCDeviceKM(IMG_UINT32 ui32DevIndex) +{ + SYS_DATA *psSysData; + PVRSRV_DEVICE_NODE **ppsDeviceNode, *psDeviceNode; + PVRSRV_DISPLAYCLASS_INFO *psDCInfo; + + if (SysAcquireData(&psSysData) != PVRSRV_OK) + { + PVR_DPF((PVR_DBG_ERROR,"PVRSRVRemoveDCDeviceKM: Failed to get SysData")); + return PVRSRV_ERROR_GENERIC; + } + + ppsDeviceNode = &psSysData->psDeviceNodeList; + while(*ppsDeviceNode) + { + switch((*ppsDeviceNode)->sDevId.eDeviceClass) + { + case PVRSRV_DEVICE_CLASS_DISPLAY : + { + if((*ppsDeviceNode)->sDevId.ui32DeviceIndex == ui32DevIndex) + { + goto FoundDevice; + } + break; + } + default: + { + break; + } + } + ppsDeviceNode = &((*ppsDeviceNode)->psNext); + } + + PVR_DPF((PVR_DBG_ERROR,"PVRSRVRemoveDCDeviceKM: requested device %d not present", ui32DevIndex)); + + return PVRSRV_ERROR_GENERIC; + +FoundDevice: + + psDeviceNode = *ppsDeviceNode; + + psDCInfo = (PVRSRV_DISPLAYCLASS_INFO*)psDeviceNode->pvDevice; + + + + + if(psDCInfo->ui32RefCount == 0) + { + + + *ppsDeviceNode = psDeviceNode->psNext; + + + SysRemoveExternalDevice(psDeviceNode); + + + + + PVR_ASSERT(psDCInfo->ui32RefCount == 0); + FreeDeviceID(psSysData, ui32DevIndex); + OSFreeMem(PVRSRV_OS_PAGEABLE_HEAP, 0, psDCInfo->psFuncTable, IMG_NULL); + OSFreeMem(PVRSRV_OS_PAGEABLE_HEAP, 0, psDCInfo, IMG_NULL); + OSFreeMem(PVRSRV_OS_PAGEABLE_HEAP, 0, psDeviceNode, IMG_NULL); + } + else + { + PVR_DPF((PVR_DBG_ERROR,"PVRSRVRemoveDCDeviceKM: failed as %d Services DC API connections are still open", psDCInfo->ui32RefCount)); + return PVRSRV_ERROR_GENERIC; + } + + return PVRSRV_OK; +} + + +PVRSRV_ERROR PVRSRVRegisterBCDeviceKM (PVRSRV_BC_SRV2BUFFER_KMJTABLE *psFuncTable, + IMG_UINT32 *pui32DeviceID) +{ + PVRSRV_BUFFERCLASS_INFO *psBCInfo = IMG_NULL; + PVRSRV_DEVICE_NODE *psDeviceNode; + SYS_DATA *psSysData; + + + + + + + + + + + + + + + if (SysAcquireData(&psSysData) != PVRSRV_OK) + { + PVR_DPF((PVR_DBG_ERROR,"PVRSRVRegisterBCDeviceKM: Failed to get SysData")); + return PVRSRV_ERROR_GENERIC; + } + + + + + + if(OSAllocMem( PVRSRV_OS_PAGEABLE_HEAP, + sizeof(*psBCInfo), + (IMG_VOID **)&psBCInfo, IMG_NULL) != PVRSRV_OK) + { + PVR_DPF((PVR_DBG_ERROR,"PVRSRVRegisterBCDeviceKM: Failed psBCInfo alloc")); + return PVRSRV_ERROR_OUT_OF_MEMORY; + } + OSMemSet (psBCInfo, 0, sizeof(*psBCInfo)); + + + if(OSAllocMem( PVRSRV_OS_PAGEABLE_HEAP, + sizeof(PVRSRV_BC_SRV2BUFFER_KMJTABLE), + (IMG_VOID **)&psBCInfo->psFuncTable, IMG_NULL) != PVRSRV_OK) + { + PVR_DPF((PVR_DBG_ERROR,"PVRSRVRegisterBCDeviceKM: Failed psFuncTable alloc")); + goto ErrorExit; + } + OSMemSet (psBCInfo->psFuncTable, 0, sizeof(PVRSRV_BC_SRV2BUFFER_KMJTABLE)); + + + *psBCInfo->psFuncTable = *psFuncTable; + + + if(OSAllocMem( PVRSRV_OS_PAGEABLE_HEAP, + sizeof(PVRSRV_DEVICE_NODE), + (IMG_VOID **)&psDeviceNode, IMG_NULL) != PVRSRV_OK) + { + PVR_DPF((PVR_DBG_ERROR,"PVRSRVRegisterBCDeviceKM: Failed psDeviceNode alloc")); + goto ErrorExit; + } + OSMemSet (psDeviceNode, 0, sizeof(PVRSRV_DEVICE_NODE)); + + psDeviceNode->pvDevice = (IMG_VOID*)psBCInfo; + psDeviceNode->ui32pvDeviceSize = sizeof(*psBCInfo); + psDeviceNode->ui32RefCount = 1; + psDeviceNode->sDevId.eDeviceType = PVRSRV_DEVICE_TYPE_EXT; + psDeviceNode->sDevId.eDeviceClass = PVRSRV_DEVICE_CLASS_BUFFER; + psDeviceNode->psSysData = psSysData; + + + AllocateDeviceID(psSysData, &psDeviceNode->sDevId.ui32DeviceIndex); + psBCInfo->ui32DeviceID = psDeviceNode->sDevId.ui32DeviceIndex; + if (pui32DeviceID) + { + *pui32DeviceID = psDeviceNode->sDevId.ui32DeviceIndex; + } + + + psDeviceNode->psNext = psSysData->psDeviceNodeList; + psSysData->psDeviceNodeList = psDeviceNode; + + return PVRSRV_OK; + +ErrorExit: + + if(psBCInfo->psFuncTable) + { + OSFreeMem(PVRSRV_OS_PAGEABLE_HEAP, sizeof(PPVRSRV_BC_SRV2BUFFER_KMJTABLE), psBCInfo->psFuncTable, IMG_NULL); + } + + OSFreeMem(PVRSRV_OS_PAGEABLE_HEAP, sizeof(PVRSRV_BUFFERCLASS_INFO), psBCInfo, IMG_NULL); + + return PVRSRV_ERROR_OUT_OF_MEMORY; +} + + +PVRSRV_ERROR PVRSRVRemoveBCDeviceKM(IMG_UINT32 ui32DevIndex) +{ + SYS_DATA *psSysData; + PVRSRV_DEVICE_NODE **ppsDevNode, *psDevNode; + PVRSRV_BUFFERCLASS_INFO *psBCInfo; + + if (SysAcquireData(&psSysData) != PVRSRV_OK) + { + PVR_DPF((PVR_DBG_ERROR,"PVRSRVRemoveBCDeviceKM: Failed to get SysData")); + return PVRSRV_ERROR_GENERIC; + } + + ppsDevNode = &psSysData->psDeviceNodeList; + while(*ppsDevNode) + { + switch((*ppsDevNode)->sDevId.eDeviceClass) + { + case PVRSRV_DEVICE_CLASS_BUFFER : + { + if((*ppsDevNode)->sDevId.ui32DeviceIndex == ui32DevIndex) + { + goto FoundDevice; + } + break; + } + default: + { + break; + } + } + ppsDevNode = &(*ppsDevNode)->psNext; + } + + PVR_DPF((PVR_DBG_ERROR,"PVRSRVRemoveBCDeviceKM: requested device %d not present", ui32DevIndex)); + + return PVRSRV_ERROR_GENERIC; + +FoundDevice: + + + psDevNode = *(ppsDevNode); + + psBCInfo = (PVRSRV_BUFFERCLASS_INFO*)psDevNode->pvDevice; + + + + + if(psBCInfo->ui32RefCount == 0) + { + + + *ppsDevNode = psDevNode->psNext; + + + + + FreeDeviceID(psSysData, ui32DevIndex); + psBCInfo = (PVRSRV_BUFFERCLASS_INFO*)psDevNode->pvDevice; + OSFreeMem(PVRSRV_OS_PAGEABLE_HEAP, 0, psBCInfo->psFuncTable, IMG_NULL); + OSFreeMem(PVRSRV_OS_PAGEABLE_HEAP, 0, psBCInfo, IMG_NULL); + OSFreeMem(PVRSRV_OS_PAGEABLE_HEAP, 0, psDevNode, IMG_NULL); + } + else + { + PVR_DPF((PVR_DBG_ERROR,"PVRSRVRemoveBCDeviceKM: failed as %d Services BC API connections are still open", psBCInfo->ui32RefCount)); + return PVRSRV_ERROR_GENERIC; + } + + return PVRSRV_OK; +} + + + +IMG_EXPORT +PVRSRV_ERROR PVRSRVCloseDCDeviceKM (IMG_HANDLE hDeviceKM, + IMG_BOOL bResManCallback) +{ + PVRSRV_ERROR eError; + PVRSRV_DISPLAYCLASS_PERCONTEXT_INFO *psDCPerContextInfo; + + PVR_UNREFERENCED_PARAMETER(bResManCallback); + + psDCPerContextInfo = (PVRSRV_DISPLAYCLASS_PERCONTEXT_INFO *)hDeviceKM; + + + eError = ResManFreeResByPtr(psDCPerContextInfo->hResItem); + + return eError; +} + + +static PVRSRV_ERROR CloseDCDeviceCallBack(IMG_PVOID pvParam, + IMG_UINT32 ui32Param) +{ + PVRSRV_DISPLAYCLASS_PERCONTEXT_INFO *psDCPerContextInfo; + PVRSRV_DISPLAYCLASS_INFO *psDCInfo; + + PVR_UNREFERENCED_PARAMETER(ui32Param); + + psDCPerContextInfo = (PVRSRV_DISPLAYCLASS_PERCONTEXT_INFO *)pvParam; + psDCInfo = psDCPerContextInfo->psDCInfo; + + psDCInfo->ui32RefCount--; + if(psDCInfo->ui32RefCount == 0) + { + + psDCInfo->psFuncTable->pfnCloseDCDevice(psDCInfo->hExtDevice); + + PVRSRVFreeSyncInfoKM(psDCInfo->sSystemBuffer.sDeviceClassBuffer.psKernelSyncInfo); + + psDCInfo->hDevMemContext = IMG_NULL; + psDCInfo->hExtDevice = IMG_NULL; + } + + OSFreeMem(PVRSRV_OS_PAGEABLE_HEAP, sizeof(PVRSRV_DISPLAYCLASS_PERCONTEXT_INFO), psDCPerContextInfo, IMG_NULL); + + return PVRSRV_OK; +} + + +IMG_EXPORT +PVRSRV_ERROR PVRSRVOpenDCDeviceKM (PVRSRV_PER_PROCESS_DATA *psPerProc, + IMG_UINT32 ui32DeviceID, + IMG_HANDLE hDevCookie, + IMG_HANDLE *phDeviceKM) +{ + PVRSRV_DISPLAYCLASS_INFO *psDCInfo; + PVRSRV_DISPLAYCLASS_PERCONTEXT_INFO *psDCPerContextInfo; + PVRSRV_DEVICE_NODE *psDeviceNode; + SYS_DATA *psSysData; + + if(!phDeviceKM || !hDevCookie) + { + PVR_DPF((PVR_DBG_ERROR,"PVRSRVOpenDCDeviceKM: Invalid params")); + return PVRSRV_ERROR_GENERIC; + } + + if (SysAcquireData(&psSysData) != PVRSRV_OK) + { + PVR_DPF((PVR_DBG_ERROR,"PVRSRVOpenDCDeviceKM: Failed to get SysData")); + return PVRSRV_ERROR_GENERIC; + } + + psDeviceNode = psSysData->psDeviceNodeList; + while(psDeviceNode) + { + if ((psDeviceNode->sDevId.eDeviceClass == PVRSRV_DEVICE_CLASS_DISPLAY) && + (psDeviceNode->sDevId.ui32DeviceIndex == ui32DeviceID)) + { + + + + psDCInfo = (PVRSRV_DISPLAYCLASS_INFO*)psDeviceNode->pvDevice; + goto FoundDevice; + } + psDeviceNode = psDeviceNode->psNext; + } + + PVR_DPF((PVR_DBG_ERROR,"PVRSRVOpenDCDeviceKM: no devnode matching index %d", ui32DeviceID)); + + return PVRSRV_ERROR_GENERIC; + +FoundDevice: + + + + + if(OSAllocMem(PVRSRV_OS_PAGEABLE_HEAP, + sizeof(*psDCPerContextInfo), + (IMG_VOID **)&psDCPerContextInfo, IMG_NULL) != PVRSRV_OK) + { + PVR_DPF((PVR_DBG_ERROR,"PVRSRVOpenDCDeviceKM: Failed psDCPerContextInfo alloc")); + return PVRSRV_ERROR_OUT_OF_MEMORY; + } + OSMemSet(psDCPerContextInfo, 0, sizeof(*psDCPerContextInfo)); + + if(psDCInfo->ui32RefCount++ == 0) + { + PVRSRV_ERROR eError; + + psDeviceNode = (PVRSRV_DEVICE_NODE *)hDevCookie; + + + psDCInfo->hDevMemContext = (IMG_HANDLE)psDeviceNode->sDevMemoryInfo.pBMKernelContext; + + + eError = PVRSRVAllocSyncInfoKM(IMG_NULL, + (IMG_HANDLE)psDeviceNode->sDevMemoryInfo.pBMKernelContext, + &psDCInfo->sSystemBuffer.sDeviceClassBuffer.psKernelSyncInfo); + if(eError != PVRSRV_OK) + { + PVR_DPF((PVR_DBG_ERROR,"PVRSRVOpenDCDeviceKM: Failed sync info alloc")); + psDCInfo->ui32RefCount--; + return eError; + } + + + eError = psDCInfo->psFuncTable->pfnOpenDCDevice(ui32DeviceID, + &psDCInfo->hExtDevice, + (PVRSRV_SYNC_DATA*)psDCInfo->sSystemBuffer.sDeviceClassBuffer.psKernelSyncInfo->psSyncDataMemInfoKM->pvLinAddrKM); + if(eError != PVRSRV_OK) + { + PVR_DPF((PVR_DBG_ERROR,"PVRSRVOpenDCDeviceKM: Failed to open external DC device")); + psDCInfo->ui32RefCount--; + PVRSRVFreeSyncInfoKM(psDCInfo->sSystemBuffer.sDeviceClassBuffer.psKernelSyncInfo); + return eError; + } + } + + psDCPerContextInfo->psDCInfo = psDCInfo; + psDCPerContextInfo->hResItem = ResManRegisterRes(psPerProc->hResManContext, + RESMAN_TYPE_DISPLAYCLASS_DEVICE, + psDCPerContextInfo, + 0, + CloseDCDeviceCallBack); + + + *phDeviceKM = (IMG_HANDLE)psDCPerContextInfo; + + return PVRSRV_OK; +} + + +IMG_EXPORT +PVRSRV_ERROR PVRSRVEnumDCFormatsKM (IMG_HANDLE hDeviceKM, + IMG_UINT32 *pui32Count, + DISPLAY_FORMAT *psFormat) +{ + PVRSRV_DISPLAYCLASS_INFO *psDCInfo; + + if(!hDeviceKM || !pui32Count || !psFormat) + { + PVR_DPF((PVR_DBG_ERROR,"PVRSRVEnumDCFormatsKM: Invalid parameters")); + return PVRSRV_ERROR_INVALID_PARAMS; + } + + psDCInfo = DCDeviceHandleToDCInfo(hDeviceKM); + + + return psDCInfo->psFuncTable->pfnEnumDCFormats(psDCInfo->hExtDevice, pui32Count, psFormat); +} + + + +IMG_EXPORT +PVRSRV_ERROR PVRSRVEnumDCDimsKM (IMG_HANDLE hDeviceKM, + DISPLAY_FORMAT *psFormat, + IMG_UINT32 *pui32Count, + DISPLAY_DIMS *psDim) +{ + PVRSRV_DISPLAYCLASS_INFO *psDCInfo; + + if(!hDeviceKM || !pui32Count || !psFormat) + { + PVR_DPF((PVR_DBG_ERROR,"PVRSRVEnumDCDimsKM: Invalid parameters")); + return PVRSRV_ERROR_INVALID_PARAMS; + } + + psDCInfo = DCDeviceHandleToDCInfo(hDeviceKM); + + + return psDCInfo->psFuncTable->pfnEnumDCDims(psDCInfo->hExtDevice, psFormat, pui32Count, psDim); +} + + +IMG_EXPORT +PVRSRV_ERROR PVRSRVGetDCSystemBufferKM (IMG_HANDLE hDeviceKM, + IMG_HANDLE *phBuffer) +{ + PVRSRV_ERROR eError; + PVRSRV_DISPLAYCLASS_INFO *psDCInfo; + IMG_HANDLE hExtBuffer; + + if(!hDeviceKM || !phBuffer) + { + PVR_DPF((PVR_DBG_ERROR,"PVRSRVGetDCSystemBufferKM: Invalid parameters")); + return PVRSRV_ERROR_INVALID_PARAMS; + } + + psDCInfo = DCDeviceHandleToDCInfo(hDeviceKM); + + + eError = psDCInfo->psFuncTable->pfnGetDCSystemBuffer(psDCInfo->hExtDevice, &hExtBuffer); + if(eError != PVRSRV_OK) + { + PVR_DPF((PVR_DBG_ERROR,"PVRSRVGetDCSystemBufferKM: Failed to get valid buffer handle from external driver")); + return eError; + } + + + psDCInfo->sSystemBuffer.sDeviceClassBuffer.pfnGetBufferAddr = psDCInfo->psFuncTable->pfnGetBufferAddr; + psDCInfo->sSystemBuffer.sDeviceClassBuffer.hDevMemContext = psDCInfo->hDevMemContext; + psDCInfo->sSystemBuffer.sDeviceClassBuffer.hExtDevice = psDCInfo->hExtDevice; + psDCInfo->sSystemBuffer.sDeviceClassBuffer.hExtBuffer = hExtBuffer; + + psDCInfo->sSystemBuffer.psDCInfo = psDCInfo; + + + *phBuffer = (IMG_HANDLE)&(psDCInfo->sSystemBuffer); + + return PVRSRV_OK; +} + + +IMG_EXPORT +PVRSRV_ERROR PVRSRVGetDCInfoKM (IMG_HANDLE hDeviceKM, + DISPLAY_INFO *psDisplayInfo) +{ + PVRSRV_DISPLAYCLASS_INFO *psDCInfo; + PVRSRV_ERROR eError; + + if(!hDeviceKM || !psDisplayInfo) + { + PVR_DPF((PVR_DBG_ERROR,"PVRSRVGetDCInfoKM: Invalid parameters")); + return PVRSRV_ERROR_INVALID_PARAMS; + } + + psDCInfo = DCDeviceHandleToDCInfo(hDeviceKM); + + + eError = psDCInfo->psFuncTable->pfnGetDCInfo(psDCInfo->hExtDevice, psDisplayInfo); + if (eError != PVRSRV_OK) + { + return eError; + } + + if (psDisplayInfo->ui32MaxSwapChainBuffers > PVRSRV_MAX_DC_SWAPCHAIN_BUFFERS) + { + psDisplayInfo->ui32MaxSwapChainBuffers = PVRSRV_MAX_DC_SWAPCHAIN_BUFFERS; + } + + return PVRSRV_OK; +} + + +IMG_EXPORT +PVRSRV_ERROR PVRSRVDestroyDCSwapChainKM(IMG_HANDLE hSwapChain) +{ + PVRSRV_ERROR eError; + PVRSRV_DC_SWAPCHAIN *psSwapChain; + + if(!hSwapChain) + { + PVR_DPF((PVR_DBG_ERROR,"PVRSRVDestroyDCSwapChainKM: Invalid parameters")); + return PVRSRV_ERROR_INVALID_PARAMS; + } + + psSwapChain = hSwapChain; + + eError = ResManFreeResByPtr(psSwapChain->hResItem); + + return eError; +} + + +static PVRSRV_ERROR DestroyDCSwapChainCallBack(IMG_PVOID pvParam, IMG_UINT32 ui32Param) +{ + PVRSRV_ERROR eError; + PVRSRV_DC_SWAPCHAIN *psSwapChain = pvParam; + PVRSRV_DISPLAYCLASS_INFO *psDCInfo = psSwapChain->psDCInfo; + IMG_UINT32 i; + + PVR_UNREFERENCED_PARAMETER(ui32Param); + + + PVRSRVDestroyCommandQueueKM(psSwapChain->psQueue); + + + eError = psDCInfo->psFuncTable->pfnDestroyDCSwapChain(psDCInfo->hExtDevice, + psSwapChain->hExtSwapChain); + + if (eError != PVRSRV_OK) + { + PVR_DPF((PVR_DBG_ERROR,"DestroyDCSwapChainCallBack: Failed to destroy DC swap chain")); + return eError; + } + + + for(i=0; iui32BufferCount; i++) + { + if(psSwapChain->asBuffer[i].sDeviceClassBuffer.psKernelSyncInfo) + { + PVRSRVFreeSyncInfoKM(psSwapChain->asBuffer[i].sDeviceClassBuffer.psKernelSyncInfo); + } + } + + OSFreeMem(PVRSRV_OS_PAGEABLE_HEAP, sizeof(PVRSRV_DC_SWAPCHAIN), psSwapChain, IMG_NULL); + + return eError; +} + + + +IMG_EXPORT +PVRSRV_ERROR PVRSRVCreateDCSwapChainKM (PVRSRV_PER_PROCESS_DATA *psPerProc, + IMG_HANDLE hDeviceKM, + IMG_UINT32 ui32Flags, + DISPLAY_SURF_ATTRIBUTES *psDstSurfAttrib, + DISPLAY_SURF_ATTRIBUTES *psSrcSurfAttrib, + IMG_UINT32 ui32BufferCount, + IMG_UINT32 ui32OEMFlags, + IMG_HANDLE *phSwapChain, + IMG_UINT32 *pui32SwapChainID) +{ + PVRSRV_DISPLAYCLASS_INFO *psDCInfo; + PVRSRV_DC_SWAPCHAIN *psSwapChain = IMG_NULL; + PVRSRV_SYNC_DATA *apsSyncData[PVRSRV_MAX_DC_SWAPCHAIN_BUFFERS]; + PVRSRV_QUEUE_INFO *psQueue = IMG_NULL; + PVRSRV_ERROR eError; + IMG_UINT32 i; + + + if(!hDeviceKM + || !psDstSurfAttrib + || !psSrcSurfAttrib + || !phSwapChain + || !pui32SwapChainID) + { + PVR_DPF((PVR_DBG_ERROR,"PVRSRVCreateDCSwapChainKM: Invalid parameters")); + return PVRSRV_ERROR_INVALID_PARAMS; + } + + if (ui32BufferCount > PVRSRV_MAX_DC_SWAPCHAIN_BUFFERS) + { + PVR_DPF((PVR_DBG_ERROR,"PVRSRVCreateDCSwapChainKM: Too many buffers")); + return PVRSRV_ERROR_TOOMANYBUFFERS; + } + + if (ui32BufferCount < 2) + { + PVR_DPF((PVR_DBG_ERROR,"PVRSRVCreateDCSwapChainKM: Too few buffers")); + return PVRSRV_ERROR_TOO_FEW_BUFFERS; + } + + psDCInfo = DCDeviceHandleToDCInfo(hDeviceKM); + + + if(OSAllocMem( PVRSRV_OS_PAGEABLE_HEAP, + sizeof(PVRSRV_DC_SWAPCHAIN), + (IMG_VOID **)&psSwapChain, IMG_NULL) != PVRSRV_OK) + { + PVR_DPF((PVR_DBG_ERROR,"PVRSRVCreateDCSwapChainKM: Failed psSwapChain alloc")); + eError = PVRSRV_ERROR_OUT_OF_MEMORY; + goto ErrorExit; + } + OSMemSet (psSwapChain, 0, sizeof(PVRSRV_DC_SWAPCHAIN)); + + + eError = PVRSRVCreateCommandQueueKM(1024, &psQueue); + if(eError != PVRSRV_OK) + { + PVR_DPF((PVR_DBG_ERROR,"PVRSRVCreateDCSwapChainKM: Failed to create CmdQueue")); + goto ErrorExit; + } + + + psSwapChain->psQueue = psQueue; + + + for(i=0; ihDevMemContext, + &psSwapChain->asBuffer[i].sDeviceClassBuffer.psKernelSyncInfo); + if(eError != PVRSRV_OK) + { + PVR_DPF((PVR_DBG_ERROR,"PVRSRVCreateDCSwapChainKM: Failed to alloc syninfo for psSwapChain")); + goto ErrorExit; + } + + + psSwapChain->asBuffer[i].sDeviceClassBuffer.pfnGetBufferAddr = psDCInfo->psFuncTable->pfnGetBufferAddr; + psSwapChain->asBuffer[i].sDeviceClassBuffer.hDevMemContext = psDCInfo->hDevMemContext; + psSwapChain->asBuffer[i].sDeviceClassBuffer.hExtDevice = psDCInfo->hExtDevice; + + + psSwapChain->asBuffer[i].psDCInfo = psDCInfo; + psSwapChain->asBuffer[i].psSwapChain = psSwapChain; + + + apsSyncData[i] = (PVRSRV_SYNC_DATA*)psSwapChain->asBuffer[i].sDeviceClassBuffer.psKernelSyncInfo->psSyncDataMemInfoKM->pvLinAddrKM; + } + + psSwapChain->ui32BufferCount = ui32BufferCount; + psSwapChain->psDCInfo = psDCInfo; + + + eError = psDCInfo->psFuncTable->pfnCreateDCSwapChain(psDCInfo->hExtDevice, + ui32Flags, + psDstSurfAttrib, + psSrcSurfAttrib, + ui32BufferCount, + apsSyncData, + ui32OEMFlags, + &psSwapChain->hExtSwapChain, + pui32SwapChainID); + if(eError != PVRSRV_OK) + { + PVR_DPF((PVR_DBG_ERROR,"PVRSRVCreateDCSwapChainKM: Failed to create 3rd party SwapChain")); + goto ErrorExit; + } + + + *phSwapChain = (IMG_HANDLE)psSwapChain; + + + + psSwapChain->hResItem = ResManRegisterRes(psPerProc->hResManContext, + RESMAN_TYPE_DISPLAYCLASS_SWAPCHAIN, + psSwapChain, + 0, + DestroyDCSwapChainCallBack); + + return eError; + +ErrorExit: + + for(i=0; iasBuffer[i].sDeviceClassBuffer.psKernelSyncInfo) + { + PVRSRVFreeSyncInfoKM(psSwapChain->asBuffer[i].sDeviceClassBuffer.psKernelSyncInfo); + } + } + + if(psQueue) + { + PVRSRVDestroyCommandQueueKM(psQueue); + } + + if(psSwapChain) + { + OSFreeMem(PVRSRV_OS_PAGEABLE_HEAP, sizeof(PVRSRV_DC_SWAPCHAIN), psSwapChain, IMG_NULL); + } + + return eError; +} + + + + +IMG_EXPORT +PVRSRV_ERROR PVRSRVSetDCDstRectKM(IMG_HANDLE hDeviceKM, + IMG_HANDLE hSwapChain, + IMG_RECT *psRect) +{ + PVRSRV_DISPLAYCLASS_INFO *psDCInfo; + PVRSRV_DC_SWAPCHAIN *psSwapChain; + + if(!hDeviceKM || !hSwapChain) + { + PVR_DPF((PVR_DBG_ERROR,"PVRSRVSetDCDstRectKM: Invalid parameters")); + return PVRSRV_ERROR_INVALID_PARAMS; + } + + psDCInfo = DCDeviceHandleToDCInfo(hDeviceKM); + psSwapChain = (PVRSRV_DC_SWAPCHAIN*)hSwapChain; + + return psDCInfo->psFuncTable->pfnSetDCDstRect(psDCInfo->hExtDevice, + psSwapChain->hExtSwapChain, + psRect); +} + + +IMG_EXPORT +PVRSRV_ERROR PVRSRVSetDCSrcRectKM(IMG_HANDLE hDeviceKM, + IMG_HANDLE hSwapChain, + IMG_RECT *psRect) +{ + PVRSRV_DISPLAYCLASS_INFO *psDCInfo; + PVRSRV_DC_SWAPCHAIN *psSwapChain; + + if(!hDeviceKM || !hSwapChain) + { + PVR_DPF((PVR_DBG_ERROR,"PVRSRVSetDCSrcRectKM: Invalid parameters")); + return PVRSRV_ERROR_INVALID_PARAMS; + } + + psDCInfo = DCDeviceHandleToDCInfo(hDeviceKM); + psSwapChain = (PVRSRV_DC_SWAPCHAIN*)hSwapChain; + + return psDCInfo->psFuncTable->pfnSetDCSrcRect(psDCInfo->hExtDevice, + psSwapChain->hExtSwapChain, + psRect); +} + + +IMG_EXPORT +PVRSRV_ERROR PVRSRVSetDCDstColourKeyKM(IMG_HANDLE hDeviceKM, + IMG_HANDLE hSwapChain, + IMG_UINT32 ui32CKColour) +{ + PVRSRV_DISPLAYCLASS_INFO *psDCInfo; + PVRSRV_DC_SWAPCHAIN *psSwapChain; + + if(!hDeviceKM || !hSwapChain) + { + PVR_DPF((PVR_DBG_ERROR,"PVRSRVSetDCDstColourKeyKM: Invalid parameters")); + return PVRSRV_ERROR_INVALID_PARAMS; + } + + psDCInfo = DCDeviceHandleToDCInfo(hDeviceKM); + psSwapChain = (PVRSRV_DC_SWAPCHAIN*)hSwapChain; + + return psDCInfo->psFuncTable->pfnSetDCDstColourKey(psDCInfo->hExtDevice, + psSwapChain->hExtSwapChain, + ui32CKColour); +} + + +IMG_EXPORT +PVRSRV_ERROR PVRSRVSetDCSrcColourKeyKM(IMG_HANDLE hDeviceKM, + IMG_HANDLE hSwapChain, + IMG_UINT32 ui32CKColour) +{ + PVRSRV_DISPLAYCLASS_INFO *psDCInfo; + PVRSRV_DC_SWAPCHAIN *psSwapChain; + + if(!hDeviceKM || !hSwapChain) + { + PVR_DPF((PVR_DBG_ERROR,"PVRSRVSetDCSrcColourKeyKM: Invalid parameters")); + return PVRSRV_ERROR_INVALID_PARAMS; + } + + psDCInfo = DCDeviceHandleToDCInfo(hDeviceKM); + psSwapChain = (PVRSRV_DC_SWAPCHAIN*)hSwapChain; + + return psDCInfo->psFuncTable->pfnSetDCSrcColourKey(psDCInfo->hExtDevice, + psSwapChain->hExtSwapChain, + ui32CKColour); +} + + +IMG_EXPORT +PVRSRV_ERROR PVRSRVGetDCBuffersKM(IMG_HANDLE hDeviceKM, + IMG_HANDLE hSwapChain, + IMG_UINT32 *pui32BufferCount, + IMG_HANDLE *phBuffer) +{ + PVRSRV_DISPLAYCLASS_INFO *psDCInfo; + PVRSRV_DC_SWAPCHAIN *psSwapChain; + IMG_HANDLE ahExtBuffer[PVRSRV_MAX_DC_SWAPCHAIN_BUFFERS]; + PVRSRV_ERROR eError; + IMG_UINT32 i; + + if(!hDeviceKM || !hSwapChain || !phBuffer) + { + PVR_DPF((PVR_DBG_ERROR,"PVRSRVGetDCBuffersKM: Invalid parameters")); + return PVRSRV_ERROR_INVALID_PARAMS; + } + + psDCInfo = DCDeviceHandleToDCInfo(hDeviceKM); + psSwapChain = (PVRSRV_DC_SWAPCHAIN*)hSwapChain; + + + eError = psDCInfo->psFuncTable->pfnGetDCBuffers(psDCInfo->hExtDevice, + psSwapChain->hExtSwapChain, + pui32BufferCount, + ahExtBuffer); + + PVR_ASSERT(*pui32BufferCount <= PVRSRV_MAX_DC_SWAPCHAIN_BUFFERS); + + + + + for(i=0; i<*pui32BufferCount; i++) + { + psSwapChain->asBuffer[i].sDeviceClassBuffer.hExtBuffer = ahExtBuffer[i]; + phBuffer[i] = (IMG_HANDLE)&psSwapChain->asBuffer[i]; + } + + return eError; +} + + +IMG_EXPORT +PVRSRV_ERROR PVRSRVSwapToDCBufferKM(IMG_HANDLE hDeviceKM, + IMG_HANDLE hBuffer, + IMG_UINT32 ui32SwapInterval, + IMG_HANDLE hPrivateTag, + IMG_UINT32 ui32ClipRectCount, + IMG_RECT *psClipRect) +{ + PVRSRV_ERROR eError; + PVRSRV_DISPLAYCLASS_INFO *psDCInfo; + PVRSRV_DC_BUFFER *psBuffer; + PVRSRV_QUEUE_INFO *psQueue; + DISPLAYCLASS_FLIP_COMMAND *psFlipCmd; + IMG_UINT32 i; + IMG_UINT32 ui32NumSrcSyncs = 1; + PVRSRV_KERNEL_SYNC_INFO *apsSrcSync[2]; + PVRSRV_COMMAND *psCommand; + + if(!hDeviceKM || !hBuffer || !psClipRect) + { + PVR_DPF((PVR_DBG_ERROR,"PVRSRVSwapToDCBufferKM: Invalid parameters")); + return PVRSRV_ERROR_INVALID_PARAMS; + } + +#if defined(SUPPORT_LMA) + eError = PVRSRVPowerLock(KERNEL_ID, IMG_FALSE); + if(eError != PVRSRV_OK) + { + return eError; + } +#endif + + psDCInfo = DCDeviceHandleToDCInfo(hDeviceKM); + psBuffer = (PVRSRV_DC_BUFFER*)hBuffer; + + + psQueue = psBuffer->psSwapChain->psQueue; + + + apsSrcSync[0] = psBuffer->sDeviceClassBuffer.psKernelSyncInfo; + if(psBuffer->psSwapChain->psLastFlipBuffer && + psBuffer != psBuffer->psSwapChain->psLastFlipBuffer) + { + apsSrcSync[1] = psBuffer->psSwapChain->psLastFlipBuffer->sDeviceClassBuffer.psKernelSyncInfo; + ui32NumSrcSyncs++; + } + + + eError = PVRSRVInsertCommandKM (psQueue, + &psCommand, + psDCInfo->ui32DeviceID, + DC_FLIP_COMMAND, + 0, + IMG_NULL, + ui32NumSrcSyncs, + apsSrcSync, + sizeof(DISPLAYCLASS_FLIP_COMMAND) + (sizeof(IMG_RECT) * ui32ClipRectCount)); + if(eError != PVRSRV_OK) + { + PVR_DPF((PVR_DBG_ERROR,"PVRSRVSwapToDCBufferKM: Failed to get space in queue")); + goto Exit; + } + + + psFlipCmd = (DISPLAYCLASS_FLIP_COMMAND*)psCommand->pvData; + + + psFlipCmd->hExtDevice = psDCInfo->hExtDevice; + + + psFlipCmd->hExtSwapChain = psBuffer->psSwapChain->hExtSwapChain; + + + psFlipCmd->hExtBuffer = psBuffer->sDeviceClassBuffer.hExtBuffer; + + + psFlipCmd->hPrivateTag = hPrivateTag; + + + psFlipCmd->ui32ClipRectCount = ui32ClipRectCount; + + psFlipCmd->psClipRect = (IMG_RECT*)((IMG_UINT8*)psFlipCmd + sizeof(DISPLAYCLASS_FLIP_COMMAND)); + + for(i=0; ipsClipRect[i] = psClipRect[i]; + } + + + psFlipCmd->ui32SwapInterval = ui32SwapInterval; + + + eError = PVRSRVSubmitCommandKM (psQueue, psCommand); + if (eError != PVRSRV_OK) + { + PVR_DPF((PVR_DBG_ERROR,"PVRSRVSwapToDCBufferKM: Failed to submit command")); + goto Exit; + } + + + + + + + + + + LOOP_UNTIL_TIMEOUT(MAX_HW_TIME_US) + { + if(PVRSRVProcessQueues(KERNEL_ID, IMG_FALSE) != PVRSRV_ERROR_PROCESSING_BLOCKED) + { + goto ProcessedQueues; + } + OSWaitus(MAX_HW_TIME_US/WAIT_TRY_COUNT); + } END_LOOP_UNTIL_TIMEOUT(); + + PVR_DPF((PVR_DBG_ERROR,"PVRSRVSwapToDCBufferKM: Failed to process queues")); + + eError = PVRSRV_ERROR_GENERIC; + goto Exit; + +ProcessedQueues: + + psBuffer->psSwapChain->psLastFlipBuffer = psBuffer; + +Exit: +#if defined(SUPPORT_LMA) + PVRSRVPowerUnlock(KERNEL_ID); +#endif + return eError; +} + + +IMG_EXPORT +PVRSRV_ERROR PVRSRVSwapToDCSystemKM(IMG_HANDLE hDeviceKM, + IMG_HANDLE hSwapChain) +{ + PVRSRV_ERROR eError; + PVRSRV_QUEUE_INFO *psQueue; + PVRSRV_DISPLAYCLASS_INFO *psDCInfo; + PVRSRV_DC_SWAPCHAIN *psSwapChain; + DISPLAYCLASS_FLIP_COMMAND *psFlipCmd; + IMG_UINT32 ui32NumSrcSyncs = 1; + PVRSRV_KERNEL_SYNC_INFO *apsSrcSync[2]; + PVRSRV_COMMAND *psCommand; + + if(!hDeviceKM || !hSwapChain) + { + PVR_DPF((PVR_DBG_ERROR,"PVRSRVSwapToDCSystemKM: Invalid parameters")); + return PVRSRV_ERROR_INVALID_PARAMS; + } + +#if defined(SUPPORT_LMA) + eError = PVRSRVPowerLock(KERNEL_ID, IMG_FALSE); + if(eError != PVRSRV_OK) + { + return eError; + } +#endif + + psDCInfo = DCDeviceHandleToDCInfo(hDeviceKM); + psSwapChain = (PVRSRV_DC_SWAPCHAIN*)hSwapChain; + + + psQueue = psSwapChain->psQueue; + + + apsSrcSync[0] = psDCInfo->sSystemBuffer.sDeviceClassBuffer.psKernelSyncInfo; + if(psSwapChain->psLastFlipBuffer) + { + + if (apsSrcSync[0] != psSwapChain->psLastFlipBuffer->sDeviceClassBuffer.psKernelSyncInfo) + { + apsSrcSync[1] = psSwapChain->psLastFlipBuffer->sDeviceClassBuffer.psKernelSyncInfo; + ui32NumSrcSyncs++; + } + } + + + eError = PVRSRVInsertCommandKM (psQueue, + &psCommand, + psDCInfo->ui32DeviceID, + DC_FLIP_COMMAND, + 0, + IMG_NULL, + ui32NumSrcSyncs, + apsSrcSync, + sizeof(DISPLAYCLASS_FLIP_COMMAND)); + if(eError != PVRSRV_OK) + { + PVR_DPF((PVR_DBG_ERROR,"PVRSRVSwapToDCSystemKM: Failed to get space in queue")); + goto Exit; + } + + + psFlipCmd = (DISPLAYCLASS_FLIP_COMMAND*)psCommand->pvData; + + + psFlipCmd->hExtDevice = psDCInfo->hExtDevice; + + + psFlipCmd->hExtSwapChain = psSwapChain->hExtSwapChain; + + + psFlipCmd->hExtBuffer = psDCInfo->sSystemBuffer.sDeviceClassBuffer.hExtBuffer; + + + psFlipCmd->hPrivateTag = IMG_NULL; + + + psFlipCmd->ui32ClipRectCount = 0; + + psFlipCmd->ui32SwapInterval = 1; + + + eError = PVRSRVSubmitCommandKM (psQueue, psCommand); + if (eError != PVRSRV_OK) + { + PVR_DPF((PVR_DBG_ERROR,"PVRSRVSwapToDCSystemKM: Failed to submit command")); + goto Exit; + } + + + + + + + + + LOOP_UNTIL_TIMEOUT(MAX_HW_TIME_US) + { + if(PVRSRVProcessQueues(KERNEL_ID, IMG_FALSE) != PVRSRV_ERROR_PROCESSING_BLOCKED) + { + goto ProcessedQueues; + } + OSWaitus(MAX_HW_TIME_US/WAIT_TRY_COUNT); + } END_LOOP_UNTIL_TIMEOUT(); + + PVR_DPF((PVR_DBG_ERROR,"PVRSRVSwapToDCSystemKM: Failed to process queues")); + eError = PVRSRV_ERROR_GENERIC; + goto Exit; + +ProcessedQueues: + + psSwapChain->psLastFlipBuffer = &psDCInfo->sSystemBuffer; + + eError = PVRSRV_OK; + +Exit: +#if defined(SUPPORT_LMA) + PVRSRVPowerUnlock(KERNEL_ID); +#endif + return eError; +} + + +PVRSRV_ERROR PVRSRVRegisterSystemISRHandler (PFN_ISR_HANDLER pfnISRHandler, + IMG_VOID *pvISRHandlerData, + IMG_UINT32 ui32ISRSourceMask, + IMG_UINT32 ui32DeviceID) +{ + SYS_DATA *psSysData; + PVRSRV_DEVICE_NODE *psDevNode; + + PVR_UNREFERENCED_PARAMETER(ui32ISRSourceMask); + + if (SysAcquireData(&psSysData) != PVRSRV_OK) + { + PVR_DPF((PVR_DBG_ERROR,"PVRSRVRegisterSystemISRHandler: Failed to get SysData")); + return PVRSRV_ERROR_GENERIC; + } + + + psDevNode = psSysData->psDeviceNodeList; + while(psDevNode) + { + if(psDevNode->sDevId.ui32DeviceIndex == ui32DeviceID) + { + break; + } + psDevNode = psDevNode->psNext; + } + + if (psDevNode == IMG_NULL) + { + PVR_DPF((PVR_DBG_ERROR,"PVRSRVRegisterSystemISRHandler: Failed to get psDevNode")); + PVR_DBG_BREAK; + return PVRSRV_ERROR_GENERIC; + } + + + psDevNode->pvISRData = (IMG_VOID*) pvISRHandlerData; + + + psDevNode->pfnDeviceISR = pfnISRHandler; + + return PVRSRV_OK; +} + + +IMG_VOID IMG_CALLCONV PVRSRVSetDCState(IMG_UINT32 ui32State) +{ + PVRSRV_DISPLAYCLASS_INFO *psDCInfo; + PVRSRV_DEVICE_NODE *psDeviceNode; + SYS_DATA *psSysData; + + if (SysAcquireData(&psSysData) != PVRSRV_OK) + { + PVR_DPF((PVR_DBG_ERROR,"PVRSRVSetDCState: Failed to get SysData")); + return; + } + + psDeviceNode = psSysData->psDeviceNodeList; + while(psDeviceNode != IMG_NULL) + { + if (psDeviceNode->sDevId.eDeviceClass == PVRSRV_DEVICE_CLASS_DISPLAY) + { + psDCInfo = (PVRSRV_DISPLAYCLASS_INFO *)psDeviceNode->pvDevice; + if (psDCInfo->psFuncTable->pfnSetDCState && psDCInfo->hExtDevice) + { + psDCInfo->psFuncTable->pfnSetDCState(psDCInfo->hExtDevice, ui32State); + } + } + psDeviceNode = psDeviceNode->psNext; + } +} + + +IMG_EXPORT +IMG_BOOL PVRGetDisplayClassJTable(PVRSRV_DC_DISP2SRV_KMJTABLE *psJTable) +{ + psJTable->ui32TableSize = sizeof(PVRSRV_DC_DISP2SRV_KMJTABLE); + psJTable->pfnPVRSRVRegisterDCDevice = PVRSRVRegisterDCDeviceKM; + psJTable->pfnPVRSRVRemoveDCDevice = PVRSRVRemoveDCDeviceKM; + psJTable->pfnPVRSRVOEMFunction = SysOEMFunction; + psJTable->pfnPVRSRVRegisterCmdProcList = PVRSRVRegisterCmdProcListKM; + psJTable->pfnPVRSRVRemoveCmdProcList = PVRSRVRemoveCmdProcListKM; + psJTable->pfnPVRSRVCmdComplete = PVRSRVCommandCompleteKM; + psJTable->pfnPVRSRVRegisterSystemISRHandler = PVRSRVRegisterSystemISRHandler; + psJTable->pfnPVRSRVRegisterPowerDevice = PVRSRVRegisterPowerDevice; + + return IMG_TRUE; +} + + + +IMG_EXPORT +PVRSRV_ERROR PVRSRVCloseBCDeviceKM (IMG_HANDLE hDeviceKM, + IMG_BOOL bResManCallback) +{ + PVRSRV_ERROR eError; + PVRSRV_BUFFERCLASS_PERCONTEXT_INFO *psBCPerContextInfo; + + PVR_UNREFERENCED_PARAMETER(bResManCallback); + + psBCPerContextInfo = (PVRSRV_BUFFERCLASS_PERCONTEXT_INFO *)hDeviceKM; + + + eError = ResManFreeResByPtr(psBCPerContextInfo->hResItem); + + return eError; +} + + +static PVRSRV_ERROR CloseBCDeviceCallBack(IMG_PVOID pvParam, + IMG_UINT32 ui32Param) +{ + PVRSRV_BUFFERCLASS_PERCONTEXT_INFO *psBCPerContextInfo; + PVRSRV_BUFFERCLASS_INFO *psBCInfo; + + PVR_UNREFERENCED_PARAMETER(ui32Param); + + psBCPerContextInfo = (PVRSRV_BUFFERCLASS_PERCONTEXT_INFO *)pvParam; + psBCInfo = psBCPerContextInfo->psBCInfo; + + psBCInfo->ui32RefCount--; + if(psBCInfo->ui32RefCount == 0) + { + IMG_UINT32 i; + + + psBCInfo->psFuncTable->pfnCloseBCDevice(psBCInfo->hExtDevice); + + + for(i=0; iui32BufferCount; i++) + { + if(psBCInfo->psBuffer[i].sDeviceClassBuffer.psKernelSyncInfo) + { + PVRSRVFreeSyncInfoKM(psBCInfo->psBuffer[i].sDeviceClassBuffer.psKernelSyncInfo); + } + } + + + if(psBCInfo->psBuffer) + { + OSFreeMem(PVRSRV_OS_PAGEABLE_HEAP, sizeof(PVRSRV_BC_BUFFER), psBCInfo->psBuffer, IMG_NULL); + } + } + + OSFreeMem(PVRSRV_OS_PAGEABLE_HEAP, sizeof(PVRSRV_BUFFERCLASS_PERCONTEXT_INFO), psBCPerContextInfo, IMG_NULL); + + return PVRSRV_OK; +} + + +IMG_EXPORT +PVRSRV_ERROR PVRSRVOpenBCDeviceKM (PVRSRV_PER_PROCESS_DATA *psPerProc, + IMG_UINT32 ui32DeviceID, + IMG_HANDLE hDevCookie, + IMG_HANDLE *phDeviceKM) +{ + PVRSRV_BUFFERCLASS_INFO *psBCInfo; + PVRSRV_BUFFERCLASS_PERCONTEXT_INFO *psBCPerContextInfo; + PVRSRV_DEVICE_NODE *psDeviceNode; + SYS_DATA *psSysData; + IMG_UINT32 i; + PVRSRV_ERROR eError; + + if(!phDeviceKM || !hDevCookie) + { + PVR_DPF((PVR_DBG_ERROR,"PVRSRVOpenBCDeviceKM: Invalid params")); + return PVRSRV_ERROR_GENERIC; + } + + if (SysAcquireData(&psSysData) != PVRSRV_OK) + { + PVR_DPF((PVR_DBG_ERROR,"PVRSRVOpenBCDeviceKM: Failed to get SysData")); + return PVRSRV_ERROR_GENERIC; + } + + + psDeviceNode = psSysData->psDeviceNodeList; + while(psDeviceNode) + { + if ((psDeviceNode->sDevId.eDeviceClass == PVRSRV_DEVICE_CLASS_BUFFER) && + (psDeviceNode->sDevId.ui32DeviceIndex == ui32DeviceID)) + { + + + + psBCInfo = (PVRSRV_BUFFERCLASS_INFO*)psDeviceNode->pvDevice; + goto FoundDevice; + } + psDeviceNode = psDeviceNode->psNext; + } + + PVR_DPF((PVR_DBG_ERROR,"PVRSRVOpenBCDeviceKM: No devnode matching index %d", ui32DeviceID)); + + return PVRSRV_ERROR_GENERIC; + +FoundDevice: + + + + + if(OSAllocMem(PVRSRV_OS_PAGEABLE_HEAP, + sizeof(*psBCPerContextInfo), + (IMG_VOID **)&psBCPerContextInfo, IMG_NULL) != PVRSRV_OK) + { + PVR_DPF((PVR_DBG_ERROR,"PVRSRVOpenBCDeviceKM: Failed psBCPerContextInfo alloc")); + return PVRSRV_ERROR_OUT_OF_MEMORY; + } + OSMemSet(psBCPerContextInfo, 0, sizeof(*psBCPerContextInfo)); + + if(psBCInfo->ui32RefCount++ == 0) + { + BUFFER_INFO sBufferInfo; + + psDeviceNode = (PVRSRV_DEVICE_NODE *)hDevCookie; + + + psBCInfo->hDevMemContext = (IMG_HANDLE)psDeviceNode->sDevMemoryInfo.pBMKernelContext; + + + eError = psBCInfo->psFuncTable->pfnOpenBCDevice(&psBCInfo->hExtDevice); + if(eError != PVRSRV_OK) + { + PVR_DPF((PVR_DBG_ERROR,"PVRSRVOpenBCDeviceKM: Failed to open external BC device")); + return eError; + } + + + eError = psBCInfo->psFuncTable->pfnGetBCInfo(psBCInfo->hExtDevice, &sBufferInfo); + if(eError != PVRSRV_OK) + { + PVR_DPF((PVR_DBG_ERROR,"PVRSRVOpenBCDeviceKM : Failed to get BC Info")); + return eError; + } + + + psBCInfo->ui32BufferCount = sBufferInfo.ui32BufferCount; + + + + eError = OSAllocMem(PVRSRV_OS_PAGEABLE_HEAP, + sizeof(PVRSRV_BC_BUFFER) * sBufferInfo.ui32BufferCount, + (IMG_VOID **)&psBCInfo->psBuffer, + IMG_NULL); + if(eError != PVRSRV_OK) + { + PVR_DPF((PVR_DBG_ERROR,"PVRSRVOpenBCDeviceKM: Failed to allocate BC buffers")); + return eError; + } + OSMemSet (psBCInfo->psBuffer, + 0, + sizeof(PVRSRV_BC_BUFFER) * sBufferInfo.ui32BufferCount); + + for(i=0; iui32BufferCount; i++) + { + + eError = PVRSRVAllocSyncInfoKM(IMG_NULL, + psBCInfo->hDevMemContext, + &psBCInfo->psBuffer[i].sDeviceClassBuffer.psKernelSyncInfo); + if(eError != PVRSRV_OK) + { + PVR_DPF((PVR_DBG_ERROR,"PVRSRVOpenBCDeviceKM: Failed sync info alloc")); + goto ErrorExit; + } + + + + + eError = psBCInfo->psFuncTable->pfnGetBCBuffer(psBCInfo->hExtDevice, + i, + psBCInfo->psBuffer[i].sDeviceClassBuffer.psKernelSyncInfo->psSyncData, + &psBCInfo->psBuffer[i].sDeviceClassBuffer.hExtBuffer); + if(eError != PVRSRV_OK) + { + PVR_DPF((PVR_DBG_ERROR,"PVRSRVOpenBCDeviceKM: Failed to get BC buffers")); + goto ErrorExit; + } + + + psBCInfo->psBuffer[i].sDeviceClassBuffer.pfnGetBufferAddr = psBCInfo->psFuncTable->pfnGetBufferAddr; + psBCInfo->psBuffer[i].sDeviceClassBuffer.hDevMemContext = psBCInfo->hDevMemContext; + psBCInfo->psBuffer[i].sDeviceClassBuffer.hExtDevice = psBCInfo->hExtDevice; + } + } + + psBCPerContextInfo->psBCInfo = psBCInfo; + psBCPerContextInfo->hResItem = ResManRegisterRes(psPerProc->hResManContext, + RESMAN_TYPE_BUFFERCLASS_DEVICE, + psBCPerContextInfo, + 0, + CloseBCDeviceCallBack); + + + *phDeviceKM = (IMG_HANDLE)psBCPerContextInfo; + + return PVRSRV_OK; + +ErrorExit: + + + for(i=0; iui32BufferCount; i++) + { + if(psBCInfo->psBuffer[i].sDeviceClassBuffer.psKernelSyncInfo) + { + PVRSRVFreeSyncInfoKM(psBCInfo->psBuffer[i].sDeviceClassBuffer.psKernelSyncInfo); + } + } + + + if(psBCInfo->psBuffer) + { + OSFreeMem(PVRSRV_OS_PAGEABLE_HEAP, sizeof(PVRSRV_BC_BUFFER), psBCInfo->psBuffer, IMG_NULL); + } + + return eError; +} + + + + +IMG_EXPORT +PVRSRV_ERROR PVRSRVGetBCInfoKM (IMG_HANDLE hDeviceKM, + BUFFER_INFO *psBufferInfo) +{ + PVRSRV_BUFFERCLASS_INFO *psBCInfo; + PVRSRV_ERROR eError; + + if(!hDeviceKM || !psBufferInfo) + { + PVR_DPF((PVR_DBG_ERROR,"PVRSRVGetBCInfoKM: Invalid parameters")); + return PVRSRV_ERROR_INVALID_PARAMS; + } + + psBCInfo = BCDeviceHandleToBCInfo(hDeviceKM); + + eError = psBCInfo->psFuncTable->pfnGetBCInfo(psBCInfo->hExtDevice, psBufferInfo); + + if(eError != PVRSRV_OK) + { + PVR_DPF((PVR_DBG_ERROR,"PVRSRVGetBCInfoKM : Failed to get BC Info")); + return eError; + } + + return PVRSRV_OK; +} + + +IMG_EXPORT +PVRSRV_ERROR PVRSRVGetBCBufferKM (IMG_HANDLE hDeviceKM, + IMG_UINT32 ui32BufferIndex, + IMG_HANDLE *phBuffer) +{ + PVRSRV_BUFFERCLASS_INFO *psBCInfo; + + if(!hDeviceKM || !phBuffer) + { + PVR_DPF((PVR_DBG_ERROR,"PVRSRVGetBCBufferKM: Invalid parameters")); + return PVRSRV_ERROR_INVALID_PARAMS; + } + + psBCInfo = BCDeviceHandleToBCInfo(hDeviceKM); + + if(ui32BufferIndex < psBCInfo->ui32BufferCount) + { + *phBuffer = (IMG_HANDLE)&psBCInfo->psBuffer[ui32BufferIndex]; + } + else + { + PVR_DPF((PVR_DBG_ERROR,"PVRSRVGetBCBufferKM: Buffer index %d out of range (%d)", ui32BufferIndex,psBCInfo->ui32BufferCount)); + return PVRSRV_ERROR_INVALID_PARAMS; + } + + return PVRSRV_OK; +} + + +IMG_EXPORT +IMG_BOOL PVRGetBufferClassJTable(PVRSRV_BC_BUFFER2SRV_KMJTABLE *psJTable) +{ + psJTable->ui32TableSize = sizeof(PVRSRV_BC_BUFFER2SRV_KMJTABLE); + + psJTable->pfnPVRSRVRegisterBCDevice = PVRSRVRegisterBCDeviceKM; + psJTable->pfnPVRSRVRemoveBCDevice = PVRSRVRemoveBCDeviceKM; + + return IMG_TRUE; +} + diff --git a/services4/srvkm/common/devicemem.c b/services4/srvkm/common/devicemem.c new file mode 100644 index 0000000..fa50292 --- /dev/null +++ b/services4/srvkm/common/devicemem.c @@ -0,0 +1,1354 @@ +/********************************************************************** + * + * Copyright(c) 2008 Imagination Technologies Ltd. All rights reserved. + * + * This program is free software; you can redistribute it and/or modify it + * under the terms and conditions of the GNU General Public License, + * version 2, as published by the Free Software Foundation. + * + * This program is distributed in the hope it will be useful but, except + * as otherwise stated in writing, without any warranty; without even the + * implied warranty of merchantability or fitness for a particular purpose. + * See the GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License along with + * this program; if not, write to the Free Software Foundation, Inc., + * 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA. + * + * The full GNU General Public License is included in this distribution in + * the file called "COPYING". + * + * Contact Information: + * Imagination Technologies Ltd. + * Home Park Estate, Kings Langley, Herts, WD4 8LZ, UK + * + ******************************************************************************/ + +#include + +#include "services_headers.h" +#include "buffer_manager.h" +#include "pdump_km.h" +#include "pvr_bridge_km.h" + +static PVRSRV_ERROR AllocDeviceMem(IMG_HANDLE hDevCookie, + IMG_HANDLE hDevMemHeap, + IMG_UINT32 ui32Flags, + IMG_UINT32 ui32Size, + IMG_UINT32 ui32Alignment, + PVRSRV_KERNEL_MEM_INFO **ppsMemInfo); + +typedef struct _RESMAN_MAP_DEVICE_MEM_DATA_ +{ + + PVRSRV_KERNEL_MEM_INFO *psMemInfo; + + PVRSRV_KERNEL_MEM_INFO *psSrcMemInfo; +} RESMAN_MAP_DEVICE_MEM_DATA; + + +IMG_EXPORT +PVRSRV_ERROR IMG_CALLCONV PVRSRVGetDeviceMemHeapsKM(IMG_HANDLE hDevCookie, + PVRSRV_HEAP_INFO *psHeapInfo + ) +{ + PVRSRV_DEVICE_NODE *psDeviceNode; + IMG_UINT32 ui32HeapCount; + DEVICE_MEMORY_HEAP_INFO *psDeviceMemoryHeap; + IMG_UINT32 i; + + if (hDevCookie == IMG_NULL) + { + PVR_DPF((PVR_DBG_ERROR, "PVRSRVGetDeviceMemHeapsKM: hDevCookie invalid")); + PVR_DBG_BREAK; + return PVRSRV_ERROR_INVALID_PARAMS; + } + + psDeviceNode = (PVRSRV_DEVICE_NODE *)hDevCookie; + + + ui32HeapCount = psDeviceNode->sDevMemoryInfo.ui32HeapCount; + psDeviceMemoryHeap = psDeviceNode->sDevMemoryInfo.psDeviceMemoryHeap; + + + PVR_ASSERT(ui32HeapCount <= PVRSRV_MAX_CLIENT_HEAPS); + + + for(i=0; isDevMemoryInfo.ui32HeapCount; + psDeviceMemoryHeap = psDeviceNode->sDevMemoryInfo.psDeviceMemoryHeap; + + + + PVR_ASSERT(ui32HeapCount <= PVRSRV_MAX_CLIENT_HEAPS); + + + + hDevMemContext = BM_CreateContext(psDeviceNode, + &sPDDevPAddr, + psPerProc, + pbCreated); + if (hDevMemContext == IMG_NULL) + { + PVR_DPF((PVR_DBG_ERROR,"PVRSRVCreateDeviceMemContextKM: Failed BM_CreateContext")); + return PVRSRV_ERROR_OUT_OF_MEMORY; + } + + + for(i=0; isDevMemoryInfo.ui32HeapCount; + psDeviceMemoryHeap = psDeviceNode->sDevMemoryInfo.psDeviceMemoryHeap; + + + + PVR_ASSERT(ui32HeapCount <= PVRSRV_MAX_CLIENT_HEAPS); + + + for(i=0; isMemBlk); + + + psMemInfo->ui32Flags = ui32Flags | PVRSRV_MEM_RAM_BACKED_ALLOCATION; + + bBMError = BM_Alloc (hDevMemHeap, + IMG_NULL, + ui32Size, + &psMemInfo->ui32Flags, + ui32Alignment, + &hBuffer); + + if (!bBMError) + { + PVR_DPF((PVR_DBG_ERROR,"AllocDeviceMem: BM_Alloc Failed")); + OSFreeMem(PVRSRV_PAGEABLE_SELECT, sizeof(PVRSRV_KERNEL_MEM_INFO), psMemInfo, IMG_NULL); + return PVRSRV_ERROR_OUT_OF_MEMORY; + } + + + psMemBlock->sDevVirtAddr = BM_HandleToDevVaddr(hBuffer); + psMemBlock->hOSMemHandle = BM_HandleToOSMemHandle(hBuffer); + + + psMemBlock->hBuffer = (IMG_HANDLE)hBuffer; + + + + psMemInfo->pvLinAddrKM = BM_HandleToCpuVaddr(hBuffer); + + psMemInfo->sDevVAddr = psMemBlock->sDevVirtAddr; + + psMemInfo->ui32AllocSize = ui32Size; + + + psMemInfo->pvSysBackupBuffer = IMG_NULL; + + + *ppsMemInfo = psMemInfo; + + + return (PVRSRV_OK); +} + + +static PVRSRV_ERROR FreeDeviceMem(PVRSRV_KERNEL_MEM_INFO *psMemInfo) +{ + BM_HANDLE hBuffer; + + if (!psMemInfo) + { + return PVRSRV_ERROR_INVALID_PARAMS; + } + + hBuffer = psMemInfo->sMemBlk.hBuffer; + + + BM_Free(hBuffer, psMemInfo->ui32Flags); + + if(psMemInfo->pvSysBackupBuffer) + { + + OSFreeMem(PVRSRV_OS_PAGEABLE_HEAP, psMemInfo->ui32AllocSize, psMemInfo->pvSysBackupBuffer, IMG_NULL); + } + + OSFreeMem(PVRSRV_PAGEABLE_SELECT, sizeof(PVRSRV_KERNEL_MEM_INFO), psMemInfo, IMG_NULL); + + return(PVRSRV_OK); +} + + +IMG_EXPORT +PVRSRV_ERROR IMG_CALLCONV PVRSRVAllocSyncInfoKM(IMG_HANDLE hDevCookie, + IMG_HANDLE hDevMemContext, + PVRSRV_KERNEL_SYNC_INFO **ppsKernelSyncInfo) +{ + IMG_HANDLE hSyncDevMemHeap; + DEVICE_MEMORY_INFO *psDevMemoryInfo; + BM_CONTEXT *pBMContext; + PVRSRV_ERROR eError; + PVRSRV_KERNEL_SYNC_INFO *psKernelSyncInfo; + PVRSRV_SYNC_DATA *psSyncData; + + eError = OSAllocMem(PVRSRV_PAGEABLE_SELECT, + sizeof(PVRSRV_KERNEL_SYNC_INFO), + (IMG_VOID **)&psKernelSyncInfo, IMG_NULL); + if (eError != PVRSRV_OK) + { + PVR_DPF((PVR_DBG_ERROR,"PVRSRVAllocSyncInfoKM: Failed to alloc memory")); + return PVRSRV_ERROR_OUT_OF_MEMORY; + } + + + pBMContext = (BM_CONTEXT*)hDevMemContext; + psDevMemoryInfo = &pBMContext->psDeviceNode->sDevMemoryInfo; + + + hSyncDevMemHeap = psDevMemoryInfo->psDeviceMemoryHeap[psDevMemoryInfo->ui32SyncHeapID].hDevMemHeap; + + + + + eError = AllocDeviceMem(hDevCookie, + hSyncDevMemHeap, + PVRSRV_MEM_CACHE_CONSISTENT, + sizeof(PVRSRV_SYNC_DATA), + sizeof(IMG_UINT32), + &psKernelSyncInfo->psSyncDataMemInfoKM); + + if (eError != PVRSRV_OK) + { + + PVR_DPF((PVR_DBG_ERROR,"PVRSRVAllocSyncInfoKM: Failed to alloc memory")); + OSFreeMem(PVRSRV_PAGEABLE_SELECT, sizeof(PVRSRV_KERNEL_SYNC_INFO), psKernelSyncInfo, IMG_NULL); + return PVRSRV_ERROR_OUT_OF_MEMORY; + } + + + psKernelSyncInfo->psSyncData = psKernelSyncInfo->psSyncDataMemInfoKM->pvLinAddrKM; + psSyncData = psKernelSyncInfo->psSyncData; + + psSyncData->ui32WriteOpsPending = 0; + psSyncData->ui32WriteOpsComplete = 0; + psSyncData->ui32ReadOpsPending = 0; + psSyncData->ui32ReadOpsComplete = 0; + psSyncData->ui32LastOpDumpVal = 0; + psSyncData->ui32LastReadOpDumpVal = 0; + +#if defined(PDUMP) + PDUMPMEM(psKernelSyncInfo->psSyncDataMemInfoKM->pvLinAddrKM, + psKernelSyncInfo->psSyncDataMemInfoKM, + 0, + psKernelSyncInfo->psSyncDataMemInfoKM->ui32AllocSize, + 0, + MAKEUNIQUETAG(psKernelSyncInfo->psSyncDataMemInfoKM)); +#endif + + psKernelSyncInfo->sWriteOpsCompleteDevVAddr.uiAddr = psKernelSyncInfo->psSyncDataMemInfoKM->sDevVAddr.uiAddr + offsetof(PVRSRV_SYNC_DATA, ui32WriteOpsComplete); + psKernelSyncInfo->sReadOpsCompleteDevVAddr.uiAddr = psKernelSyncInfo->psSyncDataMemInfoKM->sDevVAddr.uiAddr + offsetof(PVRSRV_SYNC_DATA, ui32ReadOpsComplete); + + + psKernelSyncInfo->psSyncDataMemInfoKM->psKernelSyncInfo = IMG_NULL; + + + *ppsKernelSyncInfo = psKernelSyncInfo; + + return PVRSRV_OK; +} + + +IMG_EXPORT +PVRSRV_ERROR IMG_CALLCONV PVRSRVFreeSyncInfoKM(PVRSRV_KERNEL_SYNC_INFO *psKernelSyncInfo) +{ + FreeDeviceMem(psKernelSyncInfo->psSyncDataMemInfoKM); + OSFreeMem(PVRSRV_PAGEABLE_SELECT, sizeof(PVRSRV_KERNEL_SYNC_INFO), psKernelSyncInfo, IMG_NULL); + + return PVRSRV_OK; +} + + +static PVRSRV_ERROR FreeDeviceMemCallBack(IMG_PVOID pvParam, + IMG_UINT32 ui32Param) +{ + PVRSRV_ERROR eError = PVRSRV_OK; + PVRSRV_KERNEL_MEM_INFO *psMemInfo = pvParam; + + PVR_UNREFERENCED_PARAMETER(ui32Param); + + + psMemInfo->ui32RefCount--; + + + if(psMemInfo->ui32Flags & PVRSRV_MEM_EXPORTED) + { + IMG_HANDLE hMemInfo = IMG_NULL; + + + if (psMemInfo->ui32RefCount != 0) + { + PVR_DPF((PVR_DBG_ERROR, "FreeDeviceMemCallBack: mappings are open in other processes")); + return PVRSRV_ERROR_GENERIC; + } + + + eError = PVRSRVFindHandle(KERNEL_HANDLE_BASE, + &hMemInfo, + psMemInfo, + PVRSRV_HANDLE_TYPE_MEM_INFO); + if(eError != PVRSRV_OK) + { + PVR_DPF((PVR_DBG_ERROR, "FreeDeviceMemCallBack: can't find exported meminfo in the global handle list")); + return eError; + } + + + eError = PVRSRVReleaseHandle(KERNEL_HANDLE_BASE, + hMemInfo, + PVRSRV_HANDLE_TYPE_MEM_INFO); + if(eError != PVRSRV_OK) + { + PVR_DPF((PVR_DBG_ERROR, "FreeDeviceMemCallBack: PVRSRVReleaseHandle failed for exported meminfo")); + return eError; + } + } + + PVR_ASSERT(psMemInfo->ui32RefCount == 0); + + if (psMemInfo->psKernelSyncInfo) + { + eError = PVRSRVFreeSyncInfoKM(psMemInfo->psKernelSyncInfo); + } + + if (eError == PVRSRV_OK) + { + eError = FreeDeviceMem(psMemInfo); + } + + return eError; +} + + +IMG_EXPORT +PVRSRV_ERROR IMG_CALLCONV PVRSRVFreeDeviceMemKM(IMG_HANDLE hDevCookie, + PVRSRV_KERNEL_MEM_INFO *psMemInfo) +{ + PVRSRV_ERROR eError = PVRSRV_OK; + + PVR_UNREFERENCED_PARAMETER(hDevCookie); + + if (!psMemInfo) + { + return PVRSRV_ERROR_INVALID_PARAMS; + } + + if (psMemInfo->sMemBlk.hResItem != IMG_NULL) + { + eError = ResManFreeResByPtr(psMemInfo->sMemBlk.hResItem); + } + else + { + + FreeDeviceMemCallBack(psMemInfo, 0); + } + + return eError; +} + + +IMG_EXPORT +PVRSRV_ERROR IMG_CALLCONV PVRSRVAllocDeviceMemKM(IMG_HANDLE hDevCookie, + PVRSRV_PER_PROCESS_DATA *psPerProc, + IMG_HANDLE hDevMemHeap, + IMG_UINT32 ui32Flags, + IMG_UINT32 ui32Size, + IMG_UINT32 ui32Alignment, + PVRSRV_KERNEL_MEM_INFO **ppsMemInfo) +{ + PVRSRV_KERNEL_MEM_INFO *psMemInfo; + PVRSRV_ERROR eError; + BM_HEAP *psBMHeap; + IMG_HANDLE hDevMemContext; + + if (!hDevMemHeap || + (ui32Size == 0)) + { + return PVRSRV_ERROR_INVALID_PARAMS; + } + + eError = AllocDeviceMem(hDevCookie, + hDevMemHeap, + ui32Flags, + ui32Size, + ui32Alignment, + &psMemInfo); + + if (eError != PVRSRV_OK) + { + return eError; + } + + if (ui32Flags & PVRSRV_MEM_NO_SYNCOBJ) + { + psMemInfo->psKernelSyncInfo = IMG_NULL; + } + else + { + + + + psBMHeap = (BM_HEAP*)hDevMemHeap; + hDevMemContext = (IMG_HANDLE)psBMHeap->pBMContext; + eError = PVRSRVAllocSyncInfoKM(hDevCookie, + hDevMemContext, + &psMemInfo->psKernelSyncInfo); + if(eError != PVRSRV_OK) + { + goto free_mainalloc; + } + } + + + *ppsMemInfo = psMemInfo; + + if (ui32Flags & PVRSRV_MEM_NO_RESMAN) + { + psMemInfo->sMemBlk.hResItem = IMG_NULL; + } + else + { + + psMemInfo->sMemBlk.hResItem = ResManRegisterRes(psPerProc->hResManContext, + RESMAN_TYPE_DEVICEMEM_ALLOCATION, + psMemInfo, + 0, + FreeDeviceMemCallBack); + if (psMemInfo->sMemBlk.hResItem == IMG_NULL) + { + + eError = PVRSRV_ERROR_OUT_OF_MEMORY; + goto free_mainalloc; + } + } + + + psMemInfo->ui32RefCount++; + + + return (PVRSRV_OK); + +free_mainalloc: + FreeDeviceMem(psMemInfo); + + return eError; +} + + +IMG_EXPORT +PVRSRV_ERROR IMG_CALLCONV PVRSRVDissociateDeviceMemKM(IMG_HANDLE hDevCookie, + PVRSRV_KERNEL_MEM_INFO *psMemInfo) +{ + PVRSRV_ERROR eError; + PVRSRV_DEVICE_NODE *psDeviceNode = hDevCookie; + + PVR_UNREFERENCED_PARAMETER(hDevCookie); + + if (!psMemInfo) + { + return PVRSRV_ERROR_INVALID_PARAMS; + } + + eError = ResManDissociateRes(psMemInfo->sMemBlk.hResItem, psDeviceNode->hResManContext); + + PVR_ASSERT(eError == PVRSRV_OK); + + return eError; +} + + +IMG_EXPORT +PVRSRV_ERROR IMG_CALLCONV PVRSRVGetFreeDeviceMemKM(IMG_UINT32 ui32Flags, + IMG_UINT32 *pui32Total, + IMG_UINT32 *pui32Free, + IMG_UINT32 *pui32LargestBlock) +{ + + + PVR_UNREFERENCED_PARAMETER(ui32Flags); + PVR_UNREFERENCED_PARAMETER(pui32Total); + PVR_UNREFERENCED_PARAMETER(pui32Free); + PVR_UNREFERENCED_PARAMETER(pui32LargestBlock); + + return PVRSRV_OK; +} + + + + +IMG_EXPORT +PVRSRV_ERROR IMG_CALLCONV PVRSRVUnwrapExtMemoryKM (PVRSRV_KERNEL_MEM_INFO *psMemInfo) +{ + if (!psMemInfo) + { + return PVRSRV_ERROR_INVALID_PARAMS; + } + + return ResManFreeResByPtr(psMemInfo->sMemBlk.hResItem); +} + + +static PVRSRV_ERROR UnwrapExtMemoryCallBack(IMG_PVOID pvParam, + IMG_UINT32 ui32Param) +{ + PVRSRV_ERROR eError = PVRSRV_OK; + PVRSRV_KERNEL_MEM_INFO *psMemInfo = pvParam; + IMG_HANDLE hOSWrapMem; + + PVR_UNREFERENCED_PARAMETER(ui32Param); + + hOSWrapMem = psMemInfo->sMemBlk.hOSWrapMem; + + if (psMemInfo->psKernelSyncInfo) + { + eError = PVRSRVFreeSyncInfoKM(psMemInfo->psKernelSyncInfo); + } + + + if(psMemInfo->sMemBlk.psIntSysPAddr) + { + OSFreeMem(PVRSRV_OS_PAGEABLE_HEAP, sizeof(IMG_SYS_PHYADDR), psMemInfo->sMemBlk.psIntSysPAddr, IMG_NULL); + } + + if (eError == PVRSRV_OK) + { + + psMemInfo->ui32RefCount--; + + eError = FreeDeviceMem(psMemInfo); + } + + if(hOSWrapMem) + { + OSReleasePhysPageAddr(hOSWrapMem); + } + + return eError; +} + + +IMG_EXPORT +PVRSRV_ERROR IMG_CALLCONV PVRSRVWrapExtMemoryKM(IMG_HANDLE hDevCookie, + PVRSRV_PER_PROCESS_DATA *psPerProc, + IMG_HANDLE hDevMemContext, + IMG_UINT32 ui32ByteSize, + IMG_UINT32 ui32PageOffset, + IMG_BOOL bPhysContig, + IMG_SYS_PHYADDR *psExtSysPAddr, + IMG_VOID *pvLinAddr, + PVRSRV_KERNEL_MEM_INFO **ppsMemInfo) +{ + PVRSRV_KERNEL_MEM_INFO *psMemInfo = IMG_NULL; + DEVICE_MEMORY_INFO *psDevMemoryInfo; + IMG_UINT32 ui32HostPageSize = HOST_PAGESIZE(); + IMG_HANDLE hDevMemHeap = IMG_NULL; + PVRSRV_DEVICE_NODE* psDeviceNode; + BM_HANDLE hBuffer; + PVRSRV_MEMBLK *psMemBlock; + IMG_BOOL bBMError; + BM_HEAP *psBMHeap; + PVRSRV_ERROR eError; + IMG_VOID *pvPageAlignedCPUVAddr; + IMG_SYS_PHYADDR *psIntSysPAddr = IMG_NULL; + IMG_HANDLE hOSWrapMem = IMG_NULL; + DEVICE_MEMORY_HEAP_INFO *psDeviceMemoryHeap; + IMG_UINT32 ui32PageCount = 0; + IMG_UINT32 i; + + psDeviceNode = (PVRSRV_DEVICE_NODE*)hDevCookie; + PVR_ASSERT(psDeviceNode != IMG_NULL); + + if (psDeviceNode == IMG_NULL) + { + PVR_DPF((PVR_DBG_ERROR, "PVRSRVWrapExtMemoryKM: invalid parameter")); + return PVRSRV_ERROR_INVALID_PARAMS; + } + + if(pvLinAddr) + { + + ui32PageOffset = (IMG_UINT32)pvLinAddr & (ui32HostPageSize - 1); + + + ui32PageCount = HOST_PAGEALIGN(ui32ByteSize + ui32PageOffset) / ui32HostPageSize; + pvPageAlignedCPUVAddr = (IMG_VOID *)((IMG_UINT8 *)pvLinAddr - ui32PageOffset); + + + if(OSAllocMem(PVRSRV_OS_PAGEABLE_HEAP, + ui32PageCount * sizeof(IMG_SYS_PHYADDR), + (IMG_VOID **)&psIntSysPAddr, IMG_NULL) != PVRSRV_OK) + { + PVR_DPF((PVR_DBG_ERROR,"PVRSRVWrapExtMemoryKM: Failed to alloc memory for block")); + return PVRSRV_ERROR_OUT_OF_MEMORY; + } + + eError = OSAcquirePhysPageAddr(pvPageAlignedCPUVAddr, + ui32PageCount * ui32HostPageSize, + psIntSysPAddr, + &hOSWrapMem); + if(eError != PVRSRV_OK) + { + PVR_DPF((PVR_DBG_ERROR,"PVRSRVWrapExtMemoryKM: Failed to alloc memory for block")); + eError = PVRSRV_ERROR_OUT_OF_MEMORY; + goto ErrorExitPhase1; + } + + + psExtSysPAddr = psIntSysPAddr; + + + + bPhysContig = IMG_FALSE; + } + else + { + + } + + + psDevMemoryInfo = &((BM_CONTEXT*)hDevMemContext)->psDeviceNode->sDevMemoryInfo; + psDeviceMemoryHeap = psDevMemoryInfo->psDeviceMemoryHeap; + for(i=0; iui32MappingHeapID) + { + if(psDeviceMemoryHeap[i].DevMemHeapType == DEVICE_MEMORY_HEAP_PERCONTEXT) + { + + hDevMemHeap = BM_CreateHeap(hDevMemContext, &psDeviceMemoryHeap[i]); + } + else + { + hDevMemHeap = psDevMemoryInfo->psDeviceMemoryHeap[i].hDevMemHeap; + } + break; + } + } + + if(hDevMemHeap == IMG_NULL) + { + PVR_DPF((PVR_DBG_ERROR,"PVRSRVWrapExtMemoryKM: unable to find mapping heap")); + eError = PVRSRV_ERROR_GENERIC; + goto ErrorExitPhase2; + } + + if(OSAllocMem(PVRSRV_OS_PAGEABLE_HEAP, + sizeof(PVRSRV_KERNEL_MEM_INFO), + (IMG_VOID **)&psMemInfo, IMG_NULL) != PVRSRV_OK) + { + PVR_DPF((PVR_DBG_ERROR,"PVRSRVWrapExtMemoryKM: Failed to alloc memory for block")); + eError = PVRSRV_ERROR_OUT_OF_MEMORY; + goto ErrorExitPhase2; + } + + OSMemSet(psMemInfo, 0, sizeof(*psMemInfo)); + + psMemBlock = &(psMemInfo->sMemBlk); + + bBMError = BM_Wrap(hDevMemHeap, + ui32ByteSize, + ui32PageOffset, + bPhysContig, + psExtSysPAddr, + IMG_NULL, + &psMemInfo->ui32Flags, + &hBuffer); + if (!bBMError) + { + PVR_DPF((PVR_DBG_ERROR,"PVRSRVWrapExtMemoryKM: BM_Wrap Failed")); + eError = PVRSRV_ERROR_BAD_MAPPING; + goto ErrorExitPhase3; + } + + + psMemBlock->sDevVirtAddr = BM_HandleToDevVaddr(hBuffer); + psMemBlock->hOSMemHandle = BM_HandleToOSMemHandle(hBuffer); + psMemBlock->hOSWrapMem = hOSWrapMem; + psMemBlock->psIntSysPAddr = psIntSysPAddr; + + + psMemBlock->hBuffer = (IMG_HANDLE)hBuffer; + + + psMemInfo->pvLinAddrKM = BM_HandleToCpuVaddr(hBuffer); + psMemInfo->sDevVAddr = psMemBlock->sDevVirtAddr; + psMemInfo->ui32AllocSize = ui32ByteSize; + + + + psMemInfo->pvSysBackupBuffer = IMG_NULL; + + + + + psBMHeap = (BM_HEAP*)hDevMemHeap; + hDevMemContext = (IMG_HANDLE)psBMHeap->pBMContext; + eError = PVRSRVAllocSyncInfoKM(hDevCookie, + hDevMemContext, + &psMemInfo->psKernelSyncInfo); + if(eError != PVRSRV_OK) + { + goto ErrorExitPhase4; + } + + + psMemInfo->ui32RefCount++; + + + psMemInfo->sMemBlk.hResItem = ResManRegisterRes(psPerProc->hResManContext, + RESMAN_TYPE_DEVICEMEM_WRAP, + psMemInfo, + 0, + UnwrapExtMemoryCallBack); + + + *ppsMemInfo = psMemInfo; + + return PVRSRV_OK; + + + +ErrorExitPhase4: + if(psMemInfo) + { + FreeDeviceMem(psMemInfo); + + + + psMemInfo = IMG_NULL; + } + +ErrorExitPhase3: + if(psMemInfo) + { + OSFreeMem(PVRSRV_OS_PAGEABLE_HEAP, sizeof(PVRSRV_KERNEL_MEM_INFO), psMemInfo, IMG_NULL); + } + +ErrorExitPhase2: + if(psIntSysPAddr) + { + OSReleasePhysPageAddr(hOSWrapMem); + } + +ErrorExitPhase1: + if(psIntSysPAddr) + { + OSFreeMem(PVRSRV_OS_PAGEABLE_HEAP, ui32PageCount * sizeof(IMG_SYS_PHYADDR), psIntSysPAddr, IMG_NULL); + } + + return eError; +} + + +IMG_EXPORT +PVRSRV_ERROR IMG_CALLCONV PVRSRVUnmapDeviceMemoryKM (PVRSRV_KERNEL_MEM_INFO *psMemInfo) +{ + if (!psMemInfo) + { + return PVRSRV_ERROR_INVALID_PARAMS; + } + + return ResManFreeResByPtr(psMemInfo->sMemBlk.hResItem); +} + + +static PVRSRV_ERROR UnmapDeviceMemoryCallBack(IMG_PVOID pvParam, + IMG_UINT32 ui32Param) +{ + PVRSRV_ERROR eError; + RESMAN_MAP_DEVICE_MEM_DATA *psMapData = pvParam; + + PVR_UNREFERENCED_PARAMETER(ui32Param); + + if(psMapData->psMemInfo->sMemBlk.psIntSysPAddr) + { + OSFreeMem(PVRSRV_OS_PAGEABLE_HEAP, sizeof(IMG_SYS_PHYADDR), psMapData->psMemInfo->sMemBlk.psIntSysPAddr, IMG_NULL); + } + + eError = FreeDeviceMem(psMapData->psMemInfo); + if(eError != PVRSRV_OK) + { + PVR_DPF((PVR_DBG_ERROR,"UnmapDeviceMemoryCallBack: Failed to free DST meminfo")); + return eError; + } + + + psMapData->psSrcMemInfo->ui32RefCount--; + + OSFreeMem(PVRSRV_OS_PAGEABLE_HEAP, 0, psMapData, IMG_NULL); + + return eError; +} + + +IMG_EXPORT +PVRSRV_ERROR IMG_CALLCONV PVRSRVMapDeviceMemoryKM(PVRSRV_PER_PROCESS_DATA *psPerProc, + PVRSRV_KERNEL_MEM_INFO *psSrcMemInfo, + IMG_HANDLE hDstDevMemHeap, + PVRSRV_KERNEL_MEM_INFO **ppsDstMemInfo) +{ + PVRSRV_ERROR eError; + IMG_UINT32 i; + IMG_UINT32 ui32PageCount, ui32PageOffset; + IMG_UINT32 ui32HostPageSize = HOST_PAGESIZE(); + IMG_SYS_PHYADDR *psSysPAddr = IMG_NULL; + IMG_DEV_PHYADDR sDevPAddr; + BM_BUF *psBuf; + IMG_DEV_VIRTADDR sDevVAddr; + PVRSRV_KERNEL_MEM_INFO *psMemInfo = IMG_NULL; + BM_HANDLE hBuffer; + PVRSRV_MEMBLK *psMemBlock; + IMG_BOOL bBMError; + PVRSRV_DEVICE_NODE *psDeviceNode; + IMG_VOID *pvPageAlignedCPUVAddr; + RESMAN_MAP_DEVICE_MEM_DATA *psMapData = IMG_NULL; + + + if(!psSrcMemInfo || !hDstDevMemHeap || !ppsDstMemInfo) + { + PVR_DPF((PVR_DBG_ERROR,"PVRSRVMapDeviceMemoryKM: invalid parameters")); + return PVRSRV_ERROR_INVALID_PARAMS; + } + + + *ppsDstMemInfo = IMG_NULL; + + ui32PageOffset = psSrcMemInfo->sDevVAddr.uiAddr & (ui32HostPageSize - 1); + ui32PageCount = HOST_PAGEALIGN(psSrcMemInfo->ui32AllocSize + ui32PageOffset) / ui32HostPageSize; + pvPageAlignedCPUVAddr = (IMG_VOID *)((IMG_UINT8 *)psSrcMemInfo->pvLinAddrKM - ui32PageOffset); + + + + + + if(OSAllocMem(PVRSRV_OS_PAGEABLE_HEAP, + ui32PageCount*sizeof(IMG_SYS_PHYADDR), + (IMG_VOID **)&psSysPAddr, IMG_NULL) != PVRSRV_OK) + { + PVR_DPF((PVR_DBG_ERROR,"PVRSRVMapDeviceMemoryKM: Failed to alloc memory for block")); + return PVRSRV_ERROR_OUT_OF_MEMORY; + } + + psBuf = psSrcMemInfo->sMemBlk.hBuffer; + + + psDeviceNode = psBuf->pMapping->pBMHeap->pBMContext->psDeviceNode; + + + sDevVAddr.uiAddr = psSrcMemInfo->sDevVAddr.uiAddr - ui32PageOffset; + for(i=0; isDevId.eDeviceType, sDevPAddr); + + + sDevVAddr.uiAddr += ui32HostPageSize; + } + + + if(OSAllocMem(PVRSRV_OS_PAGEABLE_HEAP, + sizeof(RESMAN_MAP_DEVICE_MEM_DATA), + (IMG_VOID **)&psMapData, IMG_NULL) != PVRSRV_OK) + { + PVR_DPF((PVR_DBG_ERROR,"PVRSRVMapDeviceMemoryKM: Failed to alloc resman map data")); + eError = PVRSRV_ERROR_OUT_OF_MEMORY; + goto ErrorExit; + } + + + if(OSAllocMem(PVRSRV_PAGEABLE_SELECT, + sizeof(PVRSRV_KERNEL_MEM_INFO), + (IMG_VOID **)&psMemInfo, IMG_NULL) != PVRSRV_OK) + { + PVR_DPF((PVR_DBG_ERROR,"PVRSRVMapDeviceMemoryKM: Failed to alloc memory for block")); + eError = PVRSRV_ERROR_OUT_OF_MEMORY; + goto ErrorExit; + } + + OSMemSet(psMemInfo, 0, sizeof(*psMemInfo)); + + psMemBlock = &(psMemInfo->sMemBlk); + + bBMError = BM_Wrap(hDstDevMemHeap, + psSrcMemInfo->ui32AllocSize, + ui32PageOffset, + IMG_FALSE, + psSysPAddr, + pvPageAlignedCPUVAddr, + &psMemInfo->ui32Flags, + &hBuffer); + + if (!bBMError) + { + PVR_DPF((PVR_DBG_ERROR,"PVRSRVMapDeviceMemoryKM: BM_Wrap Failed")); + eError = PVRSRV_ERROR_BAD_MAPPING; + goto ErrorExit; + } + + + psMemBlock->sDevVirtAddr = BM_HandleToDevVaddr(hBuffer); + psMemBlock->hOSMemHandle = BM_HandleToOSMemHandle(hBuffer); + + + psMemBlock->hBuffer = (IMG_HANDLE)hBuffer; + + + psMemBlock->psIntSysPAddr = psSysPAddr; + + + psMemInfo->pvLinAddrKM = psSrcMemInfo->pvLinAddrKM; + + + psMemInfo->sDevVAddr = psMemBlock->sDevVirtAddr; + psMemInfo->ui32AllocSize = psSrcMemInfo->ui32AllocSize; + psMemInfo->psKernelSyncInfo = psSrcMemInfo->psKernelSyncInfo; + + + + psMemInfo->pvSysBackupBuffer = IMG_NULL; + + + psSrcMemInfo->ui32RefCount++; + + + psMapData->psMemInfo = psMemInfo; + psMapData->psSrcMemInfo = psSrcMemInfo; + + + psMemInfo->sMemBlk.hResItem = ResManRegisterRes(psPerProc->hResManContext, + RESMAN_TYPE_DEVICEMEM_MAPPING, + psMapData, + 0, + UnmapDeviceMemoryCallBack); + + *ppsDstMemInfo = psMemInfo; + + return PVRSRV_OK; + + + +ErrorExit: + + if(psSysPAddr) + { + + OSFreeMem(PVRSRV_OS_PAGEABLE_HEAP, sizeof(IMG_SYS_PHYADDR), psSysPAddr, IMG_NULL); + } + + if(psMemInfo) + { + + OSFreeMem(PVRSRV_PAGEABLE_SELECT, sizeof(PVRSRV_KERNEL_MEM_INFO), psMemInfo, IMG_NULL); + } + + if(psMapData) + { + + OSFreeMem(PVRSRV_PAGEABLE_SELECT, 0, psMapData, IMG_NULL); + } + + return eError; +} + + +IMG_EXPORT +PVRSRV_ERROR IMG_CALLCONV PVRSRVUnmapDeviceClassMemoryKM(PVRSRV_KERNEL_MEM_INFO *psMemInfo) +{ + if (!psMemInfo) + { + return PVRSRV_ERROR_INVALID_PARAMS; + } + + return ResManFreeResByPtr(psMemInfo->sMemBlk.hResItem); +} + + +static PVRSRV_ERROR UnmapDeviceClassMemoryCallBack(IMG_PVOID pvParam, + IMG_UINT32 ui32Param) +{ + PVRSRV_KERNEL_MEM_INFO *psMemInfo = pvParam; + + PVR_UNREFERENCED_PARAMETER(ui32Param); + + return FreeDeviceMem(psMemInfo); +} + + +IMG_EXPORT +PVRSRV_ERROR IMG_CALLCONV PVRSRVMapDeviceClassMemoryKM(PVRSRV_PER_PROCESS_DATA *psPerProc, + IMG_HANDLE hDevMemContext, + IMG_HANDLE hDeviceClassBuffer, + PVRSRV_KERNEL_MEM_INFO **ppsMemInfo, + IMG_HANDLE *phOSMapInfo) +{ + PVRSRV_ERROR eError; + PVRSRV_KERNEL_MEM_INFO *psMemInfo; + PVRSRV_DEVICECLASS_BUFFER *psDeviceClassBuffer; + IMG_SYS_PHYADDR *psSysPAddr; + IMG_VOID *pvCPUVAddr, *pvPageAlignedCPUVAddr; + IMG_BOOL bPhysContig; + BM_CONTEXT *psBMContext; + DEVICE_MEMORY_INFO *psDevMemoryInfo; + DEVICE_MEMORY_HEAP_INFO *psDeviceMemoryHeap; + IMG_HANDLE hDevMemHeap = IMG_NULL; + IMG_UINT32 ui32ByteSize; + IMG_UINT32 ui32Offset; + IMG_UINT32 ui32PageSize = HOST_PAGESIZE(); + BM_HANDLE hBuffer; + PVRSRV_MEMBLK *psMemBlock; + IMG_BOOL bBMError; + IMG_UINT32 i; + + if(!hDeviceClassBuffer || !ppsMemInfo || !phOSMapInfo || !hDevMemContext) + { + PVR_DPF((PVR_DBG_ERROR,"PVRSRVMapDeviceClassMemoryKM: invalid parameters")); + return PVRSRV_ERROR_INVALID_PARAMS; + } + + psDeviceClassBuffer = (PVRSRV_DEVICECLASS_BUFFER*)hDeviceClassBuffer; + + + + + + + + + + + + + + + + + + + + + eError = psDeviceClassBuffer->pfnGetBufferAddr(psDeviceClassBuffer->hExtDevice, + psDeviceClassBuffer->hExtBuffer, + &psSysPAddr, + &ui32ByteSize, + &pvCPUVAddr, + phOSMapInfo, + &bPhysContig); + if(eError != PVRSRV_OK) + { + PVR_DPF((PVR_DBG_ERROR,"PVRSRVMapDeviceClassMemoryKM: unable to get buffer address")); + return PVRSRV_ERROR_GENERIC; + } + + + psBMContext = (BM_CONTEXT*)psDeviceClassBuffer->hDevMemContext; + psDevMemoryInfo = &psBMContext->psDeviceNode->sDevMemoryInfo; + psDeviceMemoryHeap = psDevMemoryInfo->psDeviceMemoryHeap; + for(i=0; iui32MappingHeapID) + { + if(psDeviceMemoryHeap[i].DevMemHeapType == DEVICE_MEMORY_HEAP_PERCONTEXT) + { + + hDevMemHeap = BM_CreateHeap(hDevMemContext, &psDeviceMemoryHeap[i]); + } + else + { + hDevMemHeap = psDevMemoryInfo->psDeviceMemoryHeap[i].hDevMemHeap; + } + break; + } + } + + if(hDevMemHeap == IMG_NULL) + { + PVR_DPF((PVR_DBG_ERROR,"PVRSRVMapDeviceClassMemoryKM: unable to find mapping heap")); + return PVRSRV_ERROR_GENERIC; + } + + + ui32Offset = ((IMG_UINT32)pvCPUVAddr) & (ui32PageSize - 1); + pvPageAlignedCPUVAddr = (IMG_VOID *)((IMG_UINT8 *)pvCPUVAddr - ui32Offset); + + if(OSAllocMem(PVRSRV_PAGEABLE_SELECT, + sizeof(PVRSRV_KERNEL_MEM_INFO), + (IMG_VOID **)&psMemInfo, IMG_NULL) != PVRSRV_OK) + { + PVR_DPF((PVR_DBG_ERROR,"PVRSRVMapDeviceClassMemoryKM: Failed to alloc memory for block")); + return (PVRSRV_ERROR_OUT_OF_MEMORY); + } + + OSMemSet(psMemInfo, 0, sizeof(*psMemInfo)); + + psMemBlock = &(psMemInfo->sMemBlk); + + bBMError = BM_Wrap(hDevMemHeap, + ui32ByteSize, + ui32Offset, + bPhysContig, + psSysPAddr, + pvPageAlignedCPUVAddr, + &psMemInfo->ui32Flags, + &hBuffer); + + if (!bBMError) + { + PVR_DPF((PVR_DBG_ERROR,"PVRSRVMapDeviceClassMemoryKM: BM_Wrap Failed")); + OSFreeMem(PVRSRV_PAGEABLE_SELECT, sizeof(PVRSRV_KERNEL_MEM_INFO), psMemInfo, IMG_NULL); + return PVRSRV_ERROR_BAD_MAPPING; + } + + + psMemBlock->sDevVirtAddr = BM_HandleToDevVaddr(hBuffer); + psMemBlock->hOSMemHandle = BM_HandleToOSMemHandle(hBuffer); + + + psMemBlock->hBuffer = (IMG_HANDLE)hBuffer; + + + + psMemInfo->pvLinAddrKM = BM_HandleToCpuVaddr(hBuffer); + + + psMemInfo->sDevVAddr = psMemBlock->sDevVirtAddr; + psMemInfo->ui32AllocSize = ui32ByteSize; + psMemInfo->psKernelSyncInfo = psDeviceClassBuffer->psKernelSyncInfo; + + + + psMemInfo->pvSysBackupBuffer = IMG_NULL; + + + psMemInfo->sMemBlk.hResItem = ResManRegisterRes(psPerProc->hResManContext, + RESMAN_TYPE_DEVICECLASSMEM_MAPPING, + psMemInfo, + 0, + UnmapDeviceClassMemoryCallBack); + + + *ppsMemInfo = psMemInfo; + + return PVRSRV_OK; +} + diff --git a/services4/srvkm/common/handle.c b/services4/srvkm/common/handle.c new file mode 100644 index 0000000..385747d --- /dev/null +++ b/services4/srvkm/common/handle.c @@ -0,0 +1,1538 @@ +/********************************************************************** + * + * Copyright(c) 2008 Imagination Technologies Ltd. All rights reserved. + * + * This program is free software; you can redistribute it and/or modify it + * under the terms and conditions of the GNU General Public License, + * version 2, as published by the Free Software Foundation. + * + * This program is distributed in the hope it will be useful but, except + * as otherwise stated in writing, without any warranty; without even the + * implied warranty of merchantability or fitness for a particular purpose. + * See the GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License along with + * this program; if not, write to the Free Software Foundation, Inc., + * 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA. + * + * The full GNU General Public License is included in this distribution in + * the file called "COPYING". + * + * Contact Information: + * Imagination Technologies Ltd. + * Home Park Estate, Kings Langley, Herts, WD4 8LZ, UK + * + ******************************************************************************/ + +#ifdef PVR_SECURE_HANDLES +#include + +#include "services_headers.h" +#include "handle.h" + +#ifdef DEBUG +#define HANDLE_BLOCK_SIZE 1 +#else +#define HANDLE_BLOCK_SIZE 256 +#endif + +#define HANDLE_HASH_TAB_INIT_SIZE 32 + +#define DEFAULT_MAX_INDEX_PLUS_ONE 0xfffffffful +#define DEFAULT_MAX_HANDLE DEFAULT_MAX_INDEX_PLUS_ONE + +#define INDEX_IS_VALID(psBase, i) ((i) < (psBase)->ui32TotalHandCount) + +#define INDEX_TO_HANDLE(psBase, idx) ((IMG_HANDLE)((idx) + 1)) +#define HANDLE_TO_INDEX(psBase, hand) ((IMG_UINT32)(hand) - 1) + +#define INDEX_TO_HANDLE_PTR(psBase, i) (((psBase)->psHandleArray) + (i)) +#define HANDLE_TO_HANDLE_PTR(psBase, h) (INDEX_TO_HANDLE_PTR(psBase, HANDLE_TO_INDEX(psBase, h))) + +#define HANDLE_PTR_TO_INDEX(psBase, psHandle) ((psHandle) - ((psBase)->psHandleArray)) +#define HANDLE_PTR_TO_HANDLE(psBase, psHandle) \ + INDEX_TO_HANDLE(psBase, HANDLE_PTR_TO_INDEX(psBase, psHandle)) + +#define ROUND_UP_TO_MULTIPLE(a, b) ((((a) + (b) - 1) / (b)) * (b)) + +#define HANDLES_BATCHED(psBase) ((psBase)->ui32HandBatchSize != 0) + +#define SET_FLAG(v, f) ((IMG_VOID)((v) |= (f))) +#define CLEAR_FLAG(v, f) ((IMG_VOID)((v) &= ~(f))) +#define TEST_FLAG(v, f) ((IMG_BOOL)(((v) & (f)) != 0)) + +#define TEST_ALLOC_FLAG(psHandle, f) TEST_FLAG((psHandle)->eFlag, f) + +#define SET_INTERNAL_FLAG(psHandle, f) SET_FLAG((psHandle)->eInternalFlag, f) +#define CLEAR_INTERNAL_FLAG(psHandle, f) CLEAR_FLAG((psHandle)->eInternalFlag, f) +#define TEST_INTERNAL_FLAG(psHandle, f) TEST_FLAG((psHandle)->eInternalFlag, f) + +#define BATCHED_HANDLE(psHandle) TEST_INTERNAL_FLAG(psHandle, INTERNAL_HANDLE_FLAG_BATCHED) + +#define SET_BATCHED_HANDLE(psHandle) SET_INTERNAL_FLAG(psHandle, INTERNAL_HANDLE_FLAG_BATCHED) + +#define SET_UNBATCHED_HANDLE(psHandle) CLEAR_INTERNAL_FLAG(psHandle, INTERNAL_HANDLE_FLAG_BATCHED) + +#define BATCHED_HANDLE_PARTIALLY_FREE(psHandle) TEST_INTERNAL_FLAG(psHandle, INTERNAL_HANDLE_FLAG_BATCHED_PARTIALLY_FREE) + +#define SET_BATCHED_HANDLE_PARTIALLY_FREE(psHandle) SET_INTERNAL_FLAG(psHandle, INTERNAL_HANDLE_FLAG_BATCHED_PARTIALLY_FREE) + +#define HANDLE_STRUCT_IS_FREE(psHandle) ((psHandle)->eType == PVRSRV_HANDLE_TYPE_NONE && (psHandle)->eInternalFlag == INTERNAL_HANDLE_FLAG_NONE) + +#ifdef MIN +#undef MIN +#endif + +#define MIN(x, y) (((x) < (y)) ? (x) : (y)) + +struct sHandleList +{ + IMG_UINT32 ui32Prev; + IMG_UINT32 ui32Next; + IMG_HANDLE hParent; +}; + +enum ePVRSRVInternalHandleFlag +{ + INTERNAL_HANDLE_FLAG_NONE = 0x00, + INTERNAL_HANDLE_FLAG_BATCHED = 0x01, + INTERNAL_HANDLE_FLAG_BATCHED_PARTIALLY_FREE = 0x02, +}; + +struct sHandle +{ + + PVRSRV_HANDLE_TYPE eType; + + + IMG_VOID *pvData; + + + IMG_UINT32 ui32NextIndexPlusOne; + + + enum ePVRSRVInternalHandleFlag eInternalFlag; + + + PVRSRV_HANDLE_ALLOC_FLAG eFlag; + + + IMG_UINT32 ui32Index; + + + struct sHandleList sChildren; + + + struct sHandleList sSiblings; +}; + +struct _PVRSRV_HANDLE_BASE_ +{ + + IMG_HANDLE hBaseBlockAlloc; + + + IMG_HANDLE hHandBlockAlloc; + + + struct sHandle *psHandleArray; + + + HASH_TABLE *psHashTab; + + + IMG_UINT32 ui32FreeHandCount; + + + IMG_UINT32 ui32FirstFreeIndex; + + + IMG_UINT32 ui32MaxIndexPlusOne; + + + IMG_UINT32 ui32TotalHandCount; + + + IMG_UINT32 ui32LastFreeIndexPlusOne; + + + IMG_UINT32 ui32HandBatchSize; + + + IMG_UINT32 ui32TotalHandCountPreBatch; + + + IMG_UINT32 ui32FirstBatchIndexPlusOne; + + + IMG_UINT32 ui32BatchHandAllocFailures; + + + IMG_BOOL bPurgingEnabled; +}; + +enum eHandKey { + HAND_KEY_DATA = 0, + HAND_KEY_TYPE, + HAND_KEY_PARENT, + HAND_KEY_LEN +}; + +PVRSRV_HANDLE_BASE *gpsKernelHandleBase = IMG_NULL; + +typedef IMG_UINTPTR_T HAND_KEY[HAND_KEY_LEN]; + +#ifdef INLINE_IS_PRAGMA +#pragma inline(HandleListInit) +#endif +static INLINE +IMG_VOID HandleListInit(IMG_UINT32 ui32Index, struct sHandleList *psList, IMG_HANDLE hParent) +{ + psList->ui32Next = ui32Index; + psList->ui32Prev = ui32Index; + psList->hParent = hParent; +} + +#ifdef INLINE_IS_PRAGMA +#pragma inline(InitParentList) +#endif +static INLINE +IMG_VOID InitParentList(PVRSRV_HANDLE_BASE *psBase, struct sHandle *psHandle) +{ + IMG_UINT32 ui32Parent = HANDLE_PTR_TO_INDEX(psBase, psHandle); + + HandleListInit(ui32Parent, &psHandle->sChildren, INDEX_TO_HANDLE(psBase, ui32Parent)); +} + +#ifdef INLINE_IS_PRAGMA +#pragma inline(InitChildEntry) +#endif +static INLINE +IMG_VOID InitChildEntry(PVRSRV_HANDLE_BASE *psBase, struct sHandle *psHandle) +{ + HandleListInit(HANDLE_PTR_TO_INDEX(psBase, psHandle), &psHandle->sSiblings, IMG_NULL); +} + +#ifdef INLINE_IS_PRAGMA +#pragma inline(HandleListIsEmpty) +#endif +static INLINE +IMG_BOOL HandleListIsEmpty(IMG_UINT32 ui32Index, struct sHandleList *psList) +{ + IMG_BOOL bIsEmpty; + + bIsEmpty = (IMG_BOOL)(psList->ui32Next == ui32Index); + +#ifdef DEBUG + { + IMG_BOOL bIsEmpty2; + + bIsEmpty2 = (IMG_BOOL)(psList->ui32Prev == ui32Index); + PVR_ASSERT(bIsEmpty == bIsEmpty2); + } +#endif + + return bIsEmpty; +} + +#ifdef DEBUG +#ifdef INLINE_IS_PRAGMA +#pragma inline(NoChildren) +#endif +static INLINE +IMG_BOOL NoChildren(PVRSRV_HANDLE_BASE *psBase, struct sHandle *psHandle) +{ + PVR_ASSERT(psHandle->sChildren.hParent == HANDLE_PTR_TO_HANDLE(psBase, psHandle)); + + return HandleListIsEmpty(HANDLE_PTR_TO_INDEX(psBase, psHandle), &psHandle->sChildren); +} + +#ifdef INLINE_IS_PRAGMA +#pragma inline(NoParent) +#endif +static INLINE +IMG_BOOL NoParent(PVRSRV_HANDLE_BASE *psBase, struct sHandle *psHandle) +{ + if (HandleListIsEmpty(HANDLE_PTR_TO_INDEX(psBase, psHandle), &psHandle->sSiblings)) + { + PVR_ASSERT(psHandle->sSiblings.hParent == IMG_NULL); + + return IMG_TRUE; + } + else + { + PVR_ASSERT(psHandle->sSiblings.hParent != IMG_NULL); + } + return IMG_FALSE; +} +#endif +#ifdef INLINE_IS_PRAGMA +#pragma inline(ParentHandle) +#endif +static INLINE +IMG_HANDLE ParentHandle(struct sHandle *psHandle) +{ + return psHandle->sSiblings.hParent; +} + +#define LIST_PTR_FROM_INDEX_AND_OFFSET(psBase, i, p, po, eo) \ + ((struct sHandleList *)((IMG_CHAR *)(INDEX_TO_HANDLE_PTR(psBase, i)) + (((i) == (p)) ? (po) : (eo)))) + +#ifdef INLINE_IS_PRAGMA +#pragma inline(HandleListInsertBefore) +#endif +static INLINE +IMG_VOID HandleListInsertBefore(PVRSRV_HANDLE_BASE *psBase, IMG_UINT32 ui32InsIndex, struct sHandleList *psIns, IMG_SIZE_T uiParentOffset, IMG_UINT32 ui32EntryIndex, struct sHandleList *psEntry, IMG_SIZE_T uiEntryOffset, IMG_UINT32 ui32ParentIndex) +{ + struct sHandleList *psPrevIns = LIST_PTR_FROM_INDEX_AND_OFFSET(psBase, psIns->ui32Prev, ui32ParentIndex, uiParentOffset, uiEntryOffset); + + PVR_ASSERT(psEntry->hParent == IMG_NULL); + PVR_ASSERT(ui32InsIndex == psPrevIns->ui32Next); + PVR_ASSERT(LIST_PTR_FROM_INDEX_AND_OFFSET(psBase, ui32ParentIndex, ui32ParentIndex, uiParentOffset, uiParentOffset)->hParent == INDEX_TO_HANDLE(psBase, ui32ParentIndex)); + + psEntry->ui32Prev = psIns->ui32Prev; + psIns->ui32Prev = ui32EntryIndex; + psEntry->ui32Next = ui32InsIndex; + psPrevIns->ui32Next = ui32EntryIndex; + + psEntry->hParent = INDEX_TO_HANDLE(psBase, ui32ParentIndex); +} + +#ifdef INLINE_IS_PRAGMA +#pragma inline(AdoptChild) +#endif +static INLINE +IMG_VOID AdoptChild(PVRSRV_HANDLE_BASE *psBase, struct sHandle *psParent, struct sHandle *psChild) +{ + IMG_UINT32 ui32Parent = HANDLE_TO_INDEX(psBase, psParent->sChildren.hParent); + + PVR_ASSERT(ui32Parent == (IMG_UINT32)HANDLE_PTR_TO_INDEX(psBase, psParent)); + + HandleListInsertBefore(psBase, ui32Parent, &psParent->sChildren, offsetof(struct sHandle, sChildren), HANDLE_PTR_TO_INDEX(psBase, psChild), &psChild->sSiblings, offsetof(struct sHandle, sSiblings), ui32Parent); + +} + +#ifdef INLINE_IS_PRAGMA +#pragma inline(HandleListRemove) +#endif +static INLINE +IMG_VOID HandleListRemove(PVRSRV_HANDLE_BASE *psBase, IMG_UINT32 ui32EntryIndex, struct sHandleList *psEntry, IMG_SIZE_T uiEntryOffset, IMG_SIZE_T uiParentOffset) +{ + if (!HandleListIsEmpty(ui32EntryIndex, psEntry)) + { + struct sHandleList *psPrev = LIST_PTR_FROM_INDEX_AND_OFFSET(psBase, psEntry->ui32Prev, HANDLE_TO_INDEX(psBase, psEntry->hParent), uiParentOffset, uiEntryOffset); + struct sHandleList *psNext = LIST_PTR_FROM_INDEX_AND_OFFSET(psBase, psEntry->ui32Next, HANDLE_TO_INDEX(psBase, psEntry->hParent), uiParentOffset, uiEntryOffset); + + + PVR_ASSERT(psEntry->hParent != IMG_NULL); + + psPrev->ui32Next = psEntry->ui32Next; + psNext->ui32Prev = psEntry->ui32Prev; + + HandleListInit(ui32EntryIndex, psEntry, IMG_NULL); + } +} + +#ifdef INLINE_IS_PRAGMA +#pragma inline(UnlinkFromParent) +#endif +static INLINE +IMG_VOID UnlinkFromParent(PVRSRV_HANDLE_BASE *psBase, struct sHandle *psHandle) +{ + HandleListRemove(psBase, HANDLE_PTR_TO_INDEX(psBase, psHandle), &psHandle->sSiblings, offsetof(struct sHandle, sSiblings), offsetof(struct sHandle, sChildren)); +} + +#ifdef INLINE_IS_PRAGMA +#pragma inline(HandleListIterate) +#endif +static INLINE +PVRSRV_ERROR HandleListIterate(PVRSRV_HANDLE_BASE *psBase, struct sHandleList *psHead, IMG_SIZE_T uiParentOffset, IMG_SIZE_T uiEntryOffset, PVRSRV_ERROR (*pfnIterFunc)(PVRSRV_HANDLE_BASE *, struct sHandle *)) +{ + IMG_UINT32 ui32Index; + IMG_UINT32 ui32Parent = HANDLE_TO_INDEX(psBase, psHead->hParent); + + PVR_ASSERT(psHead->hParent != IMG_NULL); + + + for(ui32Index = psHead->ui32Next; ui32Index != ui32Parent; ) + { + struct sHandle *psHandle = INDEX_TO_HANDLE_PTR(psBase, ui32Index); + struct sHandleList *psEntry = LIST_PTR_FROM_INDEX_AND_OFFSET(psBase, ui32Index, ui32Parent, uiParentOffset, uiEntryOffset); + PVRSRV_ERROR eError; + + PVR_ASSERT(psEntry->hParent == psHead->hParent); + + ui32Index = psEntry->ui32Next; + + eError = (*pfnIterFunc)(psBase, psHandle); + if (eError != PVRSRV_OK) + { + return eError; + } + } + + return PVRSRV_OK; +} + +#ifdef INLINE_IS_PRAGMA +#pragma inline(IterateOverChildren) +#endif +static INLINE +PVRSRV_ERROR IterateOverChildren(PVRSRV_HANDLE_BASE *psBase, struct sHandle *psParent, PVRSRV_ERROR (*pfnIterFunc)(PVRSRV_HANDLE_BASE *, struct sHandle *)) +{ + return HandleListIterate(psBase, &psParent->sChildren, offsetof(struct sHandle, sChildren), offsetof(struct sHandle, sSiblings), pfnIterFunc); +} + +#ifdef INLINE_IS_PRAGMA +#pragma inline(GetHandleStructure) +#endif +static INLINE +PVRSRV_ERROR GetHandleStructure(PVRSRV_HANDLE_BASE *psBase, struct sHandle **ppsHandle, IMG_HANDLE hHandle, PVRSRV_HANDLE_TYPE eType) +{ + IMG_UINT32 ui32Index = HANDLE_TO_INDEX(psBase, hHandle); + struct sHandle *psHandle; + + + if (!INDEX_IS_VALID(psBase, ui32Index)) + { + PVR_DPF((PVR_DBG_ERROR, "GetHandleStructure: Handle index out of range (%u >= %u)", ui32Index, psBase->ui32TotalHandCount)); + return PVRSRV_ERROR_GENERIC; + } + + psHandle = INDEX_TO_HANDLE_PTR(psBase, ui32Index); + if (psHandle->eType == PVRSRV_HANDLE_TYPE_NONE) + { + PVR_DPF((PVR_DBG_ERROR, "GetHandleStructure: Handle not allocated (index: %u)", ui32Index)); + return PVRSRV_ERROR_GENERIC; + } + + + if (eType != PVRSRV_HANDLE_TYPE_NONE && eType != psHandle->eType) + { + PVR_DPF((PVR_DBG_ERROR, "GetHandleStructure: Handle type mismatch (%d != %d)", eType, psHandle->eType)); + return PVRSRV_ERROR_GENERIC; + } + + + *ppsHandle = psHandle; + + return PVRSRV_OK; +} + +#ifdef INLINE_IS_PRAGMA +#pragma inline(ParentIfPrivate) +#endif +static INLINE +IMG_HANDLE ParentIfPrivate(struct sHandle *psHandle) +{ + return TEST_ALLOC_FLAG(psHandle, PVRSRV_HANDLE_ALLOC_FLAG_PRIVATE) ? + ParentHandle(psHandle) : IMG_NULL; +} + +#ifdef INLINE_IS_PRAGMA +#pragma inline(InitKey) +#endif +static INLINE +IMG_VOID InitKey(HAND_KEY aKey, PVRSRV_HANDLE_BASE *psBase, IMG_VOID *pvData, PVRSRV_HANDLE_TYPE eType, IMG_HANDLE hParent) +{ + PVR_UNREFERENCED_PARAMETER(psBase); + + aKey[HAND_KEY_DATA] = (IMG_UINTPTR_T)pvData; + aKey[HAND_KEY_TYPE] = (IMG_UINTPTR_T)eType; + aKey[HAND_KEY_PARENT] = (IMG_UINTPTR_T)hParent; +} + +static PVRSRV_ERROR FreeHandleArray(PVRSRV_HANDLE_BASE *psBase) +{ + PVRSRV_ERROR eError = PVRSRV_OK; + + if (psBase->psHandleArray != IMG_NULL) + { + eError = OSFreeMem(PVRSRV_OS_PAGEABLE_HEAP, + psBase->ui32TotalHandCount * sizeof(struct sHandle), + psBase->psHandleArray, + psBase->hHandBlockAlloc); + + if (eError != PVRSRV_OK) + { + PVR_DPF((PVR_DBG_ERROR, "FreeHandleArray: Error freeing memory (%d)", eError)); + } + else + { + psBase->psHandleArray = IMG_NULL; + } + } + + return eError; +} + +static PVRSRV_ERROR FreeHandle(PVRSRV_HANDLE_BASE *psBase, struct sHandle *psHandle) +{ + HAND_KEY aKey; + IMG_UINT32 ui32Index = HANDLE_PTR_TO_INDEX(psBase, psHandle); + PVRSRV_ERROR eError; + + + InitKey(aKey, psBase, psHandle->pvData, psHandle->eType, ParentIfPrivate(psHandle)); + + if (!TEST_ALLOC_FLAG(psHandle, PVRSRV_HANDLE_ALLOC_FLAG_MULTI) && !BATCHED_HANDLE_PARTIALLY_FREE(psHandle)) + { + IMG_HANDLE hHandle; + hHandle = (IMG_HANDLE) HASH_Remove_Extended(psBase->psHashTab, aKey); + + PVR_ASSERT(hHandle != IMG_NULL); + PVR_ASSERT(hHandle == INDEX_TO_HANDLE(psBase, ui32Index)); + PVR_UNREFERENCED_PARAMETER(hHandle); + } + + + UnlinkFromParent(psBase, psHandle); + + + eError = IterateOverChildren(psBase, psHandle, FreeHandle); + if (eError != PVRSRV_OK) + { + PVR_DPF((PVR_DBG_ERROR, "FreeHandle: Error whilst freeing subhandles (%d)", eError)); + return eError; + } + + + psHandle->eType = PVRSRV_HANDLE_TYPE_NONE; + + if (BATCHED_HANDLE(psHandle) && !BATCHED_HANDLE_PARTIALLY_FREE(psHandle)) + { + SET_BATCHED_HANDLE_PARTIALLY_FREE(psHandle); + + return PVRSRV_OK; + } + + + if (!psBase->bPurgingEnabled) + { + if (psBase->ui32FreeHandCount == 0) + { + PVR_ASSERT(psBase->ui32FirstFreeIndex == 0); + PVR_ASSERT(psBase->ui32LastFreeIndexPlusOne == 0); + + psBase->ui32FirstFreeIndex = ui32Index; + } + else + { + + PVR_ASSERT(psBase->ui32LastFreeIndexPlusOne != 0); + PVR_ASSERT(INDEX_TO_HANDLE_PTR(psBase, psBase->ui32LastFreeIndexPlusOne - 1)->ui32NextIndexPlusOne == 0); + INDEX_TO_HANDLE_PTR(psBase, psBase->ui32LastFreeIndexPlusOne - 1)->ui32NextIndexPlusOne = ui32Index + 1; + } + + PVR_ASSERT(psHandle->ui32NextIndexPlusOne == 0); + + + psBase->ui32LastFreeIndexPlusOne = ui32Index + 1; + } + + psBase->ui32FreeHandCount++; + + return PVRSRV_OK; +} + +static PVRSRV_ERROR FreeAllHandles(PVRSRV_HANDLE_BASE *psBase) +{ + IMG_UINT32 i; + PVRSRV_ERROR eError = PVRSRV_OK; + + if (psBase->ui32FreeHandCount == psBase->ui32TotalHandCount) + { + return eError; + } + + for (i = 0; i < psBase->ui32TotalHandCount; i++) + { + struct sHandle *psHandle; + + psHandle = INDEX_TO_HANDLE_PTR(psBase, i); + + if (psHandle->eType != PVRSRV_HANDLE_TYPE_NONE) + { + eError = FreeHandle(psBase, psHandle); + if (eError != PVRSRV_OK) + { + PVR_DPF((PVR_DBG_ERROR, "FreeAllHandles: FreeHandle failed (%d)", eError)); + break; + } + + + if (psBase->ui32FreeHandCount == psBase->ui32TotalHandCount) + { + break; + } + } + } + + return eError; +} + +static PVRSRV_ERROR FreeHandleBase(PVRSRV_HANDLE_BASE *psBase) +{ + PVRSRV_ERROR eError; + + if (HANDLES_BATCHED(psBase)) + { + PVR_DPF((PVR_DBG_WARNING, "FreeHandleBase: Uncommitted/Unreleased handle batch")); + PVRSRVReleaseHandleBatch(psBase); + } + + + eError = FreeAllHandles(psBase); + if (eError != PVRSRV_OK) + { + PVR_DPF((PVR_DBG_ERROR, "FreeHandleBase: Couldn't free handles (%d)", eError)); + return eError; + } + + + eError = FreeHandleArray(psBase); + if (eError != PVRSRV_OK) + { + PVR_DPF((PVR_DBG_ERROR, "FreeHandleBase: Couldn't free handle array (%d)", eError)); + return eError; + } + + if (psBase->psHashTab != IMG_NULL) + { + + HASH_Delete(psBase->psHashTab); + } + + eError = OSFreeMem(PVRSRV_OS_PAGEABLE_HEAP, + sizeof(*psBase), + psBase, + psBase->hBaseBlockAlloc); + if (eError != PVRSRV_OK) + { + PVR_DPF((PVR_DBG_ERROR, "FreeHandleBase: Couldn't free handle base (%d)", eError)); + return eError; + } + + return PVRSRV_OK; +} + +#ifdef INLINE_IS_PRAGMA +#pragma inline(FindHandle) +#endif +static INLINE +IMG_HANDLE FindHandle(PVRSRV_HANDLE_BASE *psBase, IMG_VOID *pvData, PVRSRV_HANDLE_TYPE eType, IMG_HANDLE hParent) +{ + HAND_KEY aKey; + + PVR_ASSERT(eType != PVRSRV_HANDLE_TYPE_NONE); + + InitKey(aKey, psBase, pvData, eType, hParent); + + return (IMG_HANDLE) HASH_Retrieve_Extended(psBase->psHashTab, aKey); +} + +static PVRSRV_ERROR ReallocMem(IMG_PVOID *ppvMem, IMG_HANDLE *phBlockAlloc, IMG_UINT32 ui32NewSize, IMG_UINT32 ui32OldSize) +{ + IMG_VOID *pvOldMem = *ppvMem; + IMG_HANDLE hOldBlockAlloc = *phBlockAlloc; + IMG_UINT32 ui32CopySize = MIN(ui32NewSize, ui32OldSize); + IMG_VOID *pvNewMem = IMG_NULL; + IMG_HANDLE hNewBlockAlloc = IMG_NULL; + PVRSRV_ERROR eError; + + if (ui32NewSize == ui32OldSize) + { + return (PVRSRV_OK); + } + + if (ui32NewSize != 0) + { + + eError = OSAllocMem(PVRSRV_OS_PAGEABLE_HEAP, + ui32NewSize, + &pvNewMem, + &hNewBlockAlloc); + if (eError != PVRSRV_OK) + { + PVR_DPF((PVR_DBG_ERROR, "ReallocMem: Couldn't allocate new memory area (%d)", eError)); + return eError; + } + } + + if (ui32CopySize != 0) + { + + OSMemCopy(pvNewMem, pvOldMem, ui32CopySize); + } + + if (ui32OldSize != 0) + { + + eError = OSFreeMem(PVRSRV_OS_PAGEABLE_HEAP, + ui32OldSize, + pvOldMem, + hOldBlockAlloc); + if (eError != PVRSRV_OK) + { + PVR_DPF((PVR_DBG_ERROR, "ReallocMem: Couldn't free old memory area (%d)", eError)); + } + } + + *ppvMem = pvNewMem; + *phBlockAlloc = hNewBlockAlloc; + + return PVRSRV_OK; +} + +#ifdef INLINE_IS_PRAGMA +#pragma inline(ReallocHandleArray) +#endif +static INLINE +PVRSRV_ERROR ReallocHandleArray(PVRSRV_HANDLE_BASE *psBase, IMG_UINT32 ui32NewCount, IMG_UINT32 ui32OldCount) +{ + return ReallocMem((IMG_PVOID *)&psBase->psHandleArray, + &psBase->hHandBlockAlloc, + ui32NewCount * sizeof(struct sHandle), + ui32OldCount * sizeof(struct sHandle)); +} + +static PVRSRV_ERROR IncreaseHandleArraySize(PVRSRV_HANDLE_BASE *psBase, IMG_UINT32 ui32Delta) +{ + PVRSRV_ERROR eError; + struct sHandle *psHandle; + IMG_UINT32 ui32DeltaAdjusted = ROUND_UP_TO_MULTIPLE(ui32Delta, HANDLE_BLOCK_SIZE); + IMG_UINT32 ui32NewTotalHandCount = psBase->ui32TotalHandCount + ui32DeltaAdjusted; +; + + PVR_ASSERT(ui32Delta != 0); + + + if (ui32NewTotalHandCount > psBase->ui32MaxIndexPlusOne || ui32NewTotalHandCount <= psBase->ui32TotalHandCount) + { + ui32NewTotalHandCount = psBase->ui32MaxIndexPlusOne; + + ui32DeltaAdjusted = ui32NewTotalHandCount - psBase->ui32TotalHandCount; + + if (ui32DeltaAdjusted < ui32Delta) + { + PVR_DPF((PVR_DBG_ERROR, "IncreaseHandleArraySize: Maximum handle limit reached (%d)", psBase->ui32MaxIndexPlusOne)); + return PVRSRV_ERROR_OUT_OF_MEMORY; + } + } + + PVR_ASSERT(ui32DeltaAdjusted >= ui32Delta); + + + eError = ReallocHandleArray(psBase, ui32NewTotalHandCount, psBase->ui32TotalHandCount); + if (eError != PVRSRV_OK) + { + PVR_DPF((PVR_DBG_ERROR, "IncreaseHandleArraySize: ReallocHandleArray failed (%d)", eError)); + return eError; + } + + + for(psHandle = psBase->psHandleArray + psBase->ui32TotalHandCount; + psHandle < psBase->psHandleArray + ui32NewTotalHandCount; + psHandle++) + { + psHandle->eType = PVRSRV_HANDLE_TYPE_NONE; + psHandle->eInternalFlag = INTERNAL_HANDLE_FLAG_NONE; + psHandle->ui32NextIndexPlusOne = 0; + } + + + psBase->ui32FreeHandCount += ui32DeltaAdjusted; + + if (psBase->ui32FirstFreeIndex == 0) + { + PVR_ASSERT(psBase->ui32LastFreeIndexPlusOne == 0); + + psBase->ui32FirstFreeIndex = psBase->ui32TotalHandCount; + } + else + { + if (!psBase->bPurgingEnabled) + { + PVR_ASSERT(psBase->ui32LastFreeIndexPlusOne != 0) + PVR_ASSERT(INDEX_TO_HANDLE_PTR(psBase, psBase->ui32LastFreeIndexPlusOne - 1)->ui32NextIndexPlusOne == 0); + + INDEX_TO_HANDLE_PTR(psBase, psBase->ui32LastFreeIndexPlusOne - 1)->ui32NextIndexPlusOne = psBase->ui32TotalHandCount + 1; + } + } + + if (!psBase->bPurgingEnabled) + { + psBase->ui32LastFreeIndexPlusOne = ui32NewTotalHandCount; + } + + psBase->ui32TotalHandCount = ui32NewTotalHandCount; + + return PVRSRV_OK; +} + +static PVRSRV_ERROR EnsureFreeHandles(PVRSRV_HANDLE_BASE *psBase, IMG_UINT32 ui32Free) +{ + PVRSRV_ERROR eError; + + if (ui32Free > psBase->ui32FreeHandCount) + { + IMG_UINT32 ui32FreeHandDelta = ui32Free - psBase->ui32FreeHandCount; + eError = IncreaseHandleArraySize(psBase, ui32FreeHandDelta); + if (eError != PVRSRV_OK) + { + PVR_DPF((PVR_DBG_ERROR, "EnsureFreeHandles: Couldn't allocate %u handles to ensure %u free handles (IncreaseHandleArraySize failed with error %d)", ui32FreeHandDelta, ui32Free, eError)); + + return eError; + } + } + + return PVRSRV_OK; +} + +static PVRSRV_ERROR AllocHandle(PVRSRV_HANDLE_BASE *psBase, IMG_HANDLE *phHandle, IMG_VOID *pvData, PVRSRV_HANDLE_TYPE eType, PVRSRV_HANDLE_ALLOC_FLAG eFlag, IMG_HANDLE hParent) +{ + IMG_UINT32 ui32NewIndex; + struct sHandle *psNewHandle = IMG_NULL; + IMG_HANDLE hHandle; + HAND_KEY aKey; + PVRSRV_ERROR eError; + + + PVR_ASSERT(eType != PVRSRV_HANDLE_TYPE_NONE); + + PVR_ASSERT(psBase->psHashTab != IMG_NULL); + + if (!TEST_FLAG(eFlag, PVRSRV_HANDLE_ALLOC_FLAG_MULTI)) + { + + PVR_ASSERT(FindHandle(psBase, pvData, eType, hParent) == IMG_NULL); + } + + if (psBase->ui32FreeHandCount == 0 && HANDLES_BATCHED(psBase)) + { + PVR_DPF((PVR_DBG_WARNING, "AllocHandle: Handle batch size (%u) was too small, allocating additional space", psBase->ui32HandBatchSize)); + } + + + eError = EnsureFreeHandles(psBase, 1); + if (eError != PVRSRV_OK) + { + PVR_DPF((PVR_DBG_ERROR, "AllocHandle: EnsureFreeHandles failed (%d)", eError)); + return eError; + } + PVR_ASSERT(psBase->ui32FreeHandCount != 0) + + if (!psBase->bPurgingEnabled) + { + + ui32NewIndex = psBase->ui32FirstFreeIndex; + + + psNewHandle = INDEX_TO_HANDLE_PTR(psBase, ui32NewIndex); + } + else + { + + for(ui32NewIndex = psBase->ui32FirstFreeIndex; ui32NewIndex < psBase->ui32TotalHandCount; ui32NewIndex++) + { + psNewHandle = INDEX_TO_HANDLE_PTR(psBase, ui32NewIndex); + if (HANDLE_STRUCT_IS_FREE(psNewHandle)) + { + break; + } + + } + psBase->ui32FirstFreeIndex = 0; + PVR_ASSERT(ui32NewIndex < psBase->ui32TotalHandCount); + } + PVR_ASSERT(psNewHandle != IMG_NULL); + + + hHandle = INDEX_TO_HANDLE(psBase, ui32NewIndex); + + + if (!TEST_FLAG(eFlag, PVRSRV_HANDLE_ALLOC_FLAG_MULTI)) + { + + InitKey(aKey, psBase, pvData, eType, hParent); + + + if (!HASH_Insert_Extended(psBase->psHashTab, aKey, (IMG_UINTPTR_T)hHandle)) + { + PVR_DPF((PVR_DBG_ERROR, "AllocHandle: Couldn't add handle to hash table")); + + return PVRSRV_ERROR_GENERIC; + } + } + + psBase->ui32FreeHandCount--; + + + if (!psBase->bPurgingEnabled) + { + + if (psBase->ui32FreeHandCount == 0) + { + PVR_ASSERT(psBase->ui32FirstFreeIndex == ui32NewIndex); + PVR_ASSERT(psBase->ui32LastFreeIndexPlusOne == (ui32NewIndex + 1)); + + psBase->ui32LastFreeIndexPlusOne = 0; + psBase->ui32FirstFreeIndex = 0; + } + else + { + + psBase->ui32FirstFreeIndex = (psNewHandle->ui32NextIndexPlusOne == 0) ? + ui32NewIndex + 1 : + psNewHandle->ui32NextIndexPlusOne - 1; + } + } + + + psNewHandle->eType = eType; + psNewHandle->pvData = pvData; + psNewHandle->eInternalFlag = INTERNAL_HANDLE_FLAG_NONE; + psNewHandle->eFlag = eFlag; + psNewHandle->ui32Index = ui32NewIndex; + + InitParentList(psBase, psNewHandle); + PVR_ASSERT(NoChildren(psBase, psNewHandle)); + + InitChildEntry(psBase, psNewHandle); + PVR_ASSERT(NoParent(psBase, psNewHandle)); + + if (HANDLES_BATCHED(psBase)) + { + + psNewHandle->ui32NextIndexPlusOne = psBase->ui32FirstBatchIndexPlusOne; + + psBase->ui32FirstBatchIndexPlusOne = ui32NewIndex + 1; + + SET_BATCHED_HANDLE(psNewHandle); + } + else + { + psNewHandle->ui32NextIndexPlusOne = 0; + } + + + *phHandle = hHandle; + + return PVRSRV_OK; +} + +PVRSRV_ERROR PVRSRVAllocHandle(PVRSRV_HANDLE_BASE *psBase, IMG_HANDLE *phHandle, IMG_VOID *pvData, PVRSRV_HANDLE_TYPE eType, PVRSRV_HANDLE_ALLOC_FLAG eFlag) +{ + IMG_HANDLE hHandle; + PVRSRV_ERROR eError; + + *phHandle = IMG_NULL; + + if (HANDLES_BATCHED(psBase)) + { + + psBase->ui32BatchHandAllocFailures++; + } + + + PVR_ASSERT(eType != PVRSRV_HANDLE_TYPE_NONE); + + if (!TEST_FLAG(eFlag, PVRSRV_HANDLE_ALLOC_FLAG_MULTI)) + { + + hHandle = FindHandle(psBase, pvData, eType, IMG_NULL); + if (hHandle != IMG_NULL) + { + struct sHandle *psHandle; + + eError = GetHandleStructure(psBase, &psHandle, hHandle, eType); + if (eError != PVRSRV_OK) + { + PVR_DPF((PVR_DBG_ERROR, "PVRSRVAllocHandle: Lookup of existing handle failed")); + return eError; + } + + + if (TEST_FLAG(psHandle->eFlag & eFlag, PVRSRV_HANDLE_ALLOC_FLAG_SHARED)) + { + *phHandle = hHandle; + eError = PVRSRV_OK; + goto exit_ok; + } + return PVRSRV_ERROR_GENERIC; + } + } + + eError = AllocHandle(psBase, phHandle, pvData, eType, eFlag, IMG_NULL); + +exit_ok: + if (HANDLES_BATCHED(psBase) && (eError == PVRSRV_OK)) + { + psBase->ui32BatchHandAllocFailures--; + } + + return eError; +} + +PVRSRV_ERROR PVRSRVAllocSubHandle(PVRSRV_HANDLE_BASE *psBase, IMG_HANDLE *phHandle, IMG_VOID *pvData, PVRSRV_HANDLE_TYPE eType, PVRSRV_HANDLE_ALLOC_FLAG eFlag, IMG_HANDLE hParent) +{ + struct sHandle *psPHand; + struct sHandle *psCHand; + PVRSRV_ERROR eError; + IMG_HANDLE hParentKey; + IMG_HANDLE hHandle; + + *phHandle = IMG_NULL; + + if (HANDLES_BATCHED(psBase)) + { + + psBase->ui32BatchHandAllocFailures++; + } + + + PVR_ASSERT(eType != PVRSRV_HANDLE_TYPE_NONE); + + hParentKey = TEST_FLAG(eFlag, PVRSRV_HANDLE_ALLOC_FLAG_PRIVATE) ? + hParent : IMG_NULL; + + + eError = GetHandleStructure(psBase, &psPHand, hParent, PVRSRV_HANDLE_TYPE_NONE); + if (eError != PVRSRV_OK) + { + return PVRSRV_ERROR_GENERIC; + } + + if (!TEST_FLAG(eFlag, PVRSRV_HANDLE_ALLOC_FLAG_MULTI)) + { + + hHandle = FindHandle(psBase, pvData, eType, hParentKey); + if (hHandle != IMG_NULL) + { + struct sHandle *psCHandle; + PVRSRV_ERROR eErr; + + eErr = GetHandleStructure(psBase, &psCHandle, hHandle, eType); + if (eErr != PVRSRV_OK) + { + PVR_DPF((PVR_DBG_ERROR, "PVRSRVAllocSubHandle: Lookup of existing handle failed")); + return eErr; + } + + PVR_ASSERT(hParentKey != IMG_NULL && ParentHandle(HANDLE_TO_HANDLE_PTR(psBase, hHandle)) == hParent); + + + if (TEST_FLAG(psCHandle->eFlag & eFlag, PVRSRV_HANDLE_ALLOC_FLAG_SHARED) && ParentHandle(HANDLE_TO_HANDLE_PTR(psBase, hHandle)) == hParent) + { + *phHandle = hHandle; + goto exit_ok; + } + return PVRSRV_ERROR_GENERIC; + } + } + + eError = AllocHandle(psBase, &hHandle, pvData, eType, eFlag, hParentKey); + if (eError != PVRSRV_OK) + { + return eError; + } + + + psPHand = HANDLE_TO_HANDLE_PTR(psBase, hParent); + + psCHand = HANDLE_TO_HANDLE_PTR(psBase, hHandle); + + AdoptChild(psBase, psPHand, psCHand); + + *phHandle = hHandle; + +exit_ok: + if (HANDLES_BATCHED(psBase)) + { + psBase->ui32BatchHandAllocFailures--; + } + + return PVRSRV_OK; +} + +PVRSRV_ERROR PVRSRVFindHandle(PVRSRV_HANDLE_BASE *psBase, IMG_HANDLE *phHandle, IMG_VOID *pvData, PVRSRV_HANDLE_TYPE eType) +{ + IMG_HANDLE hHandle; + + PVR_ASSERT(eType != PVRSRV_HANDLE_TYPE_NONE); + + + hHandle = (IMG_HANDLE) FindHandle(psBase, pvData, eType, IMG_NULL); + if (hHandle == IMG_NULL) + { + return PVRSRV_ERROR_GENERIC; + } + + *phHandle = hHandle; + + return PVRSRV_OK; +} + +PVRSRV_ERROR PVRSRVLookupHandleAnyType(PVRSRV_HANDLE_BASE *psBase, IMG_PVOID *ppvData, PVRSRV_HANDLE_TYPE *peType, IMG_HANDLE hHandle) +{ + struct sHandle *psHandle; + PVRSRV_ERROR eError; + + eError = GetHandleStructure(psBase, &psHandle, hHandle, PVRSRV_HANDLE_TYPE_NONE); + if (eError != PVRSRV_OK) + { + PVR_DPF((PVR_DBG_ERROR, "PVRSRVLookupHandleAnyType: Error looking up handle (%d)", eError)); + return eError; + } + + *ppvData = psHandle->pvData; + *peType = psHandle->eType; + + return PVRSRV_OK; +} + +PVRSRV_ERROR PVRSRVLookupHandle(PVRSRV_HANDLE_BASE *psBase, IMG_PVOID *ppvData, IMG_HANDLE hHandle, PVRSRV_HANDLE_TYPE eType) +{ + struct sHandle *psHandle; + PVRSRV_ERROR eError; + + PVR_ASSERT(eType != PVRSRV_HANDLE_TYPE_NONE); + + eError = GetHandleStructure(psBase, &psHandle, hHandle, eType); + if (eError != PVRSRV_OK) + { + PVR_DPF((PVR_DBG_ERROR, "PVRSRVLookupHandle: Error looking up handle (%d)", eError)); + return eError; + } + + *ppvData = psHandle->pvData; + + return PVRSRV_OK; +} + +PVRSRV_ERROR PVRSRVLookupSubHandle(PVRSRV_HANDLE_BASE *psBase, IMG_PVOID *ppvData, IMG_HANDLE hHandle, PVRSRV_HANDLE_TYPE eType, IMG_HANDLE hAncestor) +{ + struct sHandle *psPHand; + struct sHandle *psCHand; + PVRSRV_ERROR eError; + + PVR_ASSERT(eType != PVRSRV_HANDLE_TYPE_NONE); + + eError = GetHandleStructure(psBase, &psCHand, hHandle, eType); + if (eError != PVRSRV_OK) + { + PVR_DPF((PVR_DBG_ERROR, "PVRSRVLookupSubHandle: Error looking up subhandle (%d)", eError)); + return eError; + } + + + for (psPHand = psCHand; ParentHandle(psPHand) != hAncestor; ) + { + eError = GetHandleStructure(psBase, &psPHand, ParentHandle(psPHand), PVRSRV_HANDLE_TYPE_NONE); + if (eError != PVRSRV_OK) + { + PVR_DPF((PVR_DBG_ERROR, "PVRSRVLookupSubHandle: Subhandle doesn't belong to given ancestor")); + return PVRSRV_ERROR_GENERIC; + } + } + + *ppvData = psCHand->pvData; + + return PVRSRV_OK; +} + +PVRSRV_ERROR PVRSRVGetParentHandle(PVRSRV_HANDLE_BASE *psBase, IMG_PVOID *phParent, IMG_HANDLE hHandle, PVRSRV_HANDLE_TYPE eType) +{ + struct sHandle *psHandle; + PVRSRV_ERROR eError; + + PVR_ASSERT(eType != PVRSRV_HANDLE_TYPE_NONE); + + eError = GetHandleStructure(psBase, &psHandle, hHandle, eType); + if (eError != PVRSRV_OK) + { + PVR_DPF((PVR_DBG_ERROR, "PVRSRVGetParentHandle: Error looking up subhandle (%d)", eError)); + return eError; + } + + *phParent = ParentHandle(psHandle); + + return PVRSRV_OK; +} + +PVRSRV_ERROR PVRSRVLookupAndReleaseHandle(PVRSRV_HANDLE_BASE *psBase, IMG_PVOID *ppvData, IMG_HANDLE hHandle, PVRSRV_HANDLE_TYPE eType) +{ + struct sHandle *psHandle; + PVRSRV_ERROR eError; + + PVR_ASSERT(eType != PVRSRV_HANDLE_TYPE_NONE); + + eError = GetHandleStructure(psBase, &psHandle, hHandle, eType); + if (eError != PVRSRV_OK) + { + PVR_DPF((PVR_DBG_ERROR, "PVRSRVLookupAndReleaseHandle: Error looking up handle (%d)", eError)); + return eError; + } + + *ppvData = psHandle->pvData; + + eError = FreeHandle(psBase, psHandle); + + return eError; +} + +PVRSRV_ERROR PVRSRVReleaseHandle(PVRSRV_HANDLE_BASE *psBase, IMG_HANDLE hHandle, PVRSRV_HANDLE_TYPE eType) +{ + struct sHandle *psHandle; + PVRSRV_ERROR eError; + + PVR_ASSERT(eType != PVRSRV_HANDLE_TYPE_NONE); + + eError = GetHandleStructure(psBase, &psHandle, hHandle, eType); + if (eError != PVRSRV_OK) + { + PVR_DPF((PVR_DBG_ERROR, "PVRSRVReleaseHandle: Error looking up handle (%d)", eError)); + return eError; + } + + eError = FreeHandle(psBase, psHandle); + + return eError; +} + +PVRSRV_ERROR PVRSRVNewHandleBatch(PVRSRV_HANDLE_BASE *psBase, IMG_UINT32 ui32BatchSize) +{ + PVRSRV_ERROR eError; + + if (HANDLES_BATCHED(psBase)) + { + PVR_DPF((PVR_DBG_ERROR, "PVRSRVNewHandleBatch: There is a handle batch already in use (size %u)", psBase->ui32HandBatchSize)); + return PVRSRV_ERROR_GENERIC; + } + + if (ui32BatchSize == 0) + { + PVR_DPF((PVR_DBG_ERROR, "PVRSRVNewHandleBatch: Invalid batch size (%u)", ui32BatchSize)); + return PVRSRV_ERROR_INVALID_PARAMS; + } + + eError = EnsureFreeHandles(psBase, ui32BatchSize); + if (eError != PVRSRV_OK) + { + PVR_DPF((PVR_DBG_ERROR, "PVRSRVNewHandleBatch: EnsureFreeHandles failed (error %d)", eError)); + return eError; + } + + psBase->ui32HandBatchSize = ui32BatchSize; + + + psBase->ui32TotalHandCountPreBatch = psBase->ui32TotalHandCount; + + PVR_ASSERT(psBase->ui32BatchHandAllocFailures == 0); + + PVR_ASSERT(psBase->ui32FirstBatchIndexPlusOne == 0); + + PVR_ASSERT(HANDLES_BATCHED(psBase)); + + return PVRSRV_OK; +} + +static PVRSRV_ERROR PVRSRVHandleBatchCommitOrRelease(PVRSRV_HANDLE_BASE *psBase, IMG_BOOL bCommit) +{ + + IMG_UINT32 ui32IndexPlusOne; + IMG_BOOL bCommitBatch = bCommit; + + if (!HANDLES_BATCHED(psBase)) + { + PVR_DPF((PVR_DBG_ERROR, "PVRSRVHandleBatchCommitOrRelease: There is no handle batch")); + return PVRSRV_ERROR_INVALID_PARAMS; + + } + + if (psBase->ui32BatchHandAllocFailures != 0) + { + if (bCommit) + { + PVR_DPF((PVR_DBG_ERROR, "PVRSRVHandleBatchCommitOrRelease: Attempting to commit batch with handle allocation failures.")); + } + bCommitBatch = IMG_FALSE; + } + + PVR_ASSERT(psBase->ui32BatchHandAllocFailures == 0 || !bCommit); + + ui32IndexPlusOne = psBase->ui32FirstBatchIndexPlusOne; + while(ui32IndexPlusOne != 0) + { + struct sHandle *psHandle = INDEX_TO_HANDLE_PTR(psBase, ui32IndexPlusOne - 1); + IMG_UINT32 ui32NextIndexPlusOne = psHandle->ui32NextIndexPlusOne; + PVR_ASSERT(BATCHED_HANDLE(psHandle)); + + psHandle->ui32NextIndexPlusOne = 0; + + if (!bCommitBatch || BATCHED_HANDLE_PARTIALLY_FREE(psHandle)) + { + PVRSRV_ERROR eError; + + + if (!BATCHED_HANDLE_PARTIALLY_FREE(psHandle)) + { + SET_UNBATCHED_HANDLE(psHandle); + } + + eError = FreeHandle(psBase, psHandle); + if (eError != PVRSRV_OK) + { + PVR_DPF((PVR_DBG_ERROR, "PVRSRVHandleBatchCommitOrRelease: Error freeing handle (%d)", eError)); + } + PVR_ASSERT(eError == PVRSRV_OK); + } + else + { + SET_UNBATCHED_HANDLE(psHandle); + } + + ui32IndexPlusOne = ui32NextIndexPlusOne; + } + +#ifdef DEBUG + if (psBase->ui32TotalHandCountPreBatch != psBase->ui32TotalHandCount) + { + IMG_UINT32 ui32Delta = psBase->ui32TotalHandCount - psBase->ui32TotalHandCountPreBatch; + + PVR_ASSERT(psBase->ui32TotalHandCount > psBase->ui32TotalHandCountPreBatch); + + PVR_DPF((PVR_DBG_WARNING, "PVRSRVHandleBatchCommitOrRelease: The batch size was too small. Batch size was %u, but needs to be %u", psBase->ui32HandBatchSize, psBase->ui32HandBatchSize + ui32Delta)); + + } +#endif + + psBase->ui32HandBatchSize = 0; + psBase->ui32FirstBatchIndexPlusOne = 0; + psBase->ui32TotalHandCountPreBatch = 0; + psBase->ui32BatchHandAllocFailures = 0; + + if (psBase->ui32BatchHandAllocFailures != 0 && bCommit) + { + PVR_ASSERT(!bCommitBatch); + + return PVRSRV_ERROR_GENERIC; + } + + return PVRSRV_OK; +} + +PVRSRV_ERROR PVRSRVCommitHandleBatch(PVRSRV_HANDLE_BASE *psBase) +{ + return PVRSRVHandleBatchCommitOrRelease(psBase, IMG_TRUE); +} + +IMG_VOID PVRSRVReleaseHandleBatch(PVRSRV_HANDLE_BASE *psBase) +{ + (IMG_VOID) PVRSRVHandleBatchCommitOrRelease(psBase, IMG_FALSE); +} + +PVRSRV_ERROR PVRSRVSetMaxHandle(PVRSRV_HANDLE_BASE *psBase, IMG_UINT32 ui32MaxHandle) +{ + if (HANDLES_BATCHED(psBase)) + { + PVR_DPF((PVR_DBG_ERROR, "PVRSRVSetMaxHandle: Limit cannot be set whilst in batch mode")); + return PVRSRV_ERROR_INVALID_PARAMS; + } + + + if (ui32MaxHandle == 0 || ui32MaxHandle > DEFAULT_MAX_HANDLE) + { + PVR_DPF((PVR_DBG_ERROR, "PVRSRVSetMaxHandle: Limit must be between %u and %u, inclusive", 0, DEFAULT_MAX_HANDLE)); + + return PVRSRV_ERROR_INVALID_PARAMS; + } + + + if (psBase->ui32TotalHandCount != 0) + { + PVR_DPF((PVR_DBG_ERROR, "PVRSRVSetMaxHandle: Limit cannot be set becuase handles have already been allocated")); + + return PVRSRV_ERROR_INVALID_PARAMS; + } + + psBase->ui32MaxIndexPlusOne = ui32MaxHandle; + + return PVRSRV_OK; +} + +IMG_UINT32 PVRSRVGetMaxHandle(PVRSRV_HANDLE_BASE *psBase) +{ + return psBase->ui32MaxIndexPlusOne; +} + +PVRSRV_ERROR PVRSRVEnableHandlePurging(PVRSRV_HANDLE_BASE *psBase) +{ + if (psBase->bPurgingEnabled) + { + PVR_DPF((PVR_DBG_WARNING, "PVRSRVEnableHandlePurging: Purging already enabled")); + return PVRSRV_OK; + } + + + if (psBase->ui32TotalHandCount != 0) + { + PVR_DPF((PVR_DBG_ERROR, "PVRSRVEnableHandlePurging: Handles have already been allocated")); + return PVRSRV_ERROR_INVALID_PARAMS; + } + + psBase->bPurgingEnabled = IMG_TRUE; + + return PVRSRV_OK; +} + +PVRSRV_ERROR PVRSRVPurgeHandles(PVRSRV_HANDLE_BASE *psBase) +{ + IMG_UINT32 ui32Handle; + IMG_UINT32 ui32NewHandCount; + + if (!psBase->bPurgingEnabled) + { + PVR_DPF((PVR_DBG_ERROR, "PVRSRVPurgeHandles: Purging not enabled for this handle base")); + return PVRSRV_ERROR_NOT_SUPPORTED; + } + + if (HANDLES_BATCHED(psBase)) + { + PVR_DPF((PVR_DBG_ERROR, "PVRSRVPurgeHandles: Purging not allowed whilst in batch mode")); + return PVRSRV_ERROR_INVALID_PARAMS; + } + + for (ui32Handle = psBase->ui32TotalHandCount; ui32Handle != 0; ui32Handle--) + { + struct sHandle *psHandle = HANDLE_TO_HANDLE_PTR(psBase, ui32Handle); + if (!HANDLE_STRUCT_IS_FREE(psHandle)) + { + break; + } + } + + ui32NewHandCount = ROUND_UP_TO_MULTIPLE(ui32Handle, HANDLE_BLOCK_SIZE); + + + if (ui32NewHandCount >= ui32Handle && ui32NewHandCount <= (psBase->ui32TotalHandCount/2)) + { + IMG_UINT32 ui32Delta = psBase->ui32TotalHandCount - ui32NewHandCount; + PVRSRV_ERROR eError; + + + + eError = ReallocHandleArray(psBase, ui32NewHandCount, psBase->ui32TotalHandCount); + if (eError != PVRSRV_OK) + { + return eError; + } + + + psBase->ui32TotalHandCount = ui32NewHandCount; + psBase->ui32FreeHandCount -= ui32Delta; + psBase->ui32FirstFreeIndex = 0; + } + + return PVRSRV_OK; +} + +PVRSRV_ERROR PVRSRVAllocHandleBase(PVRSRV_HANDLE_BASE **ppsBase) +{ + PVRSRV_HANDLE_BASE *psBase; + IMG_HANDLE hBlockAlloc; + PVRSRV_ERROR eError; + + eError = OSAllocMem(PVRSRV_OS_PAGEABLE_HEAP, + sizeof(*psBase), + (IMG_PVOID *)&psBase, + &hBlockAlloc); + if (eError != PVRSRV_OK) + { + PVR_DPF((PVR_DBG_ERROR, "PVRSRVAllocHandleBase: Couldn't allocate handle base (%d)", eError)); + return eError; + } + OSMemSet(psBase, 0, sizeof(*psBase)); + + + psBase->psHashTab = HASH_Create_Extended(HANDLE_HASH_TAB_INIT_SIZE, sizeof(HAND_KEY), HASH_Func_Default, HASH_Key_Comp_Default); + if (psBase->psHashTab == IMG_NULL) + { + PVR_DPF((PVR_DBG_ERROR, "PVRSRVAllocHandleBase: Couldn't create data pointer hash table\n")); + goto failure; + } + + psBase->hBaseBlockAlloc = hBlockAlloc; + + psBase->ui32MaxIndexPlusOne = DEFAULT_MAX_INDEX_PLUS_ONE; + + *ppsBase = psBase; + + return PVRSRV_OK; +failure: + (IMG_VOID)PVRSRVFreeHandleBase(psBase); + return PVRSRV_ERROR_GENERIC; +} + +PVRSRV_ERROR PVRSRVFreeHandleBase(PVRSRV_HANDLE_BASE *psBase) +{ + PVRSRV_ERROR eError; + + PVR_ASSERT(psBase != gpsKernelHandleBase); + + eError = FreeHandleBase(psBase); + if (eError != PVRSRV_OK) + { + PVR_DPF((PVR_DBG_ERROR, "PVRSRVFreeHandleBase: FreeHandleBase failed (%d)", eError)); + } + + return eError; +} + +PVRSRV_ERROR PVRSRVHandleInit(IMG_VOID) +{ + PVRSRV_ERROR eError; + + PVR_ASSERT(gpsKernelHandleBase == IMG_NULL); + + eError = PVRSRVAllocHandleBase(&gpsKernelHandleBase); + if (eError != PVRSRV_OK) + { + PVR_DPF((PVR_DBG_ERROR, "PVRSRVHandleInit: PVRSRVAllocHandleBase failed (%d)", eError)); + goto error; + } + + eError = PVRSRVEnableHandlePurging(gpsKernelHandleBase); + if (eError != PVRSRV_OK) + { + PVR_DPF((PVR_DBG_ERROR, "PVRSRVHandleInit: PVRSRVEnableHandlePurging failed (%d)", eError)); + goto error; + } + + return PVRSRV_OK; +error: + (IMG_VOID) PVRSRVHandleDeInit(); + return eError; +} + +PVRSRV_ERROR PVRSRVHandleDeInit(IMG_VOID) +{ + PVRSRV_ERROR eError = PVRSRV_OK; + + if (gpsKernelHandleBase != IMG_NULL) + { + eError = FreeHandleBase(gpsKernelHandleBase); + if (eError == PVRSRV_OK) + { + gpsKernelHandleBase = IMG_NULL; + } + else + { + PVR_DPF((PVR_DBG_ERROR, "PVRSRVHandleDeInit: FreeHandleBase failed (%d)", eError)); + } + } + + return eError; +} +#else +#endif diff --git a/services4/srvkm/common/hash.c b/services4/srvkm/common/hash.c new file mode 100644 index 0000000..3f1f14c --- /dev/null +++ b/services4/srvkm/common/hash.c @@ -0,0 +1,446 @@ +/********************************************************************** + * + * Copyright(c) 2008 Imagination Technologies Ltd. All rights reserved. + * + * This program is free software; you can redistribute it and/or modify it + * under the terms and conditions of the GNU General Public License, + * version 2, as published by the Free Software Foundation. + * + * This program is distributed in the hope it will be useful but, except + * as otherwise stated in writing, without any warranty; without even the + * implied warranty of merchantability or fitness for a particular purpose. + * See the GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License along with + * this program; if not, write to the Free Software Foundation, Inc., + * 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA. + * + * The full GNU General Public License is included in this distribution in + * the file called "COPYING". + * + * Contact Information: + * Imagination Technologies Ltd. + * Home Park Estate, Kings Langley, Herts, WD4 8LZ, UK + * + ******************************************************************************/ + +#include "pvr_debug.h" +#include "img_defs.h" +#include "services.h" +#include "servicesint.h" +#include "hash.h" +#include "osfunc.h" + +#define PRIVATE_MAX(a,b) ((a)>(b)?(a):(b)) + +#define KEY_TO_INDEX(pHash, key, uSize) \ + ((pHash)->pfnHashFunc((pHash)->uKeySize, key, uSize) % uSize) + +#define KEY_COMPARE(pHash, pKey1, pKey2) \ + ((pHash)->pfnKeyComp((pHash)->uKeySize, pKey1, pKey2)) + +struct _BUCKET_ +{ + + struct _BUCKET_ *pNext; + + + IMG_UINTPTR_T v; + + + IMG_UINTPTR_T k[]; +}; +typedef struct _BUCKET_ BUCKET; + +struct _HASH_TABLE_ +{ + + BUCKET **ppBucketTable; + + + IMG_UINT32 uSize; + + + IMG_UINT32 uCount; + + + IMG_UINT32 uMinimumSize; + + + IMG_UINT32 uKeySize; + + + HASH_FUNC *pfnHashFunc; + + + HASH_KEY_COMP *pfnKeyComp; +}; + +IMG_UINT32 +HASH_Func_Default (IMG_SIZE_T uKeySize, IMG_VOID *pKey, IMG_UINT32 uHashTabLen) +{ + IMG_UINTPTR_T *p = (IMG_UINTPTR_T *)pKey; + IMG_UINT32 uKeyLen = uKeySize / sizeof(IMG_UINTPTR_T); + IMG_UINT32 ui; + IMG_UINT32 uHashKey = 0; + + PVR_UNREFERENCED_PARAMETER(uHashTabLen); + + PVR_ASSERT((uKeySize % sizeof(IMG_UINTPTR_T)) == 0); + + for (ui = 0; ui < uKeyLen; ui++) + { + IMG_UINT32 uHashPart = (IMG_UINT32)*p++; + + uHashPart += (uHashPart << 12); + uHashPart ^= (uHashPart >> 22); + uHashPart += (uHashPart << 4); + uHashPart ^= (uHashPart >> 9); + uHashPart += (uHashPart << 10); + uHashPart ^= (uHashPart >> 2); + uHashPart += (uHashPart << 7); + uHashPart ^= (uHashPart >> 12); + + uHashKey += uHashPart; + } + + return uHashKey; +} + +IMG_BOOL +HASH_Key_Comp_Default (IMG_SIZE_T uKeySize, IMG_VOID *pKey1, IMG_VOID *pKey2) +{ + IMG_UINTPTR_T *p1 = (IMG_UINTPTR_T *)pKey1; + IMG_UINTPTR_T *p2 = (IMG_UINTPTR_T *)pKey2; + IMG_UINT32 uKeyLen = uKeySize / sizeof(IMG_UINTPTR_T); + IMG_UINT32 ui; + + PVR_ASSERT((uKeySize % sizeof(IMG_UINTPTR_T)) == 0); + + for (ui = 0; ui < uKeyLen; ui++) + { + if (*p1++ != *p2++) + return IMG_FALSE; + } + + return IMG_TRUE; +} + +static PVRSRV_ERROR +_ChainInsert (HASH_TABLE *pHash, BUCKET *pBucket, BUCKET **ppBucketTable, IMG_UINT32 uSize) +{ + IMG_UINT32 uIndex; + + PVR_ASSERT (pBucket != IMG_NULL); + PVR_ASSERT (ppBucketTable != IMG_NULL); + PVR_ASSERT (uSize != 0); + + if ((pBucket == IMG_NULL) || (ppBucketTable == IMG_NULL) || (uSize == 0)) + { + PVR_DPF((PVR_DBG_ERROR, "_ChainInsert: invalid parameter")); + return PVRSRV_ERROR_INVALID_PARAMS; + } + + uIndex = KEY_TO_INDEX(pHash, pBucket->k, uSize); + pBucket->pNext = ppBucketTable[uIndex]; + ppBucketTable[uIndex] = pBucket; + + return PVRSRV_OK; +} + +static PVRSRV_ERROR +_Rehash (HASH_TABLE *pHash, + BUCKET **ppOldTable, IMG_UINT32 uOldSize, + BUCKET **ppNewTable, IMG_UINT32 uNewSize) +{ + IMG_UINT32 uIndex; + for (uIndex=0; uIndex< uOldSize; uIndex++) + { + BUCKET *pBucket; + pBucket = ppOldTable[uIndex]; + while (pBucket != IMG_NULL) + { + BUCKET *pNextBucket = pBucket->pNext; + if (_ChainInsert (pHash, pBucket, ppNewTable, uNewSize) != PVRSRV_OK) + { + PVR_DPF((PVR_DBG_ERROR, "_Rehash: call to _ChainInsert failed")); + return PVRSRV_ERROR_GENERIC; + } + pBucket = pNextBucket; + } + } + return PVRSRV_OK; +} + +static IMG_BOOL +_Resize (HASH_TABLE *pHash, IMG_UINT32 uNewSize) +{ + if (uNewSize != pHash->uSize) + { + BUCKET **ppNewTable; + IMG_UINT32 uIndex; + + PVR_DPF ((PVR_DBG_MESSAGE, + "HASH_Resize: oldsize=0x%x newsize=0x%x count=0x%x", + pHash->uSize, uNewSize, pHash->uCount)); + + OSAllocMem (PVRSRV_PAGEABLE_SELECT, + sizeof (BUCKET *) * uNewSize, + (IMG_PVOID*)&ppNewTable, IMG_NULL); + if (ppNewTable == IMG_NULL) + return IMG_FALSE; + + for (uIndex=0; uIndexppBucketTable, pHash->uSize, ppNewTable, uNewSize) != PVRSRV_OK) + { + return IMG_FALSE; + } + + OSFreeMem (PVRSRV_PAGEABLE_SELECT, 0, pHash->ppBucketTable, IMG_NULL); + pHash->ppBucketTable = ppNewTable; + pHash->uSize = uNewSize; + } + return IMG_TRUE; +} + + +HASH_TABLE * HASH_Create_Extended (IMG_UINT32 uInitialLen, IMG_SIZE_T uKeySize, HASH_FUNC *pfnHashFunc, HASH_KEY_COMP *pfnKeyComp) +{ + HASH_TABLE *pHash; + IMG_UINT32 uIndex; + + PVR_DPF ((PVR_DBG_MESSAGE, "HASH_Create_Extended: InitialSize=0x%x", uInitialLen)); + + if(OSAllocMem(PVRSRV_PAGEABLE_SELECT, + sizeof(HASH_TABLE), + (IMG_VOID **)&pHash, IMG_NULL) != PVRSRV_OK) + { + return IMG_NULL; + } + + pHash->uCount = 0; + pHash->uSize = uInitialLen; + pHash->uMinimumSize = uInitialLen; + pHash->uKeySize = uKeySize; + pHash->pfnHashFunc = pfnHashFunc; + pHash->pfnKeyComp = pfnKeyComp; + + OSAllocMem (PVRSRV_PAGEABLE_SELECT, + sizeof (BUCKET *) * pHash->uSize, + (IMG_PVOID*)&pHash->ppBucketTable, IMG_NULL); + + if (pHash->ppBucketTable == IMG_NULL) + { + OSFreeMem(PVRSRV_PAGEABLE_SELECT, sizeof(HASH_TABLE), pHash, IMG_NULL); + return IMG_NULL; + } + + for (uIndex=0; uIndexuSize; uIndex++) + pHash->ppBucketTable[uIndex] = IMG_NULL; + return pHash; +} + +HASH_TABLE * HASH_Create (IMG_UINT32 uInitialLen) +{ + return HASH_Create_Extended(uInitialLen, sizeof(IMG_UINTPTR_T), + &HASH_Func_Default, &HASH_Key_Comp_Default); +} + +IMG_VOID +HASH_Delete (HASH_TABLE *pHash) +{ + if (pHash != IMG_NULL) + { + PVR_DPF ((PVR_DBG_MESSAGE, "HASH_Delete")); + + PVR_ASSERT (pHash->uCount==0); + OSFreeMem(PVRSRV_PAGEABLE_SELECT, 0, pHash->ppBucketTable, IMG_NULL); + OSFreeMem(PVRSRV_PAGEABLE_SELECT, sizeof(HASH_TABLE), pHash, IMG_NULL); + } +} + +IMG_BOOL +HASH_Insert_Extended (HASH_TABLE *pHash, IMG_VOID *pKey, IMG_UINTPTR_T v) +{ + BUCKET *pBucket; + + PVR_DPF ((PVR_DBG_MESSAGE, + "HASH_Insert_Extended: Hash=%08X, pKey=%08X, v=0x%x", pHash, pKey, v)); + + PVR_ASSERT (pHash != IMG_NULL); + + if (pHash == IMG_NULL) + { + PVR_DPF((PVR_DBG_ERROR, "HASH_Insert_Extended: invalid parameter")); + return IMG_FALSE; + } + + if(OSAllocMem(PVRSRV_PAGEABLE_SELECT, + sizeof(BUCKET) + pHash->uKeySize, + (IMG_VOID **)&pBucket, IMG_NULL) != PVRSRV_OK) + { + return IMG_FALSE; + } + + pBucket->v = v; + OSMemCopy(pBucket->k, pKey, pHash->uKeySize); + if (_ChainInsert (pHash, pBucket, pHash->ppBucketTable, pHash->uSize) != PVRSRV_OK) + { + return IMG_FALSE; + } + + pHash->uCount++; + + + if (pHash->uCount << 1 > pHash->uSize) + { + + + _Resize (pHash, pHash->uSize << 1); + } + + + return IMG_TRUE; +} + +IMG_BOOL +HASH_Insert (HASH_TABLE *pHash, IMG_UINTPTR_T k, IMG_UINTPTR_T v) +{ + PVR_DPF ((PVR_DBG_MESSAGE, + "HASH_Insert: Hash=%08X, k=0x%x, v=0x%x", pHash, k, v)); + + return HASH_Insert_Extended(pHash, &k, v); +} + +IMG_UINTPTR_T +HASH_Remove_Extended(HASH_TABLE *pHash, IMG_VOID *pKey) +{ + BUCKET **ppBucket; + IMG_UINT32 uIndex; + + PVR_DPF ((PVR_DBG_MESSAGE, "HASH_Remove: Hash=%08X, pKey=%08X", pHash, pKey)); + + PVR_ASSERT (pHash != IMG_NULL); + + if (pHash == IMG_NULL) + { + PVR_DPF((PVR_DBG_ERROR, "FreeResourceByPtr: invalid parameter")); + return 0; + } + + uIndex = KEY_TO_INDEX(pHash, pKey, pHash->uSize); + + for (ppBucket = &(pHash->ppBucketTable[uIndex]); *ppBucket != IMG_NULL; ppBucket = &((*ppBucket)->pNext)) + { + if (KEY_COMPARE(pHash, (*ppBucket)->k, pKey)) + { + BUCKET *pBucket = *ppBucket; + IMG_UINTPTR_T v = pBucket->v; + (*ppBucket) = pBucket->pNext; + + OSFreeMem(PVRSRV_PAGEABLE_SELECT, sizeof(BUCKET) + pHash->uKeySize, pBucket, IMG_NULL); + + pHash->uCount--; + + + if (pHash->uSize > (pHash->uCount << 2) && + pHash->uSize > pHash->uMinimumSize) + { + + + _Resize (pHash, + PRIVATE_MAX (pHash->uSize >> 1, + pHash->uMinimumSize)); + } + + PVR_DPF ((PVR_DBG_MESSAGE, + "HASH_Remove_Extended: Hash=%08X, pKey=%08X = 0x%x", + pHash, pKey, v)); + return v; + } + } + PVR_DPF ((PVR_DBG_MESSAGE, + "HASH_Remove_Extended: Hash=%08X, pKey=%08X = 0x0 !!!!", pHash, pKey)); + return 0; +} + +IMG_UINTPTR_T +HASH_Remove (HASH_TABLE *pHash, IMG_UINTPTR_T k) +{ + PVR_DPF ((PVR_DBG_MESSAGE, "HASH_Remove: Hash=%08X, k=0x%x", pHash, k)); + + return HASH_Remove_Extended(pHash, &k); +} + +IMG_UINTPTR_T +HASH_Retrieve_Extended (HASH_TABLE *pHash, IMG_VOID *pKey) +{ + BUCKET **ppBucket; + IMG_UINT32 uIndex; + + PVR_DPF ((PVR_DBG_MESSAGE, "HASH_Retrieve: Hash=%08X, pKey=%08X", pHash,pKey)); + + PVR_ASSERT (pHash != IMG_NULL); + + if (pHash == IMG_NULL) + { + PVR_DPF((PVR_DBG_ERROR, "HASH_Retrieve_Extended: invalid parameter")); + return 0; + } + + uIndex = KEY_TO_INDEX(pHash, pKey, pHash->uSize); + + for (ppBucket = &(pHash->ppBucketTable[uIndex]); *ppBucket != IMG_NULL; ppBucket = &((*ppBucket)->pNext)) + { + if (KEY_COMPARE(pHash, (*ppBucket)->k, pKey)) + { + BUCKET *pBucket = *ppBucket; + IMG_UINTPTR_T v = pBucket->v; + + PVR_DPF ((PVR_DBG_MESSAGE, + "HASH_Retrieve: Hash=%08X, pKey=%08X = 0x%x", + pHash, pKey, v)); + return v; + } + } + PVR_DPF ((PVR_DBG_MESSAGE, + "HASH_Retrieve: Hash=%08X, pKey=%08X = 0x0 !!!!", pHash, pKey)); + return 0; +} + +IMG_UINTPTR_T +HASH_Retrieve (HASH_TABLE *pHash, IMG_UINTPTR_T k) +{ + PVR_DPF ((PVR_DBG_MESSAGE, "HASH_Retrieve: Hash=%08X, k=0x%x", pHash,k)); + return HASH_Retrieve_Extended(pHash, &k); +} + +#ifdef HASH_TRACE +IMG_VOID +HASH_Dump (HASH_TABLE *pHash) +{ + IMG_UINT32 uIndex; + IMG_UINT32 uMaxLength=0; + IMG_UINT32 uEmptyCount=0; + + PVR_ASSERT (pHash != IMG_NULL); + for (uIndex=0; uIndexuSize; uIndex++) + { + BUCKET *pBucket; + IMG_UINT32 uLength = 0; + if (pHash->ppBucketTable[uIndex] == IMG_NULL) + uEmptyCount++; + for (pBucket=pHash->ppBucketTable[uIndex]; + pBucket != IMG_NULL; + pBucket = pBucket->pNext) + uLength++; + uMaxLength = PRIVATE_MAX (uMaxLength, uLength); + } + + PVR_TRACE(("hash table: uMinimumSize=%d size=%d count=%d", + pHash->uMinimumSize, pHash->uSize, pHash->uCount)); + PVR_TRACE((" empty=%d max=%d", uEmptyCount, uMaxLength)); +} +#endif diff --git a/services4/srvkm/common/mem.c b/services4/srvkm/common/mem.c new file mode 100644 index 0000000..a566518 --- /dev/null +++ b/services4/srvkm/common/mem.c @@ -0,0 +1,158 @@ +/********************************************************************** + * + * Copyright(c) 2008 Imagination Technologies Ltd. All rights reserved. + * + * This program is free software; you can redistribute it and/or modify it + * under the terms and conditions of the GNU General Public License, + * version 2, as published by the Free Software Foundation. + * + * This program is distributed in the hope it will be useful but, except + * as otherwise stated in writing, without any warranty; without even the + * implied warranty of merchantability or fitness for a particular purpose. + * See the GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License along with + * this program; if not, write to the Free Software Foundation, Inc., + * 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA. + * + * The full GNU General Public License is included in this distribution in + * the file called "COPYING". + * + * Contact Information: + * Imagination Technologies Ltd. + * Home Park Estate, Kings Langley, Herts, WD4 8LZ, UK + * + ******************************************************************************/ + +#include "services_headers.h" + +#if defined(SUPPORT_VGX) +#include "vgxapi_km.h" +#endif + +#if defined(SUPPORT_SGX) +#include "sgxapi_km.h" +#endif + +#include "pvr_bridge_km.h" + + +static PVRSRV_ERROR +FreeSharedSysMemCallBack(IMG_PVOID pvParam, + IMG_UINT32 ui32Param) +{ + PVRSRV_KERNEL_MEM_INFO *psKernelMemInfo = pvParam; + + PVR_UNREFERENCED_PARAMETER(ui32Param); + + OSFreePages(psKernelMemInfo->ui32Flags, + psKernelMemInfo->ui32AllocSize, + psKernelMemInfo->pvLinAddrKM, + psKernelMemInfo->sMemBlk.hOSMemHandle); + + OSFreeMem(PVRSRV_OS_PAGEABLE_HEAP, + sizeof(PVRSRV_KERNEL_MEM_INFO), + psKernelMemInfo, + IMG_NULL); + + return PVRSRV_OK; +} + + +IMG_EXPORT PVRSRV_ERROR +PVRSRVAllocSharedSysMemoryKM(PVRSRV_PER_PROCESS_DATA *psPerProc, + IMG_UINT32 ui32Flags, + IMG_UINT32 ui32Size, + PVRSRV_KERNEL_MEM_INFO **ppsKernelMemInfo) +{ + PVRSRV_KERNEL_MEM_INFO *psKernelMemInfo; + + if(OSAllocMem(PVRSRV_OS_PAGEABLE_HEAP, + sizeof(PVRSRV_KERNEL_MEM_INFO), + (IMG_VOID **)&psKernelMemInfo, IMG_NULL) != PVRSRV_OK) + { + PVR_DPF((PVR_DBG_ERROR,"PVRSRVAllocSharedSysMemoryKM: Failed to alloc memory for meminfo")); + return PVRSRV_ERROR_OUT_OF_MEMORY; + } + + OSMemSet(psKernelMemInfo, 0, sizeof(*psKernelMemInfo)); + + ui32Flags &= ~PVRSRV_HAP_MAPTYPE_MASK; + ui32Flags |= PVRSRV_HAP_MULTI_PROCESS; + psKernelMemInfo->ui32Flags = ui32Flags; + psKernelMemInfo->ui32AllocSize = ui32Size; + + if(OSAllocPages(psKernelMemInfo->ui32Flags, + psKernelMemInfo->ui32AllocSize, + HOST_PAGESIZE(), + &psKernelMemInfo->pvLinAddrKM, + &psKernelMemInfo->sMemBlk.hOSMemHandle) + != PVRSRV_OK) + { + PVR_DPF((PVR_DBG_ERROR, "PVRSRVAllocSharedSysMemoryKM: Failed to alloc memory for block")); + OSFreeMem(PVRSRV_OS_PAGEABLE_HEAP, + sizeof(PVRSRV_KERNEL_MEM_INFO), + psKernelMemInfo, + 0); + return PVRSRV_ERROR_OUT_OF_MEMORY; + } + + + psKernelMemInfo->sMemBlk.hResItem = + ResManRegisterRes(psPerProc->hResManContext, + RESMAN_TYPE_SHARED_MEM_INFO, + psKernelMemInfo, + 0, + FreeSharedSysMemCallBack); + + *ppsKernelMemInfo = psKernelMemInfo; + + return PVRSRV_OK; +} + + +IMG_EXPORT PVRSRV_ERROR +PVRSRVFreeSharedSysMemoryKM(PVRSRV_KERNEL_MEM_INFO *psKernelMemInfo) +{ + PVRSRV_ERROR eError; + + if(psKernelMemInfo->sMemBlk.hResItem) + { + eError = ResManFreeResByPtr(psKernelMemInfo->sMemBlk.hResItem); + } + else + { + eError = FreeSharedSysMemCallBack(psKernelMemInfo, 0); + } + + return eError; +} + + +IMG_EXPORT PVRSRV_ERROR +PVRSRVDissociateMemFromResmanKM(PVRSRV_KERNEL_MEM_INFO *psKernelMemInfo) +{ + PVRSRV_ERROR eError = PVRSRV_OK; + + if(!psKernelMemInfo) + { + return PVRSRV_ERROR_INVALID_PARAMS; + } + + if(psKernelMemInfo->sMemBlk.hResItem) + { + eError = ResManDissociateRes(psKernelMemInfo->sMemBlk.hResItem, IMG_NULL); + + if (eError != PVRSRV_OK) + { + PVR_DPF((PVR_DBG_ERROR,"PVRSRVDissociateMemFromResmanKM: ResManDissociateRes failed")); + PVR_DBG_BREAK; + return eError; + } + + psKernelMemInfo->sMemBlk.hResItem = IMG_NULL; + } + + return eError; +} + diff --git a/services4/srvkm/common/metrics.c b/services4/srvkm/common/metrics.c new file mode 100644 index 0000000..ee5cabd --- /dev/null +++ b/services4/srvkm/common/metrics.c @@ -0,0 +1,160 @@ +/********************************************************************** + * + * Copyright(c) 2008 Imagination Technologies Ltd. All rights reserved. + * + * This program is free software; you can redistribute it and/or modify it + * under the terms and conditions of the GNU General Public License, + * version 2, as published by the Free Software Foundation. + * + * This program is distributed in the hope it will be useful but, except + * as otherwise stated in writing, without any warranty; without even the + * implied warranty of merchantability or fitness for a particular purpose. + * See the GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License along with + * this program; if not, write to the Free Software Foundation, Inc., + * 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA. + * + * The full GNU General Public License is included in this distribution in + * the file called "COPYING". + * + * Contact Information: + * Imagination Technologies Ltd. + * Home Park Estate, Kings Langley, Herts, WD4 8LZ, UK + * + ******************************************************************************/ + +#include "services_headers.h" +#include "metrics.h" + +#if defined(SUPPORT_VGX) +#include "vgxapi_km.h" +#endif + +#if defined(SUPPORT_SGX) +#include "sgxapi_km.h" +#endif + +#if defined(DEBUG) || defined(TIMING) + +static volatile IMG_UINT32 *pui32TimerRegister = 0; + +#define PVRSRV_TIMER_TOTAL_IN_TICKS(X) asTimers[X].ui32Total +#define PVRSRV_TIMER_TOTAL_IN_MS(X) ((1000*asTimers[X].ui32Total)/ui32TicksPerMS) +#define PVRSRV_TIMER_COUNT(X) asTimers[X].ui32Count + + +Temporal_Data asTimers[PVRSRV_NUM_TIMERS]; + + +IMG_UINT32 PVRSRVTimeNow(IMG_VOID) +{ + if (!pui32TimerRegister) + { + static IMG_BOOL bFirstTime = IMG_TRUE; + + if (bFirstTime) + { + PVR_DPF((PVR_DBG_ERROR,"PVRSRVTimeNow: No timer register set up")); + + bFirstTime = IMG_FALSE; + } + + return 0; + } + +#if defined(__sh__) + + return (0xffffffff-*pui32TimerRegister); + +#else + + return 0; + +#endif +} + + +static IMG_UINT32 PVRSRVGetCPUFreq(IMG_VOID) +{ + IMG_UINT32 ui32Time1, ui32Time2; + + ui32Time1 = PVRSRVTimeNow(); + + OSWaitus(1000000); + + ui32Time2 = PVRSRVTimeNow(); + + PVR_DPF((PVR_DBG_WARNING, "PVRSRVGetCPUFreq: timer frequency = %d Hz", ui32Time2 - ui32Time1)); + + return (ui32Time2 - ui32Time1); +} + + +IMG_VOID PVRSRVSetupMetricTimers(IMG_VOID *pvDevInfo) +{ + IMG_UINT32 ui32Loop; + + PVR_UNREFERENCED_PARAMETER(pvDevInfo); + + for(ui32Loop=0; ui32Loop < (PVRSRV_NUM_TIMERS); ui32Loop++) + { + asTimers[ui32Loop].ui32Total = 0; + asTimers[ui32Loop].ui32Count = 0; + } + + + #if defined(__sh__) + + + + + + *TCR_2 = TIMER_DIVISOR; + + + *TCOR_2 = *TCNT_2 = (IMG_UINT)0xffffffff; + + + *TST_REG |= (IMG_UINT8)0x04; + + pui32TimerRegister = (IMG_UINT32 *)TCNT_2; + + #else + + pui32TimerRegister = 0; + + #endif + +} + + +IMG_VOID PVRSRVOutputMetricTotals(IMG_VOID) +{ + IMG_UINT32 ui32TicksPerMS, ui32Loop; + + ui32TicksPerMS = PVRSRVGetCPUFreq(); + + if (!ui32TicksPerMS) + { + PVR_DPF((PVR_DBG_ERROR,"PVRSRVOutputMetricTotals: Failed to get CPU Freq")); + return; + } + + for(ui32Loop=0; ui32Loop < (PVRSRV_NUM_TIMERS); ui32Loop++) + { + if (asTimers[ui32Loop].ui32Count & 0x80000000L) + { + PVR_DPF((PVR_DBG_WARNING,"PVRSRVOutputMetricTotals: Timer %u is still ON", ui32Loop)); + } + } +#if 0 + + PVR_DPF((PVR_DBG_ERROR," Timer(%u): Total = %u",PVRSRV_TIMER_EXAMPLE_1, PVRSRV_TIMER_TOTAL_IN_TICKS(PVRSRV_TIMER_EXAMPLE_1))); + PVR_DPF((PVR_DBG_ERROR," Timer(%u): Time = %ums",PVRSRV_TIMER_EXAMPLE_1, PVRSRV_TIMER_TOTAL_IN_MS(PVRSRV_TIMER_EXAMPLE_1))); + PVR_DPF((PVR_DBG_ERROR," Timer(%u): Count = %u",PVRSRV_TIMER_EXAMPLE_1, PVRSRV_TIMER_COUNT(PVRSRV_TIMER_EXAMPLE_1))); +#endif +} + +#endif + diff --git a/services4/srvkm/common/pdump_common.c b/services4/srvkm/common/pdump_common.c new file mode 100644 index 0000000..8dc3798 --- /dev/null +++ b/services4/srvkm/common/pdump_common.c @@ -0,0 +1,294 @@ +/********************************************************************** + * + * Copyright(c) 2008 Imagination Technologies Ltd. All rights reserved. + * + * This program is free software; you can redistribute it and/or modify it + * under the terms and conditions of the GNU General Public License, + * version 2, as published by the Free Software Foundation. + * + * This program is distributed in the hope it will be useful but, except + * as otherwise stated in writing, without any warranty; without even the + * implied warranty of merchantability or fitness for a particular purpose. + * See the GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License along with + * this program; if not, write to the Free Software Foundation, Inc., + * 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA. + * + * The full GNU General Public License is included in this distribution in + * the file called "COPYING". + * + * Contact Information: + * Imagination Technologies Ltd. + * Home Park Estate, Kings Langley, Herts, WD4 8LZ, UK + * + ******************************************************************************/ + +#if defined(PDUMP) +#include "services_headers.h" +#include "pdump_km.h" + +#if !defined(PDUMP_TEMP_BUFFER_SIZE) +#define PDUMP_TEMP_BUFFER_SIZE (64 * 1024L) +#endif + +#define MIN(x, y) (((x) < (y)) ? (x) : (y)) +#define PTR_PLUS(t, p, x) ((t *)(((IMG_CHAR *)(p)) + (x))) +#define VPTR_PLUS(p, x) PTR_PLUS(IMG_VOID, p, x) +#define VPTR_INC(p, x) (p = VPTR_PLUS(p, x)) +#define MAX_PDUMP_MMU_CONTEXTS (10) +static IMG_VOID *gpvTempBuffer = IMG_NULL; +static IMG_HANDLE ghTempBufferBlockAlloc; +static IMG_UINT16 gui16MMUContextUsage = 0; + + + +static IMG_VOID *GetTempBuffer(IMG_VOID) +{ + + if (gpvTempBuffer == IMG_NULL) + { + PVRSRV_ERROR eError = OSAllocMem(PVRSRV_OS_PAGEABLE_HEAP, + PDUMP_TEMP_BUFFER_SIZE, + &gpvTempBuffer, + &ghTempBufferBlockAlloc); + if (eError != PVRSRV_OK) + { + PVR_DPF((PVR_DBG_ERROR, "GetTempBuffer: OSAllocMem failed: %d", eError)); + } + } + + return gpvTempBuffer; +} + +static IMG_VOID FreeTempBuffer(IMG_VOID) +{ + + if (gpvTempBuffer != IMG_NULL) + { + PVRSRV_ERROR eError = OSFreeMem(PVRSRV_OS_PAGEABLE_HEAP, + PDUMP_TEMP_BUFFER_SIZE, + gpvTempBuffer, + ghTempBufferBlockAlloc); + if (eError != PVRSRV_OK) + { + PVR_DPF((PVR_DBG_ERROR, "FreeTempBuffer: OSFreeMem failed: %d", eError)); + } + else + { + gpvTempBuffer = IMG_NULL; + } + } +} + +IMG_VOID PDumpInitCommon(IMG_VOID) +{ + + (IMG_VOID) GetTempBuffer(); + + + PDumpInit(); +} + +IMG_VOID PDumpDeInitCommon(IMG_VOID) +{ + + FreeTempBuffer(); + + + PDumpDeInit(); +} + +PVRSRV_ERROR PDumpMemUM(PVRSRV_PER_PROCESS_DATA *psPerProc, + IMG_PVOID pvAltLinAddrUM, + IMG_PVOID pvLinAddrUM, + PVRSRV_KERNEL_MEM_INFO *psMemInfo, + IMG_UINT32 ui32Offset, + IMG_UINT32 ui32Bytes, + IMG_UINT32 ui32Flags, + IMG_HANDLE hUniqueTag) +{ + IMG_VOID *pvAddrUM; + IMG_VOID *pvAddrKM; + IMG_UINT32 ui32BytesDumped; + IMG_UINT32 ui32CurrentOffset; + + if (psMemInfo->pvLinAddrKM != IMG_NULL && pvAltLinAddrUM == IMG_NULL) + { + + return PDumpMemKM(IMG_NULL, + psMemInfo, + ui32Offset, + ui32Bytes, + ui32Flags, + hUniqueTag); + } + + pvAddrUM = (pvAltLinAddrUM != IMG_NULL) ? pvAltLinAddrUM : ((pvLinAddrUM != IMG_NULL) ? VPTR_PLUS(pvLinAddrUM, ui32Offset) : IMG_NULL); + + pvAddrKM = GetTempBuffer(); + + + PVR_ASSERT(pvAddrUM != IMG_NULL && pvAddrKM != IMG_NULL); + if (pvAddrUM == IMG_NULL || pvAddrKM == IMG_NULL) + { + PVR_DPF((PVR_DBG_ERROR, "PDumpMemUM: Nothing to dump")); + return PVRSRV_ERROR_GENERIC; + } + + if (ui32Bytes > PDUMP_TEMP_BUFFER_SIZE) + { + PDumpCommentWithFlags(ui32Flags, "Dumping 0x%8.8lx bytes of memory, in blocks of 0x%8.8lx bytes", ui32Bytes, (IMG_UINT32)PDUMP_TEMP_BUFFER_SIZE); + } + + ui32CurrentOffset = ui32Offset; + for (ui32BytesDumped = 0; ui32BytesDumped < ui32Bytes;) + { + PVRSRV_ERROR eError; + IMG_UINT32 ui32BytesToDump = MIN(PDUMP_TEMP_BUFFER_SIZE, ui32Bytes - ui32BytesDumped); + + eError = OSCopyFromUser(psPerProc, + pvAddrKM, + pvAddrUM, + ui32BytesToDump); + if (eError != PVRSRV_OK) + { + PVR_DPF((PVR_DBG_ERROR, "PDumpMemUM: OSCopyFromUser failed (%d), eError")); + return PVRSRV_ERROR_GENERIC; + } + + eError = PDumpMemKM(pvAddrKM, + psMemInfo, + ui32CurrentOffset, + ui32BytesToDump, + ui32Flags, + hUniqueTag); + + if (eError != PVRSRV_OK) + { + + if (ui32BytesDumped != 0) + { + PVR_DPF((PVR_DBG_ERROR, "PDumpMemUM: PDumpMemKM failed (%d)", eError)); + } + PVR_ASSERT(ui32BytesDumped == 0); + return eError; + } + + VPTR_INC(pvAddrUM, ui32BytesToDump); + ui32CurrentOffset += ui32BytesToDump; + ui32BytesDumped += ui32BytesToDump; + } + + return PVRSRV_OK; +} + + +static PVRSRV_ERROR _PdumpAllocMMUContext(IMG_UINT32 *pui32MMUContextID) +{ + IMG_UINT32 i; + + + for(i=0; i + * Home Park Estate, Kings Langley, Herts, WD4 8LZ, UK + * + ******************************************************************************/ + +#include "services_headers.h" +#include "resman.h" +#include "handle.h" +#include "perproc.h" +#include "osperproc.h" + +#define HASH_TAB_INIT_SIZE 32 + +static HASH_TABLE *psHashTab = IMG_NULL; + +static PVRSRV_ERROR FreePerProcessData(PVRSRV_PER_PROCESS_DATA *psPerProc) +{ + PVRSRV_ERROR eError; + IMG_UINTPTR_T uiPerProc; + + PVR_ASSERT(psPerProc != IMG_NULL); + + if (psPerProc == IMG_NULL) + { + PVR_DPF((PVR_DBG_ERROR, "FreePerProcessData: invalid parameter")); + return PVRSRV_ERROR_INVALID_PARAMS; + } + + uiPerProc = HASH_Remove(psHashTab, (IMG_UINTPTR_T)psPerProc->ui32PID); + if (uiPerProc == 0) + { + PVR_DPF((PVR_DBG_ERROR, "FreePerProcessData: Couldn't find process in per-process data hash table")); + + PVR_ASSERT(psPerProc->ui32PID == 0); + } + else + { + PVR_ASSERT((PVRSRV_PER_PROCESS_DATA *)uiPerProc == psPerProc); + PVR_ASSERT(((PVRSRV_PER_PROCESS_DATA *)uiPerProc)->ui32PID == psPerProc->ui32PID); + } + + + if (psPerProc->psHandleBase != IMG_NULL) + { + eError = PVRSRVFreeHandleBase(psPerProc->psHandleBase); + if (eError != PVRSRV_OK) + { + PVR_DPF((PVR_DBG_ERROR, "FreePerProcessData: Couldn't free handle base for process (%d)", eError)); + return eError; + } + } + + + if (psPerProc->hPerProcData != IMG_NULL) + { + eError = PVRSRVReleaseHandle(KERNEL_HANDLE_BASE, psPerProc->hPerProcData, PVRSRV_HANDLE_TYPE_PERPROC_DATA); + + if (eError != PVRSRV_OK) + { + PVR_DPF((PVR_DBG_ERROR, "FreePerProcessData: Couldn't release per-process data handle (%d)", eError)); + return eError; + } + } + + + eError = OSPerProcessPrivateDataDeInit(psPerProc->hOsPrivateData); + if (eError != PVRSRV_OK) + { + PVR_DPF((PVR_DBG_ERROR, "FreePerProcessData: OSPerProcessPrivateDataDeInit failed (%d)", eError)); + return eError; + } + + eError = OSFreeMem(PVRSRV_OS_NON_PAGEABLE_HEAP, + sizeof(*psPerProc), + psPerProc, + psPerProc->hBlockAlloc); + if (eError != PVRSRV_OK) + { + PVR_DPF((PVR_DBG_ERROR, "FreePerProcessData: Couldn't free per-process data (%d)", eError)); + return eError; + } + + return PVRSRV_OK; +} + + +PVRSRV_PER_PROCESS_DATA *PVRSRVPerProcessData(IMG_UINT32 ui32PID) +{ + PVRSRV_PER_PROCESS_DATA *psPerProc; + + PVR_ASSERT(psHashTab != IMG_NULL); + + + psPerProc = (PVRSRV_PER_PROCESS_DATA *)HASH_Retrieve(psHashTab, (IMG_UINTPTR_T)ui32PID); + return psPerProc; +} + + +PVRSRV_ERROR PVRSRVPerProcessDataConnect(IMG_UINT32 ui32PID) +{ + PVRSRV_PER_PROCESS_DATA *psPerProc; + IMG_HANDLE hBlockAlloc; + PVRSRV_ERROR eError = PVRSRV_OK; + + PVR_ASSERT(psHashTab != IMG_NULL); + + + psPerProc = (PVRSRV_PER_PROCESS_DATA *)HASH_Retrieve(psHashTab, (IMG_UINTPTR_T)ui32PID); + + if (psPerProc == IMG_NULL) + { + + eError = OSAllocMem(PVRSRV_OS_NON_PAGEABLE_HEAP, + sizeof(*psPerProc), + (IMG_PVOID *)&psPerProc, + &hBlockAlloc); + if (eError != PVRSRV_OK) + { + PVR_DPF((PVR_DBG_ERROR, "PVRSRVPerProcessDataConnect: Couldn't allocate per-process data (%d)", eError)); + return eError; + } + OSMemSet(psPerProc, 0, sizeof(*psPerProc)); + psPerProc->hBlockAlloc = hBlockAlloc; + + if (!HASH_Insert(psHashTab, (IMG_UINTPTR_T)ui32PID, (IMG_UINTPTR_T)psPerProc)) + { + PVR_DPF((PVR_DBG_ERROR, "PVRSRVPerProcessDataConnect: Couldn't insert per-process data into hash table")); + eError = PVRSRV_ERROR_GENERIC; + goto failure; + } + + psPerProc->ui32PID = ui32PID; + psPerProc->ui32RefCount = 0; + + + eError = OSPerProcessPrivateDataInit(&psPerProc->hOsPrivateData); + if (eError != PVRSRV_OK) + { + PVR_DPF((PVR_DBG_ERROR, "PVRSRVPerProcessDataConnect: OSPerProcessPrivateDataInit failed (%d)", eError)); + goto failure; + } + + + eError = PVRSRVAllocHandle(KERNEL_HANDLE_BASE, + &psPerProc->hPerProcData, + psPerProc, + PVRSRV_HANDLE_TYPE_PERPROC_DATA, + PVRSRV_HANDLE_ALLOC_FLAG_NONE); + if (eError != PVRSRV_OK) + { + PVR_DPF((PVR_DBG_ERROR, "PVRSRVPerProcessDataConnect: Couldn't allocate handle for per-process data (%d)", eError)); + goto failure; + } + + + eError = PVRSRVAllocHandleBase(&psPerProc->psHandleBase); + if (eError != PVRSRV_OK) + { + PVR_DPF((PVR_DBG_ERROR, "PVRSRVPerProcessDataConnect: Couldn't allocate handle base for process (%d)", eError)); + goto failure; + } + + + eError = OSPerProcessSetHandleOptions(psPerProc->psHandleBase); + if (eError != PVRSRV_OK) + { + PVR_DPF((PVR_DBG_ERROR, "PVRSRVPerProcessDataConnect: Couldn't set handle options (%d)", eError)); + goto failure; + } + + + eError = PVRSRVResManConnect(psPerProc, &psPerProc->hResManContext); + if (eError != PVRSRV_OK) + { + PVR_DPF((PVR_DBG_ERROR, "PVRSRVPerProcessDataConnect: Couldn't register with the resource manager")); + goto failure; + } + } + + psPerProc->ui32RefCount++; + PVR_DPF((PVR_DBG_MESSAGE, + "PVRSRVPerProcessDataConnect: Process 0x%x has ref-count %d", + ui32PID, psPerProc->ui32RefCount)); + + return eError; + +failure: + (IMG_VOID)FreePerProcessData(psPerProc); + return eError; +} + + +IMG_VOID PVRSRVPerProcessDataDisconnect(IMG_UINT32 ui32PID) +{ + PVRSRV_ERROR eError; + PVRSRV_PER_PROCESS_DATA *psPerProc; + + PVR_ASSERT(psHashTab != IMG_NULL); + + psPerProc = (PVRSRV_PER_PROCESS_DATA *)HASH_Retrieve(psHashTab, (IMG_UINTPTR_T)ui32PID); + if (psPerProc == IMG_NULL) + { + PVR_DPF((PVR_DBG_ERROR, "PVRSRVPerProcessDataDealloc: Couldn't locate per-process data for PID %u", ui32PID)); + } + else + { + psPerProc->ui32RefCount--; + if (psPerProc->ui32RefCount == 0) + { + PVR_DPF((PVR_DBG_MESSAGE, "PVRSRVPerProcessDataDisconnect: " + "Last close from process 0x%x received", ui32PID)); + + + PVRSRVResManDisconnect(psPerProc->hResManContext, IMG_FALSE); + + + eError = FreePerProcessData(psPerProc); + if (eError != PVRSRV_OK) + { + PVR_DPF((PVR_DBG_ERROR, "PVRSRVPerProcessDataDisconnect: Error freeing per-process data")); + } + } + } + + eError = PVRSRVPurgeHandles(KERNEL_HANDLE_BASE); + if (eError != PVRSRV_OK) + { + PVR_DPF((PVR_DBG_ERROR, "PVRSRVPerProcessDataDisconnect: Purge of global handle pool failed (%d)", eError)); + } +} + + +PVRSRV_ERROR PVRSRVPerProcessDataInit(IMG_VOID) +{ + PVR_ASSERT(psHashTab == IMG_NULL); + + + psHashTab = HASH_Create(HASH_TAB_INIT_SIZE); + if (psHashTab == IMG_NULL) + { + PVR_DPF((PVR_DBG_ERROR, "PVRSRVPerProcessDataInit: Couldn't create per-process data hash table")); + return PVRSRV_ERROR_GENERIC; + } + + return PVRSRV_OK; +} + +PVRSRV_ERROR PVRSRVPerProcessDataDeInit(IMG_VOID) +{ + + if (psHashTab != IMG_NULL) + { + + HASH_Delete(psHashTab); + psHashTab = IMG_NULL; + } + + return PVRSRV_OK; +} + diff --git a/services4/srvkm/common/power.c b/services4/srvkm/common/power.c new file mode 100644 index 0000000..9bfa624 --- /dev/null +++ b/services4/srvkm/common/power.c @@ -0,0 +1,790 @@ +/********************************************************************** + * + * Copyright(c) 2008 Imagination Technologies Ltd. All rights reserved. + * + * This program is free software; you can redistribute it and/or modify it + * under the terms and conditions of the GNU General Public License, + * version 2, as published by the Free Software Foundation. + * + * This program is distributed in the hope it will be useful but, except + * as otherwise stated in writing, without any warranty; without even the + * implied warranty of merchantability or fitness for a particular purpose. + * See the GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License along with + * this program; if not, write to the Free Software Foundation, Inc., + * 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA. + * + * The full GNU General Public License is included in this distribution in + * the file called "COPYING". + * + * Contact Information: + * Imagination Technologies Ltd. + * Home Park Estate, Kings Langley, Herts, WD4 8LZ, UK + * + ******************************************************************************/ + +#include "services_headers.h" +#include "pdump_km.h" + +static IMG_BOOL gbInitServerRunning = IMG_FALSE; +static IMG_BOOL gbInitServerRan = IMG_FALSE; +static IMG_BOOL gbInitSuccessful = IMG_FALSE; + +IMG_EXPORT +PVRSRV_ERROR PVRSRVSetInitServerState(PVRSRV_INIT_SERVER_STATE eInitServerState, IMG_BOOL bState) +{ + + switch(eInitServerState) + { + case PVRSRV_INIT_SERVER_RUNNING: + gbInitServerRunning = bState; + break; + case PVRSRV_INIT_SERVER_RAN: + gbInitServerRan = bState; + break; + case PVRSRV_INIT_SERVER_SUCCESSFUL: + gbInitSuccessful = bState; + break; + default: + PVR_DPF((PVR_DBG_ERROR, + "PVRSRVSetInitServerState : Unknown state %lx", eInitServerState)); + return PVRSRV_ERROR_GENERIC; + } + + return PVRSRV_OK; +} + +IMG_EXPORT +IMG_BOOL PVRSRVGetInitServerState(PVRSRV_INIT_SERVER_STATE eInitServerState) +{ + IMG_BOOL bReturnVal; + + switch(eInitServerState) + { + case PVRSRV_INIT_SERVER_RUNNING: + bReturnVal = gbInitServerRunning; + break; + case PVRSRV_INIT_SERVER_RAN: + bReturnVal = gbInitServerRan; + break; + case PVRSRV_INIT_SERVER_SUCCESSFUL: + bReturnVal = gbInitSuccessful; + break; + default: + PVR_DPF((PVR_DBG_ERROR, + "PVRSRVGetInitServerState : Unknown state %lx", eInitServerState)); + bReturnVal = IMG_FALSE; + } + + return bReturnVal; +} + +static IMG_BOOL _IsSystemStatePowered(PVR_POWER_STATE eSystemPowerState) +{ + return (IMG_BOOL)(eSystemPowerState < PVRSRV_POWER_STATE_D2); +} + + +IMG_EXPORT +PVRSRV_ERROR PVRSRVPowerLock(IMG_UINT32 ui32CallerID, + IMG_BOOL bSystemPowerEvent) +{ + PVRSRV_ERROR eError; + SYS_DATA *psSysData; + IMG_UINT32 ui32Timeout = 1000000; + +#if defined(SUPPORT_LMA) + + ui32Timeout *= 60; +#endif + + eError = SysAcquireData(&psSysData); + if(eError != PVRSRV_OK) + { + return eError; + } + +#if defined(SYS_CUSTOM_POWERLOCK_WRAP) + eError = SysPowerLockWrap(psSysData); + if (eError != PVRSRV_OK) + { + return eError; + } +#endif + do + { + eError = OSLockResource(&psSysData->sPowerStateChangeResource, + ui32CallerID); + if (eError == PVRSRV_OK) + { + break; + } + else if (ui32CallerID == ISR_ID) + { + + + eError = PVRSRV_ERROR_RETRY; + break; + } + + OSWaitus(1); + ui32Timeout--; + } while (ui32Timeout > 0); + +#if defined(SYS_CUSTOM_POWERLOCK_WRAP) + if (eError != PVRSRV_OK) + { + SysPowerLockUnwrap(psSysData); + } +#endif + if ((eError == PVRSRV_OK) && + !bSystemPowerEvent && + !_IsSystemStatePowered(psSysData->eCurrentPowerState)) + { + + PVRSRVPowerUnlock(ui32CallerID); + eError = PVRSRV_ERROR_RETRY; + } + + return eError; +} + + +IMG_EXPORT +IMG_VOID PVRSRVPowerUnlock(IMG_UINT32 ui32CallerID) +{ + OSUnlockResource(&gpsSysData->sPowerStateChangeResource, ui32CallerID); +#if defined(SYS_CUSTOM_POWERLOCK_WRAP) + SysPowerLockUnwrap(gpsSysData); +#endif +} + + +static +PVRSRV_ERROR PVRSRVDevicePrePowerStateKM(IMG_BOOL bAllDevices, + IMG_UINT32 ui32DeviceIndex, + PVR_POWER_STATE eNewPowerState) +{ + PVRSRV_ERROR eError; + SYS_DATA *psSysData; + PVRSRV_POWER_DEV *psPowerDevice; + PVR_POWER_STATE eNewDevicePowerState; + + eError = SysAcquireData(&psSysData); + if (eError != PVRSRV_OK) + { + return eError; + } + + + psPowerDevice = psSysData->psPowerDeviceList; + while (psPowerDevice) + { + if (bAllDevices || (ui32DeviceIndex == psPowerDevice->ui32DeviceIndex)) + { + eNewDevicePowerState = (eNewPowerState == PVRSRV_POWER_Unspecified) ? + psPowerDevice->eDefaultPowerState : eNewPowerState; + + if (psPowerDevice->eCurrentPowerState != eNewDevicePowerState) + { + if (psPowerDevice->pfnPrePower != IMG_NULL) + { + + eError = psPowerDevice->pfnPrePower(psPowerDevice->hDevCookie, + eNewDevicePowerState, + psPowerDevice->eCurrentPowerState); + if (eError != PVRSRV_OK) + { + return eError; + } + } + + + eError = SysDevicePrePowerState(psPowerDevice->ui32DeviceIndex, + eNewDevicePowerState, + psPowerDevice->eCurrentPowerState); + if (eError != PVRSRV_OK) + { + return eError; + } + } + } + + psPowerDevice = psPowerDevice->psNext; + } + + return PVRSRV_OK; +} + + +static +PVRSRV_ERROR PVRSRVDevicePostPowerStateKM(IMG_BOOL bAllDevices, + IMG_UINT32 ui32DeviceIndex, + PVR_POWER_STATE eNewPowerState) +{ + PVRSRV_ERROR eError; + SYS_DATA *psSysData; + PVRSRV_POWER_DEV *psPowerDevice; + PVR_POWER_STATE eNewDevicePowerState; + + eError = SysAcquireData(&psSysData); + if (eError != PVRSRV_OK) + { + return eError; + } + + + psPowerDevice = psSysData->psPowerDeviceList; + while (psPowerDevice) + { + if (bAllDevices || (ui32DeviceIndex == psPowerDevice->ui32DeviceIndex)) + { + eNewDevicePowerState = (eNewPowerState == PVRSRV_POWER_Unspecified) ? + psPowerDevice->eDefaultPowerState : eNewPowerState; + + if (psPowerDevice->eCurrentPowerState != eNewDevicePowerState) + { + + eError = SysDevicePostPowerState(psPowerDevice->ui32DeviceIndex, + eNewDevicePowerState, + psPowerDevice->eCurrentPowerState); + if (eError != PVRSRV_OK) + { + return eError; + } + + if (psPowerDevice->pfnPostPower != IMG_NULL) + { + + eError = psPowerDevice->pfnPostPower(psPowerDevice->hDevCookie, + eNewDevicePowerState, + psPowerDevice->eCurrentPowerState); + if (eError != PVRSRV_OK) + { + return eError; + } + } + + psPowerDevice->eCurrentPowerState = eNewDevicePowerState; + } + } + + psPowerDevice = psPowerDevice->psNext; + } + + return PVRSRV_OK; +} + + +PVRSRV_ERROR PVRSRVSetDevicePowerStateCoreKM(IMG_UINT32 ui32DeviceIndex, + PVR_POWER_STATE eNewPowerState) +{ + PVRSRV_ERROR eError; + eError = PVRSRVDevicePrePowerStateKM(IMG_FALSE, ui32DeviceIndex, eNewPowerState); + if(eError != PVRSRV_OK) + { + return eError; + } + + eError = PVRSRVDevicePostPowerStateKM(IMG_FALSE, ui32DeviceIndex, eNewPowerState); + return eError; +} + + +IMG_EXPORT +PVRSRV_ERROR PVRSRVSetDevicePowerStateKM(IMG_UINT32 ui32DeviceIndex, + PVR_POWER_STATE eNewPowerState, + IMG_UINT32 ui32CallerID, + IMG_BOOL bRetainMutex) +{ + PVRSRV_ERROR eError; + SYS_DATA *psSysData; + + eError = SysAcquireData(&psSysData); + if (eError != PVRSRV_OK) + { + return eError; + } + + eError = PVRSRVPowerLock(ui32CallerID, IMG_FALSE); + if(eError != PVRSRV_OK) + { + return eError; + } + + #if defined(PDUMP) + if (eNewPowerState == PVRSRV_POWER_Unspecified) + { + + + + + eError = PVRSRVDevicePrePowerStateKM(IMG_FALSE, ui32DeviceIndex, PVRSRV_POWER_STATE_D0); + if(eError != PVRSRV_OK) + { + goto Exit; + } + + eError = PVRSRVDevicePostPowerStateKM(IMG_FALSE, ui32DeviceIndex, PVRSRV_POWER_STATE_D0); + + if (eError != PVRSRV_OK) + { + goto Exit; + } + + PDUMPSUSPEND(); + } + #endif + + eError = PVRSRVDevicePrePowerStateKM(IMG_FALSE, ui32DeviceIndex, eNewPowerState); + if(eError != PVRSRV_OK) + { + if (eNewPowerState == PVRSRV_POWER_Unspecified) + { + PDUMPRESUME(); + } + goto Exit; + } + + eError = PVRSRVDevicePostPowerStateKM(IMG_FALSE, ui32DeviceIndex, eNewPowerState); + + if (eNewPowerState == PVRSRV_POWER_Unspecified) + { + PDUMPRESUME(); + } + +Exit: + + if(eError != PVRSRV_OK) + { + PVR_DPF((PVR_DBG_ERROR, + "PVRSRVSetDevicePowerStateKM : Transition to %d FAILED 0x%x", eNewPowerState, eError)); + } + + if (!bRetainMutex || (eError != PVRSRV_OK)) + { + PVRSRVPowerUnlock(ui32CallerID); + } + + return eError; +} + + +IMG_EXPORT +PVRSRV_ERROR PVRSRVSystemPrePowerStateKM(PVR_POWER_STATE eNewPowerState) +{ + PVRSRV_ERROR eError; + SYS_DATA *psSysData; + PVR_POWER_STATE eNewDevicePowerState; + + eError = SysAcquireData(&psSysData); + if (eError != PVRSRV_OK) + { + return eError; + } + + + eError = PVRSRVPowerLock(KERNEL_ID, IMG_TRUE); + if(eError != PVRSRV_OK) + { + return eError; + } + + if (_IsSystemStatePowered(eNewPowerState) != + _IsSystemStatePowered(psSysData->eCurrentPowerState)) + { + if (_IsSystemStatePowered(eNewPowerState)) + { + + eNewDevicePowerState = PVRSRV_POWER_Unspecified; + } + else + { + eNewDevicePowerState = PVRSRV_POWER_STATE_D3; + } + + + eError = PVRSRVDevicePrePowerStateKM(IMG_TRUE, 0, eNewDevicePowerState); + if (eError != PVRSRV_OK) + { + goto ErrorExit; + } + } + + if (eNewPowerState != psSysData->eCurrentPowerState) + { + + eError = SysSystemPrePowerState(eNewPowerState); + if (eError != PVRSRV_OK) + { + goto ErrorExit; + } + } + + return eError; + +ErrorExit: + + PVR_DPF((PVR_DBG_ERROR, + "PVRSRVSystemPrePowerStateKM: Transition from %d to %d FAILED 0x%x", + psSysData->eCurrentPowerState, eNewPowerState, eError)); + + + psSysData->eFailedPowerState = eNewPowerState; + + PVRSRVPowerUnlock(KERNEL_ID); + + return eError; +} + + +IMG_EXPORT +PVRSRV_ERROR PVRSRVSystemPostPowerStateKM(PVR_POWER_STATE eNewPowerState) +{ + PVRSRV_ERROR eError; + SYS_DATA *psSysData; + PVR_POWER_STATE eNewDevicePowerState; + + eError = SysAcquireData(&psSysData); + if (eError != PVRSRV_OK) + { + goto Exit; + } + + if (eNewPowerState != psSysData->eCurrentPowerState) + { + + eError = SysSystemPostPowerState(eNewPowerState); + if (eError != PVRSRV_OK) + { + goto Exit; + } + } + + if (_IsSystemStatePowered(eNewPowerState) != + _IsSystemStatePowered(psSysData->eCurrentPowerState)) + { + if (_IsSystemStatePowered(eNewPowerState)) + { + + eNewDevicePowerState = PVRSRV_POWER_Unspecified; + } + else + { + eNewDevicePowerState = PVRSRV_POWER_STATE_D3; + } + + + eError = PVRSRVDevicePostPowerStateKM(IMG_TRUE, 0, eNewDevicePowerState); + if (eError != PVRSRV_OK) + { + goto Exit; + } + } + + PVR_DPF((PVR_DBG_WARNING, + "PVRSRVSystemPostPowerStateKM: System Power Transition from %d to %d OK", + psSysData->eCurrentPowerState, eNewPowerState)); + + psSysData->eCurrentPowerState = eNewPowerState; + +Exit: + + PVRSRVPowerUnlock(KERNEL_ID); + + if (_IsSystemStatePowered(eNewPowerState) && + PVRSRVGetInitServerState(PVRSRV_INIT_SERVER_SUCCESSFUL)) + { + + + + PVRSRVCommandCompleteCallbacks(); + } + + return eError; +} + + +IMG_EXPORT +PVRSRV_ERROR PVRSRVSetPowerStateKM(PVR_POWER_STATE eNewPowerState) +{ + PVRSRV_ERROR eError; + SYS_DATA *psSysData; + + eError = SysAcquireData(&psSysData); + if(eError != PVRSRV_OK) + { + return eError; + } + + eError = PVRSRVSystemPrePowerStateKM(eNewPowerState); + if(eError != PVRSRV_OK) + { + goto ErrorExit; + } + + eError = PVRSRVSystemPostPowerStateKM(eNewPowerState); + if(eError != PVRSRV_OK) + { + goto ErrorExit; + } + + + psSysData->eFailedPowerState = PVRSRV_POWER_Unspecified; + + return PVRSRV_OK; + +ErrorExit: + + PVR_DPF((PVR_DBG_ERROR, + "PVRSRVSetPowerStateKM: Transition from %d to %d FAILED 0x%x", + psSysData->eCurrentPowerState, eNewPowerState, eError)); + + + psSysData->eFailedPowerState = eNewPowerState; + + return eError; +} + + +PVRSRV_ERROR PVRSRVRegisterPowerDevice(IMG_UINT32 ui32DeviceIndex, + PFN_PRE_POWER pfnPrePower, + PFN_POST_POWER pfnPostPower, + PFN_PRE_CLOCKSPEED_CHANGE pfnPreClockSpeedChange, + PFN_POST_CLOCKSPEED_CHANGE pfnPostClockSpeedChange, + IMG_HANDLE hDevCookie, + PVR_POWER_STATE eCurrentPowerState, + PVR_POWER_STATE eDefaultPowerState) +{ + PVRSRV_ERROR eError; + SYS_DATA *psSysData; + PVRSRV_POWER_DEV *psPowerDevice; + + if (pfnPrePower == IMG_NULL && + pfnPostPower == IMG_NULL) + { + return PVRSRVRemovePowerDevice(ui32DeviceIndex); + } + + eError = SysAcquireData(&psSysData); + if(eError != PVRSRV_OK) + { + return eError; + } + + eError = OSAllocMem( PVRSRV_OS_PAGEABLE_HEAP, + sizeof(PVRSRV_POWER_DEV), + (IMG_VOID **)&psPowerDevice, IMG_NULL); + if(eError != PVRSRV_OK) + { + PVR_DPF((PVR_DBG_ERROR,"PVRSRVRegisterPowerDevice: Failed to alloc PVRSRV_POWER_DEV")); + return eError; + } + + + psPowerDevice->pfnPrePower = pfnPrePower; + psPowerDevice->pfnPostPower = pfnPostPower; + psPowerDevice->pfnPreClockSpeedChange = pfnPreClockSpeedChange; + psPowerDevice->pfnPostClockSpeedChange = pfnPostClockSpeedChange; + psPowerDevice->hDevCookie = hDevCookie; + psPowerDevice->ui32DeviceIndex = ui32DeviceIndex; + psPowerDevice->eCurrentPowerState = eCurrentPowerState; + psPowerDevice->eDefaultPowerState = eDefaultPowerState; + + + psPowerDevice->psNext = psSysData->psPowerDeviceList; + psSysData->psPowerDeviceList = psPowerDevice; + + return (PVRSRV_OK); +} + + +PVRSRV_ERROR PVRSRVRemovePowerDevice (IMG_UINT32 ui32DeviceIndex) +{ + PVRSRV_ERROR eError; + SYS_DATA *psSysData; + PVRSRV_POWER_DEV *psCurrent, *psPrevious; + + eError = SysAcquireData(&psSysData); + if(eError != PVRSRV_OK) + { + return eError; + } + + + psCurrent = psSysData->psPowerDeviceList; + psPrevious = IMG_NULL; + + while (psCurrent) + { + if (psCurrent->ui32DeviceIndex == ui32DeviceIndex) + { + + if (psPrevious) + { + psPrevious->psNext = psCurrent->psNext; + } + else + { + + psSysData->psPowerDeviceList = psCurrent->psNext; + } + + OSFreeMem(PVRSRV_OS_PAGEABLE_HEAP, sizeof(PVRSRV_POWER_DEV), psCurrent, IMG_NULL); + + break; + } + else + { + psPrevious = psCurrent; + psCurrent = psCurrent->psNext; + } + } + + return (PVRSRV_OK); +} + + +IMG_EXPORT +IMG_BOOL PVRSRVIsDevicePowered(IMG_UINT32 ui32DeviceIndex) +{ + PVRSRV_ERROR eError; + SYS_DATA *psSysData; + PVRSRV_POWER_DEV *psPowerDevice; + + eError = SysAcquireData(&psSysData); + if (eError != PVRSRV_OK) + { + return IMG_FALSE; + } + + if (OSIsResourceLocked(&psSysData->sPowerStateChangeResource, KERNEL_ID) || + OSIsResourceLocked(&psSysData->sPowerStateChangeResource, ISR_ID)) + { + return IMG_FALSE; + } + + psPowerDevice = psSysData->psPowerDeviceList; + while (psPowerDevice) + { + if (psPowerDevice->ui32DeviceIndex == ui32DeviceIndex) + { + return (IMG_BOOL)(psPowerDevice->eCurrentPowerState == PVRSRV_POWER_STATE_D0); + } + + psPowerDevice = psPowerDevice->psNext; + } + + + return IMG_FALSE; +} + + +PVRSRV_ERROR PVRSRVDevicePreClockSpeedChange(IMG_UINT32 ui32DeviceIndex, + IMG_BOOL bIdleDevice, + IMG_VOID *pvInfo) +{ + PVRSRV_ERROR eError = PVRSRV_OK; + SYS_DATA *psSysData; + PVRSRV_POWER_DEV *psPowerDevice; + + PVR_UNREFERENCED_PARAMETER(pvInfo); + + eError = SysAcquireData(&psSysData); + if(eError != PVRSRV_OK) + { + return eError; + } + + + if (bIdleDevice) + { + + eError = PVRSRVPowerLock(KERNEL_ID, IMG_FALSE); + if (eError != PVRSRV_OK) + { + PVR_DPF((PVR_DBG_ERROR, "PVRSRVDevicePreClockSpeedChange : failed to acquire lock, error:0x%lx", eError)); + return eError; + } + } + + + psPowerDevice = psSysData->psPowerDeviceList; + while (psPowerDevice) + { + if (ui32DeviceIndex == psPowerDevice->ui32DeviceIndex) + { + if (psPowerDevice->pfnPreClockSpeedChange) + { + eError = psPowerDevice->pfnPreClockSpeedChange(psPowerDevice->hDevCookie, + bIdleDevice, + psPowerDevice->eCurrentPowerState); + if (eError != PVRSRV_OK) + { + PVR_DPF((PVR_DBG_ERROR, + "PVRSRVDevicePreClockSpeedChange : Device %lu failed, error:0x%lx", + ui32DeviceIndex, eError)); + break; + } + } + } + + psPowerDevice = psPowerDevice->psNext; + } + + if (bIdleDevice && eError != PVRSRV_OK) + { + PVRSRVPowerUnlock(KERNEL_ID); + } + + return eError; +} + + +IMG_VOID PVRSRVDevicePostClockSpeedChange(IMG_UINT32 ui32DeviceIndex, + IMG_BOOL bIdleDevice, + IMG_VOID *pvInfo) +{ + PVRSRV_ERROR eError; + SYS_DATA *psSysData; + PVRSRV_POWER_DEV *psPowerDevice; + + PVR_UNREFERENCED_PARAMETER(pvInfo); + + eError = SysAcquireData(&psSysData); + if(eError != PVRSRV_OK) + { + return; + } + + + psPowerDevice = psSysData->psPowerDeviceList; + while (psPowerDevice) + { + if (ui32DeviceIndex == psPowerDevice->ui32DeviceIndex) + { + if (psPowerDevice->pfnPostClockSpeedChange) + { + eError = psPowerDevice->pfnPostClockSpeedChange(psPowerDevice->hDevCookie, + bIdleDevice, + psPowerDevice->eCurrentPowerState); + if (eError != PVRSRV_OK) + { + PVR_DPF((PVR_DBG_ERROR, + "PVRSRVDevicePostClockSpeedChange : Device %lu failed, error:0x%lx", + ui32DeviceIndex, eError)); + } + } + } + + psPowerDevice = psPowerDevice->psNext; + } + + if (bIdleDevice) + { + + PVRSRVPowerUnlock(KERNEL_ID); + } +} + diff --git a/services4/srvkm/common/pvrsrv.c b/services4/srvkm/common/pvrsrv.c new file mode 100644 index 0000000..768413f --- /dev/null +++ b/services4/srvkm/common/pvrsrv.c @@ -0,0 +1,1122 @@ +/********************************************************************** + * + * Copyright(c) 2008 Imagination Technologies Ltd. All rights reserved. + * + * This program is free software; you can redistribute it and/or modify it + * under the terms and conditions of the GNU General Public License, + * version 2, as published by the Free Software Foundation. + * + * This program is distributed in the hope it will be useful but, except + * as otherwise stated in writing, without any warranty; without even the + * implied warranty of merchantability or fitness for a particular purpose. + * See the GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License along with + * this program; if not, write to the Free Software Foundation, Inc., + * 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA. + * + * The full GNU General Public License is included in this distribution in + * the file called "COPYING". + * + * Contact Information: + * Imagination Technologies Ltd. + * Home Park Estate, Kings Langley, Herts, WD4 8LZ, UK + * + ******************************************************************************/ + +#include "services_headers.h" +#include "buffer_manager.h" +#include "handle.h" +#include "perproc.h" +#include "pdump_km.h" +#include "ra.h" + +#include "pvrversion.h" +PVRSRV_ERROR AllocateDeviceID(SYS_DATA *psSysData, IMG_UINT32 *pui32DevID) +{ + SYS_DEVICE_ID* psDeviceWalker; + SYS_DEVICE_ID* psDeviceEnd; + + psDeviceWalker = &psSysData->sDeviceID[0]; + psDeviceEnd = psDeviceWalker + psSysData->ui32NumDevices; + + + while (psDeviceWalker < psDeviceEnd) + { + if (!psDeviceWalker->bInUse) + { + psDeviceWalker->bInUse = IMG_TRUE; + *pui32DevID = psDeviceWalker->uiID; + return PVRSRV_OK; + } + psDeviceWalker++; + } + + PVR_DPF((PVR_DBG_ERROR,"AllocateDeviceID: No free and valid device IDs available!")); + + + PVR_ASSERT(psDeviceWalker < psDeviceEnd); + + return PVRSRV_ERROR_GENERIC; +} + + +PVRSRV_ERROR FreeDeviceID(SYS_DATA *psSysData, IMG_UINT32 ui32DevID) +{ + SYS_DEVICE_ID* psDeviceWalker; + SYS_DEVICE_ID* psDeviceEnd; + + psDeviceWalker = &psSysData->sDeviceID[0]; + psDeviceEnd = psDeviceWalker + psSysData->ui32NumDevices; + + + while (psDeviceWalker < psDeviceEnd) + { + + if ( + (psDeviceWalker->uiID == ui32DevID) && + (psDeviceWalker->bInUse) + ) + { + psDeviceWalker->bInUse = IMG_FALSE; + return PVRSRV_OK; + } + psDeviceWalker++; + } + + PVR_DPF((PVR_DBG_ERROR,"FreeDeviceID: no matching dev ID that is in use!")); + + + PVR_ASSERT(psDeviceWalker < psDeviceEnd); + + return PVRSRV_ERROR_GENERIC; +} + + +#ifndef ReadHWReg +IMG_EXPORT +IMG_UINT32 ReadHWReg(IMG_PVOID pvLinRegBaseAddr, IMG_UINT32 ui32Offset) +{ + return *(volatile IMG_UINT32*)((IMG_UINT32)pvLinRegBaseAddr+ui32Offset); +} +#endif + + +#ifndef WriteHWReg +IMG_EXPORT +IMG_VOID WriteHWReg(IMG_PVOID pvLinRegBaseAddr, IMG_UINT32 ui32Offset, IMG_UINT32 ui32Value) +{ + PVR_DPF((PVR_DBG_MESSAGE,"WriteHWReg Base:%x, Offset: %x, Value %x",pvLinRegBaseAddr,ui32Offset,ui32Value)); + + *(IMG_UINT32*)((IMG_UINT32)pvLinRegBaseAddr+ui32Offset) = ui32Value; +} +#endif + + +#ifndef WriteHWRegs +IMG_EXPORT +IMG_VOID WriteHWRegs(IMG_PVOID pvLinRegBaseAddr, IMG_UINT32 ui32Count, PVRSRV_HWREG *psHWRegs) +{ + while (ui32Count) + { + WriteHWReg (pvLinRegBaseAddr, psHWRegs->ui32RegAddr, psHWRegs->ui32RegVal); + psHWRegs++; + ui32Count--; + } +} +#endif + + +IMG_EXPORT +PVRSRV_ERROR IMG_CALLCONV PVRSRVEnumerateDevicesKM(IMG_UINT32 *pui32NumDevices, + PVRSRV_DEVICE_IDENTIFIER *psDevIdList) +{ + PVRSRV_ERROR eError; + SYS_DATA *psSysData; + PVRSRV_DEVICE_NODE *psDeviceNode; + IMG_UINT32 i; + + if (!pui32NumDevices || !psDevIdList) + { + PVR_DPF((PVR_DBG_ERROR,"PVRSRVEnumerateDevicesKM: Invalid params")); + return PVRSRV_ERROR_INVALID_PARAMS; + } + + eError = SysAcquireData(&psSysData); + if (eError != PVRSRV_OK) + { + PVR_DPF((PVR_DBG_ERROR,"PVRSRVEnumerateDevicesKM: Failed to get SysData")); + return eError; + } + + + + for (i=0; ipsDeviceNodeList; + for (i=0; psDeviceNode != IMG_NULL; i++) + { + + if(psDeviceNode->sDevId.eDeviceType != PVRSRV_DEVICE_TYPE_EXT) + { + + *psDevIdList++ = psDeviceNode->sDevId; + + (*pui32NumDevices)++; + } + psDeviceNode = psDeviceNode->psNext; + } + + return PVRSRV_OK; +} + + +PVRSRV_ERROR IMG_CALLCONV PVRSRVInit(PSYS_DATA psSysData) +{ + PVRSRV_ERROR eError; + + + eError = ResManInit(); + if (eError != PVRSRV_OK) + { + goto Error; + } + + eError = PVRSRVPerProcessDataInit(); + if(eError != PVRSRV_OK) + { + goto Error; + } + + + eError = PVRSRVHandleInit(); + if(eError != PVRSRV_OK) + { + goto Error; + } + + + eError = OSCreateResource(&psSysData->sPowerStateChangeResource); + if (eError != PVRSRV_OK) + { + goto Error; + } + + + psSysData->eCurrentPowerState = PVRSRV_POWER_STATE_D0; + psSysData->eFailedPowerState = PVRSRV_POWER_Unspecified; + +#if defined(PDUMP) + psSysData->bPowerUpPDumped = IMG_FALSE; +#endif + + + if(OSAllocMem( PVRSRV_PAGEABLE_SELECT, + sizeof(PVRSRV_EVENTOBJECT) , + (IMG_VOID **)&psSysData->psGlobalEventObject, 0) != PVRSRV_OK) + { + + goto Error; + } + + if(OSEventObjectCreate("PVRSRV_GLOBAL_EVENTOBJECT", psSysData->psGlobalEventObject) != PVRSRV_OK) + { + goto Error; + } + + return eError; + +Error: + PVRSRVDeInit(psSysData); + return eError; +} + + + +IMG_VOID IMG_CALLCONV PVRSRVDeInit(PSYS_DATA psSysData) +{ + PVRSRV_ERROR eError; + + PVR_UNREFERENCED_PARAMETER(psSysData); + + if (psSysData == IMG_NULL) + { + PVR_DPF((PVR_DBG_ERROR,"PVRSRVDeInit: PVRSRVHandleDeInit failed - invalid param")); + return; + } + + + if(psSysData->psGlobalEventObject) + { + OSEventObjectDestroy(psSysData->psGlobalEventObject); + OSFreeMem( PVRSRV_PAGEABLE_SELECT, + sizeof(PVRSRV_EVENTOBJECT) , + psSysData->psGlobalEventObject, 0); + } + + eError = PVRSRVHandleDeInit(); + if (eError != PVRSRV_OK) + { + PVR_DPF((PVR_DBG_ERROR,"PVRSRVDeInit: PVRSRVHandleDeInit failed")); + } + + eError = PVRSRVPerProcessDataDeInit(); + if (eError != PVRSRV_OK) + { + PVR_DPF((PVR_DBG_ERROR,"PVRSRVDeInit: PVRSRVPerProcessDataDeInit failed")); + } + + ResManDeInit(); +} + + +PVRSRV_ERROR IMG_CALLCONV PVRSRVRegisterDevice(PSYS_DATA psSysData, + PVRSRV_ERROR (*pfnRegisterDevice)(PVRSRV_DEVICE_NODE*), + IMG_UINT32 ui32SOCInterruptBit, + IMG_UINT32 *pui32DeviceIndex) +{ + PVRSRV_ERROR eError; + PVRSRV_DEVICE_NODE *psDeviceNode; + + + if(OSAllocMem( PVRSRV_OS_NON_PAGEABLE_HEAP, + sizeof(PVRSRV_DEVICE_NODE), + (IMG_VOID **)&psDeviceNode, IMG_NULL) != PVRSRV_OK) + { + PVR_DPF((PVR_DBG_ERROR,"PVRSRVRegisterDevice : Failed to alloc memory for psDeviceNode")); + return (PVRSRV_ERROR_OUT_OF_MEMORY); + } + OSMemSet (psDeviceNode, 0, sizeof(PVRSRV_DEVICE_NODE)); + + eError = pfnRegisterDevice(psDeviceNode); + if (eError != PVRSRV_OK) + { + OSFreeMem(PVRSRV_OS_NON_PAGEABLE_HEAP, + sizeof(PVRSRV_DEVICE_NODE), psDeviceNode, IMG_NULL); + PVR_DPF((PVR_DBG_ERROR,"PVRSRVRegisterDevice : Failed to register device")); + return (PVRSRV_ERROR_DEVICE_REGISTER_FAILED); + } + + + + + + + psDeviceNode->ui32RefCount = 1; + psDeviceNode->psSysData = psSysData; + psDeviceNode->ui32SOCInterruptBit = ui32SOCInterruptBit; + + + AllocateDeviceID(psSysData, &psDeviceNode->sDevId.ui32DeviceIndex); + + + psDeviceNode->psNext = psSysData->psDeviceNodeList; + psSysData->psDeviceNodeList = psDeviceNode; + + + *pui32DeviceIndex = psDeviceNode->sDevId.ui32DeviceIndex; + + return PVRSRV_OK; +} + + +PVRSRV_ERROR IMG_CALLCONV PVRSRVInitialiseDevice (IMG_UINT32 ui32DevIndex) +{ + PVRSRV_DEVICE_NODE *psDeviceNode; + SYS_DATA *psSysData; + PVRSRV_ERROR eError; + + PVR_DPF((PVR_DBG_MESSAGE, "PVRSRVInitialiseDevice")); + + eError = SysAcquireData(&psSysData); + if(eError != PVRSRV_OK) + { + PVR_DPF((PVR_DBG_ERROR,"PVRSRVInitialiseDevice: Failed to get SysData")); + return(eError); + } + + + psDeviceNode = psSysData->psDeviceNodeList; + + while (psDeviceNode) + { + if (psDeviceNode->sDevId.ui32DeviceIndex == ui32DevIndex) + { + goto FoundDevice; + } + psDeviceNode = psDeviceNode->psNext; + } + + + PVR_DPF((PVR_DBG_ERROR,"PVRSRVInitialiseDevice: requested device is not present")); + return PVRSRV_ERROR_INIT_FAILURE; + +FoundDevice: + + PVR_ASSERT (psDeviceNode->ui32RefCount > 0); + + + + eError = PVRSRVResManConnect(IMG_NULL, &psDeviceNode->hResManContext); + if (eError != PVRSRV_OK) + { + PVR_DPF((PVR_DBG_ERROR,"PVRSRVInitialiseDevice: Failed PVRSRVResManConnect call")); + return eError; + } + + + if(psDeviceNode->pfnInitDevice != IMG_NULL) + { + eError = psDeviceNode->pfnInitDevice(psDeviceNode); + if (eError != PVRSRV_OK) + { + PVR_DPF((PVR_DBG_ERROR,"PVRSRVInitialiseDevice: Failed InitDevice call")); + return eError; + } + } + + return PVRSRV_OK; +} + + +PVRSRV_ERROR IMG_CALLCONV PVRSRVFinaliseSystem(IMG_BOOL bInitSuccessful) +{ + PVRSRV_DEVICE_NODE *psDeviceNode; + SYS_DATA *psSysData; + PVRSRV_ERROR eError; + + PVR_DPF((PVR_DBG_MESSAGE, "PVRSRVFinaliseSystem")); + + eError = SysAcquireData(&psSysData); + if(eError != PVRSRV_OK) + { + PVR_DPF((PVR_DBG_ERROR,"PVRSRVFinaliseSystem: Failed to get SysData")); + return(eError); + } + + if (bInitSuccessful) + { + eError = SysFinalise(); + if (eError != PVRSRV_OK) + { + PVR_DPF((PVR_DBG_ERROR,"PVRSRVFinaliseSystem: SysFinalise failed (%d)", eError)); + return eError; + } + + + psDeviceNode = psSysData->psDeviceNodeList; + while (psDeviceNode) + { + eError = PVRSRVSetDevicePowerStateKM(psDeviceNode->sDevId.ui32DeviceIndex, + PVRSRV_POWER_Unspecified, + KERNEL_ID, IMG_FALSE); + if (eError != PVRSRV_OK) + { + PVR_DPF((PVR_DBG_ERROR,"PVRSRVFinaliseSystem: Failed PVRSRVSetDevicePowerStateKM call (device index: %d)", psDeviceNode->sDevId.ui32DeviceIndex)); + } + psDeviceNode = psDeviceNode->psNext; + } + + + psDeviceNode = psSysData->psDeviceNodeList; + while (psDeviceNode) + { + if (psDeviceNode->pfnInitDeviceCompatCheck) + { + eError = PVRSRVDevInitCompatCheck(psDeviceNode); + if (eError != PVRSRV_OK) + { + PVR_DPF((PVR_DBG_ERROR,"PVRSRVFinaliseSystem: Failed PVRSRVDevInitCompatCheck call (device index: %d)", psDeviceNode->sDevId.ui32DeviceIndex)); + return eError; + } + } + psDeviceNode = psDeviceNode->psNext; + + } + + } + + + + + + PDUMPENDINITPHASE(); + + return PVRSRV_OK; +} + + +PVRSRV_ERROR PVRSRVDevInitCompatCheck(PVRSRV_DEVICE_NODE *psDeviceNode) +{ + + return psDeviceNode->pfnInitDeviceCompatCheck(psDeviceNode); +} + +IMG_EXPORT +PVRSRV_ERROR IMG_CALLCONV PVRSRVAcquireDeviceDataKM (IMG_UINT32 ui32DevIndex, + PVRSRV_DEVICE_TYPE eDeviceType, + IMG_HANDLE *phDevCookie) +{ + PVRSRV_DEVICE_NODE *psDeviceNode; + SYS_DATA *psSysData; + PVRSRV_ERROR eError; + + PVR_DPF((PVR_DBG_MESSAGE, "PVRSRVAcquireDeviceDataKM")); + + eError = SysAcquireData(&psSysData); + if(eError != PVRSRV_OK) + { + PVR_DPF((PVR_DBG_ERROR,"PVRSRVAcquireDeviceDataKM: Failed to get SysData")); + return(eError); + } + + + psDeviceNode = psSysData->psDeviceNodeList; + + if (eDeviceType != PVRSRV_DEVICE_TYPE_UNKNOWN) + { + while (psDeviceNode) + { + if (psDeviceNode->sDevId.eDeviceType == eDeviceType) + { + goto FoundDevice; + } + psDeviceNode = psDeviceNode->psNext; + } + } + else + { + while (psDeviceNode) + { + if (psDeviceNode->sDevId.ui32DeviceIndex == ui32DevIndex) + { + goto FoundDevice; + } + psDeviceNode = psDeviceNode->psNext; + } + } + + + PVR_DPF((PVR_DBG_ERROR,"PVRSRVAcquireDeviceDataKM: requested device is not present")); + return PVRSRV_ERROR_INIT_FAILURE; + +FoundDevice: + + PVR_ASSERT (psDeviceNode->ui32RefCount > 0); + + + if (phDevCookie) + { + *phDevCookie = (IMG_HANDLE)psDeviceNode; + } + + return PVRSRV_OK; +} + + +PVRSRV_ERROR IMG_CALLCONV PVRSRVDeinitialiseDevice(IMG_UINT32 ui32DevIndex) +{ + PVRSRV_DEVICE_NODE *psDeviceNode; + PVRSRV_DEVICE_NODE **ppsDevNode; + SYS_DATA *psSysData; + PVRSRV_ERROR eError; + + eError = SysAcquireData(&psSysData); + if(eError != PVRSRV_OK) + { + PVR_DPF((PVR_DBG_ERROR,"PVRSRVDeinitialiseDevice: Failed to get SysData")); + return(eError); + } + + ppsDevNode = &psSysData->psDeviceNodeList; + while(*ppsDevNode) + { + if((*ppsDevNode)->sDevId.ui32DeviceIndex == ui32DevIndex) + { + psDeviceNode = *ppsDevNode; + goto FoundDevice; + } + ppsDevNode = &((*ppsDevNode)->psNext); + } + + PVR_DPF((PVR_DBG_ERROR,"PVRSRVDeinitialiseDevice: requested device %d is not present", ui32DevIndex)); + + return PVRSRV_ERROR_GENERIC; + +FoundDevice: + + + + eError = PVRSRVSetDevicePowerStateKM(ui32DevIndex, + PVRSRV_POWER_STATE_D3, + KERNEL_ID, + IMG_FALSE); + if (eError != PVRSRV_OK) + { + PVR_DPF((PVR_DBG_ERROR,"PVRSRVDeinitialiseDevice: Failed PVRSRVSetDevicePowerStateKM call")); + return eError; + } + + + + eError = ResManFreeResByCriteria(psDeviceNode->hResManContext, + RESMAN_CRITERIA_RESTYPE, + RESMAN_TYPE_DEVICEMEM_ALLOCATION, + IMG_NULL, 0); + if (eError != PVRSRV_OK) + { + PVR_DPF((PVR_DBG_ERROR,"PVRSRVDeinitialiseDevice: Failed ResManFreeResByCriteria call")); + return eError; + } + + + + if(psDeviceNode->pfnDeInitDevice != IMG_NULL) + { + eError = psDeviceNode->pfnDeInitDevice(psDeviceNode); + if (eError != PVRSRV_OK) + { + PVR_DPF((PVR_DBG_ERROR,"PVRSRVDeinitialiseDevice: Failed DeInitDevice call")); + return eError; + } + } + + + + PVRSRVResManDisconnect(psDeviceNode->hResManContext, IMG_TRUE); + psDeviceNode->hResManContext = IMG_NULL; + + + *ppsDevNode = psDeviceNode->psNext; + + + FreeDeviceID(psSysData, ui32DevIndex); + OSFreeMem(PVRSRV_OS_NON_PAGEABLE_HEAP, + sizeof(PVRSRV_DEVICE_NODE), psDeviceNode, IMG_NULL); + + return (PVRSRV_OK); +} + + +IMG_EXPORT +PVRSRV_ERROR IMG_CALLCONV PollForValueKM (volatile IMG_UINT32* pui32LinMemAddr, + IMG_UINT32 ui32Value, + IMG_UINT32 ui32Mask, + IMG_UINT32 ui32Waitus, + IMG_UINT32 ui32Tries) +{ + IMG_UINT32 uiMaxTime; + + uiMaxTime = ui32Tries * ui32Waitus; + + + LOOP_UNTIL_TIMEOUT(uiMaxTime) + { + if((*pui32LinMemAddr & ui32Mask) == ui32Value) + { + return PVRSRV_OK; + } + OSWaitus(ui32Waitus); + } END_LOOP_UNTIL_TIMEOUT(); + + + + + return PVRSRV_ERROR_GENERIC; +} + + +#if defined (USING_ISR_INTERRUPTS) + +extern IMG_UINT32 gui32EventStatusServicesByISR; + +PVRSRV_ERROR PollForInterruptKM (IMG_UINT32 ui32Value, + IMG_UINT32 ui32Mask, + IMG_UINT32 ui32Waitus, + IMG_UINT32 ui32Tries) +{ + IMG_UINT32 uiMaxTime; + + uiMaxTime = ui32Tries * ui32Waitus; + + + LOOP_UNTIL_TIMEOUT(uiMaxTime) + { + if ((gui32EventStatusServicesByISR & ui32Mask) == ui32Value) + { + gui32EventStatusServicesByISR = 0; + return PVRSRV_OK; + } + OSWaitus(ui32Waitus); + } END_LOOP_UNTIL_TIMEOUT(); + + return PVRSRV_ERROR_GENERIC; +} +#endif + + +IMG_EXPORT +PVRSRV_ERROR IMG_CALLCONV PVRSRVGetMiscInfoKM(PVRSRV_MISC_INFO *psMiscInfo) +{ + SYS_DATA *psSysData; + PVRSRV_ERROR eError; + + if(!psMiscInfo) + { + PVR_DPF((PVR_DBG_ERROR,"PVRSRVGetMiscInfoKM: invalid parameters")); + return PVRSRV_ERROR_INVALID_PARAMS; + } + + psMiscInfo->ui32StatePresent = 0; + + + if(psMiscInfo->ui32StateRequest & ~(PVRSRV_MISC_INFO_TIMER_PRESENT + |PVRSRV_MISC_INFO_CLOCKGATE_PRESENT + |PVRSRV_MISC_INFO_MEMSTATS_PRESENT + |PVRSRV_MISC_INFO_GLOBALEVENTOBJECT_PRESENT + |PVRSRV_MISC_INFO_DDKVERSION_PRESENT)) + { + PVR_DPF((PVR_DBG_ERROR,"PVRSRVGetMiscInfoKM: invalid state request flags")); + return PVRSRV_ERROR_INVALID_PARAMS; + } + + eError = SysAcquireData(&psSysData); + if (eError != PVRSRV_OK) + { + PVR_DPF((PVR_DBG_ERROR,"PVRSRVGetMiscInfoKM: Failed to get SysData")); + return eError; + } + + + if(((psMiscInfo->ui32StateRequest & PVRSRV_MISC_INFO_TIMER_PRESENT) != 0UL) && + (psSysData->pvSOCTimerRegisterKM != IMG_NULL)) + { + psMiscInfo->ui32StatePresent |= PVRSRV_MISC_INFO_TIMER_PRESENT; + psMiscInfo->pvSOCTimerRegisterKM = psSysData->pvSOCTimerRegisterKM; + psMiscInfo->hSOCTimerRegisterOSMemHandle = psSysData->hSOCTimerRegisterOSMemHandle; + } + else + { + psMiscInfo->pvSOCTimerRegisterKM = IMG_NULL; + psMiscInfo->hSOCTimerRegisterOSMemHandle = IMG_NULL; + } + + + if(((psMiscInfo->ui32StateRequest & PVRSRV_MISC_INFO_CLOCKGATE_PRESENT) != 0UL) && + (psSysData->pvSOCClockGateRegsBase != IMG_NULL)) + { + psMiscInfo->ui32StatePresent |= PVRSRV_MISC_INFO_CLOCKGATE_PRESENT; + psMiscInfo->pvSOCClockGateRegs = psSysData->pvSOCClockGateRegsBase; + psMiscInfo->ui32SOCClockGateRegsSize = psSysData->ui32SOCClockGateRegsSize; + } + + + if(((psMiscInfo->ui32StateRequest & PVRSRV_MISC_INFO_MEMSTATS_PRESENT) != 0UL) && + (psMiscInfo->pszMemoryStr != IMG_NULL)) + { + RA_ARENA **ppArena; + BM_HEAP *psBMHeap; + BM_CONTEXT *psBMContext; + PVRSRV_DEVICE_NODE *psDeviceNode; + IMG_CHAR *pszStr; + IMG_UINT32 ui32StrLen; + IMG_INT32 i32Count; + + pszStr = psMiscInfo->pszMemoryStr; + ui32StrLen = psMiscInfo->ui32MemoryStrLen; + + psMiscInfo->ui32StatePresent |= PVRSRV_MISC_INFO_MEMSTATS_PRESENT; + + + ppArena = &psSysData->apsLocalDevMemArena[0]; + while(*ppArena) + { + CHECK_SPACE(ui32StrLen); + i32Count = OSSNPrintf(pszStr, 100, "\nLocal Backing Store:\n"); + UPDATE_SPACE(pszStr, i32Count, ui32StrLen); + + RA_GetStats(*ppArena, + &pszStr, + &ui32StrLen); + + ppArena++; + } + + + psDeviceNode = psSysData->psDeviceNodeList; + while(psDeviceNode) + { + CHECK_SPACE(ui32StrLen); + i32Count = OSSNPrintf(pszStr, 100, "\n\nDevice Type %d:\n", psDeviceNode->sDevId.eDeviceType); + UPDATE_SPACE(pszStr, i32Count, ui32StrLen); + + + if(psDeviceNode->sDevMemoryInfo.pBMKernelContext) + { + CHECK_SPACE(ui32StrLen); + i32Count = OSSNPrintf(pszStr, 100, "\nKernel Context:\n"); + UPDATE_SPACE(pszStr, i32Count, ui32StrLen); + + psBMHeap = psDeviceNode->sDevMemoryInfo.pBMKernelContext->psBMHeap; + while(psBMHeap) + { + if(psBMHeap->pImportArena) + { + RA_GetStats(psBMHeap->pImportArena, + &pszStr, + &ui32StrLen); + } + + if(psBMHeap->pVMArena) + { + RA_GetStats(psBMHeap->pVMArena, + &pszStr, + &ui32StrLen); + } + psBMHeap = psBMHeap->psNext; + } + } + + + psBMContext = psDeviceNode->sDevMemoryInfo.pBMContext; + while(psBMContext) + { + CHECK_SPACE(ui32StrLen); + i32Count = OSSNPrintf(pszStr, 100, "\nApplication Context (hDevMemContext) 0x%08X:\n", (IMG_HANDLE)psBMContext); + UPDATE_SPACE(pszStr, i32Count, ui32StrLen); + + psBMHeap = psBMContext->psBMHeap; + while(psBMHeap) + { + if(psBMHeap->pImportArena) + { + RA_GetStats(psBMHeap->pImportArena, + &pszStr, + &ui32StrLen); + } + + if(psBMHeap->pVMArena) + { + RA_GetStats(psBMHeap->pVMArena, + &pszStr, + &ui32StrLen); + } + psBMHeap = psBMHeap->psNext; + } + psBMContext = psBMContext->psNext; + } + psDeviceNode = psDeviceNode->psNext; + } + + + i32Count = OSSNPrintf(pszStr, 100, "\n\0"); + UPDATE_SPACE(pszStr, i32Count, ui32StrLen); + } + + if(((psMiscInfo->ui32StateRequest & PVRSRV_MISC_INFO_GLOBALEVENTOBJECT_PRESENT) != 0UL) && + (psSysData->psGlobalEventObject != IMG_NULL)) + { + psMiscInfo->ui32StatePresent |= PVRSRV_MISC_INFO_GLOBALEVENTOBJECT_PRESENT; + psMiscInfo->sGlobalEventObject = *psSysData->psGlobalEventObject; + } + + + + if (((psMiscInfo->ui32StateRequest & PVRSRV_MISC_INFO_DDKVERSION_PRESENT) != 0UL) + && ((psMiscInfo->ui32StateRequest & PVRSRV_MISC_INFO_MEMSTATS_PRESENT) == 0UL) + && (psMiscInfo->pszMemoryStr != IMG_NULL)) + { + IMG_CHAR *pszStr; + IMG_UINT32 ui32StrLen; + IMG_UINT32 ui32LenStrPerNum = 12; + IMG_INT32 i32Count; + IMG_INT i; + psMiscInfo->ui32StatePresent |= PVRSRV_MISC_INFO_DDKVERSION_PRESENT; + + + psMiscInfo->aui32DDKVersion[0] = PVRVERSION_MAJ; + psMiscInfo->aui32DDKVersion[1] = PVRVERSION_MIN; + psMiscInfo->aui32DDKVersion[2] = PVRVERSION_BRANCH; + psMiscInfo->aui32DDKVersion[3] = PVRVERSION_BUILD; + + pszStr = psMiscInfo->pszMemoryStr; + ui32StrLen = psMiscInfo->ui32MemoryStrLen; + + for (i=0; i<4; i++) + { + if (ui32StrLen < ui32LenStrPerNum) + { + return PVRSRV_ERROR_INVALID_PARAMS; + } + + i32Count = OSSNPrintf(pszStr, ui32LenStrPerNum, "%ld", psMiscInfo->aui32DDKVersion[i]); + UPDATE_SPACE(pszStr, i32Count, ui32StrLen); + if (i != 3) + { + i32Count = OSSNPrintf(pszStr, 2, "."); + UPDATE_SPACE(pszStr, i32Count, ui32StrLen); + } + } + } + + return PVRSRV_OK; +} + + +PVRSRV_ERROR IMG_CALLCONV PVRSRVGetFBStatsKM(IMG_UINT32 *pui32Total, + IMG_UINT32 *pui32Available) +{ + IMG_UINT32 ui32Total = 0, i = 0; + IMG_UINT32 ui32Available = 0; + + *pui32Total = 0; + *pui32Available = 0; + + + while(BM_ContiguousStatistics(i, &ui32Total, &ui32Available) == IMG_TRUE) + { + *pui32Total += ui32Total; + *pui32Available += ui32Available; + + i++; + } + + return PVRSRV_OK; +} + + +IMG_BOOL IMG_CALLCONV PVRSRVDeviceLISR(PVRSRV_DEVICE_NODE *psDeviceNode) +{ + SYS_DATA *psSysData; + IMG_BOOL bStatus = IMG_FALSE; + IMG_UINT32 ui32InterruptSource; + + if(!psDeviceNode) + { + PVR_DPF((PVR_DBG_ERROR, "PVRSRVDeviceLISR: Invalid params\n")); + goto out; + } + psSysData = psDeviceNode->psSysData; + + + ui32InterruptSource = SysGetInterruptSource(psSysData, psDeviceNode); + if(ui32InterruptSource & psDeviceNode->ui32SOCInterruptBit) + { + if(psDeviceNode->pfnDeviceISR != IMG_NULL) + { + bStatus = (*psDeviceNode->pfnDeviceISR)(psDeviceNode->pvISRData); + } + + SysClearInterrupts(psSysData, psDeviceNode->ui32SOCInterruptBit); + } + +out: + return bStatus; +} + + +IMG_BOOL IMG_CALLCONV PVRSRVSystemLISR(IMG_VOID *pvSysData) +{ + SYS_DATA *psSysData = pvSysData; + IMG_BOOL bStatus = IMG_FALSE; + IMG_UINT32 ui32InterruptSource; + IMG_UINT32 ui32ClearInterrupts = 0; + PVRSRV_DEVICE_NODE *psDeviceNode; + + if(!psSysData) + { + PVR_DPF((PVR_DBG_ERROR, "PVRSRVSystemLISR: Invalid params\n")); + goto out; + } + + + ui32InterruptSource = SysGetInterruptSource(psSysData, IMG_NULL); + + + if(ui32InterruptSource == 0) + { + goto out; + } + + + psDeviceNode = psSysData->psDeviceNodeList; + while(psDeviceNode != IMG_NULL) + { + if(psDeviceNode->pfnDeviceISR != IMG_NULL) + { + if(ui32InterruptSource & psDeviceNode->ui32SOCInterruptBit) + { + if((*psDeviceNode->pfnDeviceISR)(psDeviceNode->pvISRData)) + { + + bStatus = IMG_TRUE; + } + + ui32ClearInterrupts |= psDeviceNode->ui32SOCInterruptBit; + } + } + psDeviceNode = psDeviceNode->psNext; + } + + SysClearInterrupts(psSysData, ui32ClearInterrupts); + +out: + return bStatus; +} + + +IMG_VOID IMG_CALLCONV PVRSRVMISR(IMG_VOID *pvSysData) +{ + SYS_DATA *psSysData = pvSysData; + PVRSRV_DEVICE_NODE *psDeviceNode; + + if(!psSysData) + { + PVR_DPF((PVR_DBG_ERROR, "PVRSRVMISR: Invalid params\n")); + return; + } + + + psDeviceNode = psSysData->psDeviceNodeList; + while(psDeviceNode != IMG_NULL) + { + if(psDeviceNode->pfnDeviceMISR != IMG_NULL) + { + (*psDeviceNode->pfnDeviceMISR)(psDeviceNode->pvISRData); + } + psDeviceNode = psDeviceNode->psNext; + } + + + if (PVRSRVProcessQueues(ISR_ID, IMG_FALSE) == PVRSRV_ERROR_PROCESSING_BLOCKED) + { + PVRSRVProcessQueues(ISR_ID, IMG_FALSE); + } + + + if (psSysData->psGlobalEventObject) + { + IMG_HANDLE hOSEventKM = psSysData->psGlobalEventObject->hOSEventKM; + if(hOSEventKM) + { + OSEventObjectSignal(hOSEventKM); + } + } +} + + +IMG_EXPORT +PVRSRV_ERROR IMG_CALLCONV PVRSRVProcessConnect(IMG_UINT32 ui32PID) +{ + return PVRSRVPerProcessDataConnect(ui32PID); +} + + +IMG_EXPORT +IMG_VOID IMG_CALLCONV PVRSRVProcessDisconnect(IMG_UINT32 ui32PID) +{ + PVRSRVPerProcessDataDisconnect(ui32PID); +} + + +PVRSRV_ERROR IMG_CALLCONV PVRSRVSaveRestoreLiveSegments(IMG_HANDLE hArena, IMG_PBYTE pbyBuffer, + IMG_UINT32 *puiBufSize, IMG_BOOL bSave) +{ + IMG_UINT32 uiBytesSaved = 0; + IMG_PVOID pvLocalMemCPUVAddr; + RA_SEGMENT_DETAILS sSegDetails; + + if (hArena == IMG_NULL) + { + return (PVRSRV_ERROR_INVALID_PARAMS); + } + + sSegDetails.uiSize = 0; + sSegDetails.sCpuPhyAddr.uiAddr = 0; + sSegDetails.hSegment = 0; + + + while (RA_GetNextLiveSegment(hArena, &sSegDetails)) + { + if (pbyBuffer == IMG_NULL) + { + + uiBytesSaved += sizeof(sSegDetails.uiSize) + sSegDetails.uiSize; + } + else + { + if ((uiBytesSaved + sizeof(sSegDetails.uiSize) + sSegDetails.uiSize) > *puiBufSize) + { + return (PVRSRV_ERROR_OUT_OF_MEMORY); + } + + PVR_DPF((PVR_DBG_MESSAGE, "PVRSRVSaveRestoreLiveSegments: Base %08x size %08x", sSegDetails.sCpuPhyAddr.uiAddr, sSegDetails.uiSize)); + + + pvLocalMemCPUVAddr = OSMapPhysToLin(sSegDetails.sCpuPhyAddr, + sSegDetails.uiSize, + PVRSRV_HAP_KERNEL_ONLY|PVRSRV_HAP_UNCACHED, + IMG_NULL); + if (pvLocalMemCPUVAddr == IMG_NULL) + { + PVR_DPF((PVR_DBG_ERROR, "PVRSRVSaveRestoreLiveSegments: Failed to map local memory to host")); + return (PVRSRV_ERROR_OUT_OF_MEMORY); + } + + if (bSave) + { + + OSMemCopy(pbyBuffer, &sSegDetails.uiSize, sizeof(sSegDetails.uiSize)); + pbyBuffer += sizeof(sSegDetails.uiSize); + + OSMemCopy(pbyBuffer, pvLocalMemCPUVAddr, sSegDetails.uiSize); + pbyBuffer += sSegDetails.uiSize; + } + else + { + IMG_UINT32 uiSize; + + OSMemCopy(&uiSize, pbyBuffer, sizeof(sSegDetails.uiSize)); + + if (uiSize != sSegDetails.uiSize) + { + PVR_DPF((PVR_DBG_ERROR, "PVRSRVSaveRestoreLiveSegments: Segment size error")); + } + else + { + pbyBuffer += sizeof(sSegDetails.uiSize); + + OSMemCopy(pvLocalMemCPUVAddr, pbyBuffer, sSegDetails.uiSize); + pbyBuffer += sSegDetails.uiSize; + } + } + + + uiBytesSaved += sizeof(sSegDetails.uiSize) + sSegDetails.uiSize; + + OSUnMapPhysToLin(pvLocalMemCPUVAddr, + sSegDetails.uiSize, + PVRSRV_HAP_KERNEL_ONLY|PVRSRV_HAP_UNCACHED, + IMG_NULL); + } + } + + if (pbyBuffer == IMG_NULL) + { + *puiBufSize = uiBytesSaved; + } + + return (PVRSRV_OK); +} + + diff --git a/services4/srvkm/common/queue.c b/services4/srvkm/common/queue.c new file mode 100644 index 0000000..ffc2cdb --- /dev/null +++ b/services4/srvkm/common/queue.c @@ -0,0 +1,953 @@ +/********************************************************************** + * + * Copyright(c) 2008 Imagination Technologies Ltd. All rights reserved. + * + * This program is free software; you can redistribute it and/or modify it + * under the terms and conditions of the GNU General Public License, + * version 2, as published by the Free Software Foundation. + * + * This program is distributed in the hope it will be useful but, except + * as otherwise stated in writing, without any warranty; without even the + * implied warranty of merchantability or fitness for a particular purpose. + * See the GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License along with + * this program; if not, write to the Free Software Foundation, Inc., + * 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA. + * + * The full GNU General Public License is included in this distribution in + * the file called "COPYING". + * + * Contact Information: + * Imagination Technologies Ltd. + * Home Park Estate, Kings Langley, Herts, WD4 8LZ, UK + * + ******************************************************************************/ + +#include "services_headers.h" + +#if defined(__linux__) && defined(__KERNEL__) +#include "proc.h" + +static IMG_INT +QueuePrintCommands (PVRSRV_QUEUE_INFO * psQueue, IMG_CHAR * buffer, size_t size) +{ + off_t off = 0; + IMG_INT cmds = 0; + IMG_UINT32 ui32ReadOffset = psQueue->ui32ReadOffset; + IMG_UINT32 ui32WriteOffset = psQueue->ui32WriteOffset; + PVRSRV_COMMAND * psCmd; + + while (ui32ReadOffset != ui32WriteOffset) + { + psCmd= (PVRSRV_COMMAND *)((IMG_UINT32)psQueue->pvLinQueueKM + ui32ReadOffset); + + off = printAppend(buffer, size, off, "%p %p %5lu %6lu %3lu %5lu %2lu %2lu %3lu \n", + psQueue, + psCmd, + psCmd->ui32ProcessID, + psCmd->CommandType, + psCmd->ui32CmdSize, + psCmd->ui32DevIndex, + psCmd->ui32DstSyncCount, + psCmd->ui32SrcSyncCount, + psCmd->ui32DataSize); + + ui32ReadOffset += psCmd->ui32CmdSize; + ui32ReadOffset &= psQueue->ui32QueueSize - 1; + cmds++; + } + if (cmds == 0) + off = printAppend(buffer, size, off, "%p \n", psQueue); + return off; +} + + +off_t +QueuePrintQueues (IMG_CHAR * buffer, size_t size, off_t off) +{ + SYS_DATA * psSysData; + PVRSRV_QUEUE_INFO * psQueue; + + if (SysAcquireData(&psSysData) != PVRSRV_OK) + return END_OF_FILE; + + if (!off) + return printAppend (buffer, size, 0, + "Command Queues\n" + "Queue CmdPtr Pid Command Size DevInd DSC SSC #Data ...\n"); + + + + for (psQueue = psSysData->psQueueList; --off && psQueue; psQueue = psQueue->psNextKM) + ; + + return psQueue ? QueuePrintCommands (psQueue, buffer, size) : END_OF_FILE; +} +#endif + +#define GET_SPACE_IN_CMDQ(psQueue) \ + (((psQueue->ui32ReadOffset - psQueue->ui32WriteOffset) \ + + (psQueue->ui32QueueSize - 1)) & (psQueue->ui32QueueSize - 1)) + +#define UPDATE_QUEUE_WOFF(psQueue, ui32Size) \ + psQueue->ui32WriteOffset = (psQueue->ui32WriteOffset + ui32Size) \ + & (psQueue->ui32QueueSize - 1); + +#define SYNCOPS_STALE(ui32OpsComplete, ui32OpsPending) \ + (ui32OpsComplete >= ui32OpsPending) + +IMG_UINT32 NearestPower2(IMG_UINT32 ui32Value) +{ + IMG_UINT32 ui32Temp, ui32Result = 1; + + if(!ui32Value) + return 0; + + ui32Temp = ui32Value - 1; + while(ui32Temp) + { + ui32Result <<= 1; + ui32Temp >>= 1; + } + + return ui32Result; +} + + +IMG_EXPORT +PVRSRV_ERROR IMG_CALLCONV PVRSRVCreateCommandQueueKM(IMG_UINT32 ui32QueueSize, + PVRSRV_QUEUE_INFO **ppsQueueInfo) +{ + PVRSRV_QUEUE_INFO *psQueueInfo; + IMG_UINT32 ui32Power2QueueSize = NearestPower2(ui32QueueSize); + SYS_DATA *psSysData; + PVRSRV_ERROR eError; + IMG_HANDLE hMemBlock; + + eError = SysAcquireData(&psSysData); + if (eError != PVRSRV_OK) + { + return eError; + } + + + if(OSAllocMem(PVRSRV_OS_NON_PAGEABLE_HEAP, + sizeof(PVRSRV_QUEUE_INFO), + (IMG_VOID **)&psQueueInfo, &hMemBlock) != PVRSRV_OK) + { + PVR_DPF((PVR_DBG_ERROR,"PVRSRVCreateCommandQueueKM: Failed to alloc queue struct")); + goto ErrorExit; + } + OSMemSet(psQueueInfo, 0, sizeof(PVRSRV_QUEUE_INFO)); + + psQueueInfo->hMemBlock[0] = hMemBlock; + psQueueInfo->ui32ProcessID = OSGetCurrentProcessIDKM(); + + + if(OSAllocMem(PVRSRV_OS_NON_PAGEABLE_HEAP, + ui32Power2QueueSize + PVRSRV_MAX_CMD_SIZE, + &psQueueInfo->pvLinQueueKM, &hMemBlock) != PVRSRV_OK) + { + PVR_DPF((PVR_DBG_ERROR,"PVRSRVCreateCommandQueueKM: Failed to alloc queue buffer")); + goto ErrorExit; + } + + psQueueInfo->hMemBlock[1] = hMemBlock; + psQueueInfo->pvLinQueueUM = psQueueInfo->pvLinQueueKM; + + + PVR_ASSERT(psQueueInfo->ui32ReadOffset == 0); + PVR_ASSERT(psQueueInfo->ui32WriteOffset == 0); + + psQueueInfo->ui32QueueSize = ui32Power2QueueSize; + + + if (psSysData->psQueueList == IMG_NULL) + { + eError = OSCreateResource(&psSysData->sQProcessResource); + if (eError != PVRSRV_OK) + { + goto ErrorExit; + } + } + + + if (OSLockResource(&psSysData->sQProcessResource, + KERNEL_ID) != PVRSRV_OK) + { + goto ErrorExit; + } + + psQueueInfo->psNextKM = psSysData->psQueueList; + psSysData->psQueueList = psQueueInfo; + + if (OSUnlockResource(&psSysData->sQProcessResource, KERNEL_ID) != PVRSRV_OK) + { + goto ErrorExit; + } + + *ppsQueueInfo = psQueueInfo; + + return PVRSRV_OK; + +ErrorExit: + + if(psQueueInfo) + { + if(psQueueInfo->pvLinQueueKM) + { + OSFreeMem(PVRSRV_OS_NON_PAGEABLE_HEAP, + psQueueInfo->ui32QueueSize, + psQueueInfo->pvLinQueueKM, + psQueueInfo->hMemBlock[1]); + } + + OSFreeMem(PVRSRV_OS_NON_PAGEABLE_HEAP, + sizeof(PVRSRV_QUEUE_INFO), + psQueueInfo, + psQueueInfo->hMemBlock[0]); + } + + return PVRSRV_ERROR_GENERIC; +} + + +IMG_EXPORT +PVRSRV_ERROR IMG_CALLCONV PVRSRVDestroyCommandQueueKM(PVRSRV_QUEUE_INFO *psQueueInfo) +{ + PVRSRV_QUEUE_INFO *psQueue; + SYS_DATA *psSysData; + PVRSRV_ERROR eError; + IMG_BOOL bTimeout = IMG_TRUE; + + eError = SysAcquireData(&psSysData); + if (eError != PVRSRV_OK) + { + return eError; + } + + psQueue = psSysData->psQueueList; + + LOOP_UNTIL_TIMEOUT(MAX_HW_TIME_US) + { + if(psQueueInfo->ui32ReadOffset == psQueueInfo->ui32WriteOffset) + { + bTimeout = IMG_FALSE; + break; + } + OSWaitus(MAX_HW_TIME_US/WAIT_TRY_COUNT); + } END_LOOP_UNTIL_TIMEOUT(); + + if (bTimeout) + { + + PVR_DPF((PVR_DBG_ERROR,"PVRSRVDestroyCommandQueueKM : Failed to empty queue")); + eError = PVRSRV_ERROR_CANNOT_FLUSH_QUEUE; + goto ErrorExit; + } + + + eError = OSLockResource(&psSysData->sQProcessResource, + KERNEL_ID); + if (eError != PVRSRV_OK) + { + goto ErrorExit; + } + + if(psQueue == psQueueInfo) + { + psSysData->psQueueList = psQueueInfo->psNextKM; + + OSFreeMem(PVRSRV_OS_NON_PAGEABLE_HEAP, + psQueueInfo->ui32QueueSize, + psQueueInfo->pvLinQueueKM, + psQueueInfo->hMemBlock[1]); + OSFreeMem(PVRSRV_OS_NON_PAGEABLE_HEAP, + sizeof(PVRSRV_QUEUE_INFO), + psQueueInfo, + psQueueInfo->hMemBlock[0]); + } + else + { + while(psQueue) + { + if(psQueue->psNextKM == psQueueInfo) + { + psQueue->psNextKM = psQueueInfo->psNextKM; + + OSFreeMem(PVRSRV_OS_NON_PAGEABLE_HEAP, + psQueueInfo->ui32QueueSize, + psQueueInfo->pvLinQueueKM, + psQueueInfo->hMemBlock[1]); + OSFreeMem(PVRSRV_OS_NON_PAGEABLE_HEAP, + sizeof(PVRSRV_QUEUE_INFO), + psQueueInfo, + psQueueInfo->hMemBlock[0]); + break; + } + psQueue = psQueue->psNextKM; + } + + if(!psQueue) + { + eError = OSUnlockResource(&psSysData->sQProcessResource, KERNEL_ID); + if (eError != PVRSRV_OK) + { + goto ErrorExit; + } + eError = PVRSRV_ERROR_INVALID_PARAMS; + goto ErrorExit; + } + } + + + eError = OSUnlockResource(&psSysData->sQProcessResource, KERNEL_ID); + if (eError != PVRSRV_OK) + { + goto ErrorExit; + } + + + if (psSysData->psQueueList == IMG_NULL) + { + eError = OSDestroyResource(&psSysData->sQProcessResource); + if (eError != PVRSRV_OK) + { + goto ErrorExit; + } + } + +ErrorExit: + + return eError; +} + + +IMG_EXPORT +PVRSRV_ERROR IMG_CALLCONV PVRSRVGetQueueSpaceKM(PVRSRV_QUEUE_INFO *psQueue, + IMG_UINT32 ui32ParamSize, + IMG_VOID **ppvSpace) +{ + IMG_BOOL bTimeout = IMG_TRUE; + + + ui32ParamSize = (ui32ParamSize+3) & 0xFFFFFFFC; + + if (ui32ParamSize > PVRSRV_MAX_CMD_SIZE) + { + PVR_DPF((PVR_DBG_WARNING,"PVRSRVGetQueueSpace: max command size is %d bytes", PVRSRV_MAX_CMD_SIZE)); + return PVRSRV_ERROR_CMD_TOO_BIG; + } + + LOOP_UNTIL_TIMEOUT(MAX_HW_TIME_US) + { + if (GET_SPACE_IN_CMDQ(psQueue) > ui32ParamSize) + { + bTimeout = IMG_FALSE; + break; + } + OSWaitus(MAX_HW_TIME_US/WAIT_TRY_COUNT); + } END_LOOP_UNTIL_TIMEOUT(); + + if (bTimeout == IMG_TRUE) + { + *ppvSpace = IMG_NULL; + + return PVRSRV_ERROR_CANNOT_GET_QUEUE_SPACE; + } + else + { + *ppvSpace = (IMG_VOID *)(psQueue->ui32WriteOffset + (IMG_UINT32)psQueue->pvLinQueueUM); + } + + return PVRSRV_OK; +} + + +IMG_EXPORT +PVRSRV_ERROR IMG_CALLCONV PVRSRVInsertCommandKM(PVRSRV_QUEUE_INFO *psQueue, + PVRSRV_COMMAND **ppsCommand, + IMG_UINT32 ui32DevIndex, + IMG_UINT16 CommandType, + IMG_UINT32 ui32DstSyncCount, + PVRSRV_KERNEL_SYNC_INFO *apsDstSync[], + IMG_UINT32 ui32SrcSyncCount, + PVRSRV_KERNEL_SYNC_INFO *apsSrcSync[], + IMG_UINT32 ui32DataByteSize ) +{ + PVRSRV_ERROR eError; + PVRSRV_COMMAND *psCommand; + IMG_UINT32 ui32CommandSize; + IMG_UINT32 i; + + + ui32DataByteSize = (ui32DataByteSize + 3) & 0xFFFFFFFC; + + + ui32CommandSize = sizeof(PVRSRV_COMMAND) + + ((ui32DstSyncCount + ui32SrcSyncCount) * sizeof(PVRSRV_SYNC_OBJECT)) + + ui32DataByteSize; + + + eError = PVRSRVGetQueueSpaceKM (psQueue, ui32CommandSize, (IMG_VOID**)&psCommand); + if(eError != PVRSRV_OK) + { + return eError; + } + + psCommand->ui32ProcessID = OSGetCurrentProcessIDKM(); + + + psCommand->ui32CmdSize = ui32CommandSize; + psCommand->ui32DevIndex = ui32DevIndex; + psCommand->CommandType = CommandType; + psCommand->ui32DstSyncCount = ui32DstSyncCount; + psCommand->ui32SrcSyncCount = ui32SrcSyncCount; + + + psCommand->psDstSync = (PVRSRV_SYNC_OBJECT*)(((IMG_UINT8 *)psCommand) + sizeof(PVRSRV_COMMAND)); + + + psCommand->psSrcSync = (PVRSRV_SYNC_OBJECT*)(((IMG_UINT8 *)psCommand->psDstSync) + + (ui32DstSyncCount * sizeof(PVRSRV_SYNC_OBJECT))); + + psCommand->pvData = (PVRSRV_SYNC_OBJECT*)(((IMG_UINT8 *)psCommand->psSrcSync) + + (ui32SrcSyncCount * sizeof(PVRSRV_SYNC_OBJECT))); + psCommand->ui32DataSize = ui32DataByteSize; + + + for (i=0; ipsDstSync[i].psKernelSyncInfoKM = apsDstSync[i]; + psCommand->psDstSync[i].ui32WriteOpsPending = PVRSRVGetWriteOpsPending(apsDstSync[i], IMG_FALSE); + psCommand->psDstSync[i].ui32ReadOpsPending = PVRSRVGetReadOpsPending(apsDstSync[i], IMG_FALSE); + } + + + for (i=0; ipsSrcSync[i].psKernelSyncInfoKM = apsSrcSync[i]; + psCommand->psSrcSync[i].ui32WriteOpsPending = PVRSRVGetWriteOpsPending(apsSrcSync[i], IMG_TRUE); + psCommand->psSrcSync[i].ui32ReadOpsPending = PVRSRVGetReadOpsPending(apsSrcSync[i], IMG_TRUE); + } + + + *ppsCommand = psCommand; + + return PVRSRV_OK; +} + + +IMG_EXPORT +PVRSRV_ERROR IMG_CALLCONV PVRSRVSubmitCommandKM(PVRSRV_QUEUE_INFO *psQueue, + PVRSRV_COMMAND *psCommand) +{ + + + + if (psCommand->ui32DstSyncCount > 0) + { + psCommand->psDstSync = (PVRSRV_SYNC_OBJECT*)(((IMG_UINT8 *)psQueue->pvLinQueueKM) + + psQueue->ui32WriteOffset + sizeof(PVRSRV_COMMAND)); + } + + if (psCommand->ui32SrcSyncCount > 0) + { + psCommand->psSrcSync = (PVRSRV_SYNC_OBJECT*)(((IMG_UINT8 *)psQueue->pvLinQueueKM) + + psQueue->ui32WriteOffset + sizeof(PVRSRV_COMMAND) + + (psCommand->ui32DstSyncCount * sizeof(PVRSRV_SYNC_OBJECT))); + } + + psCommand->pvData = (PVRSRV_SYNC_OBJECT*)(((IMG_UINT8 *)psQueue->pvLinQueueKM) + + psQueue->ui32WriteOffset + sizeof(PVRSRV_COMMAND) + + (psCommand->ui32DstSyncCount * sizeof(PVRSRV_SYNC_OBJECT)) + + (psCommand->ui32SrcSyncCount * sizeof(PVRSRV_SYNC_OBJECT))); + + + UPDATE_QUEUE_WOFF(psQueue, psCommand->ui32CmdSize); + + return PVRSRV_OK; +} + + + +IMG_EXPORT +PVRSRV_ERROR PVRSRVProcessCommand(SYS_DATA *psSysData, + PVRSRV_COMMAND *psCommand, + IMG_BOOL bFlush) +{ + PVRSRV_SYNC_OBJECT *psWalkerObj; + PVRSRV_SYNC_OBJECT *psEndObj; + IMG_UINT32 i; + COMMAND_COMPLETE_DATA *psCmdCompleteData; + PVRSRV_ERROR eError = PVRSRV_OK; + IMG_UINT32 ui32WriteOpsComplete; + IMG_UINT32 ui32ReadOpsComplete; + + + psWalkerObj = psCommand->psDstSync; + psEndObj = psWalkerObj + psCommand->ui32DstSyncCount; + while (psWalkerObj < psEndObj) + { + PVRSRV_SYNC_DATA *psSyncData = psWalkerObj->psKernelSyncInfoKM->psSyncData; + + ui32WriteOpsComplete = psSyncData->ui32WriteOpsComplete; + ui32ReadOpsComplete = psSyncData->ui32ReadOpsComplete; + + if ((ui32WriteOpsComplete != psWalkerObj->ui32WriteOpsPending) + || (ui32ReadOpsComplete != psWalkerObj->ui32ReadOpsPending)) + { + if (!bFlush || + !SYNCOPS_STALE(ui32WriteOpsComplete, psWalkerObj->ui32WriteOpsPending) || + !SYNCOPS_STALE(ui32ReadOpsComplete, psWalkerObj->ui32ReadOpsPending)) + { + return PVRSRV_ERROR_FAILED_DEPENDENCIES; + } + } + + psWalkerObj++; + } + + + psWalkerObj = psCommand->psSrcSync; + psEndObj = psWalkerObj + psCommand->ui32SrcSyncCount; + while (psWalkerObj < psEndObj) + { + PVRSRV_SYNC_DATA *psSyncData = psWalkerObj->psKernelSyncInfoKM->psSyncData; + + ui32ReadOpsComplete = psSyncData->ui32ReadOpsComplete; + ui32WriteOpsComplete = psSyncData->ui32WriteOpsComplete; + + if ((ui32WriteOpsComplete != psWalkerObj->ui32WriteOpsPending) + || (ui32ReadOpsComplete != psWalkerObj->ui32ReadOpsPending)) + { + if (!bFlush && + SYNCOPS_STALE(ui32WriteOpsComplete, psWalkerObj->ui32WriteOpsPending) && + SYNCOPS_STALE(ui32ReadOpsComplete, psWalkerObj->ui32ReadOpsPending)) + { + PVR_DPF((PVR_DBG_WARNING, + "PVRSRVProcessCommand: Stale syncops psSyncData:0x%x ui32WriteOpsComplete:0x%x ui32WriteOpsPending:0x%x", + psSyncData, ui32WriteOpsComplete, psWalkerObj->ui32WriteOpsPending)); + } + + if (!bFlush || + !SYNCOPS_STALE(ui32WriteOpsComplete, psWalkerObj->ui32WriteOpsPending) || + !SYNCOPS_STALE(ui32ReadOpsComplete, psWalkerObj->ui32ReadOpsPending)) + { + return PVRSRV_ERROR_FAILED_DEPENDENCIES; + } + } + psWalkerObj++; + } + + + if (psCommand->ui32DevIndex >= SYS_DEVICE_COUNT) + { + PVR_DPF((PVR_DBG_ERROR, + "PVRSRVProcessCommand: invalid DeviceType 0x%x", + psCommand->ui32DevIndex)); + return PVRSRV_ERROR_INVALID_PARAMS; + } + + + psCmdCompleteData = psSysData->ppsCmdCompleteData[psCommand->ui32DevIndex][psCommand->CommandType]; + if (psCmdCompleteData->bInUse) + { + + return PVRSRV_ERROR_FAILED_DEPENDENCIES; + } + + + psCmdCompleteData->bInUse = IMG_TRUE; + + + psCmdCompleteData->ui32DstSyncCount = psCommand->ui32DstSyncCount; + for (i=0; iui32DstSyncCount; i++) + { + psCmdCompleteData->psDstSync[i] = psCommand->psDstSync[i]; + } + + + psCmdCompleteData->ui32SrcSyncCount = psCommand->ui32SrcSyncCount; + for (i=0; iui32SrcSyncCount; i++) + { + psCmdCompleteData->psSrcSync[i] = psCommand->psSrcSync[i]; + } + + + + + + + + + + + + if (psSysData->ppfnCmdProcList[psCommand->ui32DevIndex][psCommand->CommandType]((IMG_HANDLE)psCmdCompleteData, + psCommand->ui32DataSize, + psCommand->pvData) == IMG_FALSE) + { + + + + psCmdCompleteData->bInUse = IMG_FALSE; + eError = PVRSRV_ERROR_CMD_NOT_PROCESSED; + } + + return eError; +} + + +IMG_EXPORT +PVRSRV_ERROR PVRSRVProcessQueues(IMG_UINT32 ui32CallerID, + IMG_BOOL bFlush) +{ + PVRSRV_QUEUE_INFO *psQueue; + SYS_DATA *psSysData; + PVRSRV_COMMAND *psCommand; + PVRSRV_DEVICE_NODE *psDeviceNode; + PVRSRV_ERROR eError; + + eError = SysAcquireData(&psSysData); + if (eError != PVRSRV_OK) + { + return eError; + } + + + psSysData->bReProcessQueues = IMG_FALSE; + + + eError = OSLockResource(&psSysData->sQProcessResource, + ui32CallerID); + if(eError != PVRSRV_OK) + { + + psSysData->bReProcessQueues = IMG_TRUE; + + + if(ui32CallerID == ISR_ID) + { + if (bFlush) + { + PVR_DPF((PVR_DBG_ERROR,"PVRSRVProcessQueues: Couldn't acquire queue processing lock for FLUSH")); + } + else + { + PVR_DPF((PVR_DBG_MESSAGE,"PVRSRVProcessQueues: Couldn't acquire queue processing lock")); + } + } + else + { + PVR_DPF((PVR_DBG_MESSAGE,"PVRSRVProcessQueues: Queue processing lock-acquire failed when called from the Services driver.")); + PVR_DPF((PVR_DBG_MESSAGE," This is due to MISR queue processing being interrupted by the Services driver.")); + } + + return PVRSRV_OK; + } + + psQueue = psSysData->psQueueList; + + if(!psQueue) + { + PVR_DPF((PVR_DBG_MESSAGE,"No Queues installed - cannot process commands")); + } + + if (bFlush) + { + PVRSRVSetDCState(DC_STATE_FLUSH_COMMANDS); + } + + while (psQueue) + { + while (psQueue->ui32ReadOffset != psQueue->ui32WriteOffset) + { + psCommand = (PVRSRV_COMMAND*)((IMG_UINT32)psQueue->pvLinQueueKM + psQueue->ui32ReadOffset); + + if (PVRSRVProcessCommand(psSysData, psCommand, bFlush) == PVRSRV_OK) + { + + UPDATE_QUEUE_ROFF(psQueue, psCommand->ui32CmdSize) + + if (bFlush) + { + continue; + } + } + + break; + } + psQueue = psQueue->psNextKM; + } + + if (bFlush) + { + PVRSRVSetDCState(DC_STATE_NO_FLUSH_COMMANDS); + } + + + psDeviceNode = psSysData->psDeviceNodeList; + while(psDeviceNode != IMG_NULL) + { + if (psDeviceNode->bReProcessDeviceCommandComplete && + psDeviceNode->pfnDeviceCommandComplete != IMG_NULL) + { + (*psDeviceNode->pfnDeviceCommandComplete)(psDeviceNode); + } + psDeviceNode = psDeviceNode->psNext; + } + + + OSUnlockResource(&psSysData->sQProcessResource, ui32CallerID); + + + if(psSysData->bReProcessQueues) + { + return PVRSRV_ERROR_PROCESSING_BLOCKED; + } + + return PVRSRV_OK; +} + + +IMG_EXPORT +IMG_VOID PVRSRVCommandCompleteKM(IMG_HANDLE hCmdCookie, IMG_BOOL bScheduleMISR) +{ + IMG_UINT32 i; + COMMAND_COMPLETE_DATA *psCmdCompleteData = (COMMAND_COMPLETE_DATA *)hCmdCookie; + SYS_DATA *psSysData; + + if (SysAcquireData(&psSysData) != PVRSRV_OK) + { + return; + } + + + for (i=0; iui32DstSyncCount; i++) + { + psCmdCompleteData->psDstSync[i].psKernelSyncInfoKM->psSyncData->ui32WriteOpsComplete++; + } + + + for (i=0; iui32SrcSyncCount; i++) + { + psCmdCompleteData->psSrcSync[i].psKernelSyncInfoKM->psSyncData->ui32ReadOpsComplete++; + } + + + psCmdCompleteData->bInUse = IMG_FALSE; + + + PVRSRVCommandCompleteCallbacks(); + +#if defined(SYS_USING_INTERRUPTS) + if(bScheduleMISR) + { + OSScheduleMISR(psSysData); + } +#else + PVR_UNREFERENCED_PARAMETER(bScheduleMISR); +#endif +} + + +IMG_VOID PVRSRVCommandCompleteCallbacks(IMG_VOID) +{ + SYS_DATA *psSysData; + PVRSRV_DEVICE_NODE *psDeviceNode; + + if (SysAcquireData(&psSysData) != PVRSRV_OK) + { + PVR_DPF((PVR_DBG_ERROR,"PVRSRVCommandCompleteCallbacks: SysAcquireData failed")); + return; + } + + psDeviceNode = psSysData->psDeviceNodeList; + while(psDeviceNode != IMG_NULL) + { + if(psDeviceNode->pfnDeviceCommandComplete != IMG_NULL) + { + + (*psDeviceNode->pfnDeviceCommandComplete)(psDeviceNode); + } + psDeviceNode = psDeviceNode->psNext; + } +} + +IMG_EXPORT +PVRSRV_ERROR PVRSRVRegisterCmdProcListKM(IMG_UINT32 ui32DevIndex, + PFN_CMD_PROC *ppfnCmdProcList, + IMG_UINT32 ui32MaxSyncsPerCmd[][2], + IMG_UINT32 ui32CmdCount) +{ + SYS_DATA *psSysData; + PVRSRV_ERROR eError; + IMG_UINT32 i; + IMG_UINT32 ui32AllocSize; + PFN_CMD_PROC *ppfnCmdProc; + COMMAND_COMPLETE_DATA *psCmdCompleteData; + + + if(ui32DevIndex >= SYS_DEVICE_COUNT) + { + PVR_DPF((PVR_DBG_ERROR, + "PVRSRVRegisterCmdProcListKM: invalid DeviceType 0x%x", + ui32DevIndex)); + return PVRSRV_ERROR_INVALID_PARAMS; + } + + + eError = SysAcquireData(&psSysData); + if (eError != PVRSRV_OK) + { + PVR_DPF((PVR_DBG_ERROR,"PVRSRVRegisterCmdProcListKM: SysAcquireData failed")); + return eError; + } + + + eError = OSAllocMem( PVRSRV_OS_PAGEABLE_HEAP, + ui32CmdCount * sizeof(PFN_CMD_PROC), + (IMG_VOID **)&psSysData->ppfnCmdProcList[ui32DevIndex], IMG_NULL); + if (eError != PVRSRV_OK) + { + PVR_DPF((PVR_DBG_ERROR,"PVRSRVRegisterCmdProcListKM: Failed to alloc queue")); + return eError; + } + + + ppfnCmdProc = psSysData->ppfnCmdProcList[ui32DevIndex]; + + + for (i=0; ippsCmdCompleteData[ui32DevIndex], IMG_NULL); + if (eError != PVRSRV_OK) + { + PVR_DPF((PVR_DBG_ERROR,"PVRSRVRegisterCmdProcListKM: Failed to alloc CC data")); + goto ErrorExit; + } + + for (i=0; ippsCmdCompleteData[ui32DevIndex][i], + IMG_NULL); + if (eError != PVRSRV_OK) + { + PVR_DPF((PVR_DBG_ERROR,"PVRSRVRegisterCmdProcListKM: Failed to alloc cmd %d",i)); + goto ErrorExit; + } + + + OSMemSet(psSysData->ppsCmdCompleteData[ui32DevIndex][i], 0x00, ui32AllocSize); + + psCmdCompleteData = psSysData->ppsCmdCompleteData[ui32DevIndex][i]; + + + psCmdCompleteData->psDstSync = (PVRSRV_SYNC_OBJECT*) + (((IMG_UINT32)psCmdCompleteData) + + sizeof(COMMAND_COMPLETE_DATA)); + psCmdCompleteData->psSrcSync = (PVRSRV_SYNC_OBJECT*) + (((IMG_UINT32)psCmdCompleteData->psDstSync) + + (sizeof(PVRSRV_SYNC_OBJECT) * ui32MaxSyncsPerCmd[i][0])); + } + + return PVRSRV_OK; + +ErrorExit: + + + + if(psSysData->ppsCmdCompleteData[ui32DevIndex] != IMG_NULL) + { + for (i=0; ippsCmdCompleteData[ui32DevIndex][i] != IMG_NULL) + { + OSFreeMem(PVRSRV_OS_NON_PAGEABLE_HEAP, 0, psSysData->ppsCmdCompleteData[ui32DevIndex][i], IMG_NULL); + } + } + + OSFreeMem(PVRSRV_OS_NON_PAGEABLE_HEAP, 0, psSysData->ppsCmdCompleteData[ui32DevIndex], IMG_NULL); + } + + if(psSysData->ppfnCmdProcList[ui32DevIndex] != IMG_NULL) + { + OSFreeMem(PVRSRV_OS_NON_PAGEABLE_HEAP, 0, psSysData->ppfnCmdProcList[ui32DevIndex], IMG_NULL); + } + + return eError; +} + + +IMG_EXPORT +PVRSRV_ERROR PVRSRVRemoveCmdProcListKM(IMG_UINT32 ui32DevIndex, + IMG_UINT32 ui32CmdCount) +{ + SYS_DATA *psSysData; + PVRSRV_ERROR eError; + IMG_UINT32 i; + + + if(ui32DevIndex >= SYS_DEVICE_COUNT) + { + PVR_DPF((PVR_DBG_ERROR, + "PVRSRVRemoveCmdProcListKM: invalid DeviceType 0x%x", + ui32DevIndex)); + return PVRSRV_ERROR_INVALID_PARAMS; + } + + + eError = SysAcquireData(&psSysData); + if (eError != PVRSRV_OK) + { + PVR_DPF((PVR_DBG_ERROR,"PVRSRVRemoveCmdProcListKM: SysAcquireData failed")); + return eError; + } + + if(psSysData->ppsCmdCompleteData[ui32DevIndex] == IMG_NULL) + { + PVR_DPF((PVR_DBG_ERROR,"PVRSRVRemoveCmdProcListKM: Invalid command array")); + return PVRSRV_ERROR_INVALID_PARAMS; + } + else + { + for(i=0; ippsCmdCompleteData[ui32DevIndex][i] != IMG_NULL) + { + OSFreeMem(PVRSRV_OS_NON_PAGEABLE_HEAP, 0, psSysData->ppsCmdCompleteData[ui32DevIndex][i], IMG_NULL); + } + } + + + OSFreeMem(PVRSRV_OS_NON_PAGEABLE_HEAP, 0, psSysData->ppsCmdCompleteData[ui32DevIndex], IMG_NULL); + } + + + if(psSysData->ppfnCmdProcList[ui32DevIndex] != IMG_NULL) + { + OSFreeMem(PVRSRV_OS_NON_PAGEABLE_HEAP, 0, psSysData->ppfnCmdProcList[ui32DevIndex], IMG_NULL); + } + + return PVRSRV_OK; +} + diff --git a/services4/srvkm/common/ra.c b/services4/srvkm/common/ra.c new file mode 100644 index 0000000..8278abd --- /dev/null +++ b/services4/srvkm/common/ra.c @@ -0,0 +1,1397 @@ +/********************************************************************** + * + * Copyright(c) 2008 Imagination Technologies Ltd. All rights reserved. + * + * This program is free software; you can redistribute it and/or modify it + * under the terms and conditions of the GNU General Public License, + * version 2, as published by the Free Software Foundation. + * + * This program is distributed in the hope it will be useful but, except + * as otherwise stated in writing, without any warranty; without even the + * implied warranty of merchantability or fitness for a particular purpose. + * See the GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License along with + * this program; if not, write to the Free Software Foundation, Inc., + * 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA. + * + * The full GNU General Public License is included in this distribution in + * the file called "COPYING". + * + * Contact Information: + * Imagination Technologies Ltd. + * Home Park Estate, Kings Langley, Herts, WD4 8LZ, UK + * + ******************************************************************************/ + +#include "services_headers.h" +#include "hash.h" +#include "ra.h" +#include "buffer_manager.h" +#include "osfunc.h" + +#ifdef __linux__ +#include +#include "proc.h" +#endif + +#ifdef USE_BM_FREESPACE_CHECK +#include +#endif + +#define MINIMUM_HASH_SIZE (64) + +struct _BT_ +{ + enum bt_type + { + btt_span, + btt_free, + btt_live + } type; + + + IMG_UINTPTR_T base; + IMG_SIZE_T uSize; + + + struct _BT_ *pNextSegment; + struct _BT_ *pPrevSegment; + + struct _BT_ *pNextFree; + struct _BT_ *pPrevFree; + + BM_MAPPING *psMapping; +}; +typedef struct _BT_ BT; + + +struct _RA_ARENA_ +{ + + IMG_CHAR *name; + + + IMG_UINT32 uQuantum; + + + IMG_BOOL (*pImportAlloc)(IMG_VOID *, + IMG_SIZE_T uSize, + IMG_SIZE_T *pActualSize, + BM_MAPPING **ppsMapping, + IMG_UINT32 uFlags, + IMG_UINTPTR_T *pBase); + IMG_VOID (*pImportFree) (IMG_VOID *, + IMG_UINTPTR_T, + BM_MAPPING *psMapping); + IMG_VOID (*pBackingStoreFree) (IMG_VOID *, IMG_UINT32, IMG_UINT32, IMG_HANDLE); + + + IMG_VOID *pImportHandle; + + +#define FREE_TABLE_LIMIT 32 + + + BT *aHeadFree [FREE_TABLE_LIMIT]; + + + BT *pHeadSegment; + BT *pTailSegment; + + + HASH_TABLE *pSegmentHash; + +#ifdef RA_STATS + RA_STATISTICS sStatistics; +#endif + +#if defined(CONFIG_PROC_FS) && defined(DEBUG) +#define PROC_NAME_SIZE 32 + IMG_CHAR szProcInfoName[PROC_NAME_SIZE]; + IMG_CHAR szProcSegsName[PROC_NAME_SIZE]; + IMG_BOOL bInitProcEntry; +#endif +}; +#if defined(ENABLE_RA_DUMP) +IMG_VOID RA_Dump (RA_ARENA *pArena); +#endif + +#if defined(CONFIG_PROC_FS) && defined(DEBUG) +static IMG_INT +RA_DumpSegs(IMG_CHAR *page, IMG_CHAR **start, off_t off, IMG_INT count, IMG_INT *eof, IMG_VOID *data); +static IMG_INT +RA_DumpInfo(IMG_CHAR *page, IMG_CHAR **start, off_t off, IMG_INT count, IMG_INT *eof, IMG_VOID *data); +#endif + +#ifdef USE_BM_FREESPACE_CHECK +IMG_VOID CheckBMFreespace(IMG_VOID); +#endif + +#if defined(CONFIG_PROC_FS) && defined(DEBUG) +static IMG_CHAR *ReplaceSpaces(IMG_CHAR * const pS) +{ + IMG_CHAR *pT; + + for(pT = pS; *pT != 0; pT++) + { + if (*pT == ' ' || *pT == '\t') + { + *pT = '_'; + } + } + + return pS; +} +#endif + +static IMG_BOOL +_RequestAllocFail (IMG_VOID *_h, + IMG_SIZE_T _uSize, + IMG_SIZE_T *_pActualSize, + BM_MAPPING **_ppsMapping, + IMG_UINT32 _uFlags, + IMG_UINTPTR_T *_pBase) +{ + PVR_UNREFERENCED_PARAMETER (_h); + PVR_UNREFERENCED_PARAMETER (_uSize); + PVR_UNREFERENCED_PARAMETER (_pActualSize); + PVR_UNREFERENCED_PARAMETER (_ppsMapping); + PVR_UNREFERENCED_PARAMETER (_uFlags); + PVR_UNREFERENCED_PARAMETER (_pBase); + + return IMG_FALSE; +} + +static IMG_UINT32 +pvr_log2 (IMG_SIZE_T n) +{ + IMG_UINT32 l = 0; + n>>=1; + while (n>0) + { + n>>=1; + l++; + } + return l; +} + +static PVRSRV_ERROR +_SegmentListInsertAfter (RA_ARENA *pArena, + BT *pInsertionPoint, + BT *pBT) +{ + PVR_ASSERT (pArena != IMG_NULL); + PVR_ASSERT (pInsertionPoint != IMG_NULL); + + if ((pInsertionPoint == IMG_NULL) || (pArena == IMG_NULL)) + { + PVR_DPF ((PVR_DBG_ERROR,"_SegmentListInsertAfter: invalid parameters")); + return PVRSRV_ERROR_INVALID_PARAMS; + } + + pBT->pNextSegment = pInsertionPoint->pNextSegment; + pBT->pPrevSegment = pInsertionPoint; + if (pInsertionPoint->pNextSegment == IMG_NULL) + pArena->pTailSegment = pBT; + else + pInsertionPoint->pNextSegment->pPrevSegment = pBT; + pInsertionPoint->pNextSegment = pBT; + + return PVRSRV_OK; +} + +static PVRSRV_ERROR +_SegmentListInsert (RA_ARENA *pArena, BT *pBT) +{ + PVRSRV_ERROR eError = PVRSRV_OK; + + + if (pArena->pHeadSegment == IMG_NULL) + { + pArena->pHeadSegment = pArena->pTailSegment = pBT; + pBT->pNextSegment = pBT->pPrevSegment = IMG_NULL; + } + else + { + BT *pBTScan; + + if (pBT->base < pArena->pHeadSegment->base) + { + + pBT->pNextSegment = pArena->pHeadSegment; + pArena->pHeadSegment->pPrevSegment = pBT; + pArena->pHeadSegment = pBT; + pBT->pPrevSegment = IMG_NULL; + } + else + { + + + + + pBTScan = pArena->pHeadSegment; + + while ((pBTScan->pNextSegment != IMG_NULL) && (pBT->base >= pBTScan->pNextSegment->base)) + { + pBTScan = pBTScan->pNextSegment; + } + + eError = _SegmentListInsertAfter (pArena, pBTScan, pBT); + if (eError != PVRSRV_OK) + { + return eError; + } + } + } + return eError; +} + +static IMG_VOID +_SegmentListRemove (RA_ARENA *pArena, BT *pBT) +{ + if (pBT->pPrevSegment == IMG_NULL) + pArena->pHeadSegment = pBT->pNextSegment; + else + pBT->pPrevSegment->pNextSegment = pBT->pNextSegment; + + if (pBT->pNextSegment == IMG_NULL) + pArena->pTailSegment = pBT->pPrevSegment; + else + pBT->pNextSegment->pPrevSegment = pBT->pPrevSegment; +} + +static BT * +_SegmentSplit (RA_ARENA *pArena, BT *pBT, IMG_SIZE_T uSize) +{ + BT *pNeighbour; + + PVR_ASSERT (pArena != IMG_NULL); + + if (pArena == IMG_NULL) + { + PVR_DPF ((PVR_DBG_ERROR,"_SegmentSplit: invalid parameter - pArena")); + return IMG_NULL; + } + + if(OSAllocMem(PVRSRV_OS_PAGEABLE_HEAP, + sizeof(BT), + (IMG_VOID **)&pNeighbour, IMG_NULL) != PVRSRV_OK) + { + return IMG_NULL; + } + + pNeighbour->pPrevSegment = pBT; + pNeighbour->pNextSegment = pBT->pNextSegment; + if (pBT->pNextSegment == IMG_NULL) + pArena->pTailSegment = pNeighbour; + else + pBT->pNextSegment->pPrevSegment = pNeighbour; + pBT->pNextSegment = pNeighbour; + + pNeighbour->type = btt_free; + pNeighbour->uSize = pBT->uSize - uSize; + pNeighbour->base = pBT->base + uSize; + pNeighbour->psMapping = pBT->psMapping; + pBT->uSize = uSize; + return pNeighbour; +} + +static IMG_VOID +_FreeListInsert (RA_ARENA *pArena, BT *pBT) +{ + IMG_UINT32 uIndex; + uIndex = pvr_log2 (pBT->uSize); + pBT->type = btt_free; + pBT->pNextFree = pArena->aHeadFree [uIndex]; + pBT->pPrevFree = IMG_NULL; + if (pArena->aHeadFree[uIndex] != IMG_NULL) + pArena->aHeadFree[uIndex]->pPrevFree = pBT; + pArena->aHeadFree [uIndex] = pBT; +} + +static IMG_VOID +_FreeListRemove (RA_ARENA *pArena, BT *pBT) +{ + IMG_UINT32 uIndex; + uIndex = pvr_log2 (pBT->uSize); + if (pBT->pNextFree != IMG_NULL) + pBT->pNextFree->pPrevFree = pBT->pPrevFree; + if (pBT->pPrevFree == IMG_NULL) + pArena->aHeadFree[uIndex] = pBT->pNextFree; + else + pBT->pPrevFree->pNextFree = pBT->pNextFree; +} + +static BT * +_BuildSpanMarker (IMG_UINTPTR_T base, IMG_SIZE_T uSize) +{ + BT *pBT; + + if(OSAllocMem(PVRSRV_OS_PAGEABLE_HEAP, + sizeof(BT), + (IMG_VOID **)&pBT, IMG_NULL) != PVRSRV_OK) + { + return IMG_NULL; + } + + pBT->type = btt_span; + pBT->base = base; + pBT->uSize = uSize; + pBT->psMapping = IMG_NULL; + + return pBT; +} + +static BT * +_BuildBT (IMG_UINTPTR_T base, IMG_SIZE_T uSize) +{ + BT *pBT; + + if(OSAllocMem(PVRSRV_OS_PAGEABLE_HEAP, + sizeof(BT), + (IMG_VOID **)&pBT, IMG_NULL) != PVRSRV_OK) + { + return IMG_NULL; + } + + pBT->type = btt_free; + pBT->base = base; + pBT->uSize = uSize; + + return pBT; +} + +static BT * +_InsertResource (RA_ARENA *pArena, IMG_UINTPTR_T base, IMG_SIZE_T uSize) +{ + BT *pBT; + PVR_ASSERT (pArena!=IMG_NULL); + if (pArena == IMG_NULL) + { + PVR_DPF ((PVR_DBG_ERROR,"_InsertResource: invalid parameter - pArena")); + return IMG_NULL; + } + + pBT = _BuildBT (base, uSize); + if (pBT != IMG_NULL) + { + if (_SegmentListInsert (pArena, pBT) != PVRSRV_OK) + { + PVR_DPF ((PVR_DBG_ERROR,"_InsertResource: call to _SegmentListInsert failed")); + return IMG_NULL; + } + _FreeListInsert (pArena, pBT); +#ifdef RA_STATS + pArena->sStatistics.uTotalResourceCount+=uSize; + pArena->sStatistics.uFreeResourceCount+=uSize; + pArena->sStatistics.uSpanCount++; +#endif + } + return pBT; +} + +static BT * +_InsertResourceSpan (RA_ARENA *pArena, IMG_UINTPTR_T base, IMG_SIZE_T uSize) +{ + PVRSRV_ERROR eError; + BT *pSpanStart; + BT *pSpanEnd; + BT *pBT; + + PVR_ASSERT (pArena != IMG_NULL); + if (pArena == IMG_NULL) + { + PVR_DPF ((PVR_DBG_ERROR,"_InsertResourceSpan: invalid parameter - pArena")); + return IMG_NULL; + } + + PVR_DPF ((PVR_DBG_MESSAGE, + "RA_InsertResourceSpan: arena='%s', base=0x%x, size=0x%x", + pArena->name, base, uSize)); + + pSpanStart = _BuildSpanMarker (base, uSize); + if (pSpanStart == IMG_NULL) + { + goto fail_start; + } + pSpanEnd = _BuildSpanMarker (base + uSize, 0); + if (pSpanEnd == IMG_NULL) + { + goto fail_end; + } + + pBT = _BuildBT (base, uSize); + if (pBT == IMG_NULL) + { + goto fail_bt; + } + + eError = _SegmentListInsert (pArena, pSpanStart); + if (eError != PVRSRV_OK) + { + goto fail_SegListInsert; + } + + eError = _SegmentListInsertAfter (pArena, pSpanStart, pBT); + if (eError != PVRSRV_OK) + { + goto fail_SegListInsert; + } + + _FreeListInsert (pArena, pBT); + + eError = _SegmentListInsertAfter (pArena, pBT, pSpanEnd); + if (eError != PVRSRV_OK) + { + goto fail_SegListInsert; + } + +#ifdef RA_STATS + pArena->sStatistics.uTotalResourceCount+=uSize; +#endif + return pBT; + + fail_SegListInsert: + OSFreeMem(PVRSRV_OS_PAGEABLE_HEAP, sizeof(BT), pBT, IMG_NULL); + fail_bt: + OSFreeMem(PVRSRV_OS_PAGEABLE_HEAP, sizeof(BT), pSpanEnd, IMG_NULL); + fail_end: + OSFreeMem(PVRSRV_OS_PAGEABLE_HEAP, sizeof(BT), pSpanStart, IMG_NULL); + fail_start: + return IMG_NULL; +} + +static IMG_VOID +_FreeBT (RA_ARENA *pArena, BT *pBT, IMG_BOOL bFreeBackingStore) +{ + BT *pNeighbour; + IMG_UINTPTR_T uOrigBase; + IMG_SIZE_T uOrigSize; + + PVR_ASSERT (pArena!=IMG_NULL); + PVR_ASSERT (pBT!=IMG_NULL); + + if ((pArena == IMG_NULL) || (pBT == IMG_NULL)) + { + PVR_DPF ((PVR_DBG_ERROR,"_FreeBT: invalid parameter")); + return; + } + +#ifdef RA_STATS + pArena->sStatistics.uLiveSegmentCount--; + pArena->sStatistics.uFreeSegmentCount++; + pArena->sStatistics.uFreeResourceCount+=pBT->uSize; +#endif + + uOrigBase = pBT->base; + uOrigSize = pBT->uSize; + + + pNeighbour = pBT->pPrevSegment; + if (pNeighbour!=IMG_NULL + && pNeighbour->type == btt_free + && pNeighbour->base + pNeighbour->uSize == pBT->base) + { + _FreeListRemove (pArena, pNeighbour); + _SegmentListRemove (pArena, pNeighbour); + pBT->base = pNeighbour->base; + pBT->uSize += pNeighbour->uSize; + OSFreeMem(PVRSRV_OS_PAGEABLE_HEAP, sizeof(BT), pNeighbour, IMG_NULL); +#ifdef RA_STATS + pArena->sStatistics.uFreeSegmentCount--; +#endif + } + + + pNeighbour = pBT->pNextSegment; + if (pNeighbour!=IMG_NULL + && pNeighbour->type == btt_free + && pBT->base + pBT->uSize == pNeighbour->base) + { + _FreeListRemove (pArena, pNeighbour); + _SegmentListRemove (pArena, pNeighbour); + pBT->uSize += pNeighbour->uSize; + OSFreeMem(PVRSRV_OS_PAGEABLE_HEAP, sizeof(BT), pNeighbour, IMG_NULL); +#ifdef RA_STATS + pArena->sStatistics.uFreeSegmentCount--; +#endif + } + + + if (pArena->pBackingStoreFree != IMG_NULL && bFreeBackingStore) + { + IMG_UINTPTR_T uRoundedStart, uRoundedEnd; + + + uRoundedStart = (uOrigBase / pArena->uQuantum) * pArena->uQuantum; + + if (uRoundedStart < pBT->base) + { + uRoundedStart += pArena->uQuantum; + } + + + uRoundedEnd = ((uOrigBase + uOrigSize + pArena->uQuantum - 1) / pArena->uQuantum) * pArena->uQuantum; + + if (uRoundedEnd > (pBT->base + pBT->uSize)) + { + uRoundedEnd -= pArena->uQuantum; + } + + if (uRoundedStart < uRoundedEnd) + { + pArena->pBackingStoreFree(pArena->pImportHandle, uRoundedStart, uRoundedEnd, (IMG_HANDLE)0); + } + } + + if (pBT->pNextSegment!=IMG_NULL && pBT->pNextSegment->type == btt_span + && pBT->pPrevSegment!=IMG_NULL && pBT->pPrevSegment->type == btt_span) + { + BT *next = pBT->pNextSegment; + BT *prev = pBT->pPrevSegment; + _SegmentListRemove (pArena, next); + _SegmentListRemove (pArena, prev); + _SegmentListRemove (pArena, pBT); + pArena->pImportFree (pArena->pImportHandle, pBT->base, pBT->psMapping); +#ifdef RA_STATS + pArena->sStatistics.uSpanCount--; + pArena->sStatistics.uExportCount++; + pArena->sStatistics.uFreeSegmentCount--; + pArena->sStatistics.uFreeResourceCount-=pBT->uSize; + pArena->sStatistics.uTotalResourceCount-=pBT->uSize; +#endif + OSFreeMem(PVRSRV_OS_PAGEABLE_HEAP, sizeof(BT), next, IMG_NULL); + OSFreeMem(PVRSRV_OS_PAGEABLE_HEAP, sizeof(BT), prev, IMG_NULL); + OSFreeMem(PVRSRV_OS_PAGEABLE_HEAP, sizeof(BT), pBT, IMG_NULL); + } + else + _FreeListInsert (pArena, pBT); +} + + +static IMG_BOOL +_AttemptAllocAligned (RA_ARENA *pArena, + IMG_SIZE_T uSize, + BM_MAPPING **ppsMapping, + IMG_UINT32 uFlags, + IMG_UINT32 uAlignment, + IMG_UINT32 uAlignmentOffset, + IMG_UINTPTR_T *base) +{ + IMG_UINT32 uIndex; + PVR_ASSERT (pArena!=IMG_NULL); + if (pArena == IMG_NULL) + { + PVR_DPF ((PVR_DBG_ERROR,"_AttemptAllocAligned: invalid parameter - pArena")); + return IMG_FALSE; + } + + if (uAlignment>1) + uAlignmentOffset %= uAlignment; + + + + uIndex = pvr_log2 (uSize); + +#if 0 + + if (1u<aHeadFree[uIndex]==IMG_NULL) + uIndex++; + + while (uIndex < FREE_TABLE_LIMIT) + { + if (pArena->aHeadFree[uIndex]!=IMG_NULL) + { + + BT *pBT; + + pBT = pArena->aHeadFree [uIndex]; + while (pBT!=IMG_NULL) + { + IMG_UINTPTR_T aligned_base; + + if (uAlignment>1) + aligned_base = (pBT->base + uAlignmentOffset + uAlignment - 1) / uAlignment * uAlignment - uAlignmentOffset; + else + aligned_base = pBT->base; + PVR_DPF ((PVR_DBG_MESSAGE, + "RA_AttemptAllocAligned: pBT-base=0x%x " + "pBT-size=0x%x alignedbase=0x%x size=0x%x", + pBT->base, pBT->uSize, aligned_base, uSize)); + + if (pBT->base + pBT->uSize >= aligned_base + uSize) + { + if(!pBT->psMapping || pBT->psMapping->ui32Flags == uFlags) + { + _FreeListRemove (pArena, pBT); + + PVR_ASSERT (pBT->type == btt_free); + +#ifdef RA_STATS + pArena->sStatistics.uLiveSegmentCount++; + pArena->sStatistics.uFreeSegmentCount--; + pArena->sStatistics.uFreeResourceCount-=pBT->uSize; +#endif + + + if (aligned_base > pBT->base) + { + BT *pNeighbour; + + pNeighbour = _SegmentSplit (pArena, pBT, aligned_base-pBT->base); + + if (pNeighbour==IMG_NULL) + { + PVR_DPF ((PVR_DBG_ERROR,"_AttemptAllocAligned: Front split failed")); + + _FreeListInsert (pArena, pBT); + return IMG_FALSE; + } + + _FreeListInsert (pArena, pBT); + #ifdef RA_STATS + pArena->sStatistics.uFreeSegmentCount++; + pArena->sStatistics.uFreeResourceCount+=pBT->uSize; + #endif + pBT = pNeighbour; + } + + + if (pBT->uSize > uSize) + { + BT *pNeighbour; + pNeighbour = _SegmentSplit (pArena, pBT, uSize); + + if (pNeighbour==IMG_NULL) + { + PVR_DPF ((PVR_DBG_ERROR,"_AttemptAllocAligned: Back split failed")); + + _FreeListInsert (pArena, pBT); + return IMG_FALSE; + } + + _FreeListInsert (pArena, pNeighbour); + #ifdef RA_STATS + pArena->sStatistics.uFreeSegmentCount++; + pArena->sStatistics.uFreeResourceCount+=pNeighbour->uSize; + #endif + } + + pBT->type = btt_live; + + if (!HASH_Insert (pArena->pSegmentHash, pBT->base, (IMG_UINTPTR_T) pBT)) + { + _FreeBT (pArena, pBT, IMG_FALSE); + return IMG_FALSE; + } + + if (ppsMapping!=IMG_NULL) + *ppsMapping = pBT->psMapping; + + *base = pBT->base; + + return IMG_TRUE; + } + else + { + PVR_DPF ((PVR_DBG_MESSAGE, + "AttemptAllocAligned: mismatch in flags. Import has %x, request was %x", pBT->psMapping->ui32Flags, uFlags)); + + } + } + pBT = pBT->pNextFree; + } + + } + uIndex++; + } + + return IMG_FALSE; +} + + + +RA_ARENA * +RA_Create (IMG_CHAR *name, + IMG_UINTPTR_T base, + IMG_SIZE_T uSize, + BM_MAPPING *psMapping, + IMG_SIZE_T uQuantum, + IMG_BOOL (*imp_alloc)(IMG_VOID *, IMG_SIZE_T uSize, IMG_SIZE_T *pActualSize, + BM_MAPPING **ppsMapping, IMG_UINT32 _flags, IMG_UINTPTR_T *pBase), + IMG_VOID (*imp_free) (IMG_VOID *, IMG_UINTPTR_T, BM_MAPPING *), + IMG_VOID (*backingstore_free) (IMG_VOID*, IMG_UINT32, IMG_UINT32, IMG_HANDLE), + IMG_VOID *pImportHandle) +{ + RA_ARENA *pArena; + BT *pBT; + IMG_INT i; + + PVR_DPF ((PVR_DBG_MESSAGE, + "RA_Create: name='%s', base=0x%x, uSize=0x%x, alloc=0x%x, free=0x%x", + name, base, uSize, imp_alloc, imp_free)); + + + if (OSAllocMem(PVRSRV_OS_PAGEABLE_HEAP, + sizeof (*pArena), + (IMG_VOID **)&pArena, IMG_NULL) != PVRSRV_OK) + { + goto arena_fail; + } + + pArena->name = name; + pArena->pImportAlloc = (imp_alloc!=IMG_NULL) ? imp_alloc : _RequestAllocFail; + pArena->pImportFree = imp_free; + pArena->pBackingStoreFree = backingstore_free; + pArena->pImportHandle = pImportHandle; + for (i=0; iaHeadFree[i] = IMG_NULL; + pArena->pHeadSegment = IMG_NULL; + pArena->pTailSegment = IMG_NULL; + pArena->uQuantum = uQuantum; + +#ifdef RA_STATS + pArena->sStatistics.uSpanCount = 0; + pArena->sStatistics.uLiveSegmentCount = 0; + pArena->sStatistics.uFreeSegmentCount = 0; + pArena->sStatistics.uFreeResourceCount = 0; + pArena->sStatistics.uTotalResourceCount = 0; + pArena->sStatistics.uCumulativeAllocs = 0; + pArena->sStatistics.uCumulativeFrees = 0; + pArena->sStatistics.uImportCount = 0; + pArena->sStatistics.uExportCount = 0; +#endif + +#if defined(CONFIG_PROC_FS) && defined(DEBUG) + if(strcmp(pArena->name,"") != 0) + { + IMG_INT ret; + IMG_INT (*pfnCreateProcEntry)(const IMG_CHAR *, read_proc_t, write_proc_t, IMG_VOID *); + + pArena->bInitProcEntry = !PVRSRVGetInitServerState(PVRSRV_INIT_SERVER_SUCCESSFUL); + + + pfnCreateProcEntry = pArena->bInitProcEntry ? CreateProcEntry : CreatePerProcessProcEntry; + + ret = snprintf(pArena->szProcInfoName, sizeof(pArena->szProcInfoName), "ra_info_%s", pArena->name); + if (ret > 0 && ret < sizeof(pArena->szProcInfoName)) + { + (IMG_VOID) pfnCreateProcEntry(ReplaceSpaces(pArena->szProcInfoName), RA_DumpInfo, 0, pArena); + } + else + { + pArena->szProcInfoName[0] = 0; + PVR_DPF((PVR_DBG_ERROR, "RA_Create: couldn't create ra_info proc entry for arena %s", pArena->name)); + } + + ret = snprintf(pArena->szProcSegsName, sizeof(pArena->szProcSegsName), "ra_segs_%s", pArena->name); + if (ret > 0 && ret < sizeof(pArena->szProcInfoName)) + { + (IMG_VOID) pfnCreateProcEntry(ReplaceSpaces(pArena->szProcSegsName), RA_DumpSegs, 0, pArena); + } + else + { + pArena->szProcSegsName[0] = 0; + PVR_DPF((PVR_DBG_ERROR, "RA_Create: couldn't create ra_segs proc entry for arena %s", pArena->name)); + } + } +#endif + + pArena->pSegmentHash = HASH_Create (MINIMUM_HASH_SIZE); + if (pArena->pSegmentHash==IMG_NULL) + { + goto hash_fail; + } + if (uSize>0) + { + uSize = (uSize + uQuantum - 1) / uQuantum * uQuantum; + pBT = _InsertResource (pArena, base, uSize); + if (pBT == IMG_NULL) + { + goto insert_fail; + } + pBT->psMapping = psMapping; + + } + return pArena; + +insert_fail: + HASH_Delete (pArena->pSegmentHash); +hash_fail: + OSFreeMem(PVRSRV_OS_PAGEABLE_HEAP, sizeof(RA_ARENA), pArena, IMG_NULL); +arena_fail: + return IMG_NULL; +} + +IMG_VOID +RA_Delete (RA_ARENA *pArena) +{ + IMG_UINT32 uIndex; + + PVR_ASSERT(pArena != IMG_NULL); + + if (pArena == IMG_NULL) + { + PVR_DPF ((PVR_DBG_ERROR,"RA_Delete: invalid parameter - pArena")); + return; + } + + PVR_DPF ((PVR_DBG_MESSAGE, + "RA_Delete: name='%s'", pArena->name)); + + for (uIndex=0; uIndexaHeadFree[uIndex] = IMG_NULL; + + while (pArena->pHeadSegment != IMG_NULL) + { + BT *pBT = pArena->pHeadSegment; + PVR_ASSERT (pBT->type == btt_free); + _SegmentListRemove (pArena, pBT); + OSFreeMem(PVRSRV_OS_PAGEABLE_HEAP, sizeof(BT), pBT, IMG_NULL); +#ifdef RA_STATS + pArena->sStatistics.uSpanCount--; +#endif + } +#if defined(CONFIG_PROC_FS) && defined(DEBUG) + { + IMG_VOID (*pfnRemoveProcEntry)(const IMG_CHAR *); + + pfnRemoveProcEntry = pArena->bInitProcEntry ? RemoveProcEntry : RemovePerProcessProcEntry; + + if (pArena->szProcInfoName[0] != 0) + { + pfnRemoveProcEntry(pArena->szProcInfoName); + } + + if (pArena->szProcSegsName[0] != 0) + { + pfnRemoveProcEntry(pArena->szProcSegsName); + } + } +#endif + HASH_Delete (pArena->pSegmentHash); + OSFreeMem(PVRSRV_OS_PAGEABLE_HEAP, sizeof(RA_ARENA), pArena, IMG_NULL); +} + +IMG_BOOL +RA_TestDelete (RA_ARENA *pArena) +{ + PVR_ASSERT(pArena != IMG_NULL); + + if (pArena != IMG_NULL) + { + while (pArena->pHeadSegment != IMG_NULL) + { + BT *pBT = pArena->pHeadSegment; + if (pBT->type != btt_free) + { + return IMG_FALSE; + } + } + } + + return IMG_TRUE; +} + +IMG_BOOL +RA_Add (RA_ARENA *pArena, IMG_UINTPTR_T base, IMG_SIZE_T uSize) +{ + PVR_ASSERT (pArena != IMG_NULL); + + if (pArena == IMG_NULL) + { + PVR_DPF ((PVR_DBG_ERROR,"RA_Add: invalid parameter - pArena")); + return IMG_FALSE; + } + + PVR_DPF ((PVR_DBG_MESSAGE, + "RA_Add: name='%s', base=0x%x, size=0x%x", pArena->name, base, uSize)); + + uSize = (uSize + pArena->uQuantum - 1) / pArena->uQuantum * pArena->uQuantum; + return ((IMG_BOOL)(_InsertResource (pArena, base, uSize) != IMG_NULL)); +} + +IMG_BOOL +RA_Alloc (RA_ARENA *pArena, + IMG_SIZE_T uRequestSize, + IMG_SIZE_T *pActualSize, + BM_MAPPING **ppsMapping, + IMG_UINT32 uFlags, + IMG_UINT32 uAlignment, + IMG_UINT32 uAlignmentOffset, + IMG_UINTPTR_T *base) +{ + IMG_BOOL bResult; + IMG_SIZE_T uSize = uRequestSize; + + PVR_ASSERT (pArena!=IMG_NULL); + + if (pArena == IMG_NULL) + { + PVR_DPF ((PVR_DBG_ERROR,"RA_Alloc: invalid parameter - pArena")); + return IMG_FALSE; + } + +#ifdef USE_BM_FREESPACE_CHECK + CheckBMFreespace(); +#endif + + if (pActualSize != IMG_NULL) + { + *pActualSize = uSize; + } + + PVR_DPF ((PVR_DBG_MESSAGE, + "RA_Alloc: arena='%s', size=0x%x(0x%x), alignment=0x%x, offset=0x%x", + pArena->name, uSize, uRequestSize, uAlignment, uAlignmentOffset)); + + + + bResult = _AttemptAllocAligned (pArena, uSize, ppsMapping, uFlags, + uAlignment, uAlignmentOffset, base); + if (!bResult) + { + BM_MAPPING *psImportMapping; + IMG_UINTPTR_T import_base; + IMG_SIZE_T uImportSize = uSize; + + + + + if (uAlignment > pArena->uQuantum) + { + uImportSize += (uAlignment - 1); + } + + + uImportSize = ((uImportSize + pArena->uQuantum - 1)/pArena->uQuantum)*pArena->uQuantum; + + bResult = + pArena->pImportAlloc (pArena->pImportHandle, uImportSize, &uImportSize, + &psImportMapping, uFlags, &import_base); + if (bResult) + { + BT *pBT; + pBT = _InsertResourceSpan (pArena, import_base, uImportSize); + + if (pBT == IMG_NULL) + { + + pArena->pImportFree(pArena->pImportHandle, import_base, + psImportMapping); + PVR_DPF ((PVR_DBG_MESSAGE, + "RA_Alloc: name='%s', size=0x%x failed!", + pArena->name, uSize)); + + return IMG_FALSE; + } + pBT->psMapping = psImportMapping; +#ifdef RA_STATS + pArena->sStatistics.uFreeSegmentCount++; + pArena->sStatistics.uFreeResourceCount += uImportSize; + pArena->sStatistics.uImportCount++; + pArena->sStatistics.uSpanCount++; +#endif + bResult = _AttemptAllocAligned(pArena, uSize, ppsMapping, uFlags, + uAlignment, uAlignmentOffset, + base); + if (!bResult) + { + PVR_DPF ((PVR_DBG_MESSAGE, + "RA_Alloc: name='%s' uAlignment failed!", + pArena->name)); + } + } + } +#ifdef RA_STATS + if (bResult) + pArena->sStatistics.uCumulativeAllocs++; +#endif + + PVR_DPF ((PVR_DBG_MESSAGE, + "RA_Alloc: name='%s', size=0x%x, *base=0x%x = %d", + pArena->name, uSize, *base, bResult)); + + + + return bResult; +} + +IMG_VOID +RA_Free (RA_ARENA *pArena, IMG_UINTPTR_T base, IMG_BOOL bFreeBackingStore) +{ + BT *pBT; + + PVR_ASSERT (pArena != IMG_NULL); + + if (pArena == IMG_NULL) + { + PVR_DPF ((PVR_DBG_ERROR,"RA_Free: invalid parameter - pArena")); + return; + } + +#ifdef USE_BM_FREESPACE_CHECK + CheckBMFreespace(); +#endif + + PVR_DPF ((PVR_DBG_MESSAGE, + "RA_Free: name='%s', base=0x%x", pArena->name, base)); + + pBT = (BT *) HASH_Remove (pArena->pSegmentHash, base); + PVR_ASSERT (pBT != IMG_NULL); + + if (pBT) + { + PVR_ASSERT (pBT->base == base); + +#ifdef RA_STATS + pArena->sStatistics.uCumulativeFrees++; +#endif + +#ifdef USE_BM_FREESPACE_CHECK +{ + IMG_BYTE* p; + IMG_BYTE* endp; + + p = (IMG_BYTE*)pBT->base + SysGetDevicePhysOffset(); + endp = (IMG_BYTE*)((IMG_UINT32)(p + pBT->uSize)); + while ((IMG_UINT32)p & 3) + { + *p++ = 0xAA; + } + while (p < (IMG_BYTE*)((IMG_UINT32)endp & 0xfffffffc)) + { + *(IMG_UINT32*)p = 0xAAAAAAAA; + p += sizeof(IMG_UINT32); + } + while (p < endp) + { + *p++ = 0xAA; + } + PVR_DPF((PVR_DBG_MESSAGE,"BM_FREESPACE_CHECK: RA_Free Cleared %08X to %08X (size=0x%x)",(IMG_BYTE*)pBT->base + SysGetDevicePhysOffset(),endp-1,pBT->uSize)); +} +#endif + _FreeBT (pArena, pBT, bFreeBackingStore); + } +} + + +IMG_BOOL RA_GetNextLiveSegment(IMG_HANDLE hArena, RA_SEGMENT_DETAILS *psSegDetails) +{ + BT *pBT; + + if (psSegDetails->hSegment) + { + pBT = (BT *)psSegDetails->hSegment; + } + else + { + RA_ARENA *pArena = (RA_ARENA *)hArena; + + pBT = pArena->pHeadSegment; + } + + while (pBT != IMG_NULL) + { + if (pBT->type == btt_live) + { + psSegDetails->uiSize = pBT->uSize; + psSegDetails->sCpuPhyAddr.uiAddr = pBT->base; + psSegDetails->hSegment = (IMG_HANDLE)pBT->pNextSegment; + + return IMG_TRUE; + } + + pBT = pBT->pNextSegment; + } + + psSegDetails->uiSize = 0; + psSegDetails->sCpuPhyAddr.uiAddr = 0; + psSegDetails->hSegment = (IMG_HANDLE)-1; + + return IMG_FALSE; +} + + +#ifdef USE_BM_FREESPACE_CHECK +RA_ARENA* pJFSavedArena = IMG_NULL; + +IMG_VOID CheckBMFreespace(IMG_VOID) +{ + BT *pBT; + IMG_BYTE* p; + IMG_BYTE* endp; + + if (pJFSavedArena != IMG_NULL) + { + for (pBT=pJFSavedArena->pHeadSegment; pBT!=IMG_NULL; pBT=pBT->pNextSegment) + { + if (pBT->type == btt_free) + { + p = (IMG_BYTE*)pBT->base + SysGetDevicePhysOffset(); + endp = (IMG_BYTE*)((IMG_UINT32)(p + pBT->uSize) & 0xfffffffc); + + while ((IMG_UINT32)p & 3) + { + if (*p++ != 0xAA) + { + fprintf(stderr,"BM_FREESPACE_CHECK: Blank space at %08X has changed to 0x%x\n",p,*(IMG_UINT32*)p); + for (;;); + break; + } + } + while (p < endp) + { + if (*(IMG_UINT32*)p != 0xAAAAAAAA) + { + fprintf(stderr,"BM_FREESPACE_CHECK: Blank space at %08X has changed to 0x%x\n",p,*(IMG_UINT32*)p); + for (;;); + break; + } + p += 4; + } + } + } + } +} +#endif + + +#if (defined(CONFIG_PROC_FS) && defined(DEBUG)) || defined (RA_STATS) +static IMG_CHAR * +_BTType (IMG_INT eType) +{ + switch (eType) + { + case btt_span: return "span"; + case btt_free: return "free"; + case btt_live: return "live"; + } + return "junk"; +} +#endif + +#if defined(ENABLE_RA_DUMP) +IMG_VOID +RA_Dump (RA_ARENA *pArena) +{ + BT *pBT; + PVR_ASSERT (pArena != IMG_NULL); + PVR_DPF ((PVR_DBG_MESSAGE,"Arena '%s':", pArena->name)); + PVR_DPF ((PVR_DBG_MESSAGE," alloc=%08X free=%08X handle=%08X quantum=%d", + pArena->pImportAlloc, pArena->pImportFree, pArena->pImportHandle, + pArena->uQuantum)); + PVR_DPF ((PVR_DBG_MESSAGE," segment Chain:")); + if (pArena->pHeadSegment != IMG_NULL && + pArena->pHeadSegment->pPrevSegment != IMG_NULL) + PVR_DPF ((PVR_DBG_MESSAGE," error: head boundary tag has invalid pPrevSegment")); + if (pArena->pTailSegment != IMG_NULL && + pArena->pTailSegment->pNextSegment != IMG_NULL) + PVR_DPF ((PVR_DBG_MESSAGE," error: tail boundary tag has invalid pNextSegment")); + + for (pBT=pArena->pHeadSegment; pBT!=IMG_NULL; pBT=pBT->pNextSegment) + { + PVR_DPF ((PVR_DBG_MESSAGE,"\tbase=0x%x size=0x%x type=%s ref=%08X", + (IMG_UINT32) pBT->base, pBT->uSize, _BTType (pBT->type), + pBT->pRef)); + } + +#ifdef HASH_TRACE + HASH_Dump (pArena->pSegmentHash); +#endif +} +#endif + + +#if defined(CONFIG_PROC_FS) && defined(DEBUG) +static IMG_INT +RA_DumpSegs(IMG_CHAR *page, IMG_CHAR **start, off_t off, IMG_INT count, IMG_INT *eof, IMG_VOID *data) +{ + BT *pBT = 0; + IMG_INT len = 0; + RA_ARENA *pArena = (RA_ARENA *)data; + + if (count < 80) + { + *start = (IMG_CHAR *)0; + return (0); + } + *eof = 0; + *start = (IMG_CHAR *)1; + if (off == 0) + { + return printAppend(page, count, 0, "Arena \"%s\"\nBase Size Type Ref\n", pArena->name); + } + for (pBT=pArena->pHeadSegment; --off && pBT; pBT=pBT->pNextSegment) + ; + if (pBT) + { + len = printAppend(page, count, 0, "%08x %8x %4s %08x\n", + (IMG_UINT)pBT->base, (IMG_UINT)pBT->uSize, _BTType (pBT->type), + (IMG_UINT)pBT->psMapping); + } + else + { + *eof = 1; + } + return (len); +} + +static IMG_INT +RA_DumpInfo(IMG_CHAR *page, IMG_CHAR **start, off_t off, IMG_INT count, IMG_INT *eof, IMG_VOID *data) +{ + IMG_INT len = 0; + RA_ARENA *pArena = (RA_ARENA *)data; + + if (count < 80) + { + *start = (IMG_CHAR *)0; + return (0); + } + *eof = 0; + switch (off) + { + case 0: + len = printAppend(page, count, 0, "quantum\t\t\t%lu\n", pArena->uQuantum); + break; + case 1: + len = printAppend(page, count, 0, "import_handle\t\t%08X\n", (IMG_UINT)pArena->pImportHandle); + break; +#ifdef RA_STATS + case 2: + len = printAppend(page, count, 0, "span count\t\t%lu\n", pArena->sStatistics.uSpanCount); + break; + case 3: + len = printAppend(page, count, 0, "live segment count\t%lu\n", pArena->sStatistics.uLiveSegmentCount); + break; + case 4: + len = printAppend(page, count, 0, "free segment count\t%lu\n", pArena->sStatistics.uFreeSegmentCount); + break; + case 5: + len = printAppend(page, count, 0, "free resource count\t%lu (0x%x)\n", + pArena->sStatistics.uFreeResourceCount, + (IMG_UINT)pArena->sStatistics.uFreeResourceCount); + break; + case 6: + len = printAppend(page, count, 0, "total allocs\t\t%lu\n", pArena->sStatistics.uCumulativeAllocs); + break; + case 7: + len = printAppend(page, count, 0, "total frees\t\t%lu\n", pArena->sStatistics.uCumulativeFrees); + break; + case 8: + len = printAppend(page, count, 0, "import count\t\t%lu\n", pArena->sStatistics.uImportCount); + break; + case 9: + len = printAppend(page, count, 0, "export count\t\t%lu\n", pArena->sStatistics.uExportCount); + break; +#endif + + default: + *eof = 1; + } + *start = (IMG_CHAR *)1; + return (len); +} +#endif + + +#ifdef RA_STATS +PVRSRV_ERROR RA_GetStats(RA_ARENA *pArena, + IMG_CHAR **ppszStr, + IMG_UINT32 *pui32StrLen) +{ + IMG_CHAR *pszStr = *ppszStr; + IMG_UINT32 ui32StrLen = *pui32StrLen; + IMG_INT32 i32Count; + BT *pBT; + + CHECK_SPACE(ui32StrLen); + i32Count = OSSNPrintf(pszStr, 100, "\nArena '%s':\n", pArena->name); + UPDATE_SPACE(pszStr, i32Count, ui32StrLen); + + + CHECK_SPACE(ui32StrLen); + i32Count = OSSNPrintf(pszStr, 100, " allocCB=%08X freeCB=%08X handle=%08X quantum=%d\n", + pArena->pImportAlloc, + pArena->pImportFree, + pArena->pImportHandle, + pArena->uQuantum); + UPDATE_SPACE(pszStr, i32Count, ui32StrLen); + + CHECK_SPACE(ui32StrLen); + i32Count = OSSNPrintf(pszStr, 100, "span count\t\t%lu\n", pArena->sStatistics.uSpanCount); + UPDATE_SPACE(pszStr, i32Count, ui32StrLen); + + CHECK_SPACE(ui32StrLen); + i32Count = OSSNPrintf(pszStr, 100, "live segment count\t%lu\n", pArena->sStatistics.uLiveSegmentCount); + UPDATE_SPACE(pszStr, i32Count, ui32StrLen); + + CHECK_SPACE(ui32StrLen); + i32Count = OSSNPrintf(pszStr, 100, "free segment count\t%lu\n", pArena->sStatistics.uFreeSegmentCount); + UPDATE_SPACE(pszStr, i32Count, ui32StrLen); + + CHECK_SPACE(ui32StrLen); + i32Count = OSSNPrintf(pszStr, 100, "free resource count\t%lu (0x%x)\n", + pArena->sStatistics.uFreeResourceCount, + (IMG_UINT)pArena->sStatistics.uFreeResourceCount); + UPDATE_SPACE(pszStr, i32Count, ui32StrLen); + + CHECK_SPACE(ui32StrLen); + i32Count = OSSNPrintf(pszStr, 100, "total allocs\t\t%lu\n", pArena->sStatistics.uCumulativeAllocs); + UPDATE_SPACE(pszStr, i32Count, ui32StrLen); + + CHECK_SPACE(ui32StrLen); + i32Count = OSSNPrintf(pszStr, 100, "total frees\t\t%lu\n", pArena->sStatistics.uCumulativeFrees); + UPDATE_SPACE(pszStr, i32Count, ui32StrLen); + + CHECK_SPACE(ui32StrLen); + i32Count = OSSNPrintf(pszStr, 100, "import count\t\t%lu\n", pArena->sStatistics.uImportCount); + UPDATE_SPACE(pszStr, i32Count, ui32StrLen); + + CHECK_SPACE(ui32StrLen); + i32Count = OSSNPrintf(pszStr, 100, "export count\t\t%lu\n", pArena->sStatistics.uExportCount); + UPDATE_SPACE(pszStr, i32Count, ui32StrLen); + + CHECK_SPACE(ui32StrLen); + i32Count = OSSNPrintf(pszStr, 100, " segment Chain:\n"); + UPDATE_SPACE(pszStr, i32Count, ui32StrLen); + + if (pArena->pHeadSegment != IMG_NULL && + pArena->pHeadSegment->pPrevSegment != IMG_NULL) + { + CHECK_SPACE(ui32StrLen); + i32Count = OSSNPrintf(pszStr, 100, " error: head boundary tag has invalid pPrevSegment\n"); + UPDATE_SPACE(pszStr, i32Count, ui32StrLen); + } + + if (pArena->pTailSegment != IMG_NULL && + pArena->pTailSegment->pNextSegment != IMG_NULL) + { + CHECK_SPACE(ui32StrLen); + i32Count = OSSNPrintf(pszStr, 100, " error: tail boundary tag has invalid pNextSegment\n"); + UPDATE_SPACE(pszStr, i32Count, ui32StrLen); + } + + for (pBT=pArena->pHeadSegment; pBT!=IMG_NULL; pBT=pBT->pNextSegment) + { + CHECK_SPACE(ui32StrLen); + i32Count = OSSNPrintf(pszStr, 100, "\tbase=0x%x size=0x%x type=%s ref=%08X\n", + (IMG_UINT32) pBT->base, + pBT->uSize, + _BTType(pBT->type), + pBT->psMapping); + UPDATE_SPACE(pszStr, i32Count, ui32StrLen); + } + + *ppszStr = pszStr; + *pui32StrLen = ui32StrLen; + + return PVRSRV_OK; +} +#endif + diff --git a/services4/srvkm/common/resman.c b/services4/srvkm/common/resman.c new file mode 100644 index 0000000..d713c3c --- /dev/null +++ b/services4/srvkm/common/resman.c @@ -0,0 +1,729 @@ +/********************************************************************** + * + * Copyright(c) 2008 Imagination Technologies Ltd. All rights reserved. + * + * This program is free software; you can redistribute it and/or modify it + * under the terms and conditions of the GNU General Public License, + * version 2, as published by the Free Software Foundation. + * + * This program is distributed in the hope it will be useful but, except + * as otherwise stated in writing, without any warranty; without even the + * implied warranty of merchantability or fitness for a particular purpose. + * See the GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License along with + * this program; if not, write to the Free Software Foundation, Inc., + * 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA. + * + * The full GNU General Public License is included in this distribution in + * the file called "COPYING". + * + * Contact Information: + * Imagination Technologies Ltd. + * Home Park Estate, Kings Langley, Herts, WD4 8LZ, UK + * + ******************************************************************************/ + +#include "services_headers.h" +#include "resman.h" + +#ifdef __linux__ +#ifndef AUTOCONF_INCLUDED + #include +#endif + +#include +#include +#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,9) +#include +#else +#include +#endif + +#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,27) +#include +#else +#include +#endif + +static DECLARE_MUTEX(lock); + +#define ACQUIRE_SYNC_OBJ do { \ + if (in_interrupt()) { \ + printk ("ISR cannot take RESMAN mutex\n"); \ + BUG(); \ + } \ + else down (&lock); \ +} while (0) +#define RELEASE_SYNC_OBJ up (&lock) + +#else + +#define ACQUIRE_SYNC_OBJ +#define RELEASE_SYNC_OBJ + +#endif + +#define RESMAN_SIGNATURE 0x12345678 + +typedef struct _RESMAN_ITEM_ +{ +#ifdef DEBUG + IMG_UINT32 ui32Signature; +#endif + struct _RESMAN_ITEM_ **ppsThis; + struct _RESMAN_ITEM_ *psNext; + + IMG_UINT32 ui32Flags; + IMG_UINT32 ui32ResType; + + IMG_PVOID pvParam; + IMG_UINT32 ui32Param; + + RESMAN_FREE_FN pfnFreeResource; +} RESMAN_ITEM; + + +typedef struct _RESMAN_CONTEXT_ +{ +#ifdef DEBUG + IMG_UINT32 ui32Signature; +#endif + struct _RESMAN_CONTEXT_ **ppsThis; + struct _RESMAN_CONTEXT_ *psNext; + + PVRSRV_PER_PROCESS_DATA *psPerProc; + + RESMAN_ITEM *psResItemList; + +} RESMAN_CONTEXT; + + +typedef struct +{ + RESMAN_CONTEXT *psContextList; + +} RESMAN_LIST, *PRESMAN_LIST; + + +PRESMAN_LIST gpsResList = IMG_NULL; + + +#define PRINT_RESLIST(x, y, z) + +static PVRSRV_ERROR FreeResourceByPtr(RESMAN_ITEM *psItem, IMG_BOOL bExecuteCallback); + +static PVRSRV_ERROR FreeResourceByCriteria(PRESMAN_CONTEXT psContext, + IMG_UINT32 ui32SearchCriteria, + IMG_UINT32 ui32ResType, + IMG_PVOID pvParam, + IMG_UINT32 ui32Param, + IMG_BOOL bExecuteCallback); + + +#ifdef DEBUG + static IMG_VOID ValidateResList(PRESMAN_LIST psResList); + #define VALIDATERESLIST() ValidateResList(gpsResList) +#else + #define VALIDATERESLIST() +#endif + + + + + + +PVRSRV_ERROR ResManInit(IMG_VOID) +{ + if (gpsResList == IMG_NULL) + { + + if (OSAllocMem(PVRSRV_OS_PAGEABLE_HEAP, + sizeof(*gpsResList), + (IMG_VOID **)&gpsResList, IMG_NULL) != PVRSRV_OK) + { + return PVRSRV_ERROR_OUT_OF_MEMORY; + } + + + gpsResList->psContextList = IMG_NULL; + + + VALIDATERESLIST(); + } + + return PVRSRV_OK; +} + + +IMG_VOID ResManDeInit(IMG_VOID) +{ + if (gpsResList != IMG_NULL) + { + + OSFreeMem(PVRSRV_OS_PAGEABLE_HEAP, sizeof(*gpsResList), gpsResList, IMG_NULL); + } +} + + +PVRSRV_ERROR PVRSRVResManConnect(IMG_HANDLE hPerProc, + PRESMAN_CONTEXT *phResManContext) +{ + PVRSRV_ERROR eError; + PRESMAN_CONTEXT psResManContext; + + + ACQUIRE_SYNC_OBJ; + + + VALIDATERESLIST(); + + + eError = OSAllocMem(PVRSRV_OS_PAGEABLE_HEAP, sizeof(*psResManContext), + (IMG_VOID **)&psResManContext, IMG_NULL); + if (eError != PVRSRV_OK) + { + PVR_DPF((PVR_DBG_ERROR, "PVRSRVResManConnect: ERROR allocating new RESMAN context struct")); + + + VALIDATERESLIST(); + + + RELEASE_SYNC_OBJ; + + return eError; + } + +#ifdef DEBUG + psResManContext->ui32Signature = RESMAN_SIGNATURE; +#endif + psResManContext->psResItemList = IMG_NULL; + psResManContext->psPerProc = hPerProc; + + + psResManContext->psNext = gpsResList->psContextList; + psResManContext->ppsThis = &gpsResList->psContextList; + gpsResList->psContextList = psResManContext; + if (psResManContext->psNext) + { + psResManContext->psNext->ppsThis = &(psResManContext->psNext); + } + + + VALIDATERESLIST(); + + + RELEASE_SYNC_OBJ; + + *phResManContext = psResManContext; + + return PVRSRV_OK; +} + + +IMG_VOID PVRSRVResManDisconnect(PRESMAN_CONTEXT psResManContext, + IMG_BOOL bKernelContext) +{ + + ACQUIRE_SYNC_OBJ; + + + VALIDATERESLIST(); + + + PRINT_RESLIST(gpsResList, psResManContext, IMG_TRUE); + + + + if (!bKernelContext) + { + + FreeResourceByCriteria(psResManContext, RESMAN_CRITERIA_RESTYPE, RESMAN_TYPE_OS_USERMODE_MAPPING, 0, 0, IMG_TRUE); + + + FreeResourceByCriteria(psResManContext, RESMAN_CRITERIA_RESTYPE, RESMAN_TYPE_EVENT_OBJECT, 0, 0, IMG_TRUE); + + + FreeResourceByCriteria(psResManContext, RESMAN_CRITERIA_RESTYPE, RESMAN_TYPE_HW_RENDER_CONTEXT, 0, 0, IMG_TRUE); + FreeResourceByCriteria(psResManContext, RESMAN_CRITERIA_RESTYPE, RESMAN_TYPE_HW_TRANSFER_CONTEXT, 0, 0, IMG_TRUE); + FreeResourceByCriteria(psResManContext, RESMAN_CRITERIA_RESTYPE, RESMAN_TYPE_HW_2D_CONTEXT, 0, 0, IMG_TRUE); + FreeResourceByCriteria(psResManContext, RESMAN_CRITERIA_RESTYPE, RESMAN_TYPE_TRANSFER_CONTEXT, 0, 0, IMG_TRUE); + FreeResourceByCriteria(psResManContext, RESMAN_CRITERIA_RESTYPE, RESMAN_TYPE_SHARED_PB_DESC_CREATE_LOCK, 0, 0, IMG_TRUE); + FreeResourceByCriteria(psResManContext, RESMAN_CRITERIA_RESTYPE, RESMAN_TYPE_SHARED_PB_DESC, 0, 0, IMG_TRUE); + + + + + FreeResourceByCriteria(psResManContext, RESMAN_CRITERIA_RESTYPE, RESMAN_TYPE_DISPLAYCLASS_SWAPCHAIN, 0, 0, IMG_TRUE); + FreeResourceByCriteria(psResManContext, RESMAN_CRITERIA_RESTYPE, RESMAN_TYPE_DISPLAYCLASS_DEVICE, 0, 0, IMG_TRUE); + + + FreeResourceByCriteria(psResManContext, RESMAN_CRITERIA_RESTYPE, RESMAN_TYPE_BUFFERCLASS_DEVICE, 0, 0, IMG_TRUE); + + + FreeResourceByCriteria(psResManContext, RESMAN_CRITERIA_RESTYPE, RESMAN_TYPE_DEVICECLASSMEM_MAPPING, 0, 0, IMG_TRUE); + FreeResourceByCriteria(psResManContext, RESMAN_CRITERIA_RESTYPE, RESMAN_TYPE_DEVICEMEM_WRAP, 0, 0, IMG_TRUE); + FreeResourceByCriteria(psResManContext, RESMAN_CRITERIA_RESTYPE, RESMAN_TYPE_DEVICEMEM_MAPPING, 0, 0, IMG_TRUE); + FreeResourceByCriteria(psResManContext, RESMAN_CRITERIA_RESTYPE, RESMAN_TYPE_KERNEL_DEVICEMEM_ALLOCATION, 0, 0, IMG_TRUE); + FreeResourceByCriteria(psResManContext, RESMAN_CRITERIA_RESTYPE, RESMAN_TYPE_DEVICEMEM_ALLOCATION, 0, 0, IMG_TRUE); + FreeResourceByCriteria(psResManContext, RESMAN_CRITERIA_RESTYPE, RESMAN_TYPE_DEVICEMEM_CONTEXT, 0, 0, IMG_TRUE); + } + + + PVR_ASSERT(psResManContext->psResItemList == IMG_NULL); + + + *(psResManContext->ppsThis) = psResManContext->psNext; + if (psResManContext->psNext) + { + psResManContext->psNext->ppsThis = psResManContext->ppsThis; + } + + + OSFreeMem(PVRSRV_OS_PAGEABLE_HEAP, sizeof(RESMAN_CONTEXT), psResManContext, IMG_NULL); + + + + VALIDATERESLIST(); + + + PRINT_RESLIST(gpsResList, psResManContext, IMG_FALSE); + + + RELEASE_SYNC_OBJ; +} + + +PRESMAN_ITEM ResManRegisterRes(PRESMAN_CONTEXT psResManContext, + IMG_UINT32 ui32ResType, + IMG_PVOID pvParam, + IMG_UINT32 ui32Param, + RESMAN_FREE_FN pfnFreeResource) +{ + PRESMAN_ITEM psNewResItem; + + PVR_ASSERT(psResManContext != IMG_NULL); + PVR_ASSERT(ui32ResType != 0); + + if (psResManContext == IMG_NULL) + { + PVR_DPF((PVR_DBG_ERROR, "ResManRegisterRes: invalid parameter - psResManContext")); + return (PRESMAN_ITEM) IMG_NULL; + } + + + ACQUIRE_SYNC_OBJ; + + + VALIDATERESLIST(); + + PVR_DPF((PVR_DBG_MESSAGE, "ResManRegisterRes: register resource " + "Context 0x%x, ResType 0x%x, pvParam 0x%x, ui32Param 0x%x, " + "FreeFunc %08X", + psResManContext, ui32ResType, (IMG_UINT32)pvParam, + ui32Param, pfnFreeResource)); + + + if (OSAllocMem(PVRSRV_OS_PAGEABLE_HEAP, + sizeof(RESMAN_ITEM), (IMG_VOID **)&psNewResItem, + IMG_NULL) != PVRSRV_OK) + { + PVR_DPF((PVR_DBG_ERROR, "ResManRegisterRes: " + "ERROR allocating new resource item")); + + + RELEASE_SYNC_OBJ; + + return((PRESMAN_ITEM)IMG_NULL); + } + + +#ifdef DEBUG + psNewResItem->ui32Signature = RESMAN_SIGNATURE; +#endif + psNewResItem->ui32ResType = ui32ResType; + psNewResItem->pvParam = pvParam; + psNewResItem->ui32Param = ui32Param; + psNewResItem->pfnFreeResource = pfnFreeResource; + psNewResItem->ui32Flags = 0; + + + psNewResItem->ppsThis = &psResManContext->psResItemList; + psNewResItem->psNext = psResManContext->psResItemList; + psResManContext->psResItemList = psNewResItem; + if (psNewResItem->psNext) + { + psNewResItem->psNext->ppsThis = &psNewResItem->psNext; + } + + + VALIDATERESLIST(); + + + RELEASE_SYNC_OBJ; + + return(psNewResItem); +} + +PVRSRV_ERROR ResManFreeResByPtr(RESMAN_ITEM *psResItem) +{ + PVRSRV_ERROR eError; + + PVR_ASSERT(psResItem != IMG_NULL); + + if (psResItem == IMG_NULL) + { + PVR_DPF((PVR_DBG_MESSAGE, "ResManFreeResByPtr: NULL ptr - nothing to do")); + return PVRSRV_OK; + } + + PVR_DPF((PVR_DBG_MESSAGE, "ResManFreeResByPtr: freeing resource at %08X", psResItem)); + + + ACQUIRE_SYNC_OBJ; + + + VALIDATERESLIST(); + + + eError = FreeResourceByPtr(psResItem, IMG_TRUE); + + + VALIDATERESLIST(); + + + RELEASE_SYNC_OBJ; + + return(eError); +} + + +PVRSRV_ERROR ResManFreeResByCriteria(PRESMAN_CONTEXT psResManContext, + IMG_UINT32 ui32SearchCriteria, + IMG_UINT32 ui32ResType, + IMG_PVOID pvParam, + IMG_UINT32 ui32Param) +{ + PVRSRV_ERROR eError; + + PVR_ASSERT(psResManContext != IMG_NULL); + + + ACQUIRE_SYNC_OBJ; + + + VALIDATERESLIST(); + + PVR_DPF((PVR_DBG_MESSAGE, "ResManFreeResByCriteria: " + "Context 0x%x, Criteria 0x%x, Type 0x%x, Addr 0x%x, Param 0x%x", + psResManContext, ui32SearchCriteria, ui32ResType, + (IMG_UINT32)pvParam, ui32Param)); + + + eError = FreeResourceByCriteria(psResManContext, ui32SearchCriteria, + ui32ResType, pvParam, ui32Param, + IMG_TRUE); + + + VALIDATERESLIST(); + + + RELEASE_SYNC_OBJ; + + return eError; +} + + +PVRSRV_ERROR ResManDissociateRes(RESMAN_ITEM *psResItem, + PRESMAN_CONTEXT psNewResManContext) +{ + PVRSRV_ERROR eError = PVRSRV_OK; + + PVR_ASSERT(psResItem != IMG_NULL); + + if (psResItem == IMG_NULL) + { + PVR_DPF((PVR_DBG_ERROR, "ResManDissociateRes: invalid parameter - psResItem")); + PVR_DBG_BREAK; + return PVRSRV_ERROR_INVALID_PARAMS; + } + +#ifdef DEBUG + PVR_ASSERT(psResItem->ui32Signature == RESMAN_SIGNATURE); +#endif + + if (psNewResManContext != IMG_NULL) + { + + if (psResItem->psNext) + { + psResItem->psNext->ppsThis = psResItem->ppsThis; + } + *psResItem->ppsThis = psResItem->psNext; + + + psResItem->ppsThis = &psNewResManContext->psResItemList; + psResItem->psNext = psNewResManContext->psResItemList; + psNewResManContext->psResItemList = psResItem; + if (psResItem->psNext) + { + psResItem->psNext->ppsThis = &psResItem->psNext; + } + } + else + { + eError = FreeResourceByPtr(psResItem, IMG_FALSE); + if(eError != PVRSRV_OK) + { + PVR_DPF((PVR_DBG_ERROR, "ResManDissociateRes: failed to free resource by pointer")); + return eError; + } + } + + return eError; +} + + +IMG_INTERNAL PVRSRV_ERROR ResManFindResourceByPtr(PRESMAN_CONTEXT psResManContext, + RESMAN_ITEM *psItem) +{ + RESMAN_ITEM *psCurItem; + + PVR_ASSERT(psResManContext != IMG_NULL); + PVR_ASSERT(psItem != IMG_NULL); + + if ((psItem == IMG_NULL) || (psResManContext == IMG_NULL)) + { + PVR_DPF((PVR_DBG_ERROR, "ResManFindResourceByPtr: invalid parameter")); + PVR_DBG_BREAK; + return PVRSRV_ERROR_INVALID_PARAMS; + } + +#ifdef DEBUG + PVR_ASSERT(psItem->ui32Signature == RESMAN_SIGNATURE); +#endif + + + ACQUIRE_SYNC_OBJ; + + PVR_DPF((PVR_DBG_MESSAGE, + "FindResourceByPtr: psItem=%08X, psItem->psNext=%08X", + psItem, psItem->psNext)); + + PVR_DPF((PVR_DBG_MESSAGE, + "FindResourceByPtr: Resource Ctx 0x%x, Type 0x%x, Addr 0x%x, " + "Param 0x%x, FnCall %08X, Flags 0x%x", + psResManContext, + psItem->ui32ResType, (IMG_UINT32)psItem->pvParam, psItem->ui32Param, + psItem->pfnFreeResource, psItem->ui32Flags)); + + + psCurItem = psResManContext->psResItemList; + + while(psCurItem != IMG_NULL) + { + + if(psCurItem != psItem) + { + + psCurItem = psCurItem->psNext; + } + else + { + + RELEASE_SYNC_OBJ; + return PVRSRV_OK; + } + } + + + RELEASE_SYNC_OBJ; + + return PVRSRV_ERROR_NOT_OWNER; +} + +static PVRSRV_ERROR FreeResourceByPtr(RESMAN_ITEM *psItem, + IMG_BOOL bExecuteCallback) +{ + PVRSRV_ERROR eError = PVRSRV_OK; + + PVR_ASSERT(psItem != IMG_NULL); + + if (psItem == IMG_NULL) + { + PVR_DPF((PVR_DBG_ERROR, "FreeResourceByPtr: invalid parameter")); + return PVRSRV_ERROR_INVALID_PARAMS; + } + +#ifdef DEBUG + PVR_ASSERT(psItem->ui32Signature == RESMAN_SIGNATURE); +#endif + + PVR_DPF((PVR_DBG_MESSAGE, + "FreeResourceByPtr: psItem=%08X, psItem->psNext=%08X", + psItem, psItem->psNext)); + + PVR_DPF((PVR_DBG_MESSAGE, + "FreeResourceByPtr: Type 0x%x, Addr 0x%x, " + "Param 0x%x, FnCall %08X, Flags 0x%x", + psItem->ui32ResType, (IMG_UINT32)psItem->pvParam, psItem->ui32Param, + psItem->pfnFreeResource, psItem->ui32Flags)); + + + if (psItem->psNext) + { + psItem->psNext->ppsThis = psItem->ppsThis; + } + *psItem->ppsThis = psItem->psNext; + + + RELEASE_SYNC_OBJ; + + + if (bExecuteCallback) + { + eError = psItem->pfnFreeResource(psItem->pvParam, psItem->ui32Param); + if (eError != PVRSRV_OK) + { + PVR_DPF((PVR_DBG_ERROR, "FreeResourceByPtr: ERROR calling FreeResource function")); + } + } + + + ACQUIRE_SYNC_OBJ; + + + if(OSFreeMem(PVRSRV_OS_PAGEABLE_HEAP, sizeof(RESMAN_ITEM), psItem, IMG_NULL) != PVRSRV_OK) + { + PVR_DPF((PVR_DBG_ERROR, "FreeResourceByPtr: ERROR freeing resource list item memory")); + eError = PVRSRV_ERROR_GENERIC; + } + + return(eError); +} + + +static PVRSRV_ERROR FreeResourceByCriteria(PRESMAN_CONTEXT psResManContext, + IMG_UINT32 ui32SearchCriteria, + IMG_UINT32 ui32ResType, + IMG_PVOID pvParam, + IMG_UINT32 ui32Param, + IMG_BOOL bExecuteCallback) +{ + PRESMAN_ITEM psCurItem; + IMG_BOOL bMatch; + PVRSRV_ERROR eError = PVRSRV_OK; + + + psCurItem = psResManContext->psResItemList; + + while(psCurItem != IMG_NULL) + { + + bMatch = IMG_TRUE; + + + if(((ui32SearchCriteria & RESMAN_CRITERIA_RESTYPE) != 0UL) && + (psCurItem->ui32ResType != ui32ResType)) + { + bMatch = IMG_FALSE; + } + + + else if(((ui32SearchCriteria & RESMAN_CRITERIA_PVOID_PARAM) != 0UL) && + (psCurItem->pvParam != pvParam)) + { + bMatch = IMG_FALSE; + } + + + else if(((ui32SearchCriteria & RESMAN_CRITERIA_UI32_PARAM) != 0UL) && + (psCurItem->ui32Param != ui32Param)) + { + bMatch = IMG_FALSE; + } + + if(!bMatch) + { + + psCurItem = psCurItem->psNext; + } + else + { + + eError = FreeResourceByPtr(psCurItem, bExecuteCallback); + + if(eError != PVRSRV_OK) + { + return eError; + } + + + + + psCurItem = psResManContext->psResItemList; + } + } + + return eError; +} + + +#ifdef DEBUG +static IMG_VOID ValidateResList(PRESMAN_LIST psResList) +{ + PRESMAN_ITEM psCurItem, *ppsThisItem; + PRESMAN_CONTEXT psCurContext, *ppsThisContext; + + + if (psResList == IMG_NULL) + { + PVR_DPF((PVR_DBG_MESSAGE, "ValidateResList: resman not initialised yet")); + return; + } + + psCurContext = psResList->psContextList; + ppsThisContext = &psResList->psContextList; + + + while(psCurContext != IMG_NULL) + { + + PVR_ASSERT(psCurContext->ui32Signature == RESMAN_SIGNATURE); + if (psCurContext->ppsThis != ppsThisContext) + { + PVR_DPF((PVR_DBG_WARNING, + "psCC=%08X psCC->ppsThis=%08X psCC->psNext=%08X ppsTC=%08X", + psCurContext, psCurContext->ppsThis, + psCurContext->psNext, ppsThisContext)); + PVR_ASSERT(psCurContext->ppsThis == ppsThisContext); + } + + + psCurItem = psCurContext->psResItemList; + ppsThisItem = &psCurContext->psResItemList; + while(psCurItem != IMG_NULL) + { + + PVR_ASSERT(psCurItem->ui32Signature == RESMAN_SIGNATURE); + if (psCurItem->ppsThis != ppsThisItem) + { + PVR_DPF((PVR_DBG_WARNING, + "psCurItem=%08X psCurItem->ppsThis=%08X psCurItem->psNext=%08X ppsThisItem=%08X", + psCurItem, psCurItem->ppsThis, psCurItem->psNext, ppsThisItem)); + PVR_ASSERT(psCurItem->ppsThis == ppsThisItem); + } + + + ppsThisItem = &psCurItem->psNext; + psCurItem = psCurItem->psNext; + } + + + ppsThisContext = &psCurContext->psNext; + psCurContext = psCurContext->psNext; + } +} +#endif + + diff --git a/services4/srvkm/devices/sgx/mmu.c b/services4/srvkm/devices/sgx/mmu.c new file mode 100644 index 0000000..cd35220 --- /dev/null +++ b/services4/srvkm/devices/sgx/mmu.c @@ -0,0 +1,2496 @@ +/********************************************************************** + * + * Copyright(c) 2008 Imagination Technologies Ltd. All rights reserved. + * + * This program is free software; you can redistribute it and/or modify it + * under the terms and conditions of the GNU General Public License, + * version 2, as published by the Free Software Foundation. + * + * This program is distributed in the hope it will be useful but, except + * as otherwise stated in writing, without any warranty; without even the + * implied warranty of merchantability or fitness for a particular purpose. + * See the GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License along with + * this program; if not, write to the Free Software Foundation, Inc., + * 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA. + * + * The full GNU General Public License is included in this distribution in + * the file called "COPYING". + * + * Contact Information: + * Imagination Technologies Ltd. + * Home Park Estate, Kings Langley, Herts, WD4 8LZ, UK + * + ******************************************************************************/ + +#include "sgxdefs.h" +#include "sgxmmu.h" +#include "services_headers.h" +#include "buffer_manager.h" +#include "hash.h" +#include "ra.h" +#include "pdump_km.h" +#include "sgxapi_km.h" +#include "sgxinfo.h" +#include "sgxinfokm.h" +#include "mmu.h" + +#define UINT32_MAX_VALUE 0xFFFFFFFFUL + +typedef struct _MMU_PT_INFO_ +{ + + IMG_VOID *hPTPageOSMemHandle; + IMG_CPU_VIRTADDR PTPageCpuVAddr; + IMG_UINT32 ui32ValidPTECount; +} MMU_PT_INFO; + +struct _MMU_CONTEXT_ +{ + + PVRSRV_DEVICE_NODE *psDeviceNode; + + + IMG_CPU_VIRTADDR pvPDCpuVAddr; + IMG_DEV_PHYADDR sPDDevPAddr; + + IMG_VOID *hPDOSMemHandle; + + + MMU_PT_INFO *apsPTInfoList[1024]; + + PVRSRV_SGXDEV_INFO *psDevInfo; + + struct _MMU_CONTEXT_ *psNext; +}; + +struct _MMU_HEAP_ +{ + MMU_CONTEXT *psMMUContext; + + IMG_UINT32 ui32PTBaseIndex; + IMG_UINT32 ui32PTPageCount; + IMG_UINT32 ui32PTEntryCount; + + + RA_ARENA *psVMArena; + + DEV_ARENA_DESCRIPTOR *psDevArena; +}; + +#if defined (SUPPORT_SGX_MMU_DUMMY_PAGE) +#define DUMMY_DATA_PAGE_SIGNATURE 0xDEADBEEF +#endif + +#if defined(PDUMP) +static IMG_VOID +MMU_PDumpPageTables (MMU_HEAP *pMMUHeap, + IMG_DEV_VIRTADDR DevVAddr, + IMG_SIZE_T uSize, + IMG_BOOL bForUnmap, + IMG_HANDLE hUniqueTag); +#endif + +#define PAGE_TEST 0 +#if PAGE_TEST +static IMG_VOID PageTest(IMG_VOID* pMem, IMG_DEV_PHYADDR sDevPAddr); +#endif + + +#ifdef SUPPORT_SGX_MMU_BYPASS +IMG_VOID +EnableHostAccess (MMU_CONTEXT *psMMUContext) +{ + IMG_UINT32 ui32RegVal; + IMG_VOID *pvRegsBaseKM = psMMUContext->psDevInfo->pvRegsBaseKM; + + + + + ui32RegVal = OSReadHWReg(pvRegsBaseKM, EUR_CR_BIF_CTRL); + + OSWriteHWReg(pvRegsBaseKM, + EUR_CR_BIF_CTRL, + ui32RegVal | EUR_CR_BIF_CTRL_MMU_BYPASS_HOST_MASK); + + PDUMPREG(EUR_CR_BIF_CTRL, EUR_CR_BIF_CTRL_MMU_BYPASS_HOST_MASK); +} + +IMG_VOID +DisableHostAccess (MMU_CONTEXT *psMMUContext) +{ + IMG_UINT32 ui32RegVal; + IMG_VOID *pvRegsBaseKM = psMMUContext->psDevInfo->pvRegsBaseKM; + + + + + + OSWriteHWReg(pvRegsBaseKM, + EUR_CR_BIF_CTRL, + ui32RegVal & ~EUR_CR_BIF_CTRL_MMU_BYPASS_HOST_MASK); + + PDUMPREG(EUR_CR_BIF_CTRL, 0); +} +#endif + +IMG_VOID MMU_InvalidateDirectoryCache(PVRSRV_SGXDEV_INFO *psDevInfo) +{ + psDevInfo->ui32CacheControl |= SGX_BIF_INVALIDATE_PDCACHE; +} + + +IMG_VOID MMU_InvalidatePageTableCache(PVRSRV_SGXDEV_INFO *psDevInfo) +{ + psDevInfo->ui32CacheControl |= SGX_BIF_INVALIDATE_PTCACHE; +} + + +static IMG_BOOL +_AllocPageTables (MMU_HEAP *pMMUHeap) +{ + PVR_DPF ((PVR_DBG_MESSAGE, "_AllocPageTables()")); + + PVR_ASSERT (pMMUHeap!=IMG_NULL); + PVR_ASSERT (HOST_PAGESIZE() == SGX_MMU_PAGE_SIZE); + + if (pMMUHeap == IMG_NULL) + { + PVR_DPF((PVR_DBG_ERROR, "_AllocPageTables: invalid parameter")); + return IMG_FALSE; + } + + + + + + + + + pMMUHeap->ui32PTEntryCount = pMMUHeap->psDevArena->ui32Size >> SGX_MMU_PAGE_SHIFT; + + + pMMUHeap->ui32PTBaseIndex = (pMMUHeap->psDevArena->BaseDevVAddr.uiAddr & (SGX_MMU_PD_MASK | SGX_MMU_PT_MASK)) >> SGX_MMU_PAGE_SHIFT; + + + + + pMMUHeap->ui32PTPageCount = (pMMUHeap->ui32PTEntryCount + SGX_MMU_PT_SIZE - 1) >> SGX_MMU_PT_SHIFT; + + return IMG_TRUE; +} + +static IMG_VOID +_DeferredFreePageTable (MMU_HEAP *pMMUHeap, IMG_UINT32 ui32PTIndex) +{ + IMG_UINT32 *pui32PDEntry; + IMG_UINT32 i; + IMG_UINT32 ui32PDIndex; + SYS_DATA *psSysData; + MMU_PT_INFO **ppsPTInfoList; + + if (SysAcquireData(&psSysData) != PVRSRV_OK) + { + PVR_DPF((PVR_DBG_ERROR, "_DeferredFreePageTables: ERROR call to SysAcquireData failed")); + return; + } + + + ui32PDIndex = pMMUHeap->psDevArena->BaseDevVAddr.uiAddr >> (SGX_MMU_PAGE_SHIFT + SGX_MMU_PT_SHIFT); + + + ppsPTInfoList = &pMMUHeap->psMMUContext->apsPTInfoList[ui32PDIndex]; + + { + + PVR_ASSERT(ppsPTInfoList[ui32PTIndex] == IMG_NULL || ppsPTInfoList[ui32PTIndex]->ui32ValidPTECount == 0); + } + + + PDUMPCOMMENT("Free page table (page count == %08X)", pMMUHeap->ui32PTPageCount); + if(ppsPTInfoList[ui32PTIndex] && ppsPTInfoList[ui32PTIndex]->PTPageCpuVAddr) + { + PDUMPFREEPAGETABLE(PVRSRV_DEVICE_TYPE_SGX, ppsPTInfoList[ui32PTIndex]->PTPageCpuVAddr, SGX_MMU_PAGE_SIZE, PDUMP_PT_UNIQUETAG); + } + + switch(pMMUHeap->psDevArena->DevMemHeapType) + { + case DEVICE_MEMORY_HEAP_SHARED : + case DEVICE_MEMORY_HEAP_SHARED_EXPORTED : + { + + MMU_CONTEXT *psMMUContext = (MMU_CONTEXT*)pMMUHeap->psMMUContext->psDevInfo->pvMMUContextList; + + while(psMMUContext) + { + + pui32PDEntry = (IMG_UINT32*)psMMUContext->pvPDCpuVAddr; + pui32PDEntry += ui32PDIndex; + +#if defined(SUPPORT_SGX_MMU_DUMMY_PAGE) + + pui32PDEntry[ui32PTIndex] = psMMUContext->psDevInfo->sDummyPTDevPAddr.uiAddr | SGX_MMU_PDE_VALID; +#else + + pui32PDEntry[ui32PTIndex] = 0; +#endif + + + PDUMPMEM2(PVRSRV_DEVICE_TYPE_SGX, (IMG_VOID*)&pui32PDEntry[ui32PTIndex], sizeof(IMG_UINT32), 0, IMG_FALSE, PDUMP_PT_UNIQUETAG, PDUMP_PT_UNIQUETAG); + + + psMMUContext = psMMUContext->psNext; + } + break; + } + case DEVICE_MEMORY_HEAP_PERCONTEXT : + case DEVICE_MEMORY_HEAP_KERNEL : + { + + pui32PDEntry = (IMG_UINT32*)pMMUHeap->psMMUContext->pvPDCpuVAddr; + pui32PDEntry += ui32PDIndex; + +#if defined(SUPPORT_SGX_MMU_DUMMY_PAGE) + + pui32PDEntry[ui32PTIndex] = pMMUHeap->psMMUContext->psDevInfo->sDummyPTDevPAddr.uiAddr | SGX_MMU_PDE_VALID; +#else + + pui32PDEntry[ui32PTIndex] = 0; +#endif + + + PDUMPMEM2(PVRSRV_DEVICE_TYPE_SGX, (IMG_VOID*)&pui32PDEntry[ui32PTIndex], sizeof(IMG_UINT32), 0, IMG_FALSE, PDUMP_PD_UNIQUETAG, PDUMP_PT_UNIQUETAG); + break; + } + default: + { + PVR_DPF((PVR_DBG_ERROR, "_DeferredFreePagetable: ERROR invalid heap type")); + return; + } + } + + + if(ppsPTInfoList[ui32PTIndex] != IMG_NULL) + { + if(ppsPTInfoList[ui32PTIndex]->PTPageCpuVAddr != IMG_NULL) + { + IMG_PUINT32 pui32Tmp; + + pui32Tmp = (IMG_UINT32*)ppsPTInfoList[ui32PTIndex]->PTPageCpuVAddr; + + + + + for(i=0; (iui32PTEntryCount) && (i<1024); i++) + { + pui32Tmp[i] = 0; + } + + + + + + if(pMMUHeap->psDevArena->psDeviceMemoryHeapInfo->psLocalDevMemArena == IMG_NULL) + { + OSFreePages(PVRSRV_HAP_WRITECOMBINE | PVRSRV_HAP_KERNEL_ONLY, + SGX_MMU_PAGE_SIZE, + ppsPTInfoList[ui32PTIndex]->PTPageCpuVAddr, + ppsPTInfoList[ui32PTIndex]->hPTPageOSMemHandle); + } + else + { + IMG_SYS_PHYADDR sSysPAddr; + IMG_CPU_PHYADDR sCpuPAddr; + + + sCpuPAddr = OSMapLinToCPUPhys(ppsPTInfoList[ui32PTIndex]->PTPageCpuVAddr); + sSysPAddr = SysCpuPAddrToSysPAddr (sCpuPAddr); + + + OSUnMapPhysToLin(ppsPTInfoList[ui32PTIndex]->PTPageCpuVAddr, + SGX_MMU_PAGE_SIZE, + PVRSRV_HAP_WRITECOMBINE|PVRSRV_HAP_KERNEL_ONLY, + ppsPTInfoList[ui32PTIndex]->hPTPageOSMemHandle); + + + + + RA_Free (pMMUHeap->psDevArena->psDeviceMemoryHeapInfo->psLocalDevMemArena, sSysPAddr.uiAddr, IMG_FALSE); + } + + + + + pMMUHeap->ui32PTEntryCount -= i; + } + else + { + + pMMUHeap->ui32PTEntryCount -= 1024; + } + + + OSFreeMem(PVRSRV_OS_PAGEABLE_HEAP, + sizeof(MMU_PT_INFO), + ppsPTInfoList[ui32PTIndex], + IMG_NULL); + ppsPTInfoList[ui32PTIndex] = IMG_NULL; + } + else + { + + pMMUHeap->ui32PTEntryCount -= 1024; + } + + PDUMPCOMMENT("Finished free page table (page count == %08X)", pMMUHeap->ui32PTPageCount); +} + +static IMG_VOID +_DeferredFreePageTables (MMU_HEAP *pMMUHeap) +{ + IMG_UINT32 i; + + for(i=0; iui32PTPageCount; i++) + { + _DeferredFreePageTable(pMMUHeap, i); + } + MMU_InvalidateDirectoryCache(pMMUHeap->psMMUContext->psDevInfo); +} + + +static IMG_BOOL +_DeferredAllocPagetables(MMU_HEAP *pMMUHeap, IMG_DEV_VIRTADDR DevVAddr, IMG_UINT32 ui32Size) +{ + IMG_UINT32 ui32PTPageCount; + IMG_UINT32 ui32PDIndex; + IMG_UINT32 i; + IMG_UINT32 *pui32PDEntry; + MMU_PT_INFO **ppsPTInfoList; + SYS_DATA *psSysData; + IMG_DEV_VIRTADDR sHighDevVAddr; + + +#if SGX_FEATURE_ADDRESS_SPACE_SIZE < 32 + PVR_ASSERT(DevVAddr.uiAddr < (1<> (SGX_MMU_PAGE_SHIFT + SGX_MMU_PT_SHIFT); + + + + if((UINT32_MAX_VALUE - DevVAddr.uiAddr) + < (ui32Size + (1<<(SGX_MMU_PAGE_SHIFT+SGX_MMU_PT_SHIFT)) - 1)) + { + + sHighDevVAddr.uiAddr = UINT32_MAX_VALUE; + } + else + { + sHighDevVAddr.uiAddr = DevVAddr.uiAddr + + ui32Size + + (1<<(SGX_MMU_PAGE_SHIFT+SGX_MMU_PT_SHIFT)) + - 1; + } + + ui32PTPageCount = sHighDevVAddr.uiAddr >> (SGX_MMU_PAGE_SHIFT + SGX_MMU_PT_SHIFT); + + ui32PTPageCount -= ui32PDIndex; + + + pui32PDEntry = (IMG_UINT32*)pMMUHeap->psMMUContext->pvPDCpuVAddr; + pui32PDEntry += ui32PDIndex; + + + ppsPTInfoList = &pMMUHeap->psMMUContext->apsPTInfoList[ui32PDIndex]; + + PDUMPCOMMENT("Alloc page table (page count == %08X)", ui32PTPageCount); + PDUMPCOMMENT("Page directory mods (page count == %08X)", ui32PTPageCount); + + + for(i=0; ihPTPageOSMemHandle == IMG_NULL + && ppsPTInfoList[i]->PTPageCpuVAddr == IMG_NULL) + { + IMG_CPU_PHYADDR sCpuPAddr; + IMG_DEV_PHYADDR sDevPAddr; +#if defined(SUPPORT_SGX_MMU_DUMMY_PAGE) + IMG_UINT32 *pui32Tmp; + IMG_UINT32 j; +#else + + PVR_ASSERT(pui32PDEntry[i] == 0); +#endif + + + + + if(pMMUHeap->psDevArena->psDeviceMemoryHeapInfo->psLocalDevMemArena == IMG_NULL) + { + if (OSAllocPages(PVRSRV_HAP_WRITECOMBINE | PVRSRV_HAP_KERNEL_ONLY, + SGX_MMU_PAGE_SIZE, + SGX_MMU_PAGE_SIZE, + (IMG_VOID **)&ppsPTInfoList[i]->PTPageCpuVAddr, + &ppsPTInfoList[i]->hPTPageOSMemHandle) != PVRSRV_OK) + { + PVR_DPF((PVR_DBG_ERROR, "_DeferredAllocPagetables: ERROR call to OSAllocPages failed")); + return IMG_FALSE; + } + + + if(ppsPTInfoList[i]->PTPageCpuVAddr) + { + sCpuPAddr = OSMapLinToCPUPhys(ppsPTInfoList[i]->PTPageCpuVAddr); + } + else + { + + sCpuPAddr = OSMemHandleToCpuPAddr(ppsPTInfoList[i]->hPTPageOSMemHandle, 0); + } + sDevPAddr = SysCpuPAddrToDevPAddr (PVRSRV_DEVICE_TYPE_SGX, sCpuPAddr); + } + else + { + IMG_SYS_PHYADDR sSysPAddr; + + + + + if(RA_Alloc(pMMUHeap->psDevArena->psDeviceMemoryHeapInfo->psLocalDevMemArena, + SGX_MMU_PAGE_SIZE, + IMG_NULL, + IMG_NULL, + 0, + SGX_MMU_PAGE_SIZE, + 0, + &(sSysPAddr.uiAddr))!= IMG_TRUE) + { + PVR_DPF((PVR_DBG_ERROR, "_DeferredAllocPagetables: ERROR call to RA_Alloc failed")); + return IMG_FALSE; + } + + + sCpuPAddr = SysSysPAddrToCpuPAddr(sSysPAddr); + ppsPTInfoList[i]->PTPageCpuVAddr = OSMapPhysToLin(sCpuPAddr, + SGX_MMU_PAGE_SIZE, + PVRSRV_HAP_WRITECOMBINE|PVRSRV_HAP_KERNEL_ONLY, + &ppsPTInfoList[i]->hPTPageOSMemHandle); + if(!ppsPTInfoList[i]->PTPageCpuVAddr) + { + PVR_DPF((PVR_DBG_ERROR, "_DeferredAllocPagetables: ERROR failed to map page tables")); + return IMG_FALSE; + } + + + sDevPAddr = SysCpuPAddrToDevPAddr (PVRSRV_DEVICE_TYPE_SGX, sCpuPAddr); + + #if PAGE_TEST + PageTest(ppsPTInfoList[i]->PTPageCpuVAddr, sDevPAddr); + #endif + } + +#if defined(SUPPORT_SGX_MMU_DUMMY_PAGE) + pui32Tmp = (IMG_UINT32*)ppsPTInfoList[i]->PTPageCpuVAddr; + + for(j=0; jpsMMUContext->psDevInfo->sDummyDataDevPAddr.uiAddr | SGX_MMU_PTE_VALID; + } +#else + + OSMemSet(ppsPTInfoList[i]->PTPageCpuVAddr, 0, SGX_MMU_PAGE_SIZE); +#endif + + PDUMPMALLOCPAGETABLE(PVRSRV_DEVICE_TYPE_SGX, ppsPTInfoList[i]->PTPageCpuVAddr, SGX_MMU_PAGE_SIZE, PDUMP_PT_UNIQUETAG); + + PDUMPMEM2(PVRSRV_DEVICE_TYPE_SGX, ppsPTInfoList[i]->PTPageCpuVAddr, SGX_MMU_PAGE_SIZE, 0, IMG_TRUE, PDUMP_PT_UNIQUETAG, PDUMP_PT_UNIQUETAG); + + switch(pMMUHeap->psDevArena->DevMemHeapType) + { + case DEVICE_MEMORY_HEAP_SHARED : + case DEVICE_MEMORY_HEAP_SHARED_EXPORTED : + { + + MMU_CONTEXT *psMMUContext = (MMU_CONTEXT*)pMMUHeap->psMMUContext->psDevInfo->pvMMUContextList; + + while(psMMUContext) + { + + pui32PDEntry = (IMG_UINT32*)psMMUContext->pvPDCpuVAddr; + pui32PDEntry += ui32PDIndex; + + + pui32PDEntry[i] = sDevPAddr.uiAddr | SGX_MMU_PDE_VALID; + + + PDUMPMEM2(PVRSRV_DEVICE_TYPE_SGX, (IMG_VOID*)&pui32PDEntry[i], sizeof(IMG_UINT32), 0, IMG_FALSE, PDUMP_PD_UNIQUETAG, PDUMP_PT_UNIQUETAG); + + + psMMUContext = psMMUContext->psNext; + } + break; + } + case DEVICE_MEMORY_HEAP_PERCONTEXT : + case DEVICE_MEMORY_HEAP_KERNEL : + { + + pui32PDEntry[i] = sDevPAddr.uiAddr | SGX_MMU_PDE_VALID; + + + PDUMPMEM2(PVRSRV_DEVICE_TYPE_SGX, (IMG_VOID*)&pui32PDEntry[i], sizeof(IMG_UINT32), 0, IMG_FALSE, PDUMP_PD_UNIQUETAG, PDUMP_PT_UNIQUETAG); + + break; + } + default: + { + PVR_DPF((PVR_DBG_ERROR, "_DeferredAllocPagetables: ERROR invalid heap type")); + return IMG_FALSE; + } + } + +#if !defined(SGX_FEATURE_MULTIPLE_MEM_CONTEXTS) + + + + + MMU_InvalidateDirectoryCache(pMMUHeap->psMMUContext->psDevInfo); +#endif + } + else + { + + PVR_ASSERT(pui32PDEntry[i] != 0); + } + } + + return IMG_TRUE; +} + + +PVRSRV_ERROR +MMU_Initialise (PVRSRV_DEVICE_NODE *psDeviceNode, MMU_CONTEXT **ppsMMUContext, IMG_DEV_PHYADDR *psPDDevPAddr) +{ + IMG_UINT32 *pui32Tmp; + IMG_UINT32 i; + IMG_CPU_VIRTADDR pvPDCpuVAddr; + IMG_DEV_PHYADDR sPDDevPAddr; + IMG_CPU_PHYADDR sCpuPAddr; + MMU_CONTEXT *psMMUContext; + IMG_HANDLE hPDOSMemHandle; + SYS_DATA *psSysData; + PVRSRV_SGXDEV_INFO *psDevInfo; + + PVR_DPF ((PVR_DBG_MESSAGE, "MMU_Initialise")); + + + + if (SysAcquireData(&psSysData) != PVRSRV_OK) + { + PVR_DPF((PVR_DBG_ERROR, "MMU_Initialise: ERROR call to SysAcquireData failed")); + return PVRSRV_ERROR_GENERIC; + } + + OSAllocMem(PVRSRV_OS_PAGEABLE_HEAP, + sizeof (MMU_CONTEXT), + (IMG_VOID **)&psMMUContext, IMG_NULL); + if (psMMUContext == IMG_NULL) + { + PVR_DPF((PVR_DBG_ERROR, "MMU_Initialise: ERROR call to OSAllocMem failed")); + return PVRSRV_ERROR_GENERIC; + } + OSMemSet (psMMUContext, 0, sizeof(MMU_CONTEXT)); + + + psDevInfo = (PVRSRV_SGXDEV_INFO*)psDeviceNode->pvDevice; + psMMUContext->psDevInfo = psDevInfo; + + + psMMUContext->psDeviceNode = psDeviceNode; + + + if(psDeviceNode->psLocalDevMemArena == IMG_NULL) + { + if (OSAllocPages(PVRSRV_HAP_WRITECOMBINE | PVRSRV_HAP_KERNEL_ONLY, + SGX_MMU_PAGE_SIZE, + SGX_MMU_PAGE_SIZE, + &pvPDCpuVAddr, + &hPDOSMemHandle) != PVRSRV_OK) + { + PVR_DPF((PVR_DBG_ERROR, "MMU_Initialise: ERROR call to OSAllocPages failed")); + return PVRSRV_ERROR_GENERIC; + } + + if(pvPDCpuVAddr) + { + sCpuPAddr = OSMapLinToCPUPhys(pvPDCpuVAddr); + } + else + { + + sCpuPAddr = OSMemHandleToCpuPAddr(hPDOSMemHandle, 0); + } + sPDDevPAddr = SysCpuPAddrToDevPAddr (PVRSRV_DEVICE_TYPE_SGX, sCpuPAddr); + + #if PAGE_TEST + PageTest(pvPDCpuVAddr, sPDDevPAddr); + #endif + +#if defined(SUPPORT_SGX_MMU_DUMMY_PAGE) + + if(!psDevInfo->pvMMUContextList) + { + + if (OSAllocPages(PVRSRV_HAP_WRITECOMBINE | PVRSRV_HAP_KERNEL_ONLY, + SGX_MMU_PAGE_SIZE, + SGX_MMU_PAGE_SIZE, + &psDevInfo->pvDummyPTPageCpuVAddr, + &psDevInfo->hDummyPTPageOSMemHandle) != PVRSRV_OK) + { + PVR_DPF((PVR_DBG_ERROR, "MMU_Initialise: ERROR call to OSAllocPages failed")); + return PVRSRV_ERROR_GENERIC; + } + + if(psDevInfo->pvDummyPTPageCpuVAddr) + { + sCpuPAddr = OSMapLinToCPUPhys(psDevInfo->pvDummyPTPageCpuVAddr); + } + else + { + + sCpuPAddr = OSMemHandleToCpuPAddr(psDevInfo->hDummyPTPageOSMemHandle, 0); + } + psDevInfo->sDummyPTDevPAddr = SysCpuPAddrToDevPAddr (PVRSRV_DEVICE_TYPE_SGX, sCpuPAddr); + + + if (OSAllocPages(PVRSRV_HAP_WRITECOMBINE | PVRSRV_HAP_KERNEL_ONLY, + SGX_MMU_PAGE_SIZE, + SGX_MMU_PAGE_SIZE, + &psDevInfo->pvDummyDataPageCpuVAddr, + &psDevInfo->hDummyDataPageOSMemHandle) != PVRSRV_OK) + { + PVR_DPF((PVR_DBG_ERROR, "MMU_Initialise: ERROR call to OSAllocPages failed")); + return PVRSRV_ERROR_GENERIC; + } + + if(psDevInfo->pvDummyDataPageCpuVAddr) + { + sCpuPAddr = OSMapLinToCPUPhys(psDevInfo->pvDummyDataPageCpuVAddr); + } + else + { + sCpuPAddr = OSMemHandleToCpuPAddr(psDevInfo->hDummyDataPageOSMemHandle, 0); + } + psDevInfo->sDummyDataDevPAddr = SysCpuPAddrToDevPAddr (PVRSRV_DEVICE_TYPE_SGX, sCpuPAddr); + } +#endif + } + else + { + IMG_SYS_PHYADDR sSysPAddr; + + + if(RA_Alloc(psDeviceNode->psLocalDevMemArena, + SGX_MMU_PAGE_SIZE, + IMG_NULL, + IMG_NULL, + 0, + SGX_MMU_PAGE_SIZE, + 0, + &(sSysPAddr.uiAddr))!= IMG_TRUE) + { + PVR_DPF((PVR_DBG_ERROR, "MMU_Initialise: ERROR call to RA_Alloc failed")); + return PVRSRV_ERROR_GENERIC; + } + + + sCpuPAddr = SysSysPAddrToCpuPAddr(sSysPAddr); + sPDDevPAddr = SysSysPAddrToDevPAddr(PVRSRV_DEVICE_TYPE_SGX, sSysPAddr); + pvPDCpuVAddr = OSMapPhysToLin(sCpuPAddr, + SGX_MMU_PAGE_SIZE, + PVRSRV_HAP_WRITECOMBINE|PVRSRV_HAP_KERNEL_ONLY, + &hPDOSMemHandle); + if(!pvPDCpuVAddr) + { + PVR_DPF((PVR_DBG_ERROR, "MMU_Initialise: ERROR failed to map page tables")); + return PVRSRV_ERROR_GENERIC; + } + + #if PAGE_TEST + PageTest(pvPDCpuVAddr, sPDDevPAddr); + #endif + +#if defined(SUPPORT_SGX_MMU_DUMMY_PAGE) + + if(!psDevInfo->pvMMUContextList) + { + + if(RA_Alloc(psDeviceNode->psLocalDevMemArena, + SGX_MMU_PAGE_SIZE, + IMG_NULL, + IMG_NULL, + 0, + SGX_MMU_PAGE_SIZE, + 0, + &(sSysPAddr.uiAddr))!= IMG_TRUE) + { + PVR_DPF((PVR_DBG_ERROR, "MMU_Initialise: ERROR call to RA_Alloc failed")); + return PVRSRV_ERROR_GENERIC; + } + + + sCpuPAddr = SysSysPAddrToCpuPAddr(sSysPAddr); + psDevInfo->sDummyPTDevPAddr = SysSysPAddrToDevPAddr(PVRSRV_DEVICE_TYPE_SGX, sSysPAddr); + psDevInfo->pvDummyPTPageCpuVAddr = OSMapPhysToLin(sCpuPAddr, + SGX_MMU_PAGE_SIZE, + PVRSRV_HAP_WRITECOMBINE|PVRSRV_HAP_KERNEL_ONLY, + &psDevInfo->hDummyPTPageOSMemHandle); + if(!psDevInfo->pvDummyPTPageCpuVAddr) + { + PVR_DPF((PVR_DBG_ERROR, "MMU_Initialise: ERROR failed to map page tables")); + return PVRSRV_ERROR_GENERIC; + } + + + if(RA_Alloc(psDeviceNode->psLocalDevMemArena, + SGX_MMU_PAGE_SIZE, + IMG_NULL, + IMG_NULL, + 0, + SGX_MMU_PAGE_SIZE, + 0, + &(sSysPAddr.uiAddr))!= IMG_TRUE) + { + PVR_DPF((PVR_DBG_ERROR, "MMU_Initialise: ERROR call to RA_Alloc failed")); + return PVRSRV_ERROR_GENERIC; + } + + + sCpuPAddr = SysSysPAddrToCpuPAddr(sSysPAddr); + psDevInfo->sDummyDataDevPAddr = SysSysPAddrToDevPAddr(PVRSRV_DEVICE_TYPE_SGX, sSysPAddr); + psDevInfo->pvDummyDataPageCpuVAddr = OSMapPhysToLin(sCpuPAddr, + SGX_MMU_PAGE_SIZE, + PVRSRV_HAP_WRITECOMBINE|PVRSRV_HAP_KERNEL_ONLY, + &psDevInfo->hDummyDataPageOSMemHandle); + if(!psDevInfo->pvDummyDataPageCpuVAddr) + { + PVR_DPF((PVR_DBG_ERROR, "MMU_Initialise: ERROR failed to map page tables")); + return PVRSRV_ERROR_GENERIC; + } + } +#endif + } + + + PDUMPCOMMENT("Alloc page directory"); +#ifdef SUPPORT_SGX_MMU_BYPASS + EnableHostAccess(psMMUContext); +#endif + + PDUMPMALLOCPAGETABLE(PVRSRV_DEVICE_TYPE_SGX, pvPDCpuVAddr, SGX_MMU_PAGE_SIZE, PDUMP_PD_UNIQUETAG); + + if (pvPDCpuVAddr) + { + pui32Tmp = (IMG_UINT32 *)pvPDCpuVAddr; + } + else + { + PVR_DPF((PVR_DBG_ERROR, "MMU_Initialise: pvPDCpuVAddr invalid")); + return PVRSRV_ERROR_GENERIC; + } + +#if defined(SUPPORT_SGX_MMU_DUMMY_PAGE) + + for(i=0; isDummyPTDevPAddr.uiAddr | SGX_MMU_PDE_VALID; + } + + if(!psDevInfo->pvMMUContextList) + { + + + + pui32Tmp = (IMG_UINT32 *)psDevInfo->pvDummyPTPageCpuVAddr; + for(i=0; isDummyDataDevPAddr.uiAddr | SGX_MMU_PTE_VALID; + } + + PDUMPCOMMENT("Dummy Page table contents"); + PDUMPMEM2(PVRSRV_DEVICE_TYPE_SGX, psDevInfo->pvDummyPTPageCpuVAddr, SGX_MMU_PAGE_SIZE, 0, IMG_TRUE, PDUMP_PD_UNIQUETAG, PDUMP_PT_UNIQUETAG); + + + + pui32Tmp = (IMG_UINT32 *)psDevInfo->pvDummyDataPageCpuVAddr; + for(i=0; i<(SGX_MMU_PAGE_SIZE/4); i++) + { + pui32Tmp[i] = DUMMY_DATA_PAGE_SIGNATURE; + } + + PDUMPCOMMENT("Dummy Data Page contents"); + PDUMPMEM2(PVRSRV_DEVICE_TYPE_SGX, psDevInfo->pvDummyDataPageCpuVAddr, SGX_MMU_PAGE_SIZE, 0, IMG_TRUE, PDUMP_PD_UNIQUETAG, PDUMP_PT_UNIQUETAG); + } +#else + + for(i=0; ipvPDCpuVAddr = pvPDCpuVAddr; + psMMUContext->sPDDevPAddr = sPDDevPAddr; + psMMUContext->hPDOSMemHandle = hPDOSMemHandle; + + + *ppsMMUContext = psMMUContext; + + + *psPDDevPAddr = sPDDevPAddr; + + + psMMUContext->psNext = (MMU_CONTEXT*)psDevInfo->pvMMUContextList; + psDevInfo->pvMMUContextList = (IMG_VOID*)psMMUContext; + +#ifdef SUPPORT_SGX_MMU_BYPASS + DisableHostAccess(psMMUContext); +#endif + + return PVRSRV_OK; +} + +IMG_VOID +MMU_Finalise (MMU_CONTEXT *psMMUContext) +{ + IMG_UINT32 *pui32Tmp, i; + SYS_DATA *psSysData; + MMU_CONTEXT **ppsMMUContext; +#if defined(SUPPORT_SGX_MMU_DUMMY_PAGE) + PVRSRV_SGXDEV_INFO *psDevInfo = (PVRSRV_SGXDEV_INFO*)psMMUContext->psDevInfo; + MMU_CONTEXT *psMMUContextList = (MMU_CONTEXT*)psDevInfo->pvMMUContextList; +#endif + + if (SysAcquireData(&psSysData) != PVRSRV_OK) + { + PVR_DPF((PVR_DBG_ERROR, "MMU_Finalise: ERROR call to SysAcquireData failed")); + return; + } + + + PDUMPCOMMENT("Free page directory"); + PDUMPFREEPAGETABLE(PVRSRV_DEVICE_TYPE_SGX, psMMUContext->pvPDCpuVAddr, SGX_MMU_PAGE_SIZE, PDUMP_PT_UNIQUETAG); +#if defined(SUPPORT_SGX_MMU_DUMMY_PAGE) + PDUMPFREEPAGETABLE(PVRSRV_DEVICE_TYPE_SGX, psDevInfo->pvDummyPTPageCpuVAddr, SGX_MMU_PAGE_SIZE, PDUMP_PT_UNIQUETAG); + PDUMPFREEPAGETABLE(PVRSRV_DEVICE_TYPE_SGX, psDevInfo->pvDummyDataPageCpuVAddr, SGX_MMU_PAGE_SIZE, PDUMP_PT_UNIQUETAG); +#endif + + pui32Tmp = (IMG_UINT32 *)psMMUContext->pvPDCpuVAddr; + + + + + for(i=0; ipsDeviceNode->psLocalDevMemArena == IMG_NULL) + { + OSFreePages(PVRSRV_HAP_WRITECOMBINE | PVRSRV_HAP_KERNEL_ONLY, + SGX_MMU_PAGE_SIZE, + psMMUContext->pvPDCpuVAddr, + psMMUContext->hPDOSMemHandle); + +#if defined(SUPPORT_SGX_MMU_DUMMY_PAGE) + + if(!psMMUContextList->psNext) + { + OSFreePages(PVRSRV_HAP_WRITECOMBINE | PVRSRV_HAP_KERNEL_ONLY, + SGX_MMU_PAGE_SIZE, + psDevInfo->pvDummyPTPageCpuVAddr, + psDevInfo->hDummyPTPageOSMemHandle); + OSFreePages(PVRSRV_HAP_WRITECOMBINE | PVRSRV_HAP_KERNEL_ONLY, + SGX_MMU_PAGE_SIZE, + psDevInfo->pvDummyDataPageCpuVAddr, + psDevInfo->hDummyDataPageOSMemHandle); + } +#endif + } + else + { + IMG_SYS_PHYADDR sSysPAddr; + IMG_CPU_PHYADDR sCpuPAddr; + + + sCpuPAddr = OSMapLinToCPUPhys(psMMUContext->pvPDCpuVAddr); + sSysPAddr = SysCpuPAddrToSysPAddr(sCpuPAddr); + + + OSUnMapPhysToLin(psMMUContext->pvPDCpuVAddr, + SGX_MMU_PAGE_SIZE, + PVRSRV_HAP_WRITECOMBINE|PVRSRV_HAP_KERNEL_ONLY, + psMMUContext->hPDOSMemHandle); + + RA_Free (psMMUContext->psDeviceNode->psLocalDevMemArena, sSysPAddr.uiAddr, IMG_FALSE); + +#if defined(SUPPORT_SGX_MMU_DUMMY_PAGE) + + if(!psMMUContextList->psNext) + { + + sCpuPAddr = OSMapLinToCPUPhys(psDevInfo->pvDummyPTPageCpuVAddr); + sSysPAddr = SysCpuPAddrToSysPAddr(sCpuPAddr); + + + OSUnMapPhysToLin(psDevInfo->pvDummyPTPageCpuVAddr, + SGX_MMU_PAGE_SIZE, + PVRSRV_HAP_WRITECOMBINE|PVRSRV_HAP_KERNEL_ONLY, + psDevInfo->hDummyPTPageOSMemHandle); + + RA_Free (psMMUContext->psDeviceNode->psLocalDevMemArena, sSysPAddr.uiAddr, IMG_FALSE); + + + sCpuPAddr = OSMapLinToCPUPhys(psDevInfo->pvDummyDataPageCpuVAddr); + sSysPAddr = SysCpuPAddrToSysPAddr(sCpuPAddr); + + + OSUnMapPhysToLin(psDevInfo->pvDummyDataPageCpuVAddr, + SGX_MMU_PAGE_SIZE, + PVRSRV_HAP_WRITECOMBINE|PVRSRV_HAP_KERNEL_ONLY, + psDevInfo->hDummyDataPageOSMemHandle); + + RA_Free (psMMUContext->psDeviceNode->psLocalDevMemArena, sSysPAddr.uiAddr, IMG_FALSE); + } +#endif + } + + PVR_DPF ((PVR_DBG_MESSAGE, "MMU_Finalise")); + + + ppsMMUContext = (MMU_CONTEXT**)&psMMUContext->psDevInfo->pvMMUContextList; + while(*ppsMMUContext) + { + if(*ppsMMUContext == psMMUContext) + { + + *ppsMMUContext = psMMUContext->psNext; + break; + } + + + ppsMMUContext = &((*ppsMMUContext)->psNext); + } + + + OSFreeMem(PVRSRV_OS_PAGEABLE_HEAP, sizeof(MMU_CONTEXT), psMMUContext, IMG_NULL); +} + + +IMG_VOID +MMU_InsertHeap(MMU_CONTEXT *psMMUContext, MMU_HEAP *psMMUHeap) +{ + IMG_UINT32 *pui32PDCpuVAddr = (IMG_UINT32 *) psMMUContext->pvPDCpuVAddr; + IMG_UINT32 *pui32KernelPDCpuVAddr = (IMG_UINT32 *) psMMUHeap->psMMUContext->pvPDCpuVAddr; + IMG_UINT32 ui32PDEntry; +#if !defined(SGX_FEATURE_MULTIPLE_MEM_CONTEXTS) + IMG_BOOL bInvalidateDirectoryCache = IMG_FALSE; +#endif + + + pui32PDCpuVAddr += psMMUHeap->psDevArena->BaseDevVAddr.uiAddr >> (SGX_MMU_PAGE_SHIFT + SGX_MMU_PT_SHIFT); + pui32KernelPDCpuVAddr += psMMUHeap->psDevArena->BaseDevVAddr.uiAddr >> (SGX_MMU_PAGE_SHIFT + SGX_MMU_PT_SHIFT); + + + + + PDUMPCOMMENT("Page directory shared heap range copy"); +#ifdef SUPPORT_SGX_MMU_BYPASS + EnableHostAccess(psMMUContext); +#endif + + for (ui32PDEntry = 0; ui32PDEntry < psMMUHeap->ui32PTPageCount; ui32PDEntry++) + { +#if !defined(SUPPORT_SGX_MMU_DUMMY_PAGE) + + PVR_ASSERT(pui32PDCpuVAddr[ui32PDEntry] == 0); +#endif + + + pui32PDCpuVAddr[ui32PDEntry] = pui32KernelPDCpuVAddr[ui32PDEntry]; + if (pui32PDCpuVAddr[ui32PDEntry]) + { + PDUMPMEM2(PVRSRV_DEVICE_TYPE_SGX, (IMG_VOID *) &pui32PDCpuVAddr[ui32PDEntry], sizeof(IMG_UINT32), 0, IMG_FALSE, PDUMP_PD_UNIQUETAG, PDUMP_PT_UNIQUETAG); + +#if !defined(SGX_FEATURE_MULTIPLE_MEM_CONTEXTS) + bInvalidateDirectoryCache = IMG_TRUE; +#endif + } + } + +#ifdef SUPPORT_SGX_MMU_BYPASS + DisableHostAccess(psMMUContext); +#endif + +#if !defined(SGX_FEATURE_MULTIPLE_MEM_CONTEXTS) + if (bInvalidateDirectoryCache) + { + + + + + MMU_InvalidateDirectoryCache(psMMUContext->psDevInfo); + } +#endif +} + + +static IMG_VOID +MMU_UnmapPagesAndFreePTs (MMU_HEAP *psMMUHeap, + IMG_DEV_VIRTADDR sDevVAddr, + IMG_UINT32 ui32PageCount, + IMG_HANDLE hUniqueTag) +{ + IMG_UINT32 uPageSize = HOST_PAGESIZE(); + IMG_DEV_VIRTADDR sTmpDevVAddr; + IMG_UINT32 i; + IMG_UINT32 ui32PDIndex; + IMG_UINT32 ui32PTIndex; + IMG_UINT32 *pui32Tmp; + IMG_BOOL bInvalidateDirectoryCache = IMG_FALSE; + +#if !defined (PDUMP) + PVR_UNREFERENCED_PARAMETER(hUniqueTag); +#endif + + sTmpDevVAddr = sDevVAddr; + + for(i=0; i> (SGX_MMU_PAGE_SHIFT + SGX_MMU_PT_SHIFT); + + + ppsPTInfoList = &psMMUHeap->psMMUContext->apsPTInfoList[ui32PDIndex]; + + { + + ui32PTIndex = (sTmpDevVAddr.uiAddr & SGX_MMU_PT_MASK) >> SGX_MMU_PAGE_SHIFT; + + + if (!ppsPTInfoList[0]) + { + PVR_DPF((PVR_DBG_MESSAGE, "MMU_UnmapPagesAndFreePTs: Invalid PT for alloc at VAddr:0x%08lX (VaddrIni:0x%08lX AllocPage:%u) PDIdx:%u PTIdx:%u",sTmpDevVAddr.uiAddr, sDevVAddr.uiAddr,i, ui32PDIndex, ui32PTIndex )); + + + sTmpDevVAddr.uiAddr += uPageSize; + + + continue; + } + + + pui32Tmp = (IMG_UINT32*)ppsPTInfoList[0]->PTPageCpuVAddr; + + + if (!pui32Tmp) + { + continue; + } + + + if (pui32Tmp[ui32PTIndex] & SGX_MMU_PTE_VALID) + { + ppsPTInfoList[0]->ui32ValidPTECount--; + } + else + { + PVR_DPF((PVR_DBG_MESSAGE, "MMU_UnmapPagesAndFreePTs: Page is already invalid for alloc at VAddr:0x%08lX (VAddrIni:0x%08lX AllocPage:%u) PDIdx:%u PTIdx:%u",sTmpDevVAddr.uiAddr, sDevVAddr.uiAddr,i, ui32PDIndex, ui32PTIndex )); + } + + + PVR_ASSERT((IMG_INT32)ppsPTInfoList[0]->ui32ValidPTECount >= 0); + +#if defined(SUPPORT_SGX_MMU_DUMMY_PAGE) + + pui32Tmp[ui32PTIndex] = psMMUHeap->psMMUContext->psDevInfo->sDummyDataDevPAddr.uiAddr | SGX_MMU_PTE_VALID; +#else + + pui32Tmp[ui32PTIndex] = 0; +#endif + } + + + + if (ppsPTInfoList[0] && ppsPTInfoList[0]->ui32ValidPTECount == 0) + { + _DeferredFreePageTable(psMMUHeap, ui32PDIndex - (psMMUHeap->ui32PTBaseIndex >> SGX_MMU_PT_SHIFT)); + bInvalidateDirectoryCache = IMG_TRUE; + } + + + sTmpDevVAddr.uiAddr += uPageSize; + } + + if(bInvalidateDirectoryCache) + { + MMU_InvalidateDirectoryCache(psMMUHeap->psMMUContext->psDevInfo); + } + else + { + MMU_InvalidatePageTableCache(psMMUHeap->psMMUContext->psDevInfo); + } + +#if defined(PDUMP) + MMU_PDumpPageTables (psMMUHeap, sDevVAddr, uPageSize*ui32PageCount, IMG_TRUE, hUniqueTag); +#endif +} + + +IMG_VOID MMU_FreePageTables(IMG_PVOID pvMMUHeap, + IMG_UINT32 ui32Start, + IMG_UINT32 ui32End, + IMG_HANDLE hUniqueTag) +{ + MMU_HEAP *pMMUHeap = (MMU_HEAP*)pvMMUHeap; + IMG_DEV_VIRTADDR Start; + + Start.uiAddr = ui32Start; + + MMU_UnmapPagesAndFreePTs(pMMUHeap, Start, (ui32End - ui32Start) / SGX_MMU_PAGE_SIZE, hUniqueTag); +} + +MMU_HEAP * +MMU_Create (MMU_CONTEXT *psMMUContext, + DEV_ARENA_DESCRIPTOR *psDevArena, + RA_ARENA **ppsVMArena) +{ + MMU_HEAP *pMMUHeap; + IMG_BOOL bRes; + + PVR_ASSERT (psDevArena != IMG_NULL); + + if (psDevArena == IMG_NULL) + { + PVR_DPF((PVR_DBG_ERROR, "MMU_Create: invalid parameter")); + return IMG_NULL; + } + + OSAllocMem(PVRSRV_OS_PAGEABLE_HEAP, + sizeof (MMU_HEAP), + (IMG_VOID **)&pMMUHeap, IMG_NULL); + if (pMMUHeap == IMG_NULL) + { + PVR_DPF((PVR_DBG_ERROR, "MMU_Create: ERROR call to OSAllocMem failed")); + return IMG_NULL; + } + + pMMUHeap->psMMUContext = psMMUContext; + pMMUHeap->psDevArena = psDevArena; + + bRes = _AllocPageTables (pMMUHeap); + if (!bRes) + { + PVR_DPF((PVR_DBG_ERROR, "MMU_Create: ERROR call to _AllocPageTables failed")); + OSFreeMem (PVRSRV_OS_PAGEABLE_HEAP, sizeof(MMU_HEAP), pMMUHeap, IMG_NULL); + return IMG_NULL; + } + + + pMMUHeap->psVMArena = RA_Create(psDevArena->pszName, + psDevArena->BaseDevVAddr.uiAddr, + psDevArena->ui32Size, + IMG_NULL, + SGX_MMU_PAGE_SIZE, + IMG_NULL, + IMG_NULL, + MMU_FreePageTables, + pMMUHeap); + + if (pMMUHeap->psVMArena == IMG_NULL) + { + PVR_DPF((PVR_DBG_ERROR, "MMU_Create: ERROR call to RA_Create failed")); + _DeferredFreePageTables (pMMUHeap); + OSFreeMem (PVRSRV_OS_PAGEABLE_HEAP, sizeof(MMU_HEAP), pMMUHeap, IMG_NULL); + return IMG_NULL; + } + +#if 0 + + if(psDevArena->ui32HeapID == SGX_TILED_HEAP_ID) + { + IMG_UINT32 ui32RegVal; + IMG_UINT32 ui32XTileStride; + + + + + + + ui32XTileStride = 2; + + ui32RegVal = (EUR_CR_BIF_TILE0_MIN_ADDRESS_MASK + & ((psDevArena->BaseDevVAddr.uiAddr>>20) + << EUR_CR_BIF_TILE0_MIN_ADDRESS_SHIFT)) + |(EUR_CR_BIF_TILE0_MAX_ADDRESS_MASK + & (((psDevArena->BaseDevVAddr.uiAddr+psDevArena->ui32Size)>>20) + << EUR_CR_BIF_TILE0_MAX_ADDRESS_SHIFT)) + |(EUR_CR_BIF_TILE0_CFG_MASK + & (((ui32XTileStride<<1)|8) << EUR_CR_BIF_TILE0_CFG_SHIFT)); + PDUMPREG(EUR_CR_BIF_TILE0, ui32RegVal); + } +#endif + + + + *ppsVMArena = pMMUHeap->psVMArena; + + return pMMUHeap; +} + +IMG_VOID +MMU_Delete (MMU_HEAP *pMMUHeap) +{ + if (pMMUHeap != IMG_NULL) + { + PVR_DPF ((PVR_DBG_MESSAGE, "MMU_Delete")); + + if(pMMUHeap->psVMArena) + { + RA_Delete (pMMUHeap->psVMArena); + } + +#ifdef SUPPORT_SGX_MMU_BYPASS + EnableHostAccess(pMMUHeap->psMMUContext); +#endif + _DeferredFreePageTables (pMMUHeap); +#ifdef SUPPORT_SGX_MMU_BYPASS + DisableHostAccess(pMMUHeap->psMMUContext); +#endif + + OSFreeMem (PVRSRV_OS_PAGEABLE_HEAP, sizeof(MMU_HEAP), pMMUHeap, IMG_NULL); + } +} + +IMG_BOOL +MMU_Alloc (MMU_HEAP *pMMUHeap, + IMG_SIZE_T uSize, + IMG_SIZE_T *pActualSize, + IMG_UINT32 uFlags, + IMG_UINT32 uDevVAddrAlignment, + IMG_DEV_VIRTADDR *psDevVAddr) +{ + IMG_BOOL bStatus; + + PVR_DPF ((PVR_DBG_MESSAGE, + "MMU_Alloc: uSize=0x%x, flags=0x%x, align=0x%x", + uSize, uFlags, uDevVAddrAlignment)); + + + + if((uFlags & PVRSRV_MEM_USER_SUPPLIED_DEVVADDR) == 0) + { + bStatus = RA_Alloc (pMMUHeap->psVMArena, + uSize, + pActualSize, + IMG_NULL, + 0, + uDevVAddrAlignment, + 0, + &(psDevVAddr->uiAddr)); + if(!bStatus) + { + PVR_DPF((PVR_DBG_ERROR,"MMU_Alloc: RA_Alloc of VMArena failed")); + return bStatus; + } + } + + #ifdef SUPPORT_SGX_MMU_BYPASS + EnableHostAccess(pMMUHeap->psMMUContext); + #endif + + + bStatus = _DeferredAllocPagetables(pMMUHeap, *psDevVAddr, uSize); + + #ifdef SUPPORT_SGX_MMU_BYPASS + DisableHostAccess(pMMUHeap->psMMUContext); + #endif + + if (!bStatus) + { + PVR_DPF((PVR_DBG_ERROR,"MMU_Alloc: _DeferredAllocPagetables failed")); + if((uFlags & PVRSRV_MEM_USER_SUPPLIED_DEVVADDR) == 0) + { + + RA_Free (pMMUHeap->psVMArena, psDevVAddr->uiAddr, IMG_FALSE); + } + } + + return bStatus; +} + +IMG_VOID +MMU_Free (MMU_HEAP *pMMUHeap, IMG_DEV_VIRTADDR DevVAddr, IMG_UINT32 ui32Size) +{ + PVR_ASSERT (pMMUHeap != IMG_NULL); + + if (pMMUHeap == IMG_NULL) + { + PVR_DPF((PVR_DBG_ERROR, "MMU_Free: invalid parameter")); + return; + } + + PVR_DPF ((PVR_DBG_MESSAGE, + "MMU_Free: mmu=%08X, dev_vaddr=%08X", pMMUHeap, DevVAddr.uiAddr)); + + if((DevVAddr.uiAddr >= pMMUHeap->psDevArena->BaseDevVAddr.uiAddr) && + (DevVAddr.uiAddr + ui32Size <= pMMUHeap->psDevArena->BaseDevVAddr.uiAddr + pMMUHeap->psDevArena->ui32Size)) + { + RA_Free (pMMUHeap->psVMArena, DevVAddr.uiAddr, IMG_TRUE); + return; + } + + PVR_DPF((PVR_DBG_ERROR,"MMU_Free: Couldn't find DevVAddr %08X in a DevArena",DevVAddr.uiAddr)); +} + +IMG_VOID +MMU_Enable (MMU_HEAP *pMMUHeap) +{ + PVR_UNREFERENCED_PARAMETER(pMMUHeap); + +} + +IMG_VOID +MMU_Disable (MMU_HEAP *pMMUHeap) +{ + PVR_UNREFERENCED_PARAMETER(pMMUHeap); + +} + +#if defined(PDUMP) +static IMG_VOID +MMU_PDumpPageTables (MMU_HEAP *pMMUHeap, + IMG_DEV_VIRTADDR DevVAddr, + IMG_SIZE_T uSize, + IMG_BOOL bForUnmap, + IMG_HANDLE hUniqueTag) +{ + IMG_UINT32 ui32NumPTEntries; + IMG_UINT32 ui32PTIndex; + IMG_UINT32 *pui32PTEntry; + + MMU_PT_INFO **ppsPTInfoList; + IMG_UINT32 ui32PDIndex; + IMG_UINT32 ui32PTDumpCount; + + + ui32NumPTEntries = (uSize + SGX_MMU_PAGE_SIZE - 1) >> SGX_MMU_PAGE_SHIFT; + + + ui32PDIndex = DevVAddr.uiAddr >> (SGX_MMU_PAGE_SHIFT + SGX_MMU_PT_SHIFT); + + + ppsPTInfoList = &pMMUHeap->psMMUContext->apsPTInfoList[ui32PDIndex]; + + + ui32PTIndex = (DevVAddr.uiAddr & SGX_MMU_PT_MASK) >> SGX_MMU_PAGE_SHIFT; + + + PDUMPCOMMENT("Page table mods (num entries == %08X) %s", ui32NumPTEntries, bForUnmap ? "(for unmap)" : ""); + + + while(ui32NumPTEntries > 0) + { + MMU_PT_INFO* psPTInfo = *ppsPTInfoList++; + + if(ui32NumPTEntries <= 1024 - ui32PTIndex) + { + ui32PTDumpCount = ui32NumPTEntries; + } + else + { + ui32PTDumpCount = 1024 - ui32PTIndex; + } + + if (psPTInfo) + { + pui32PTEntry = (IMG_UINT32*)psPTInfo->PTPageCpuVAddr; + PDUMPMEM2(PVRSRV_DEVICE_TYPE_SGX, (IMG_VOID *) &pui32PTEntry[ui32PTIndex], ui32PTDumpCount * sizeof(IMG_UINT32), 0, IMG_FALSE, PDUMP_PT_UNIQUETAG, hUniqueTag); + } + + + ui32NumPTEntries -= ui32PTDumpCount; + + + ui32PTIndex = 0; + } + + PDUMPCOMMENT("Finished page table mods %s", bForUnmap ? "(for unmap)" : ""); +} +#endif + + +static IMG_VOID +MMU_MapPage (MMU_HEAP *pMMUHeap, + IMG_DEV_VIRTADDR DevVAddr, + IMG_DEV_PHYADDR DevPAddr, + IMG_UINT32 ui32MemFlags) +{ + IMG_UINT32 ui32Index; + IMG_UINT32 *pui32Tmp; + IMG_UINT32 ui32MMUFlags = 0; + MMU_PT_INFO **ppsPTInfoList; + + + + if(((PVRSRV_MEM_READ|PVRSRV_MEM_WRITE) & ui32MemFlags) == (PVRSRV_MEM_READ|PVRSRV_MEM_WRITE)) + { + + ui32MMUFlags = 0; + } + else if(PVRSRV_MEM_READ & ui32MemFlags) + { + + ui32MMUFlags |= SGX_MMU_PTE_READONLY; + } + else if(PVRSRV_MEM_WRITE & ui32MemFlags) + { + + ui32MMUFlags |= SGX_MMU_PTE_WRITEONLY; + } + + + if(PVRSRV_MEM_CACHE_CONSISTENT & ui32MemFlags) + { + ui32MMUFlags |= SGX_MMU_PTE_CACHECONSISTENT; + } + +#if !defined(FIX_HW_BRN_25503) + + if(PVRSRV_MEM_EDM_PROTECT & ui32MemFlags) + { + ui32MMUFlags |= SGX_MMU_PTE_EDMPROTECT; + } +#endif + + + + + + ui32Index = DevVAddr.uiAddr >> (SGX_MMU_PAGE_SHIFT + SGX_MMU_PT_SHIFT); + + + ppsPTInfoList = &pMMUHeap->psMMUContext->apsPTInfoList[ui32Index]; + + + ui32Index = (DevVAddr.uiAddr & SGX_MMU_PT_MASK) >> SGX_MMU_PAGE_SHIFT; + + + pui32Tmp = (IMG_UINT32*)ppsPTInfoList[0]->PTPageCpuVAddr; + +#if !defined(SUPPORT_SGX_MMU_DUMMY_PAGE) + + if (pui32Tmp[ui32Index] & SGX_MMU_PTE_VALID) + { + PVR_DPF((PVR_DBG_ERROR, "MMU_MapPage: Page is already valid for alloc at VAddr:0x%08lX PDIdx:%u PTIdx:%u",DevVAddr.uiAddr, DevVAddr.uiAddr >> (SGX_MMU_PAGE_SHIFT + SGX_MMU_PT_SHIFT), ui32Index )); + } + + PVR_ASSERT((pui32Tmp[ui32Index] & SGX_MMU_PTE_VALID) == 0); +#endif + + + ppsPTInfoList[0]->ui32ValidPTECount++; + + + pui32Tmp[ui32Index] = (DevPAddr.uiAddr & SGX_MMU_PTE_ADDR_MASK) + | SGX_MMU_PTE_VALID + | ui32MMUFlags; +} + + +IMG_VOID +MMU_MapScatter (MMU_HEAP *pMMUHeap, + IMG_DEV_VIRTADDR DevVAddr, + IMG_SYS_PHYADDR *psSysAddr, + IMG_SIZE_T uSize, + IMG_UINT32 ui32MemFlags, + IMG_HANDLE hUniqueTag) +{ +#if defined(PDUMP) + IMG_DEV_VIRTADDR MapBaseDevVAddr; +#endif + IMG_UINT32 uCount, i; + IMG_DEV_PHYADDR DevPAddr; + + PVR_ASSERT (pMMUHeap != IMG_NULL); + +#if defined(PDUMP) + MapBaseDevVAddr = DevVAddr; +#else + PVR_UNREFERENCED_PARAMETER(hUniqueTag); +#endif + + for (i=0, uCount=0; uCountuiAddr = MapBaseDevVAddr.uiAddr; + +#if defined(FIX_HW_BRN_23281) + if(ui32MemFlags & PVRSRV_MEM_INTERLEAVED) + { + ui32VAdvance *= 2; + } +#endif + + + + + if(ui32MemFlags & PVRSRV_MEM_DUMMY) + { + ui32PAdvance = 0; + } + + + MapDevVAddr = MapBaseDevVAddr; + for (i=0; i> (SGX_MMU_PAGE_SHIFT + SGX_MMU_PT_SHIFT); + + + ppsPTInfoList = &psMMUHeap->psMMUContext->apsPTInfoList[ui32PDIndex]; + + + ui32PTIndex = (sTmpDevVAddr.uiAddr & SGX_MMU_PT_MASK) >> SGX_MMU_PAGE_SHIFT; + + + if (!ppsPTInfoList[0]) + { + PVR_DPF((PVR_DBG_ERROR, "MMU_UnmapPages: ERROR Invalid PT for alloc at VAddr:0x%08lX (VaddrIni:0x%08lX AllocPage:%u) PDIdx:%u PTIdx:%u",sTmpDevVAddr.uiAddr, sDevVAddr.uiAddr,i, ui32PDIndex, ui32PTIndex )); + + + sTmpDevVAddr.uiAddr += uPageSize; + + + continue; + } + + + pui32Tmp = (IMG_UINT32*)ppsPTInfoList[0]->PTPageCpuVAddr; + + + if (pui32Tmp[ui32PTIndex] & SGX_MMU_PTE_VALID) + { + ppsPTInfoList[0]->ui32ValidPTECount--; + } + else + { + PVR_DPF((PVR_DBG_ERROR, "MMU_UnmapPages: Page is already invalid for alloc at VAddr:0x%08lX (VAddrIni:0x%08lX AllocPage:%u) PDIdx:%u PTIdx:%u",sTmpDevVAddr.uiAddr, sDevVAddr.uiAddr,i, ui32PDIndex, ui32PTIndex )); + } + + + PVR_ASSERT((IMG_INT32)ppsPTInfoList[0]->ui32ValidPTECount >= 0); + +#if defined(SUPPORT_SGX_MMU_DUMMY_PAGE) + + pui32Tmp[ui32PTIndex] = psMMUHeap->psMMUContext->psDevInfo->sDummyDataDevPAddr.uiAddr | SGX_MMU_PTE_VALID; +#else + + pui32Tmp[ui32PTIndex] = 0; +#endif + + + sTmpDevVAddr.uiAddr += uPageSize; + } + + MMU_InvalidatePageTableCache(psMMUHeap->psMMUContext->psDevInfo); + +#if defined(PDUMP) + MMU_PDumpPageTables (psMMUHeap, sDevVAddr, uPageSize*ui32PageCount, IMG_TRUE, hUniqueTag); +#endif +} + + +IMG_DEV_PHYADDR +MMU_GetPhysPageAddr(MMU_HEAP *pMMUHeap, IMG_DEV_VIRTADDR sDevVPageAddr) +{ + IMG_UINT32 *pui32PageTable; + IMG_UINT32 ui32Index; + IMG_DEV_PHYADDR sDevPAddr; + MMU_PT_INFO **ppsPTInfoList; + + + ui32Index = sDevVPageAddr.uiAddr >> (SGX_MMU_PAGE_SHIFT + SGX_MMU_PT_SHIFT); + + + ppsPTInfoList = &pMMUHeap->psMMUContext->apsPTInfoList[ui32Index]; + if (!ppsPTInfoList[0]) + { + PVR_DPF((PVR_DBG_ERROR,"MMU_GetPhysPageAddr: Not mapped in at 0x%08x", sDevVPageAddr.uiAddr)); + sDevPAddr.uiAddr = 0; + return sDevPAddr; + } + + + ui32Index = (sDevVPageAddr.uiAddr & SGX_MMU_PT_MASK) >> SGX_MMU_PAGE_SHIFT; + + + pui32PageTable = (IMG_UINT32*)ppsPTInfoList[0]->PTPageCpuVAddr; + + + sDevPAddr.uiAddr = pui32PageTable[ui32Index]; + + + sDevPAddr.uiAddr &= SGX_MMU_PTE_ADDR_MASK; + + return sDevPAddr; +} + + +IMG_DEV_PHYADDR MMU_GetPDDevPAddr(MMU_CONTEXT *pMMUContext) +{ + return (pMMUContext->sPDDevPAddr); +} + + +IMG_EXPORT +PVRSRV_ERROR SGXGetPhysPageAddrKM (IMG_HANDLE hDevMemHeap, + IMG_DEV_VIRTADDR sDevVAddr, + IMG_DEV_PHYADDR *pDevPAddr, + IMG_CPU_PHYADDR *pCpuPAddr) +{ + MMU_HEAP *pMMUHeap; + IMG_DEV_PHYADDR DevPAddr; + + + + pMMUHeap = (MMU_HEAP*)BM_GetMMUHeap(hDevMemHeap); + + DevPAddr = MMU_GetPhysPageAddr(pMMUHeap, sDevVAddr); + pCpuPAddr->uiAddr = DevPAddr.uiAddr; + pDevPAddr->uiAddr = DevPAddr.uiAddr; + + return (pDevPAddr->uiAddr != 0) ? PVRSRV_OK : PVRSRV_ERROR_INVALID_PARAMS; +} + + +PVRSRV_ERROR SGXGetMMUPDAddrKM(IMG_HANDLE hDevCookie, + IMG_HANDLE hDevMemContext, + IMG_DEV_PHYADDR *psPDDevPAddr) +{ + if (!hDevCookie || !hDevMemContext || !psPDDevPAddr) + { + return PVRSRV_ERROR_INVALID_PARAMS; + } + + + *psPDDevPAddr = ((BM_CONTEXT*)hDevMemContext)->psMMUContext->sPDDevPAddr; + + return PVRSRV_OK; +} + +PVRSRV_ERROR MMU_BIFResetPDAlloc(PVRSRV_SGXDEV_INFO *psDevInfo) +{ + PVRSRV_ERROR eError; + SYS_DATA *psSysData; + RA_ARENA *psLocalDevMemArena; + IMG_HANDLE hOSMemHandle = IMG_NULL; + IMG_BYTE *pui8MemBlock = IMG_NULL; + IMG_SYS_PHYADDR sMemBlockSysPAddr; + IMG_CPU_PHYADDR sMemBlockCpuPAddr; + + eError = SysAcquireData(&psSysData); + if (eError != PVRSRV_OK) + { + PVR_DPF((PVR_DBG_ERROR, "MMU_BIFResetPDAlloc: ERROR call to SysAcquireData failed")); + return eError; + } + + psLocalDevMemArena = psSysData->apsLocalDevMemArena[0]; + + + if(psLocalDevMemArena == IMG_NULL) + { + + eError = OSAllocPages(PVRSRV_HAP_WRITECOMBINE | PVRSRV_HAP_KERNEL_ONLY, + 3 * SGX_MMU_PAGE_SIZE, + SGX_MMU_PAGE_SIZE, + (IMG_VOID **)&pui8MemBlock, + &hOSMemHandle); + if (eError != PVRSRV_OK) + { + PVR_DPF((PVR_DBG_ERROR, "MMU_BIFResetPDAlloc: ERROR call to OSAllocPages failed")); + return eError; + } + + + if(pui8MemBlock) + { + sMemBlockCpuPAddr = OSMapLinToCPUPhys(pui8MemBlock); + } + else + { + + sMemBlockCpuPAddr = OSMemHandleToCpuPAddr(hOSMemHandle, 0); + } + } + else + { + + + if(RA_Alloc(psLocalDevMemArena, + 3 * SGX_MMU_PAGE_SIZE, + IMG_NULL, + IMG_NULL, + 0, + SGX_MMU_PAGE_SIZE, + 0, + &(sMemBlockSysPAddr.uiAddr)) != IMG_TRUE) + { + PVR_DPF((PVR_DBG_ERROR, "MMU_BIFResetPDAlloc: ERROR call to RA_Alloc failed")); + return PVRSRV_ERROR_OUT_OF_MEMORY; + } + + + sMemBlockCpuPAddr = SysSysPAddrToCpuPAddr(sMemBlockSysPAddr); + pui8MemBlock = OSMapPhysToLin(sMemBlockCpuPAddr, + SGX_MMU_PAGE_SIZE * 3, + PVRSRV_HAP_WRITECOMBINE|PVRSRV_HAP_KERNEL_ONLY, + &hOSMemHandle); + if(!pui8MemBlock) + { + PVR_DPF((PVR_DBG_ERROR, "MMU_BIFResetPDAlloc: ERROR failed to map page tables")); + return PVRSRV_ERROR_BAD_MAPPING; + } + } + + psDevInfo->hBIFResetPDOSMemHandle = hOSMemHandle; + psDevInfo->sBIFResetPDDevPAddr = SysCpuPAddrToDevPAddr(PVRSRV_DEVICE_TYPE_SGX, sMemBlockCpuPAddr); + psDevInfo->sBIFResetPTDevPAddr.uiAddr = psDevInfo->sBIFResetPDDevPAddr.uiAddr + SGX_MMU_PAGE_SIZE; + psDevInfo->sBIFResetPageDevPAddr.uiAddr = psDevInfo->sBIFResetPTDevPAddr.uiAddr + SGX_MMU_PAGE_SIZE; + + + psDevInfo->pui32BIFResetPD = (IMG_UINT32 *)pui8MemBlock; + psDevInfo->pui32BIFResetPT = (IMG_UINT32 *)(pui8MemBlock + SGX_MMU_PAGE_SIZE); + + + OSMemSet(psDevInfo->pui32BIFResetPD, 0, SGX_MMU_PAGE_SIZE); + OSMemSet(psDevInfo->pui32BIFResetPT, 0, SGX_MMU_PAGE_SIZE); + + OSMemSet(pui8MemBlock + (2 * SGX_MMU_PAGE_SIZE), 0xDB, SGX_MMU_PAGE_SIZE); + + return PVRSRV_OK; +} + +IMG_VOID MMU_BIFResetPDFree(PVRSRV_SGXDEV_INFO *psDevInfo) +{ + PVRSRV_ERROR eError; + SYS_DATA *psSysData; + RA_ARENA *psLocalDevMemArena; + IMG_SYS_PHYADDR sPDSysPAddr; + + eError = SysAcquireData(&psSysData); + if (eError != PVRSRV_OK) + { + PVR_DPF((PVR_DBG_ERROR, "MMU_BIFResetPDFree: ERROR call to SysAcquireData failed")); + return; + } + + psLocalDevMemArena = psSysData->apsLocalDevMemArena[0]; + + + if(psLocalDevMemArena == IMG_NULL) + { + OSFreePages(PVRSRV_HAP_WRITECOMBINE | PVRSRV_HAP_KERNEL_ONLY, + 3 * SGX_MMU_PAGE_SIZE, + psDevInfo->pui32BIFResetPD, + psDevInfo->hBIFResetPDOSMemHandle); + } + else + { + OSUnMapPhysToLin(psDevInfo->pui32BIFResetPD, + 3 * SGX_MMU_PAGE_SIZE, + PVRSRV_HAP_WRITECOMBINE|PVRSRV_HAP_KERNEL_ONLY, + psDevInfo->hBIFResetPDOSMemHandle); + + sPDSysPAddr = SysDevPAddrToSysPAddr(PVRSRV_DEVICE_TYPE_SGX, psDevInfo->sBIFResetPDDevPAddr); + RA_Free(psLocalDevMemArena, sPDSysPAddr.uiAddr, IMG_FALSE); + } +} + + +#if defined(FIX_HW_BRN_22997) && defined(FIX_HW_BRN_23030) && defined(SGX_FEATURE_HOST_PORT) +PVRSRV_ERROR WorkaroundBRN22997Alloc(PVRSRV_SGXDEV_INFO *psDevInfo) +{ + PVRSRV_ERROR eError; + SYS_DATA *psSysData; + RA_ARENA *psLocalDevMemArena; + IMG_HANDLE hPTPageOSMemHandle = IMG_NULL; + IMG_HANDLE hPDPageOSMemHandle = IMG_NULL; + IMG_UINT32 *pui32PD = IMG_NULL; + IMG_UINT32 *pui32PT = IMG_NULL; + IMG_CPU_PHYADDR sCpuPAddr; + IMG_DEV_PHYADDR sPTDevPAddr; + IMG_DEV_PHYADDR sPDDevPAddr; + + eError = SysAcquireData(&psSysData); + if (eError != PVRSRV_OK) + { + PVR_DPF((PVR_DBG_ERROR, "WorkaroundBRN22997: ERROR call to SysAcquireData failed")); + return eError; + } + + psLocalDevMemArena = psSysData->apsLocalDevMemArena[0]; + + + if(psLocalDevMemArena == IMG_NULL) + { + + eError = OSAllocPages(PVRSRV_HAP_WRITECOMBINE | PVRSRV_HAP_KERNEL_ONLY, + SGX_MMU_PAGE_SIZE, + SGX_MMU_PAGE_SIZE, + (IMG_VOID **)&pui32PT, + &hPTPageOSMemHandle); + if (eError != PVRSRV_OK) + { + PVR_DPF((PVR_DBG_ERROR, "WorkaroundBRN22997: ERROR call to OSAllocPages failed")); + return eError; + } + + eError = OSAllocPages(PVRSRV_HAP_WRITECOMBINE | PVRSRV_HAP_KERNEL_ONLY, + SGX_MMU_PAGE_SIZE, + SGX_MMU_PAGE_SIZE, + (IMG_VOID **)&pui32PD, + &hPDPageOSMemHandle); + if (eError != PVRSRV_OK) + { + PVR_DPF((PVR_DBG_ERROR, "WorkaroundBRN22997: ERROR call to OSAllocPages failed")); + return eError; + } + + + if(pui32PT) + { + sCpuPAddr = OSMapLinToCPUPhys(pui32PT); + } + else + { + + sCpuPAddr = OSMemHandleToCpuPAddr(hPTPageOSMemHandle, 0); + } + sPTDevPAddr = SysCpuPAddrToDevPAddr(PVRSRV_DEVICE_TYPE_SGX, sCpuPAddr); + + if(pui32PD) + { + sCpuPAddr = OSMapLinToCPUPhys(pui32PD); + } + else + { + + sCpuPAddr = OSMemHandleToCpuPAddr(hPDPageOSMemHandle, 0); + } + sPDDevPAddr = SysCpuPAddrToDevPAddr(PVRSRV_DEVICE_TYPE_SGX, sCpuPAddr); + + } + else + { + + + if(RA_Alloc(psLocalDevMemArena, + SGX_MMU_PAGE_SIZE * 2, + IMG_NULL, + IMG_NULL, + 0, + SGX_MMU_PAGE_SIZE, + 0, + &(psDevInfo->sBRN22997SysPAddr.uiAddr))!= IMG_TRUE) + { + PVR_DPF((PVR_DBG_ERROR, "WorkaroundBRN22997: ERROR call to RA_Alloc failed")); + return PVRSRV_ERROR_OUT_OF_MEMORY; + } + + + sCpuPAddr = SysSysPAddrToCpuPAddr(psDevInfo->sBRN22997SysPAddr); + pui32PT = OSMapPhysToLin(sCpuPAddr, + SGX_MMU_PAGE_SIZE * 2, + PVRSRV_HAP_WRITECOMBINE|PVRSRV_HAP_KERNEL_ONLY, + &hPTPageOSMemHandle); + if(!pui32PT) + { + PVR_DPF((PVR_DBG_ERROR, "WorkaroundBRN22997: ERROR failed to map page tables")); + return PVRSRV_ERROR_BAD_MAPPING; + } + + + sPTDevPAddr = SysCpuPAddrToDevPAddr(PVRSRV_DEVICE_TYPE_SGX, sCpuPAddr); + + pui32PD = pui32PT + 1024; + sPDDevPAddr.uiAddr = sPTDevPAddr.uiAddr + 4096; + } + + OSMemSet(pui32PD, 0, SGX_MMU_PAGE_SIZE); + OSMemSet(pui32PT, 0, SGX_MMU_PAGE_SIZE); + + + PDUMPMALLOCPAGETABLE(PVRSRV_DEVICE_TYPE_SGX, pui32PD, SGX_MMU_PAGE_SIZE, PDUMP_PD_UNIQUETAG); + PDUMPMALLOCPAGETABLE(PVRSRV_DEVICE_TYPE_SGX, pui32PT, SGX_MMU_PAGE_SIZE, PDUMP_PT_UNIQUETAG); + PDUMPMEM2(PVRSRV_DEVICE_TYPE_SGX, pui32PD, SGX_MMU_PAGE_SIZE, 0, IMG_TRUE, PDUMP_PD_UNIQUETAG, PDUMP_PT_UNIQUETAG); + PDUMPMEM2(PVRSRV_DEVICE_TYPE_SGX, pui32PT, SGX_MMU_PAGE_SIZE, 0, IMG_TRUE, PDUMP_PT_UNIQUETAG, PDUMP_PD_UNIQUETAG); + + psDevInfo->hBRN22997PTPageOSMemHandle = hPTPageOSMemHandle; + psDevInfo->hBRN22997PDPageOSMemHandle = hPDPageOSMemHandle; + psDevInfo->sBRN22997PTDevPAddr = sPTDevPAddr; + psDevInfo->sBRN22997PDDevPAddr = sPDDevPAddr; + psDevInfo->pui32BRN22997PD = pui32PD; + psDevInfo->pui32BRN22997PT = pui32PT; + + return PVRSRV_OK; +} + + +IMG_VOID WorkaroundBRN22997ReadHostPort(PVRSRV_SGXDEV_INFO *psDevInfo) +{ + IMG_UINT32 *pui32PD = psDevInfo->pui32BRN22997PD; + IMG_UINT32 *pui32PT = psDevInfo->pui32BRN22997PT; + IMG_UINT32 ui32PDIndex; + IMG_UINT32 ui32PTIndex; + IMG_DEV_VIRTADDR sDevVAddr; + volatile IMG_UINT32 *pui32HostPort; + IMG_UINT32 ui32BIFCtrl; + + + + + pui32HostPort = (volatile IMG_UINT32*)(((IMG_UINT8*)psDevInfo->pvHostPortBaseKM) + SYS_SGX_HOSTPORT_BRN23030_OFFSET); + + + sDevVAddr.uiAddr = SYS_SGX_HOSTPORT_BASE_DEVVADDR + SYS_SGX_HOSTPORT_BRN23030_OFFSET; + + ui32PDIndex = (sDevVAddr.uiAddr & SGX_MMU_PD_MASK) >> (SGX_MMU_PAGE_SHIFT + SGX_MMU_PT_SHIFT); + ui32PTIndex = (sDevVAddr.uiAddr & SGX_MMU_PT_MASK) >> SGX_MMU_PAGE_SHIFT; + + + pui32PD[ui32PDIndex] = psDevInfo->sBRN22997PTDevPAddr.uiAddr | SGX_MMU_PDE_VALID; + + pui32PT[ui32PTIndex] = psDevInfo->sBRN22997PTDevPAddr.uiAddr | SGX_MMU_PTE_VALID; + + PDUMPMEM2(PVRSRV_DEVICE_TYPE_SGX, pui32PD, SGX_MMU_PAGE_SIZE, 0, IMG_TRUE, PDUMP_PD_UNIQUETAG, PDUMP_PT_UNIQUETAG); + PDUMPMEM2(PVRSRV_DEVICE_TYPE_SGX, pui32PT, SGX_MMU_PAGE_SIZE, 0, IMG_TRUE, PDUMP_PT_UNIQUETAG, PDUMP_PD_UNIQUETAG); + + + OSWriteHWReg(psDevInfo->pvRegsBaseKM, EUR_CR_BIF_DIR_LIST_BASE0, + psDevInfo->sBRN22997PDDevPAddr.uiAddr); + PDUMPPDREG(EUR_CR_BIF_DIR_LIST_BASE0, psDevInfo->sBRN22997PDDevPAddr.uiAddr, PDUMP_PD_UNIQUETAG); + + + ui32BIFCtrl = OSReadHWReg(psDevInfo->pvRegsBaseKM, EUR_CR_BIF_CTRL); + OSWriteHWReg(psDevInfo->pvRegsBaseKM, EUR_CR_BIF_CTRL, ui32BIFCtrl | EUR_CR_BIF_CTRL_INVALDC_MASK); + PDUMPREG(EUR_CR_BIF_CTRL, ui32BIFCtrl | EUR_CR_BIF_CTRL_INVALDC_MASK); + OSWriteHWReg(psDevInfo->pvRegsBaseKM, EUR_CR_BIF_CTRL, ui32BIFCtrl); + PDUMPREG(EUR_CR_BIF_CTRL, ui32BIFCtrl); + + + if (pui32HostPort == IMG_NULL) + { + PVR_DPF((PVR_DBG_ERROR,"Host Port not present for BRN22997 workaround")); + } + + + + + + + + PDUMPCOMMENT("RDW :SGXMEM:v4:%08lX\r\n", sDevVAddr.uiAddr); + + PDUMPCOMMENT("SAB :SGXMEM:v4:%08lX 4 0 hostport.bin", sDevVAddr.uiAddr); + + + pui32PD[ui32PDIndex] = 0; + pui32PT[ui32PTIndex] = 0; + + + PDUMPMEM2(PVRSRV_DEVICE_TYPE_SGX, pui32PD, SGX_MMU_PAGE_SIZE, 0, IMG_TRUE, PDUMP_PD_UNIQUETAG, PDUMP_PT_UNIQUETAG); + PDUMPMEM2(PVRSRV_DEVICE_TYPE_SGX, pui32PT, SGX_MMU_PAGE_SIZE, 0, IMG_TRUE, PDUMP_PT_UNIQUETAG, PDUMP_PD_UNIQUETAG); + + OSWriteHWReg(psDevInfo->pvRegsBaseKM, EUR_CR_BIF_CTRL, ui32BIFCtrl | EUR_CR_BIF_CTRL_INVALDC_MASK); + PDUMPREG(EUR_CR_BIF_CTRL, ui32BIFCtrl | EUR_CR_BIF_CTRL_INVALDC_MASK); + OSWriteHWReg(psDevInfo->pvRegsBaseKM, EUR_CR_BIF_CTRL, ui32BIFCtrl); + PDUMPREG(EUR_CR_BIF_CTRL, ui32BIFCtrl); +} + + +IMG_VOID WorkaroundBRN22997Free(PVRSRV_SGXDEV_INFO *psDevInfo) +{ + PVRSRV_ERROR eError; + SYS_DATA *psSysData; + RA_ARENA *psLocalDevMemArena; + + eError = SysAcquireData(&psSysData); + if (eError != PVRSRV_OK) + { + PVR_DPF((PVR_DBG_ERROR, "WorkaroundBRN22997Free: ERROR call to SysAcquireData failed")); + return; + } + + psLocalDevMemArena = psSysData->apsLocalDevMemArena[0]; + + PDUMPFREEPAGETABLE(PVRSRV_DEVICE_TYPE_SGX, psDevInfo->pui32BRN22997PD, SGX_MMU_PAGE_SIZE, PDUMP_PD_UNIQUETAG); + PDUMPFREEPAGETABLE(PVRSRV_DEVICE_TYPE_SGX, psDevInfo->pui32BRN22997PT, SGX_MMU_PAGE_SIZE, PDUMP_PT_UNIQUETAG); + + + if(psLocalDevMemArena == IMG_NULL) + { + if (psDevInfo->pui32BRN22997PD != IMG_NULL) + { + OSFreePages(PVRSRV_HAP_WRITECOMBINE | PVRSRV_HAP_KERNEL_ONLY, + SGX_MMU_PAGE_SIZE, + psDevInfo->pui32BRN22997PD, + psDevInfo->hBRN22997PDPageOSMemHandle); + } + + if (psDevInfo->pui32BRN22997PT != IMG_NULL) + { + OSFreePages(PVRSRV_HAP_WRITECOMBINE | PVRSRV_HAP_KERNEL_ONLY, + SGX_MMU_PAGE_SIZE, + psDevInfo->pui32BRN22997PT, + psDevInfo->hBRN22997PTPageOSMemHandle); + } + } + else + { + if (psDevInfo->pui32BRN22997PT != IMG_NULL) + { + OSUnMapPhysToLin(psDevInfo->pui32BRN22997PT, + SGX_MMU_PAGE_SIZE * 2, + PVRSRV_HAP_WRITECOMBINE|PVRSRV_HAP_KERNEL_ONLY, + psDevInfo->hBRN22997PTPageOSMemHandle); + + + RA_Free(psLocalDevMemArena, psDevInfo->sBRN22997SysPAddr.uiAddr, IMG_FALSE); + } + } +} +#endif + + +#if defined(SUPPORT_EXTERNAL_SYSTEM_CACHE) +PVRSRV_ERROR MMU_MapExtSystemCacheRegs(PVRSRV_DEVICE_NODE *psDeviceNode) +{ + PVRSRV_ERROR eError; + SYS_DATA *psSysData; + RA_ARENA *psLocalDevMemArena; + IMG_HANDLE hPTPageOSMemHandle = IMG_NULL; + IMG_UINT32 *pui32PD; + IMG_UINT32 *pui32PT = IMG_NULL; + IMG_CPU_PHYADDR sCpuPAddr; + IMG_DEV_PHYADDR sPTDevPAddr; + PVRSRV_SGXDEV_INFO *psDevInfo; + IMG_UINT32 ui32PDIndex; + IMG_UINT32 ui32PTIndex; + + psDevInfo = (PVRSRV_SGXDEV_INFO*)psDeviceNode->pvDevice; + pui32PD = (IMG_UINT32*)psDeviceNode->sDevMemoryInfo.pBMKernelContext->psMMUContext->pvPDCpuVAddr; + + eError = SysAcquireData(&psSysData); + if (eError != PVRSRV_OK) + { + PVR_DPF((PVR_DBG_ERROR, "MMU_MapExtSystemCacheRegs: ERROR call to SysAcquireData failed")); + return eError; + } + + psLocalDevMemArena = psSysData->apsLocalDevMemArena[0]; + + + if(psLocalDevMemArena == IMG_NULL) + { + + eError = OSAllocPages(PVRSRV_HAP_WRITECOMBINE | PVRSRV_HAP_KERNEL_ONLY, + SGX_MMU_PAGE_SIZE, + SGX_MMU_PAGE_SIZE, + (IMG_VOID **)&pui32PT, + &hPTPageOSMemHandle); + if (eError != PVRSRV_OK) + { + PVR_DPF((PVR_DBG_ERROR, "MMU_MapExtSystemCacheRegs: ERROR call to OSAllocPages failed")); + return eError; + } + + + if(pui32PT) + { + sCpuPAddr = OSMapLinToCPUPhys(pui32PT); + } + else + { + + sCpuPAddr = OSMemHandleToCpuPAddr(hPTPageOSMemHandle, 0); + } + sPTDevPAddr = SysCpuPAddrToDevPAddr(PVRSRV_DEVICE_TYPE_SGX, sCpuPAddr); + } + else + { + IMG_SYS_PHYADDR sSysPAddr; + + + if(RA_Alloc(psLocalDevMemArena, + SGX_MMU_PAGE_SIZE, + IMG_NULL, + IMG_NULL, + 0, + SGX_MMU_PAGE_SIZE, + 0, + &(sSysPAddr.uiAddr))!= IMG_TRUE) + { + PVR_DPF((PVR_DBG_ERROR, "MMU_MapExtSystemCacheRegs: ERROR call to RA_Alloc failed")); + return PVRSRV_ERROR_OUT_OF_MEMORY; + } + + + sCpuPAddr = SysSysPAddrToCpuPAddr(sSysPAddr); + pui32PT = OSMapPhysToLin(sCpuPAddr, + SGX_MMU_PAGE_SIZE, + PVRSRV_HAP_WRITECOMBINE|PVRSRV_HAP_KERNEL_ONLY, + &hPTPageOSMemHandle); + if(!pui32PT) + { + PVR_DPF((PVR_DBG_ERROR, "MMU_MapExtSystemCacheRegs: ERROR failed to map page tables")); + return PVRSRV_ERROR_BAD_MAPPING; + } + + + sPTDevPAddr = SysCpuPAddrToDevPAddr(PVRSRV_DEVICE_TYPE_SGX, sCpuPAddr); + + + psDevInfo->sExtSystemCacheRegsPTSysPAddr = sSysPAddr; + } + + OSMemSet(pui32PT, 0, SGX_MMU_PAGE_SIZE); + + ui32PDIndex = (SGX_EXT_SYSTEM_CACHE_REGS_DEVVADDR_BASE & SGX_MMU_PD_MASK) >> (SGX_MMU_PAGE_SHIFT + SGX_MMU_PT_SHIFT); + ui32PTIndex = (SGX_EXT_SYSTEM_CACHE_REGS_DEVVADDR_BASE & SGX_MMU_PT_MASK) >> SGX_MMU_PAGE_SHIFT; + + + pui32PD[ui32PDIndex] = (sPTDevPAddr.uiAddr>>SGX_MMU_PDE_ADDR_ALIGNSHIFT) + | SGX_MMU_PDE_VALID; + + pui32PT[ui32PTIndex] = (psDevInfo->sExtSysCacheRegsDevPBase.uiAddr>>SGX_MMU_PTE_ADDR_ALIGNSHIFT) + | SGX_MMU_PTE_VALID; + + + PDUMPMALLOCPAGETABLE(PVRSRV_DEVICE_TYPE_SGX, pui32PT, SGX_MMU_PAGE_SIZE, PDUMP_PT_UNIQUETAG); + PDUMPMEM2(PVRSRV_DEVICE_TYPE_SGX, pui32PD, SGX_MMU_PAGE_SIZE, 0, IMG_TRUE, PDUMP_PD_UNIQUETAG, PDUMP_PT_UNIQUETAG); + PDUMPMEM2(PVRSRV_DEVICE_TYPE_SGX, pui32PT, SGX_MMU_PAGE_SIZE, 0, IMG_TRUE, PDUMP_PT_UNIQUETAG, PDUMP_PD_UNIQUETAG); + + + psDevInfo->pui32ExtSystemCacheRegsPT = pui32PT; + psDevInfo->hExtSystemCacheRegsPTPageOSMemHandle = hPTPageOSMemHandle; + + return PVRSRV_OK; +} + + +PVRSRV_ERROR MMU_UnmapExtSystemCacheRegs(PVRSRV_DEVICE_NODE *psDeviceNode) +{ + PVRSRV_ERROR eError; + SYS_DATA *psSysData; + RA_ARENA *psLocalDevMemArena; + PVRSRV_SGXDEV_INFO *psDevInfo; + IMG_UINT32 ui32PDIndex; + IMG_UINT32 *pui32PD; + + psDevInfo = (PVRSRV_SGXDEV_INFO*)psDeviceNode->pvDevice; + pui32PD = (IMG_UINT32*)psDeviceNode->sDevMemoryInfo.pBMKernelContext->psMMUContext->pvPDCpuVAddr; + + eError = SysAcquireData(&psSysData); + if (eError != PVRSRV_OK) + { + PVR_DPF((PVR_DBG_ERROR, "WorkaroundBRN22997Free: ERROR call to SysAcquireData failed")); + return eError; + } + + psLocalDevMemArena = psSysData->apsLocalDevMemArena[0]; + + + ui32PDIndex = (SGX_EXT_SYSTEM_CACHE_REGS_DEVVADDR_BASE & SGX_MMU_PD_MASK) >> (SGX_MMU_PAGE_SHIFT + SGX_MMU_PT_SHIFT); + pui32PD[ui32PDIndex] = 0; + + PDUMPMEM2(PVRSRV_DEVICE_TYPE_SGX, pui32PD, SGX_MMU_PAGE_SIZE, 0, IMG_TRUE, PDUMP_PD_UNIQUETAG, PDUMP_PT_UNIQUETAG); + PDUMPFREEPAGETABLE(PVRSRV_DEVICE_TYPE_SGX, psDevInfo->pui32ExtSystemCacheRegsPT, SGX_MMU_PAGE_SIZE, PDUMP_PT_UNIQUETAG); + + + if(psLocalDevMemArena == IMG_NULL) + { + if (psDevInfo->pui32ExtSystemCacheRegsPT != IMG_NULL) + { + OSFreePages(PVRSRV_HAP_WRITECOMBINE | PVRSRV_HAP_KERNEL_ONLY, + SGX_MMU_PAGE_SIZE, + psDevInfo->pui32ExtSystemCacheRegsPT, + psDevInfo->hExtSystemCacheRegsPTPageOSMemHandle); + } + } + else + { + if (psDevInfo->pui32ExtSystemCacheRegsPT != IMG_NULL) + { + OSUnMapPhysToLin(psDevInfo->pui32ExtSystemCacheRegsPT, + SGX_MMU_PAGE_SIZE, + PVRSRV_HAP_WRITECOMBINE|PVRSRV_HAP_KERNEL_ONLY, + psDevInfo->hExtSystemCacheRegsPTPageOSMemHandle); + + RA_Free(psLocalDevMemArena, psDevInfo->sExtSystemCacheRegsPTSysPAddr.uiAddr, IMG_FALSE); + } + } + + return PVRSRV_OK; +} +#endif + + +#if PAGE_TEST +static IMG_VOID PageTest(IMG_VOID* pMem, IMG_DEV_PHYADDR sDevPAddr) +{ + volatile IMG_UINT32 ui32WriteData; + volatile IMG_UINT32 ui32ReadData; + volatile IMG_UINT32 *pMem32 = (volatile IMG_UINT32 *)pMem; + IMG_INT n; + IMG_BOOL bOK=IMG_TRUE; + + ui32WriteData = 0xffffffff; + + for (n=0; n<1024; n++) + { + pMem32[n] = ui32WriteData; + ui32ReadData = pMem32[n]; + + if (ui32WriteData != ui32ReadData) + { + + PVR_DPF ((PVR_DBG_ERROR, "Error - memory page test failed at device phys address 0x%08X", sDevPAddr.uiAddr + (n<<2) )); + PVR_DBG_BREAK; + bOK = IMG_FALSE; + } + } + + ui32WriteData = 0; + + for (n=0; n<1024; n++) + { + pMem32[n] = ui32WriteData; + ui32ReadData = pMem32[n]; + + if (ui32WriteData != ui32ReadData) + { + + PVR_DPF ((PVR_DBG_ERROR, "Error - memory page test failed at device phys address 0x%08X", sDevPAddr.uiAddr + (n<<2) )); + PVR_DBG_BREAK; + bOK = IMG_FALSE; + } + } + + if (bOK) + { + PVR_DPF ((PVR_DBG_VERBOSE, "MMU Page 0x%08X is OK", sDevPAddr.uiAddr)); + } + else + { + PVR_DPF ((PVR_DBG_VERBOSE, "MMU Page 0x%08X *** FAILED ***", sDevPAddr.uiAddr)); + } +} +#endif + diff --git a/services4/srvkm/devices/sgx/mmu.h b/services4/srvkm/devices/sgx/mmu.h new file mode 100644 index 0000000..2319da8 --- /dev/null +++ b/services4/srvkm/devices/sgx/mmu.h @@ -0,0 +1,139 @@ +/********************************************************************** + * + * Copyright(c) 2008 Imagination Technologies Ltd. All rights reserved. + * + * This program is free software; you can redistribute it and/or modify it + * under the terms and conditions of the GNU General Public License, + * version 2, as published by the Free Software Foundation. + * + * This program is distributed in the hope it will be useful but, except + * as otherwise stated in writing, without any warranty; without even the + * implied warranty of merchantability or fitness for a particular purpose. + * See the GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License along with + * this program; if not, write to the Free Software Foundation, Inc., + * 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA. + * + * The full GNU General Public License is included in this distribution in + * the file called "COPYING". + * + * Contact Information: + * Imagination Technologies Ltd. + * Home Park Estate, Kings Langley, Herts, WD4 8LZ, UK + * + ******************************************************************************/ + +#ifndef _MMU_H_ +#define _MMU_H_ + +#include "sgxinfokm.h" + +PVRSRV_ERROR +MMU_Initialise (PVRSRV_DEVICE_NODE *psDeviceNode, MMU_CONTEXT **ppsMMUContext, IMG_DEV_PHYADDR *psPDDevPAddr); + +IMG_VOID +MMU_Finalise (MMU_CONTEXT *psMMUContext); + + +IMG_VOID +MMU_InsertHeap(MMU_CONTEXT *psMMUContext, MMU_HEAP *psMMUHeap); + +MMU_HEAP * +MMU_Create (MMU_CONTEXT *psMMUContext, + DEV_ARENA_DESCRIPTOR *psDevArena, + RA_ARENA **ppsVMArena); + +IMG_VOID +MMU_Delete (MMU_HEAP *pMMU); + +IMG_BOOL +MMU_Alloc (MMU_HEAP *pMMU, + IMG_SIZE_T uSize, + IMG_SIZE_T *pActualSize, + IMG_UINT32 uFlags, + IMG_UINT32 uDevVAddrAlignment, + IMG_DEV_VIRTADDR *pDevVAddr); + +IMG_VOID +MMU_Free (MMU_HEAP *pMMU, + IMG_DEV_VIRTADDR DevVAddr, + IMG_UINT32 ui32Size); + +IMG_VOID +MMU_Enable (MMU_HEAP *pMMU); + +IMG_VOID +MMU_Disable (MMU_HEAP *pMMU); + +IMG_VOID +MMU_MapPages (MMU_HEAP *pMMU, + IMG_DEV_VIRTADDR devVAddr, + IMG_SYS_PHYADDR SysPAddr, + IMG_SIZE_T uSize, + IMG_UINT32 ui32MemFlags, + IMG_HANDLE hUniqueTag); + +IMG_VOID +MMU_MapShadow (MMU_HEAP * pMMU, + IMG_DEV_VIRTADDR MapBaseDevVAddr, + IMG_SIZE_T uSize, + IMG_CPU_VIRTADDR CpuVAddr, + IMG_HANDLE hOSMemHandle, + IMG_DEV_VIRTADDR * pDevVAddr, + IMG_UINT32 ui32MemFlags, + IMG_HANDLE hUniqueTag); + +IMG_VOID +MMU_UnmapPages (MMU_HEAP *pMMU, + IMG_DEV_VIRTADDR dev_vaddr, + IMG_UINT32 ui32PageCount, + IMG_HANDLE hUniqueTag); + +IMG_VOID +MMU_MapScatter (MMU_HEAP *pMMU, + IMG_DEV_VIRTADDR DevVAddr, + IMG_SYS_PHYADDR *psSysAddr, + IMG_SIZE_T uSize, + IMG_UINT32 ui32MemFlags, + IMG_HANDLE hUniqueTag); + + +IMG_DEV_PHYADDR +MMU_GetPhysPageAddr(MMU_HEAP *pMMUHeap, IMG_DEV_VIRTADDR sDevVPageAddr); + + +IMG_DEV_PHYADDR +MMU_GetPDDevPAddr(MMU_CONTEXT *pMMUContext); + + +#ifdef SUPPORT_SGX_MMU_BYPASS +IMG_VOID +EnableHostAccess (MMU_CONTEXT *psMMUContext); + + +IMG_VOID +DisableHostAccess (MMU_CONTEXT *psMMUContext); +#endif + +IMG_VOID MMU_InvalidateDirectoryCache(PVRSRV_SGXDEV_INFO *psDevInfo); + +PVRSRV_ERROR MMU_BIFResetPDAlloc(PVRSRV_SGXDEV_INFO *psDevInfo); + +IMG_VOID MMU_BIFResetPDFree(PVRSRV_SGXDEV_INFO *psDevInfo); + +#if defined(FIX_HW_BRN_22997) && defined(FIX_HW_BRN_23030) && defined(SGX_FEATURE_HOST_PORT) +PVRSRV_ERROR WorkaroundBRN22997Alloc(PVRSRV_SGXDEV_INFO *psDevInfo); + +IMG_VOID WorkaroundBRN22997ReadHostPort(PVRSRV_SGXDEV_INFO *psDevInfo); + +IMG_VOID WorkaroundBRN22997Free(PVRSRV_SGXDEV_INFO *psDevInfo); +#endif + +#if defined(SUPPORT_EXTERNAL_SYSTEM_CACHE) +PVRSRV_ERROR MMU_MapExtSystemCacheRegs(PVRSRV_DEVICE_NODE *psDeviceNode); + +PVRSRV_ERROR MMU_UnmapExtSystemCacheRegs(PVRSRV_DEVICE_NODE *psDeviceNode); +#endif + +#endif diff --git a/services4/srvkm/devices/sgx/pb.c b/services4/srvkm/devices/sgx/pb.c new file mode 100644 index 0000000..7b91abd --- /dev/null +++ b/services4/srvkm/devices/sgx/pb.c @@ -0,0 +1,449 @@ +/********************************************************************** + * + * Copyright(c) 2008 Imagination Technologies Ltd. All rights reserved. + * + * This program is free software; you can redistribute it and/or modify it + * under the terms and conditions of the GNU General Public License, + * version 2, as published by the Free Software Foundation. + * + * This program is distributed in the hope it will be useful but, except + * as otherwise stated in writing, without any warranty; without even the + * implied warranty of merchantability or fitness for a particular purpose. + * See the GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License along with + * this program; if not, write to the Free Software Foundation, Inc., + * 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA. + * + * The full GNU General Public License is included in this distribution in + * the file called "COPYING". + * + * Contact Information: + * Imagination Technologies Ltd. + * Home Park Estate, Kings Langley, Herts, WD4 8LZ, UK + * + ******************************************************************************/ + +#include + +#include "services_headers.h" +#include "sgxapi_km.h" +#include "sgxinfo.h" +#include "sgxinfokm.h" +#include "pvr_bridge_km.h" +#include "pdump_km.h" +#include "sgxutils.h" + +#ifndef __linux__ +#pragma message("TODO: Review use of OS_PAGEABLE vs OS_NON_PAGEABLE") +#endif + +static PRESMAN_ITEM psResItemCreateSharedPB = IMG_NULL; +static PVRSRV_PER_PROCESS_DATA *psPerProcCreateSharedPB = IMG_NULL; + +static PVRSRV_ERROR SGXCleanupSharedPBDescCallback(IMG_PVOID pvParam, IMG_UINT32 ui32Param); +static PVRSRV_ERROR SGXCleanupSharedPBDescCreateLockCallback(IMG_PVOID pvParam, IMG_UINT32 ui32Param); + +IMG_EXPORT PVRSRV_ERROR +SGXFindSharedPBDescKM(PVRSRV_PER_PROCESS_DATA *psPerProc, + IMG_HANDLE hDevCookie, + IMG_BOOL bLockOnFailure, + IMG_UINT32 ui32TotalPBSize, + IMG_HANDLE *phSharedPBDesc, + PVRSRV_KERNEL_MEM_INFO **ppsSharedPBDescKernelMemInfo, + PVRSRV_KERNEL_MEM_INFO **ppsHWPBDescKernelMemInfo, + PVRSRV_KERNEL_MEM_INFO **ppsBlockKernelMemInfo, + PVRSRV_KERNEL_MEM_INFO ***pppsSharedPBDescSubKernelMemInfos, + IMG_UINT32 *ui32SharedPBDescSubKernelMemInfosCount) +{ + PVRSRV_STUB_PBDESC *psStubPBDesc; + PVRSRV_KERNEL_MEM_INFO **ppsSharedPBDescSubKernelMemInfos=IMG_NULL; + PVRSRV_SGXDEV_INFO *psSGXDevInfo; + PVRSRV_ERROR eError; + + psSGXDevInfo = ((PVRSRV_DEVICE_NODE *)hDevCookie)->pvDevice; + + psStubPBDesc = psSGXDevInfo->psStubPBDescListKM; + if (psStubPBDesc != IMG_NULL) + { + IMG_UINT32 i; + PRESMAN_ITEM psResItem; + + if(psStubPBDesc->ui32TotalPBSize != ui32TotalPBSize) + { + PVR_DPF((PVR_DBG_WARNING, + "SGXFindSharedPBDescKM: Shared PB requested with different size (0x%x) from existing shared PB (0x%x) - requested size ignored", + ui32TotalPBSize, psStubPBDesc->ui32TotalPBSize)); + } + + if(OSAllocMem(PVRSRV_OS_PAGEABLE_HEAP, + sizeof(PVRSRV_KERNEL_MEM_INFO *) + * psStubPBDesc->ui32SubKernelMemInfosCount, + (IMG_VOID **)&ppsSharedPBDescSubKernelMemInfos, + IMG_NULL) != PVRSRV_OK) + { + PVR_DPF((PVR_DBG_ERROR, "SGXFindSharedPBDescKM: OSAllocMem failed")); + + eError = PVRSRV_ERROR_OUT_OF_MEMORY; + goto ExitNotFound; + } + + psResItem = ResManRegisterRes(psPerProc->hResManContext, + RESMAN_TYPE_SHARED_PB_DESC, + psStubPBDesc, + 0, + &SGXCleanupSharedPBDescCallback); + + if (psResItem == IMG_NULL) + { + OSFreeMem(PVRSRV_OS_NON_PAGEABLE_HEAP, + sizeof(PVRSRV_KERNEL_MEM_INFO *) + * psStubPBDesc->ui32SubKernelMemInfosCount, + ppsSharedPBDescSubKernelMemInfos, + 0); + + PVR_DPF((PVR_DBG_ERROR, "SGXFindSharedPBDescKM: ResManRegisterRes failed")); + + eError = PVRSRV_ERROR_GENERIC; + goto ExitNotFound; + } + + *ppsSharedPBDescKernelMemInfo = psStubPBDesc->psSharedPBDescKernelMemInfo; + *ppsHWPBDescKernelMemInfo = psStubPBDesc->psHWPBDescKernelMemInfo; + *ppsBlockKernelMemInfo = psStubPBDesc->psBlockKernelMemInfo; + + *ui32SharedPBDescSubKernelMemInfosCount = + psStubPBDesc->ui32SubKernelMemInfosCount; + + *pppsSharedPBDescSubKernelMemInfos = ppsSharedPBDescSubKernelMemInfos; + + for(i=0; iui32SubKernelMemInfosCount; i++) + { + ppsSharedPBDescSubKernelMemInfos[i] = + psStubPBDesc->ppsSubKernelMemInfos[i]; + } + + psStubPBDesc->ui32RefCount++; + *phSharedPBDesc = (IMG_HANDLE)psResItem; + return PVRSRV_OK; + } + + eError = PVRSRV_OK; + if (bLockOnFailure) + { + if (psResItemCreateSharedPB == IMG_NULL) + { + psResItemCreateSharedPB = ResManRegisterRes(psPerProc->hResManContext, + RESMAN_TYPE_SHARED_PB_DESC_CREATE_LOCK, + psPerProc, + 0, + &SGXCleanupSharedPBDescCreateLockCallback); + + if (psResItemCreateSharedPB == IMG_NULL) + { + PVR_DPF((PVR_DBG_ERROR, "SGXFindSharedPBDescKM: ResManRegisterRes failed")); + + eError = PVRSRV_ERROR_GENERIC; + goto ExitNotFound; + } + PVR_ASSERT(psPerProcCreateSharedPB == IMG_NULL); + psPerProcCreateSharedPB = psPerProc; + } + else + { + eError = PVRSRV_ERROR_PROCESSING_BLOCKED; + } + } +ExitNotFound: + *phSharedPBDesc = IMG_NULL; + + return eError; +} + + +static PVRSRV_ERROR +SGXCleanupSharedPBDescKM(PVRSRV_STUB_PBDESC *psStubPBDescIn) +{ + PVRSRV_STUB_PBDESC **ppsStubPBDesc; + IMG_UINT32 i; + PVRSRV_DEVICE_NODE *psDeviceNode; + PVRSRV_SGXDEV_INFO *psSGXDevInfo; + + psDeviceNode = (PVRSRV_DEVICE_NODE*)psStubPBDescIn->hDevCookie; + psSGXDevInfo = (PVRSRV_SGXDEV_INFO *)psDeviceNode->pvDevice; + + + for(ppsStubPBDesc = (PVRSRV_STUB_PBDESC **)&psSGXDevInfo->psStubPBDescListKM; + *ppsStubPBDesc != IMG_NULL; + ppsStubPBDesc = &(*ppsStubPBDesc)->psNext) + { + PVRSRV_STUB_PBDESC *psStubPBDesc = *ppsStubPBDesc; + + if(psStubPBDesc == psStubPBDescIn) + { + psStubPBDesc->ui32RefCount--; + PVR_ASSERT((IMG_INT32)psStubPBDesc->ui32RefCount >= 0); + + if(psStubPBDesc->ui32RefCount == 0) + { + *ppsStubPBDesc = psStubPBDesc->psNext; + + for(i=0 ; iui32SubKernelMemInfosCount; i++) + { + + PVRSRVFreeDeviceMemKM(psStubPBDesc->hDevCookie, + psStubPBDesc->ppsSubKernelMemInfos[i]); + } + + OSFreeMem(PVRSRV_OS_NON_PAGEABLE_HEAP, + sizeof(PVRSRV_KERNEL_MEM_INFO *) + * psStubPBDesc->ui32SubKernelMemInfosCount, + psStubPBDesc->ppsSubKernelMemInfos, + 0); + + PVRSRVFreeSharedSysMemoryKM(psStubPBDesc->psBlockKernelMemInfo); + + PVRSRVFreeDeviceMemKM(psStubPBDesc->hDevCookie, psStubPBDesc->psHWPBDescKernelMemInfo); + + PVRSRVFreeSharedSysMemoryKM(psStubPBDesc->psSharedPBDescKernelMemInfo); + + OSFreeMem(PVRSRV_OS_NON_PAGEABLE_HEAP, + sizeof(PVRSRV_STUB_PBDESC), + psStubPBDesc, + 0); + + + SGXCleanupRequest(psDeviceNode, + IMG_NULL, + PVRSRV_USSE_EDM_RESMAN_CLEANUP_SHAREDPBDESC); + } + return PVRSRV_OK; + } + } + + return PVRSRV_ERROR_INVALID_PARAMS; +} + +static PVRSRV_ERROR SGXCleanupSharedPBDescCallback(IMG_PVOID pvParam, IMG_UINT32 ui32Param) +{ + PVRSRV_STUB_PBDESC *psStubPBDesc = (PVRSRV_STUB_PBDESC *)pvParam; + + PVR_UNREFERENCED_PARAMETER(ui32Param); + + return SGXCleanupSharedPBDescKM(psStubPBDesc); +} + +static PVRSRV_ERROR SGXCleanupSharedPBDescCreateLockCallback(IMG_PVOID pvParam, IMG_UINT32 ui32Param) +{ +#ifdef DEBUG + PVRSRV_PER_PROCESS_DATA *psPerProc = (PVRSRV_PER_PROCESS_DATA *)pvParam; + PVR_ASSERT(psPerProc == psPerProcCreateSharedPB); +#else + PVR_UNREFERENCED_PARAMETER(pvParam); +#endif + + PVR_UNREFERENCED_PARAMETER(ui32Param); + + psPerProcCreateSharedPB = IMG_NULL; + psResItemCreateSharedPB = IMG_NULL; + + return PVRSRV_OK; +} + + +IMG_EXPORT PVRSRV_ERROR +SGXUnrefSharedPBDescKM(IMG_HANDLE hSharedPBDesc) +{ + PVR_ASSERT(hSharedPBDesc != IMG_NULL); + + return ResManFreeResByPtr(hSharedPBDesc); +} + + +IMG_EXPORT PVRSRV_ERROR +SGXAddSharedPBDescKM(PVRSRV_PER_PROCESS_DATA *psPerProc, + IMG_HANDLE hDevCookie, + PVRSRV_KERNEL_MEM_INFO *psSharedPBDescKernelMemInfo, + PVRSRV_KERNEL_MEM_INFO *psHWPBDescKernelMemInfo, + PVRSRV_KERNEL_MEM_INFO *psBlockKernelMemInfo, + IMG_UINT32 ui32TotalPBSize, + IMG_HANDLE *phSharedPBDesc, + PVRSRV_KERNEL_MEM_INFO **ppsSharedPBDescSubKernelMemInfos, + IMG_UINT32 ui32SharedPBDescSubKernelMemInfosCount) +{ + PVRSRV_STUB_PBDESC *psStubPBDesc=IMG_NULL; + PVRSRV_ERROR eRet = PVRSRV_ERROR_GENERIC; + IMG_UINT32 i; + PVRSRV_SGXDEV_INFO *psSGXDevInfo; + PRESMAN_ITEM psResItem; + + + if (psPerProcCreateSharedPB != psPerProc) + { + goto NoAdd; + } + else + { + PVR_ASSERT(psResItemCreateSharedPB != IMG_NULL); + + ResManFreeResByPtr(psResItemCreateSharedPB); + + PVR_ASSERT(psResItemCreateSharedPB == IMG_NULL); + PVR_ASSERT(psPerProcCreateSharedPB == IMG_NULL); + } + + psSGXDevInfo = (PVRSRV_SGXDEV_INFO *)((PVRSRV_DEVICE_NODE *)hDevCookie)->pvDevice; + + psStubPBDesc = psSGXDevInfo->psStubPBDescListKM; + if (psStubPBDesc != IMG_NULL) + { + if(psStubPBDesc->ui32TotalPBSize != ui32TotalPBSize) + { + PVR_DPF((PVR_DBG_WARNING, + "SGXAddSharedPBDescKM: Shared PB requested with different size (0x%x) from existing shared PB (0x%x) - requested size ignored", + ui32TotalPBSize, psStubPBDesc->ui32TotalPBSize)); + + } + + + psResItem = ResManRegisterRes(psPerProc->hResManContext, + RESMAN_TYPE_SHARED_PB_DESC, + psStubPBDesc, + 0, + &SGXCleanupSharedPBDescCallback); + if (psResItem == IMG_NULL) + { + PVR_DPF((PVR_DBG_ERROR, + "SGXAddSharedPBDescKM: " + "Failed to register existing shared " + "PBDesc with the resource manager")); + goto NoAddKeepPB; + } + + + psStubPBDesc->ui32RefCount++; + + *phSharedPBDesc = (IMG_HANDLE)psResItem; + eRet = PVRSRV_OK; + goto NoAddKeepPB; + } + + if(OSAllocMem(PVRSRV_OS_NON_PAGEABLE_HEAP, + sizeof(PVRSRV_STUB_PBDESC), + (IMG_VOID **)&psStubPBDesc, + 0) != PVRSRV_OK) + { + PVR_DPF((PVR_DBG_ERROR, "SGXAddSharedPBDescKM: Failed to alloc " + "StubPBDesc")); + eRet = PVRSRV_ERROR_OUT_OF_MEMORY; + goto NoAdd; + } + + + psStubPBDesc->ppsSubKernelMemInfos = IMG_NULL; + + if(OSAllocMem(PVRSRV_OS_NON_PAGEABLE_HEAP, + sizeof(PVRSRV_KERNEL_MEM_INFO *) + * ui32SharedPBDescSubKernelMemInfosCount, + (IMG_VOID **)&psStubPBDesc->ppsSubKernelMemInfos, + 0) != PVRSRV_OK) + { + PVR_DPF((PVR_DBG_ERROR, "SGXAddSharedPBDescKM: " + "Failed to alloc " + "StubPBDesc->ppsSubKernelMemInfos")); + eRet = PVRSRV_ERROR_OUT_OF_MEMORY; + goto NoAdd; + } + + if(PVRSRVDissociateMemFromResmanKM(psSharedPBDescKernelMemInfo) + != PVRSRV_OK) + { + goto NoAdd; + } + + if(PVRSRVDissociateMemFromResmanKM(psHWPBDescKernelMemInfo) + != PVRSRV_OK) + { + goto NoAdd; + } + + if(PVRSRVDissociateMemFromResmanKM(psBlockKernelMemInfo) + != PVRSRV_OK) + { + goto NoAdd; + } + + psStubPBDesc->ui32RefCount = 1; + psStubPBDesc->ui32TotalPBSize = ui32TotalPBSize; + psStubPBDesc->psSharedPBDescKernelMemInfo = psSharedPBDescKernelMemInfo; + psStubPBDesc->psHWPBDescKernelMemInfo = psHWPBDescKernelMemInfo; + psStubPBDesc->psBlockKernelMemInfo = psBlockKernelMemInfo; + + psStubPBDesc->ui32SubKernelMemInfosCount = + ui32SharedPBDescSubKernelMemInfosCount; + for(i=0; ippsSubKernelMemInfos[i] = ppsSharedPBDescSubKernelMemInfos[i]; + if(PVRSRVDissociateMemFromResmanKM(ppsSharedPBDescSubKernelMemInfos[i]) + != PVRSRV_OK) + { + PVR_DPF((PVR_DBG_ERROR, "SGXAddSharedPBDescKM: " + "Failed to dissociate shared PBDesc " + "from process")); + goto NoAdd; + } + } + + psResItem = ResManRegisterRes(psPerProc->hResManContext, + RESMAN_TYPE_SHARED_PB_DESC, + psStubPBDesc, + 0, + &SGXCleanupSharedPBDescCallback); + if (psResItem == IMG_NULL) + { + PVR_DPF((PVR_DBG_ERROR, "SGXAddSharedPBDescKM: " + "Failed to register shared PBDesc " + " with the resource manager")); + goto NoAdd; + } + psStubPBDesc->hDevCookie = hDevCookie; + + + psStubPBDesc->psNext = psSGXDevInfo->psStubPBDescListKM; + psSGXDevInfo->psStubPBDescListKM = psStubPBDesc; + + *phSharedPBDesc = (IMG_HANDLE)psResItem; + + return PVRSRV_OK; + +NoAdd: + if(psStubPBDesc) + { + if(psStubPBDesc->ppsSubKernelMemInfos) + { + OSFreeMem(PVRSRV_OS_NON_PAGEABLE_HEAP, + sizeof(PVRSRV_KERNEL_MEM_INFO *) + * ui32SharedPBDescSubKernelMemInfosCount, + psStubPBDesc->ppsSubKernelMemInfos, + 0); + } + OSFreeMem(PVRSRV_OS_NON_PAGEABLE_HEAP, + sizeof(PVRSRV_STUB_PBDESC), + psStubPBDesc, + 0); + } + +NoAddKeepPB: + for (i = 0; i < ui32SharedPBDescSubKernelMemInfosCount; i++) + { + PVRSRVFreeDeviceMemKM(hDevCookie, ppsSharedPBDescSubKernelMemInfos[i]); + } + + PVRSRVFreeSharedSysMemoryKM(psSharedPBDescKernelMemInfo); + PVRSRVFreeDeviceMemKM(hDevCookie, psHWPBDescKernelMemInfo); + + PVRSRVFreeSharedSysMemoryKM(psBlockKernelMemInfo); + + return eRet; +} + diff --git a/services4/srvkm/devices/sgx/sgx_bridge_km.h b/services4/srvkm/devices/sgx/sgx_bridge_km.h new file mode 100644 index 0000000..c2c9647 --- /dev/null +++ b/services4/srvkm/devices/sgx/sgx_bridge_km.h @@ -0,0 +1,144 @@ +/********************************************************************** + * + * Copyright(c) 2008 Imagination Technologies Ltd. All rights reserved. + * + * This program is free software; you can redistribute it and/or modify it + * under the terms and conditions of the GNU General Public License, + * version 2, as published by the Free Software Foundation. + * + * This program is distributed in the hope it will be useful but, except + * as otherwise stated in writing, without any warranty; without even the + * implied warranty of merchantability or fitness for a particular purpose. + * See the GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License along with + * this program; if not, write to the Free Software Foundation, Inc., + * 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA. + * + * The full GNU General Public License is included in this distribution in + * the file called "COPYING". + * + * Contact Information: + * Imagination Technologies Ltd. + * Home Park Estate, Kings Langley, Herts, WD4 8LZ, UK + * + ******************************************************************************/ + +#if !defined(__SGX_BRIDGE_KM_H__) +#define __SGX_BRIDGE_KM_H__ + +#include "sgxapi_km.h" +#include "sgxinfo.h" +#include "sgxinfokm.h" +#include "sgx_bridge.h" +#include "pvr_bridge.h" +#include "perproc.h" + +#if defined (__cplusplus) +extern "C" { +#endif + +IMG_IMPORT +PVRSRV_ERROR SGXSubmitTransferKM(IMG_HANDLE hDevHandle, PVRSRV_TRANSFER_SGX_KICK *psKick); + +#if defined(SGX_FEATURE_2D_HARDWARE) +IMG_IMPORT +PVRSRV_ERROR SGXSubmit2DKM(IMG_HANDLE hDevHandle, PVRSRV_2D_SGX_KICK *psKick); +#endif + +IMG_IMPORT +PVRSRV_ERROR SGXDoKickKM(IMG_HANDLE hDevHandle, + SGX_CCB_KICK *psCCBKick); + +IMG_IMPORT +PVRSRV_ERROR SGXGetPhysPageAddrKM(IMG_HANDLE hDevMemHeap, + IMG_DEV_VIRTADDR sDevVAddr, + IMG_DEV_PHYADDR *pDevPAddr, + IMG_CPU_PHYADDR *pCpuPAddr); + +IMG_IMPORT +PVRSRV_ERROR IMG_CALLCONV SGXGetMMUPDAddrKM(IMG_HANDLE hDevCookie, + IMG_HANDLE hDevMemContext, + IMG_DEV_PHYADDR *psPDDevPAddr); + +IMG_IMPORT +PVRSRV_ERROR SGXGetClientInfoKM(IMG_HANDLE hDevCookie, + SGX_CLIENT_INFO* psClientInfo); + +IMG_IMPORT +PVRSRV_ERROR SGXGetMiscInfoKM(PVRSRV_SGXDEV_INFO *psDevInfo, + SGX_MISC_INFO *psMiscInfo, + PVRSRV_DEVICE_NODE *psDeviceNode); + +#if defined(SUPPORT_SGX_HWPERF) +IMG_IMPORT +PVRSRV_ERROR SGXReadDiffCountersKM(IMG_HANDLE hDevHandle, + IMG_UINT32 ui32Reg, + IMG_UINT32 *pui32Old, + IMG_BOOL bNew, + IMG_UINT32 ui32New, + IMG_UINT32 ui32NewReset, + IMG_UINT32 ui32CountersReg, + IMG_UINT32 *pui32Time, + IMG_BOOL *pbActive, + PVRSRV_SGXDEV_DIFF_INFO *psDiffs); +IMG_IMPORT +PVRSRV_ERROR SGXReadHWPerfCBKM(IMG_HANDLE hDevHandle, + IMG_UINT32 ui32ArraySize, + PVRSRV_SGX_HWPERF_CB_ENTRY *psHWPerfCBData, + IMG_UINT32 *pui32DataCount, + IMG_UINT32 *pui32ClockSpeed, + IMG_UINT32 *pui32HostTimeStamp); +#endif + +IMG_IMPORT +PVRSRV_ERROR SGX2DQueryBlitsCompleteKM(PVRSRV_SGXDEV_INFO *psDevInfo, + PVRSRV_KERNEL_SYNC_INFO *psSyncInfo, + IMG_BOOL bWaitForComplete); + +IMG_IMPORT +PVRSRV_ERROR SGXGetInfoForSrvinitKM(IMG_HANDLE hDevHandle, + SGX_BRIDGE_INFO_FOR_SRVINIT *psInitInfo); + +IMG_IMPORT +PVRSRV_ERROR DevInitSGXPart2KM(PVRSRV_PER_PROCESS_DATA *psPerProc, + IMG_HANDLE hDevHandle, + SGX_BRIDGE_INIT_INFO *psInitInfo); + +IMG_IMPORT PVRSRV_ERROR +SGXFindSharedPBDescKM(PVRSRV_PER_PROCESS_DATA *psPerProc, + IMG_HANDLE hDevCookie, + IMG_BOOL bLockOnFailure, + IMG_UINT32 ui32TotalPBSize, + IMG_HANDLE *phSharedPBDesc, + PVRSRV_KERNEL_MEM_INFO **ppsSharedPBDescKernelMemInfo, + PVRSRV_KERNEL_MEM_INFO **ppsHWPBDescKernelMemInfo, + PVRSRV_KERNEL_MEM_INFO **ppsBlockKernelMemInfo, + PVRSRV_KERNEL_MEM_INFO ***pppsSharedPBDescSubKernelMemInfos, + IMG_UINT32 *ui32SharedPBDescSubKernelMemInfosCount); + +IMG_IMPORT PVRSRV_ERROR +SGXUnrefSharedPBDescKM(IMG_HANDLE hSharedPBDesc); + +IMG_IMPORT PVRSRV_ERROR +SGXAddSharedPBDescKM(PVRSRV_PER_PROCESS_DATA *psPerProc, + IMG_HANDLE hDevCookie, + PVRSRV_KERNEL_MEM_INFO *psSharedPBDescKernelMemInfo, + PVRSRV_KERNEL_MEM_INFO *psHWPBDescKernelMemInfo, + PVRSRV_KERNEL_MEM_INFO *psBlockKernelMemInfo, + IMG_UINT32 ui32TotalPBSize, + IMG_HANDLE *phSharedPBDesc, + PVRSRV_KERNEL_MEM_INFO **psSharedPBDescSubKernelMemInfos, + IMG_UINT32 ui32SharedPBDescSubKernelMemInfosCount); + + +IMG_IMPORT PVRSRV_ERROR +SGXGetInternalDevInfoKM(IMG_HANDLE hDevCookie, + SGX_INTERNAL_DEVINFO *psSGXInternalDevInfo); + +#if defined (__cplusplus) +} +#endif + +#endif + diff --git a/services4/srvkm/devices/sgx/sgxconfig.h b/services4/srvkm/devices/sgx/sgxconfig.h new file mode 100644 index 0000000..824192d --- /dev/null +++ b/services4/srvkm/devices/sgx/sgxconfig.h @@ -0,0 +1,135 @@ +/********************************************************************** + * + * Copyright(c) 2008 Imagination Technologies Ltd. All rights reserved. + * + * This program is free software; you can redistribute it and/or modify it + * under the terms and conditions of the GNU General Public License, + * version 2, as published by the Free Software Foundation. + * + * This program is distributed in the hope it will be useful but, except + * as otherwise stated in writing, without any warranty; without even the + * implied warranty of merchantability or fitness for a particular purpose. + * See the GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License along with + * this program; if not, write to the Free Software Foundation, Inc., + * 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA. + * + * The full GNU General Public License is included in this distribution in + * the file called "COPYING". + * + * Contact Information: + * Imagination Technologies Ltd. + * Home Park Estate, Kings Langley, Herts, WD4 8LZ, UK + * + ******************************************************************************/ + +#ifndef __SGXCONFIG_H__ +#define __SGXCONFIG_H__ + +#define DEV_DEVICE_TYPE PVRSRV_DEVICE_TYPE_SGX +#define DEV_DEVICE_CLASS PVRSRV_DEVICE_CLASS_3D + +#define DEV_MAJOR_VERSION 1 +#define DEV_MINOR_VERSION 0 + +#if SGX_FEATURE_ADDRESS_SPACE_SIZE == 32 + #if defined(SGX_FEATURE_2D_HARDWARE) + #define SGX_2D_HEAP_BASE 0x00100000 + #define SGX_2D_HEAP_SIZE (0x08000000-0x00100000-0x00001000) + #endif + + #if defined(SUPPORT_SGX_GENERAL_MAPPING_HEAP) + #define SGX_GENERAL_MAPPING_HEAP_BASE 0x08000000 + #define SGX_GENERAL_MAPPING_HEAP_SIZE (0x08000000-0x00001000) + #endif + + #define SGX_GENERAL_HEAP_BASE 0x10000000 + #define SGX_GENERAL_HEAP_SIZE (0xC8000000-0x00001000) + + #define SGX_3DPARAMETERS_HEAP_BASE 0xD8000000 + #define SGX_3DPARAMETERS_HEAP_SIZE (0x10000000-0x00001000) + + #define SGX_TADATA_HEAP_BASE 0xE8000000 + #define SGX_TADATA_HEAP_SIZE (0x0D000000-0x00001000) + + #define SGX_SYNCINFO_HEAP_BASE 0xF5000000 + #define SGX_SYNCINFO_HEAP_SIZE (0x01000000-0x00001000) + + #define SGX_PDSPIXEL_CODEDATA_HEAP_BASE 0xF6000000 + #define SGX_PDSPIXEL_CODEDATA_HEAP_SIZE (0x02000000-0x00001000) + + #define SGX_PDSVERTEX_CODEDATA_HEAP_BASE 0xF8000000 + #define SGX_PDSVERTEX_CODEDATA_HEAP_SIZE (0x01E00000-0x00001000) + + #define SGX_KERNEL_CODE_HEAP_BASE 0xF9E00000 + #define SGX_KERNEL_CODE_HEAP_SIZE (0x00080000-0x00001000) + + + #define SGX_RESERVED_CODE_HEAP_BASE 0xF9F00000 + #define SGX_RESERVED_CODE_HEAP_SIZE (0x00080000-0x00001000) + + #define SGX_KERNEL_DATA_HEAP_BASE 0xFA000000 + #define SGX_KERNEL_DATA_HEAP_SIZE (0x05000000-0x00001000) + + #define SGX_PIXELSHADER_HEAP_BASE 0xFF000000 + #define SGX_PIXELSHADER_HEAP_SIZE (0x00500000-0x00001000) + + #define SGX_VERTEXSHADER_HEAP_BASE 0xFF500000 + #define SGX_VERTEXSHADER_HEAP_SIZE (0x00200000-0x00001000) + + + #define SGX_CORE_IDENTIFIED +#endif + +#if SGX_FEATURE_ADDRESS_SPACE_SIZE == 28 + #if defined(SUPPORT_SGX_GENERAL_MAPPING_HEAP) + #define SGX_GENERAL_MAPPING_HEAP_BASE 0x00001000 + #define SGX_GENERAL_MAPPING_HEAP_SIZE (0x01800000-0x00001000-0x00001000) + #endif + + #define SGX_GENERAL_HEAP_BASE 0x01800000 + #define SGX_GENERAL_HEAP_SIZE (0x06C00000-0x00001000) + + #define SGX_3DPARAMETERS_HEAP_BASE 0x08400000 + #define SGX_3DPARAMETERS_HEAP_SIZE (0x04000000-0x00001000) + + #define SGX_TADATA_HEAP_BASE 0x0C400000 + #define SGX_TADATA_HEAP_SIZE (0x01000000-0x00001000) + + #define SGX_SYNCINFO_HEAP_BASE 0x0D400000 + #define SGX_SYNCINFO_HEAP_SIZE (0x00400000-0x00001000) + + #define SGX_PDSPIXEL_CODEDATA_HEAP_BASE 0x0D800000 + #define SGX_PDSPIXEL_CODEDATA_HEAP_SIZE (0x00800000-0x00001000) + + #define SGX_PDSVERTEX_CODEDATA_HEAP_BASE 0x0E000000 + #define SGX_PDSVERTEX_CODEDATA_HEAP_SIZE (0x00800000-0x00001000) + + + #define SGX_RESERVED_CODE_HEAP_BASE 0x0E800000 + #define SGX_RESERVED_CODE_HEAP_SIZE (0x00080000-0x00001000) + + #define SGX_KERNEL_CODE_HEAP_BASE 0x0EC00000 + #define SGX_KERNEL_CODE_HEAP_SIZE (0x00080000-0x00001000) + + #define SGX_KERNEL_DATA_HEAP_BASE 0x0F000000 + #define SGX_KERNEL_DATA_HEAP_SIZE (0x00400000-0x00001000) + + #define SGX_PIXELSHADER_HEAP_BASE 0x0F400000 + #define SGX_PIXELSHADER_HEAP_SIZE (0x00500000-0x00001000) + + #define SGX_VERTEXSHADER_HEAP_BASE 0x0FC00000 + #define SGX_VERTEXSHADER_HEAP_SIZE (0x00200000-0x00001000) + + + #define SGX_CORE_IDENTIFIED + +#endif + +#if !defined(SGX_CORE_IDENTIFIED) + #error "sgxconfig.h: ERROR: unspecified SGX Core version" +#endif + +#endif + diff --git a/services4/srvkm/devices/sgx/sgxinfokm.h b/services4/srvkm/devices/sgx/sgxinfokm.h new file mode 100644 index 0000000..fac1aee --- /dev/null +++ b/services4/srvkm/devices/sgx/sgxinfokm.h @@ -0,0 +1,360 @@ +/********************************************************************** + * + * Copyright(c) 2008 Imagination Technologies Ltd. All rights reserved. + * + * This program is free software; you can redistribute it and/or modify it + * under the terms and conditions of the GNU General Public License, + * version 2, as published by the Free Software Foundation. + * + * This program is distributed in the hope it will be useful but, except + * as otherwise stated in writing, without any warranty; without even the + * implied warranty of merchantability or fitness for a particular purpose. + * See the GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License along with + * this program; if not, write to the Free Software Foundation, Inc., + * 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA. + * + * The full GNU General Public License is included in this distribution in + * the file called "COPYING". + * + * Contact Information: + * Imagination Technologies Ltd. + * Home Park Estate, Kings Langley, Herts, WD4 8LZ, UK + * + ******************************************************************************/ + +#ifndef __SGXINFOKM_H__ +#define __SGXINFOKM_H__ + +#include "sgxdefs.h" +#include "device.h" +#include "sysconfig.h" +#include "sgxscript.h" +#include "sgxinfo.h" + +#if defined (__cplusplus) +extern "C" { +#endif + +#define SGX_HOSTPORT_PRESENT 0x00000001UL + +#define PVRSRV_USSE_EDM_POWMAN_IDLE_COMPLETE (1UL << 2) +#define PVRSRV_USSE_EDM_POWMAN_POWEROFF_COMPLETE (1UL << 3) +#define PVRSRV_USSE_EDM_POWMAN_POWEROFF_RESTART_IMMEDIATE (1UL << 4) +#define PVRSRV_USSE_EDM_POWMAN_NO_WORK (1UL << 5) + +#define PVRSRV_USSE_EDM_INTERRUPT_HWR (1UL << 0) +#define PVRSRV_USSE_EDM_INTERRUPT_ACTIVE_POWER (1UL << 1) + +#define PVRSRV_USSE_EDM_RESMAN_CLEANUP_RT_REQUEST 0x01UL +#define PVRSRV_USSE_EDM_RESMAN_CLEANUP_RC_REQUEST 0x02UL +#define PVRSRV_USSE_EDM_RESMAN_CLEANUP_TC_REQUEST 0x04UL +#define PVRSRV_USSE_EDM_RESMAN_CLEANUP_2DC_REQUEST 0x08UL +#define PVRSRV_USSE_EDM_RESMAN_CLEANUP_SHAREDPBDESC 0x10UL +#define PVRSRV_USSE_EDM_RESMAN_CLEANUP_INVALPD 0x20UL +#define PVRSRV_USSE_EDM_RESMAN_CLEANUP_INVALPT 0x40UL +#define PVRSRV_USSE_EDM_RESMAN_CLEANUP_COMPLETE 0x80UL + +#define PVRSRV_USSE_MISCINFO_READY 0x1UL + +typedef struct _PVRSRV_SGX_CCB_INFO_ *PPVRSRV_SGX_CCB_INFO; + +typedef struct _PVRSRV_SGXDEV_INFO_ +{ + PVRSRV_DEVICE_TYPE eDeviceType; + PVRSRV_DEVICE_CLASS eDeviceClass; + + IMG_UINT8 ui8VersionMajor; + IMG_UINT8 ui8VersionMinor; + IMG_UINT32 ui32CoreConfig; + IMG_UINT32 ui32CoreFlags; + + + IMG_PVOID pvRegsBaseKM; + +#if defined(SGX_FEATURE_HOST_PORT) + + IMG_PVOID pvHostPortBaseKM; + + IMG_UINT32 ui32HPSize; + + IMG_SYS_PHYADDR sHPSysPAddr; +#endif + + + IMG_HANDLE hRegMapping; + + + IMG_SYS_PHYADDR sRegsPhysBase; + + IMG_UINT32 ui32RegSize; + +#if defined(SUPPORT_EXTERNAL_SYSTEM_CACHE) + + IMG_UINT32 ui32ExtSysCacheRegsSize; + + IMG_DEV_PHYADDR sExtSysCacheRegsDevPBase; + + IMG_UINT32 *pui32ExtSystemCacheRegsPT; + + IMG_HANDLE hExtSystemCacheRegsPTPageOSMemHandle; + + IMG_SYS_PHYADDR sExtSystemCacheRegsPTSysPAddr; +#endif + + + IMG_UINT32 ui32CoreClockSpeed; + IMG_UINT32 ui32uKernelTimerClock; + + + IMG_VOID *psStubPBDescListKM; + + + + IMG_DEV_PHYADDR sKernelPDDevPAddr; + + IMG_VOID *pvDeviceMemoryHeap; + PPVRSRV_KERNEL_MEM_INFO psKernelCCBMemInfo; + PVRSRV_SGX_KERNEL_CCB *psKernelCCB; + PPVRSRV_SGX_CCB_INFO psKernelCCBInfo; + PPVRSRV_KERNEL_MEM_INFO psKernelCCBCtlMemInfo; + PVRSRV_SGX_CCB_CTL *psKernelCCBCtl; + PPVRSRV_KERNEL_MEM_INFO psKernelCCBEventKickerMemInfo; + IMG_UINT32 *pui32KernelCCBEventKicker; + PVRSRV_KERNEL_MEM_INFO *psKernelSGXMiscMemInfo; + IMG_UINT32 ui32HostKickAddress; + IMG_UINT32 ui32GetMiscInfoAddress; +#if defined(SGX_SUPPORT_HWPROFILING) + PPVRSRV_KERNEL_MEM_INFO psKernelHWProfilingMemInfo; +#endif + IMG_UINT32 ui32KickTACounter; + IMG_UINT32 ui32KickTARenderCounter; +#if defined(SUPPORT_SGX_HWPERF) + PPVRSRV_KERNEL_MEM_INFO psKernelHWPerfCBMemInfo; + PVRSRV_SGXDEV_DIFF_INFO sDiffInfo; + IMG_UINT32 ui32HWGroupRequested; + IMG_UINT32 ui32HWReset; +#endif +#ifdef PVRSRV_USSE_EDM_STATUS_DEBUG + PPVRSRV_KERNEL_MEM_INFO psKernelEDMStatusBufferMemInfo; +#endif +#if defined(SGX_FEATURE_OVERLAPPED_SPM) + PPVRSRV_KERNEL_MEM_INFO psKernelTmpRgnHeaderMemInfo; +#endif +#if defined(SGX_FEATURE_SPM_MODE_0) + PPVRSRV_KERNEL_MEM_INFO psKernelTmpDPMStateMemInfo; +#endif + + + IMG_UINT32 ui32ClientRefCount; + + + IMG_UINT32 ui32CacheControl; + + + + + IMG_VOID *pvMMUContextList; + + + IMG_BOOL bForcePTOff; + + IMG_UINT32 ui32EDMTaskReg0; + IMG_UINT32 ui32EDMTaskReg1; + + IMG_UINT32 ui32ClkGateStatusReg; + IMG_UINT32 ui32ClkGateStatusMask; +#if defined(SGX_FEATURE_MP) + IMG_UINT32 ui32MasterClkGateStatusReg; + IMG_UINT32 ui32MasterClkGateStatusMask; +#endif + SGX_INIT_SCRIPTS sScripts; + + + IMG_HANDLE hBIFResetPDOSMemHandle; + IMG_DEV_PHYADDR sBIFResetPDDevPAddr; + IMG_DEV_PHYADDR sBIFResetPTDevPAddr; + IMG_DEV_PHYADDR sBIFResetPageDevPAddr; + IMG_UINT32 *pui32BIFResetPD; + IMG_UINT32 *pui32BIFResetPT; + +#if defined(FIX_HW_BRN_22997) && defined(FIX_HW_BRN_23030) && defined(SGX_FEATURE_HOST_PORT) + + IMG_HANDLE hBRN22997PTPageOSMemHandle; + IMG_HANDLE hBRN22997PDPageOSMemHandle; + IMG_DEV_PHYADDR sBRN22997PTDevPAddr; + IMG_DEV_PHYADDR sBRN22997PDDevPAddr; + IMG_UINT32 *pui32BRN22997PT; + IMG_UINT32 *pui32BRN22997PD; + IMG_SYS_PHYADDR sBRN22997SysPAddr; +#endif + +#if defined(SUPPORT_HW_RECOVERY) + + IMG_HANDLE hTimer; + + IMG_UINT32 ui32TimeStamp; +#endif + + + IMG_UINT32 ui32NumResets; + + + PVRSRV_KERNEL_MEM_INFO *psKernelSGXHostCtlMemInfo; + SGXMKIF_HOST_CTL *psSGXHostCtl; + + + PVRSRV_KERNEL_MEM_INFO *psKernelSGXTA3DCtlMemInfo; + + IMG_UINT32 ui32Flags; + + #if defined(PDUMP) + PVRSRV_SGX_PDUMP_CONTEXT sPDContext; + #endif + +#if defined(SUPPORT_SGX_MMU_DUMMY_PAGE) + + IMG_VOID *pvDummyPTPageCpuVAddr; + IMG_DEV_PHYADDR sDummyPTDevPAddr; + IMG_HANDLE hDummyPTPageOSMemHandle; + IMG_VOID *pvDummyDataPageCpuVAddr; + IMG_DEV_PHYADDR sDummyDataDevPAddr; + IMG_HANDLE hDummyDataPageOSMemHandle; +#endif + + IMG_UINT32 asSGXDevData[SGX_MAX_DEV_DATA]; + +} PVRSRV_SGXDEV_INFO; + + +typedef struct _SGX_TIMING_INFORMATION_ +{ + IMG_UINT32 ui32CoreClockSpeed; + IMG_UINT32 ui32HWRecoveryFreq; + IMG_UINT32 ui32ActivePowManLatencyms; + IMG_UINT32 ui32uKernelFreq; +} SGX_TIMING_INFORMATION; + +typedef struct _SGX_DEVICE_MAP_ +{ + IMG_UINT32 ui32Flags; + + + IMG_SYS_PHYADDR sRegsSysPBase; + IMG_CPU_PHYADDR sRegsCpuPBase; + IMG_CPU_VIRTADDR pvRegsCpuVBase; + IMG_UINT32 ui32RegsSize; + +#if defined(SGX_FEATURE_HOST_PORT) + IMG_SYS_PHYADDR sHPSysPBase; + IMG_CPU_PHYADDR sHPCpuPBase; + IMG_UINT32 ui32HPSize; +#endif + + + IMG_SYS_PHYADDR sLocalMemSysPBase; + IMG_DEV_PHYADDR sLocalMemDevPBase; + IMG_CPU_PHYADDR sLocalMemCpuPBase; + IMG_UINT32 ui32LocalMemSize; + +#if defined(SUPPORT_EXTERNAL_SYSTEM_CACHE) + IMG_UINT32 ui32ExtSysCacheRegsSize; + IMG_DEV_PHYADDR sExtSysCacheRegsDevPBase; +#endif + + + IMG_UINT32 ui32IRQ; + +#if !defined(SGX_DYNAMIC_TIMING_INFO) + + SGX_TIMING_INFORMATION sTimingInfo; +#endif +} SGX_DEVICE_MAP; + + +typedef struct _PVRSRV_STUB_PBDESC_ PVRSRV_STUB_PBDESC; +struct _PVRSRV_STUB_PBDESC_ +{ + IMG_UINT32 ui32RefCount; + IMG_UINT32 ui32TotalPBSize; + PVRSRV_KERNEL_MEM_INFO *psSharedPBDescKernelMemInfo; + PVRSRV_KERNEL_MEM_INFO *psHWPBDescKernelMemInfo; + PVRSRV_KERNEL_MEM_INFO **ppsSubKernelMemInfos; + IMG_UINT32 ui32SubKernelMemInfosCount; + IMG_HANDLE hDevCookie; + PVRSRV_KERNEL_MEM_INFO *psBlockKernelMemInfo; + PVRSRV_STUB_PBDESC *psNext; +}; + +typedef struct _PVRSRV_SGX_CCB_INFO_ +{ + PVRSRV_KERNEL_MEM_INFO *psCCBMemInfo; + PVRSRV_KERNEL_MEM_INFO *psCCBCtlMemInfo; + SGXMKIF_COMMAND *psCommands; + IMG_UINT32 *pui32WriteOffset; + volatile IMG_UINT32 *pui32ReadOffset; +#if defined(PDUMP) + IMG_UINT32 ui32CCBDumpWOff; +#endif +} PVRSRV_SGX_CCB_INFO; + +PVRSRV_ERROR SGXRegisterDevice (PVRSRV_DEVICE_NODE *psDeviceNode); + +IMG_VOID SGXOSTimer(IMG_VOID *pvData); + +IMG_VOID SGXReset(PVRSRV_SGXDEV_INFO *psDevInfo, + IMG_UINT32 ui32PDUMPFlags); + +PVRSRV_ERROR SGXInitialise(PVRSRV_SGXDEV_INFO *psDevInfo, + IMG_BOOL bHardwareRecovery); +PVRSRV_ERROR SGXDeinitialise(IMG_HANDLE hDevCookie); + +IMG_VOID SGXStartTimer(PVRSRV_SGXDEV_INFO *psDevInfo, + IMG_BOOL bStartOSTimer); + +PVRSRV_ERROR SGXPrePowerStateExt(IMG_HANDLE hDevHandle, + PVR_POWER_STATE eNewPowerState, + PVR_POWER_STATE eCurrentPowerState); + +PVRSRV_ERROR SGXPostPowerStateExt(IMG_HANDLE hDevHandle, + PVR_POWER_STATE eNewPowerState, + PVR_POWER_STATE eCurrentPowerState); + +PVRSRV_ERROR SGXPreClockSpeedChange(IMG_HANDLE hDevHandle, + IMG_BOOL bIdleDevice, + PVR_POWER_STATE eCurrentPowerState); + +PVRSRV_ERROR SGXPostClockSpeedChange(IMG_HANDLE hDevHandle, + IMG_BOOL bIdleDevice, + PVR_POWER_STATE eCurrentPowerState); + +PVRSRV_ERROR SGXDevInitCompatCheck(PVRSRV_DEVICE_NODE *psDeviceNode); + +#if defined(SGX_DYNAMIC_TIMING_INFO) +IMG_VOID SysGetSGXTimingInformation(SGX_TIMING_INFORMATION *psSGXTimingInfo); +#endif + +#if defined(NO_HARDWARE) +static INLINE IMG_VOID NoHardwareGenerateEvent(PVRSRV_SGXDEV_INFO *psDevInfo, + IMG_UINT32 ui32StatusRegister, + IMG_UINT32 ui32StatusValue, + IMG_UINT32 ui32StatusMask) +{ + IMG_UINT32 ui32RegVal; + + ui32RegVal = OSReadHWReg(psDevInfo->pvRegsBaseKM, ui32StatusRegister); + + ui32RegVal &= ~ui32StatusMask; + ui32RegVal |= (ui32StatusValue & ui32StatusMask); + + OSWriteHWReg(psDevInfo->pvRegsBaseKM, ui32StatusRegister, ui32RegVal); +} +#endif + +#if defined(__cplusplus) +} +#endif + +#endif + diff --git a/services4/srvkm/devices/sgx/sgxinit.c b/services4/srvkm/devices/sgx/sgxinit.c new file mode 100644 index 0000000..7b23933 --- /dev/null +++ b/services4/srvkm/devices/sgx/sgxinit.c @@ -0,0 +1,1707 @@ +/********************************************************************** + * + * Copyright(c) 2008 Imagination Technologies Ltd. All rights reserved. + * + * This program is free software; you can redistribute it and/or modify it + * under the terms and conditions of the GNU General Public License, + * version 2, as published by the Free Software Foundation. + * + * This program is distributed in the hope it will be useful but, except + * as otherwise stated in writing, without any warranty; without even the + * implied warranty of merchantability or fitness for a particular purpose. + * See the GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License along with + * this program; if not, write to the Free Software Foundation, Inc., + * 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA. + * + * The full GNU General Public License is included in this distribution in + * the file called "COPYING". + * + * Contact Information: + * Imagination Technologies Ltd. + * Home Park Estate, Kings Langley, Herts, WD4 8LZ, UK + * + ******************************************************************************/ + +#include + +#include "sgxdefs.h" +#include "sgxmmu.h" +#include "services_headers.h" +#include "buffer_manager.h" +#include "sgxapi_km.h" +#include "sgxinfo.h" +#include "sgxinfokm.h" +#include "sgxconfig.h" +#include "sysconfig.h" +#include "pvr_bridge_km.h" + +#include "pdump_km.h" +#include "ra.h" +#include "mmu.h" +#include "handle.h" +#include "perproc.h" + +#include "sgxutils.h" +#include "pvrversion.h" +#include "sgx_options.h" + +IMG_BOOL SGX_ISRHandler(IMG_VOID *pvData); + +IMG_UINT32 gui32EventStatusServicesByISR = 0; + +#if defined (PVRSRV_USSE_EDM_STATUS_RUNTIME) +extern IMG_VOID RuntimeEDMEventStatusDebug(PPVRSRV_KERNEL_MEM_INFO psEDMStatusBufferMemInfo); +#endif + + +static +PVRSRV_ERROR SGXGetBuildInfoKM(PVRSRV_SGXDEV_INFO *psDevInfo, + PVRSRV_DEVICE_NODE *psDeviceNode); + + +static IMG_VOID SGXCommandComplete(PVRSRV_DEVICE_NODE *psDeviceNode) +{ +#if defined(OS_SUPPORTS_IN_LISR) + if (OSInLISR(psDeviceNode->psSysData)) + { + + psDeviceNode->bReProcessDeviceCommandComplete = IMG_TRUE; + } + else + { + SGXScheduleProcessQueuesKM(psDeviceNode); + } +#else + SGXScheduleProcessQueuesKM(psDeviceNode); +#endif +} + +static IMG_UINT32 DeinitDevInfo(PVRSRV_SGXDEV_INFO *psDevInfo) +{ + if (psDevInfo->psKernelCCBInfo != IMG_NULL) + { + + + OSFreeMem(PVRSRV_OS_PAGEABLE_HEAP, sizeof(PVRSRV_SGX_CCB_INFO), psDevInfo->psKernelCCBInfo, IMG_NULL); + } + + return PVRSRV_OK; +} + +static PVRSRV_ERROR InitDevInfo(PVRSRV_PER_PROCESS_DATA *psPerProc, + PVRSRV_DEVICE_NODE *psDeviceNode, + SGX_BRIDGE_INIT_INFO *psInitInfo) +{ + PVRSRV_SGXDEV_INFO *psDevInfo = (PVRSRV_SGXDEV_INFO *)psDeviceNode->pvDevice; + PVRSRV_ERROR eError; + + PVRSRV_SGX_CCB_INFO *psKernelCCBInfo = IMG_NULL; + + PVR_UNREFERENCED_PARAMETER(psPerProc); + psDevInfo->sScripts = psInitInfo->sScripts; + + psDevInfo->psKernelCCBMemInfo = (PVRSRV_KERNEL_MEM_INFO *)psInitInfo->hKernelCCBMemInfo; + psDevInfo->psKernelCCB = (PVRSRV_SGX_KERNEL_CCB *) psDevInfo->psKernelCCBMemInfo->pvLinAddrKM; + + psDevInfo->psKernelCCBCtlMemInfo = (PVRSRV_KERNEL_MEM_INFO *)psInitInfo->hKernelCCBCtlMemInfo; + psDevInfo->psKernelCCBCtl = (PVRSRV_SGX_CCB_CTL *) psDevInfo->psKernelCCBCtlMemInfo->pvLinAddrKM; + + psDevInfo->psKernelCCBEventKickerMemInfo = (PVRSRV_KERNEL_MEM_INFO *)psInitInfo->hKernelCCBEventKickerMemInfo; + psDevInfo->pui32KernelCCBEventKicker = (IMG_UINT32 *)psDevInfo->psKernelCCBEventKickerMemInfo->pvLinAddrKM; + + psDevInfo->psKernelSGXHostCtlMemInfo = (PVRSRV_KERNEL_MEM_INFO *)psInitInfo->hKernelSGXHostCtlMemInfo; + psDevInfo->psSGXHostCtl = (SGXMKIF_HOST_CTL *)psDevInfo->psKernelSGXHostCtlMemInfo->pvLinAddrKM; + + psDevInfo->psKernelSGXTA3DCtlMemInfo = (PVRSRV_KERNEL_MEM_INFO *)psInitInfo->hKernelSGXTA3DCtlMemInfo; + + psDevInfo->psKernelSGXMiscMemInfo = (PVRSRV_KERNEL_MEM_INFO *)psInitInfo->hKernelSGXMiscMemInfo; + +#if defined(SGX_SUPPORT_HWPROFILING) + psDevInfo->psKernelHWProfilingMemInfo = (PVRSRV_KERNEL_MEM_INFO *)psInitInfo->hKernelHWProfilingMemInfo; +#endif +#if defined(SUPPORT_SGX_HWPERF) + psDevInfo->psKernelHWPerfCBMemInfo = (PVRSRV_KERNEL_MEM_INFO *)psInitInfo->hKernelHWPerfCBMemInfo; +#endif +#ifdef PVRSRV_USSE_EDM_STATUS_DEBUG + psDevInfo->psKernelEDMStatusBufferMemInfo = (PVRSRV_KERNEL_MEM_INFO *)psInitInfo->hKernelEDMStatusBufferMemInfo; +#endif +#if defined(SGX_FEATURE_OVERLAPPED_SPM) + psDevInfo->psKernelTmpRgnHeaderMemInfo = (PVRSRV_KERNEL_MEM_INFO *)psInitInfo->hKernelTmpRgnHeaderMemInfo; +#endif +#if defined(SGX_FEATURE_SPM_MODE_0) + psDevInfo->psKernelTmpDPMStateMemInfo = (PVRSRV_KERNEL_MEM_INFO *)psInitInfo->hKernelTmpDPMStateMemInfo; +#endif + + + eError = OSAllocMem(PVRSRV_OS_PAGEABLE_HEAP, + sizeof(PVRSRV_SGX_CCB_INFO), + (IMG_VOID **)&psKernelCCBInfo, 0); + if (eError != PVRSRV_OK) + { + PVR_DPF((PVR_DBG_ERROR,"InitDevInfo: Failed to alloc memory")); + goto failed_allockernelccb; + } + + + OSMemSet(psKernelCCBInfo, 0, sizeof(PVRSRV_SGX_CCB_INFO)); + psKernelCCBInfo->psCCBMemInfo = psDevInfo->psKernelCCBMemInfo; + psKernelCCBInfo->psCCBCtlMemInfo = psDevInfo->psKernelCCBCtlMemInfo; + psKernelCCBInfo->psCommands = psDevInfo->psKernelCCB->asCommands; + psKernelCCBInfo->pui32WriteOffset = &psDevInfo->psKernelCCBCtl->ui32WriteOffset; + psKernelCCBInfo->pui32ReadOffset = &psDevInfo->psKernelCCBCtl->ui32ReadOffset; + psDevInfo->psKernelCCBInfo = psKernelCCBInfo; + + + + psDevInfo->ui32HostKickAddress = psInitInfo->ui32HostKickAddress; + + + psDevInfo->ui32GetMiscInfoAddress = psInitInfo->ui32GetMiscInfoAddress; + + psDevInfo->bForcePTOff = IMG_FALSE; + + psDevInfo->ui32CacheControl = psInitInfo->ui32CacheControl; + + psDevInfo->ui32EDMTaskReg0 = psInitInfo->ui32EDMTaskReg0; + psDevInfo->ui32EDMTaskReg1 = psInitInfo->ui32EDMTaskReg1; + psDevInfo->ui32ClkGateStatusReg = psInitInfo->ui32ClkGateStatusReg; + psDevInfo->ui32ClkGateStatusMask = psInitInfo->ui32ClkGateStatusMask; +#if defined(SGX_FEATURE_MP) + psDevInfo->ui32MasterClkGateStatusReg = psInitInfo->ui32MasterClkGateStatusReg; + psDevInfo->ui32MasterClkGateStatusMask = psInitInfo->ui32MasterClkGateStatusMask; +#endif + + + + OSMemCopy(&psDevInfo->asSGXDevData, &psInitInfo->asInitDevData, sizeof(psDevInfo->asSGXDevData)); + + return PVRSRV_OK; + +failed_allockernelccb: + DeinitDevInfo(psDevInfo); + + return eError; +} + + + + +static PVRSRV_ERROR SGXRunScript(PVRSRV_SGXDEV_INFO *psDevInfo, SGX_INIT_COMMAND *psScript, IMG_UINT32 ui32NumInitCommands) +{ + IMG_UINT32 ui32PC; + SGX_INIT_COMMAND *psComm; + + for (ui32PC = 0, psComm = psScript; + ui32PC < ui32NumInitCommands; + ui32PC++, psComm++) + { + switch (psComm->eOp) + { + case SGX_INIT_OP_WRITE_HW_REG: + { + OSWriteHWReg(psDevInfo->pvRegsBaseKM, psComm->sWriteHWReg.ui32Offset, psComm->sWriteHWReg.ui32Value); + PDUMPREG(psComm->sWriteHWReg.ui32Offset, psComm->sWriteHWReg.ui32Value); + break; + } +#if defined(PDUMP) + case SGX_INIT_OP_PDUMP_HW_REG: + { + PDUMPREG(psComm->sPDumpHWReg.ui32Offset, psComm->sPDumpHWReg.ui32Value); + break; + } +#endif + case SGX_INIT_OP_HALT: + { + return PVRSRV_OK; + } + case SGX_INIT_OP_ILLEGAL: + + default: + { + PVR_DPF((PVR_DBG_ERROR,"SGXRunScript: PC %d: Illegal command: %d", ui32PC, psComm->eOp)); + return PVRSRV_ERROR_GENERIC; + } + } + + } + + return PVRSRV_ERROR_GENERIC; +} + +PVRSRV_ERROR SGXInitialise(PVRSRV_SGXDEV_INFO *psDevInfo, + IMG_BOOL bHardwareRecovery) +{ + PVRSRV_ERROR eError; + + + + PDUMPCOMMENTWITHFLAGS(PDUMP_FLAGS_CONTINUOUS, "SGX initialisation script part 1\n"); + eError = SGXRunScript(psDevInfo, psDevInfo->sScripts.asInitCommandsPart1, SGX_MAX_INIT_COMMANDS); + if (eError != PVRSRV_OK) + { + PVR_DPF((PVR_DBG_ERROR,"SGXInitialise: SGXRunScript (part 1) failed (%d)", eError)); + return (PVRSRV_ERROR_GENERIC); + } + PDUMPCOMMENTWITHFLAGS(PDUMP_FLAGS_CONTINUOUS, "End of SGX initialisation script part 1\n"); + + + SGXReset(psDevInfo, PDUMP_FLAGS_CONTINUOUS); + +#if defined(EUR_CR_POWER) +#if defined(SGX531) + + + + + + OSWriteHWReg(psDevInfo->pvRegsBaseKM, EUR_CR_POWER, 1); + PDUMPREG(EUR_CR_POWER, 1); +#else + + OSWriteHWReg(psDevInfo->pvRegsBaseKM, EUR_CR_POWER, 0); + PDUMPREG(EUR_CR_POWER, 0); +#endif +#endif + + + *psDevInfo->pui32KernelCCBEventKicker = 0; +#if defined(PDUMP) + PDUMPMEM(IMG_NULL, psDevInfo->psKernelCCBEventKickerMemInfo, 0, + sizeof(*psDevInfo->pui32KernelCCBEventKicker), PDUMP_FLAGS_CONTINUOUS, + MAKEUNIQUETAG(psDevInfo->psKernelCCBEventKickerMemInfo)); +#endif + + + + PDUMPCOMMENTWITHFLAGS(PDUMP_FLAGS_CONTINUOUS, "SGX initialisation script part 2\n"); + eError = SGXRunScript(psDevInfo, psDevInfo->sScripts.asInitCommandsPart2, SGX_MAX_INIT_COMMANDS); + if (eError != PVRSRV_OK) + { + PVR_DPF((PVR_DBG_ERROR,"SGXInitialise: SGXRunScript (part 2) failed (%d)", eError)); + return (PVRSRV_ERROR_GENERIC); + } + PDUMPCOMMENTWITHFLAGS(PDUMP_FLAGS_CONTINUOUS, "End of SGX initialisation script part 2\n"); + +#ifdef PLAT_TI8168 + OSWriteHWReg(psDevInfo->pvRegsBaseKM, 0xFF08, 0x80000000);//OCP Bypass mode +#else + if(cpu_is_omap3630()) + OSWriteHWReg(psDevInfo->pvRegsBaseKM, 0xFF08, 0x80000000);//OCP Bypass mode +#endif + + SGXStartTimer(psDevInfo, (IMG_BOOL)!bHardwareRecovery); + + if (bHardwareRecovery) + { + SGXMKIF_HOST_CTL *psSGXHostCtl = (SGXMKIF_HOST_CTL *)psDevInfo->psSGXHostCtl; + + + if (PollForValueKM((volatile IMG_UINT32 *)(&psSGXHostCtl->ui32InterruptClearFlags), + 0, + PVRSRV_USSE_EDM_INTERRUPT_HWR, + MAX_HW_TIME_US/WAIT_TRY_COUNT, + 1000) != PVRSRV_OK) + { + PVR_DPF((PVR_DBG_ERROR, "SGXInitialise: Wait for uKernel HW Recovery failed")); + PVR_DBG_BREAK; + return PVRSRV_ERROR_RETRY; + } + } + +#if defined(FIX_HW_BRN_22997) && defined(FIX_HW_BRN_23030) && defined(SGX_FEATURE_HOST_PORT) + + + + WorkaroundBRN22997ReadHostPort(psDevInfo); +#endif + + PVR_ASSERT(psDevInfo->psKernelCCBCtl->ui32ReadOffset == psDevInfo->psKernelCCBCtl->ui32WriteOffset); + + return PVRSRV_OK; +} + +PVRSRV_ERROR SGXDeinitialise(IMG_HANDLE hDevCookie) + +{ + PVRSRV_SGXDEV_INFO *psDevInfo = (PVRSRV_SGXDEV_INFO *) hDevCookie; + PVRSRV_ERROR eError; + + + if (psDevInfo->pvRegsBaseKM == IMG_NULL) + { + return PVRSRV_OK; + } + + eError = SGXRunScript(psDevInfo, psDevInfo->sScripts.asDeinitCommands, SGX_MAX_DEINIT_COMMANDS); + if (eError != PVRSRV_OK) + { + PVR_DPF((PVR_DBG_ERROR,"SGXDeinitialise: SGXRunScript failed (%d)", eError)); + return (PVRSRV_ERROR_GENERIC); + } + + return PVRSRV_OK; +} + + +static PVRSRV_ERROR DevInitSGXPart1 (IMG_VOID *pvDeviceNode) +{ + PVRSRV_SGXDEV_INFO *psDevInfo; + IMG_HANDLE hKernelDevMemContext; + IMG_DEV_PHYADDR sPDDevPAddr; + IMG_UINT32 i; + PVRSRV_DEVICE_NODE *psDeviceNode = (PVRSRV_DEVICE_NODE *)pvDeviceNode; + DEVICE_MEMORY_HEAP_INFO *psDeviceMemoryHeap = psDeviceNode->sDevMemoryInfo.psDeviceMemoryHeap; + PVRSRV_ERROR eError; + + PDUMPCOMMENT("SGX Initialisation Part 1"); + + + PDUMPCOMMENT("SGX Core Version Information: %s", SGX_CORE_FRIENDLY_NAME); +#ifdef SGX_CORE_REV + PDUMPCOMMENT("SGX Core Revision Information: %d", SGX_CORE_REV); +#else + PDUMPCOMMENT("SGX Core Revision Information: head rtl"); +#endif + + + + if(OSAllocMem( PVRSRV_OS_NON_PAGEABLE_HEAP, + sizeof(PVRSRV_SGXDEV_INFO), + (IMG_VOID **)&psDevInfo, IMG_NULL) != PVRSRV_OK) + { + PVR_DPF((PVR_DBG_ERROR,"DevInitSGXPart1 : Failed to alloc memory for DevInfo")); + return (PVRSRV_ERROR_OUT_OF_MEMORY); + } + OSMemSet (psDevInfo, 0, sizeof(PVRSRV_SGXDEV_INFO)); + + + psDevInfo->eDeviceType = DEV_DEVICE_TYPE; + psDevInfo->eDeviceClass = DEV_DEVICE_CLASS; + + + psDeviceNode->pvDevice = (IMG_PVOID)psDevInfo; + + + psDevInfo->pvDeviceMemoryHeap = (IMG_VOID*)psDeviceMemoryHeap; + + + hKernelDevMemContext = BM_CreateContext(psDeviceNode, + &sPDDevPAddr, + IMG_NULL, + IMG_NULL); + + psDevInfo->sKernelPDDevPAddr = sPDDevPAddr; + + + + for(i=0; isDevMemoryInfo.ui32HeapCount; i++) + { + IMG_HANDLE hDevMemHeap; + + switch(psDeviceMemoryHeap[i].DevMemHeapType) + { + case DEVICE_MEMORY_HEAP_KERNEL: + case DEVICE_MEMORY_HEAP_SHARED: + case DEVICE_MEMORY_HEAP_SHARED_EXPORTED: + { + hDevMemHeap = BM_CreateHeap (hKernelDevMemContext, + &psDeviceMemoryHeap[i]); + + + + psDeviceMemoryHeap[i].hDevMemHeap = hDevMemHeap; + break; + } + } + } + + eError = MMU_BIFResetPDAlloc(psDevInfo); + if (eError != PVRSRV_OK) + { + PVR_DPF((PVR_DBG_ERROR,"DevInitSGX : Failed to alloc memory for BIF reset")); + return PVRSRV_ERROR_GENERIC; + } + + return PVRSRV_OK; +} + +IMG_EXPORT +PVRSRV_ERROR SGXGetInfoForSrvinitKM(IMG_HANDLE hDevHandle, SGX_BRIDGE_INFO_FOR_SRVINIT *psInitInfo) +{ + PVRSRV_DEVICE_NODE *psDeviceNode; + PVRSRV_SGXDEV_INFO *psDevInfo; + PVRSRV_ERROR eError; + + PDUMPCOMMENT("SGXGetInfoForSrvinit"); + + psDeviceNode = (PVRSRV_DEVICE_NODE *)hDevHandle; + psDevInfo = (PVRSRV_SGXDEV_INFO *)psDeviceNode->pvDevice; + + psInitInfo->sPDDevPAddr = psDevInfo->sKernelPDDevPAddr; + + eError = PVRSRVGetDeviceMemHeapsKM(hDevHandle, &psInitInfo->asHeapInfo[0]); + if (eError != PVRSRV_OK) + { + PVR_DPF((PVR_DBG_ERROR,"SGXGetInfoForSrvinit: PVRSRVGetDeviceMemHeapsKM failed (%d)", eError)); + return PVRSRV_ERROR_GENERIC; + } + + return eError; +} + +IMG_EXPORT +PVRSRV_ERROR DevInitSGXPart2KM (PVRSRV_PER_PROCESS_DATA *psPerProc, + IMG_HANDLE hDevHandle, + SGX_BRIDGE_INIT_INFO *psInitInfo) +{ + PVRSRV_DEVICE_NODE *psDeviceNode; + PVRSRV_SGXDEV_INFO *psDevInfo; + PVRSRV_ERROR eError; + SGX_DEVICE_MAP *psSGXDeviceMap; + PVR_POWER_STATE eDefaultPowerState; + + PDUMPCOMMENT("SGX Initialisation Part 2"); + + psDeviceNode = (PVRSRV_DEVICE_NODE *)hDevHandle; + psDevInfo = (PVRSRV_SGXDEV_INFO *)psDeviceNode->pvDevice; + + + + eError = InitDevInfo(psPerProc, psDeviceNode, psInitInfo); + if (eError != PVRSRV_OK) + { + PVR_DPF((PVR_DBG_ERROR,"DevInitSGXPart2KM: Failed to load EDM program")); + goto failed_init_dev_info; + } + + + eError = SysGetDeviceMemoryMap(PVRSRV_DEVICE_TYPE_SGX, + (IMG_VOID**)&psSGXDeviceMap); + if (eError != PVRSRV_OK) + { + PVR_DPF((PVR_DBG_ERROR,"DevInitSGXPart2KM: Failed to get device memory map!")); + return PVRSRV_ERROR_INIT_FAILURE; + } + + + if (psSGXDeviceMap->pvRegsCpuVBase) + { + psDevInfo->pvRegsBaseKM = psSGXDeviceMap->pvRegsCpuVBase; + } + else + { + + psDevInfo->pvRegsBaseKM = OSMapPhysToLin(psSGXDeviceMap->sRegsCpuPBase, + psSGXDeviceMap->ui32RegsSize, + PVRSRV_HAP_KERNEL_ONLY|PVRSRV_HAP_UNCACHED, + IMG_NULL); + if (!psDevInfo->pvRegsBaseKM) + { + PVR_DPF((PVR_DBG_ERROR,"DevInitSGXPart2KM: Failed to map in regs\n")); + return PVRSRV_ERROR_BAD_MAPPING; + } + } + psDevInfo->ui32RegSize = psSGXDeviceMap->ui32RegsSize; + psDevInfo->sRegsPhysBase = psSGXDeviceMap->sRegsSysPBase; + + +#if defined(SGX_FEATURE_HOST_PORT) + if (psSGXDeviceMap->ui32Flags & SGX_HOSTPORT_PRESENT) + { + + psDevInfo->pvHostPortBaseKM = OSMapPhysToLin(psSGXDeviceMap->sHPCpuPBase, + psSGXDeviceMap->ui32HPSize, + PVRSRV_HAP_KERNEL_ONLY|PVRSRV_HAP_UNCACHED, + IMG_NULL); + if (!psDevInfo->pvHostPortBaseKM) + { + PVR_DPF((PVR_DBG_ERROR,"DevInitSGXPart2KM: Failed to map in host port\n")); + return PVRSRV_ERROR_BAD_MAPPING; + } + psDevInfo->ui32HPSize = psSGXDeviceMap->ui32HPSize; + psDevInfo->sHPSysPAddr = psSGXDeviceMap->sHPSysPBase; + } +#endif + +#if defined (SYS_USING_INTERRUPTS) + + + psDeviceNode->pvISRData = psDeviceNode; + + PVR_ASSERT(psDeviceNode->pfnDeviceISR == SGX_ISRHandler); + +#endif + + +#if defined(SUPPORT_ACTIVE_POWER_MANAGEMENT) + + psDevInfo->psSGXHostCtl->ui32PowerStatus |= PVRSRV_USSE_EDM_POWMAN_NO_WORK; + eDefaultPowerState = PVRSRV_POWER_STATE_D3; +#else + eDefaultPowerState = PVRSRV_POWER_STATE_D0; +#endif + eError = PVRSRVRegisterPowerDevice (psDeviceNode->sDevId.ui32DeviceIndex, + SGXPrePowerStateExt, SGXPostPowerStateExt, + SGXPreClockSpeedChange, SGXPostClockSpeedChange, + (IMG_HANDLE)psDeviceNode, + PVRSRV_POWER_STATE_D3, + eDefaultPowerState); + if (eError != PVRSRV_OK) + { + PVR_DPF((PVR_DBG_ERROR,"DevInitSGXPart2KM: failed to register device with power manager")); + return eError; + } + +#if defined(FIX_HW_BRN_22997) && defined(FIX_HW_BRN_23030) && defined(SGX_FEATURE_HOST_PORT) + eError = WorkaroundBRN22997Alloc(psDevInfo); + if (eError != PVRSRV_OK) + { + PVR_DPF((PVR_DBG_ERROR,"SGXInitialise : Failed to alloc memory for BRN22997 workaround")); + return eError; + } +#endif + +#if defined(SUPPORT_EXTERNAL_SYSTEM_CACHE) + + psDevInfo->ui32ExtSysCacheRegsSize = psSGXDeviceMap->ui32ExtSysCacheRegsSize; + psDevInfo->sExtSysCacheRegsDevPBase = psSGXDeviceMap->sExtSysCacheRegsDevPBase; + eError = MMU_MapExtSystemCacheRegs(psDeviceNode); + if (eError != PVRSRV_OK) + { + PVR_DPF((PVR_DBG_ERROR,"SGXInitialise : Failed to map external system cache registers")); + return eError; + } +#endif + + + + OSMemSet(psDevInfo->psKernelCCB, 0, sizeof(PVRSRV_SGX_KERNEL_CCB)); + OSMemSet(psDevInfo->psKernelCCBCtl, 0, sizeof(PVRSRV_SGX_CCB_CTL)); + OSMemSet(psDevInfo->pui32KernelCCBEventKicker, 0, sizeof(*psDevInfo->pui32KernelCCBEventKicker)); + PDUMPCOMMENT("Initialise Kernel CCB"); + PDUMPMEM(IMG_NULL, psDevInfo->psKernelCCBMemInfo, 0, sizeof(PVRSRV_SGX_KERNEL_CCB), PDUMP_FLAGS_CONTINUOUS, MAKEUNIQUETAG(psDevInfo->psKernelCCBMemInfo)); + PDUMPCOMMENT("Initialise Kernel CCB Control"); + PDUMPMEM(IMG_NULL, psDevInfo->psKernelCCBCtlMemInfo, 0, sizeof(PVRSRV_SGX_CCB_CTL), PDUMP_FLAGS_CONTINUOUS, MAKEUNIQUETAG(psDevInfo->psKernelCCBCtlMemInfo)); + PDUMPCOMMENT("Initialise Kernel CCB Event Kicker"); + PDUMPMEM(IMG_NULL, psDevInfo->psKernelCCBEventKickerMemInfo, 0, sizeof(*psDevInfo->pui32KernelCCBEventKicker), PDUMP_FLAGS_CONTINUOUS, MAKEUNIQUETAG(psDevInfo->psKernelCCBEventKickerMemInfo)); + + return PVRSRV_OK; + +failed_init_dev_info: + return eError; +} + +static PVRSRV_ERROR DevDeInitSGX (IMG_VOID *pvDeviceNode) +{ + PVRSRV_DEVICE_NODE *psDeviceNode = (PVRSRV_DEVICE_NODE *)pvDeviceNode; + PVRSRV_SGXDEV_INFO *psDevInfo = (PVRSRV_SGXDEV_INFO*)psDeviceNode->pvDevice; + PVRSRV_ERROR eError; + IMG_UINT32 ui32Heap; + DEVICE_MEMORY_HEAP_INFO *psDeviceMemoryHeap; + SGX_DEVICE_MAP *psSGXDeviceMap; + + if (!psDevInfo) + { + + PVR_DPF((PVR_DBG_ERROR,"DevDeInitSGX: Null DevInfo")); + return PVRSRV_OK; + } + +#if defined(SUPPORT_HW_RECOVERY) + if (psDevInfo->hTimer) + { + eError = OSRemoveTimer(psDevInfo->hTimer); + if (eError != PVRSRV_OK) + { + PVR_DPF((PVR_DBG_ERROR,"DevDeInitSGX: Failed to remove timer")); + return eError; + } + psDevInfo->hTimer = IMG_NULL; + } +#endif + +#if defined(SUPPORT_EXTERNAL_SYSTEM_CACHE) + + eError = MMU_UnmapExtSystemCacheRegs(psDeviceNode); + if (eError != PVRSRV_OK) + { + PVR_DPF((PVR_DBG_ERROR,"DevDeInitSGX: Failed to unmap ext system cache registers")); + return eError; + } +#endif + +#if defined(FIX_HW_BRN_22997) && defined(FIX_HW_BRN_23030) && defined(SGX_FEATURE_HOST_PORT) + WorkaroundBRN22997Free(psDevInfo); +#endif + + MMU_BIFResetPDFree(psDevInfo); + + + + + DeinitDevInfo(psDevInfo); + + + psDeviceMemoryHeap = (DEVICE_MEMORY_HEAP_INFO *)psDevInfo->pvDeviceMemoryHeap; + for(ui32Heap=0; ui32HeapsDevMemoryInfo.ui32HeapCount; ui32Heap++) + { + switch(psDeviceMemoryHeap[ui32Heap].DevMemHeapType) + { + case DEVICE_MEMORY_HEAP_KERNEL: + case DEVICE_MEMORY_HEAP_SHARED: + case DEVICE_MEMORY_HEAP_SHARED_EXPORTED: + { + if (psDeviceMemoryHeap[ui32Heap].hDevMemHeap != IMG_NULL) + { + BM_DestroyHeap(psDeviceMemoryHeap[ui32Heap].hDevMemHeap); + } + break; + } + } + } + + + eError = BM_DestroyContext(psDeviceNode->sDevMemoryInfo.pBMKernelContext, IMG_NULL); + if (eError != PVRSRV_OK) + { + PVR_DPF((PVR_DBG_ERROR,"DevDeInitSGX : Failed to destroy kernel context")); + return eError; + } + + + eError = PVRSRVRemovePowerDevice (((PVRSRV_DEVICE_NODE*)pvDeviceNode)->sDevId.ui32DeviceIndex); + if (eError != PVRSRV_OK) + { + return eError; + } + + eError = SysGetDeviceMemoryMap(PVRSRV_DEVICE_TYPE_SGX, + (IMG_VOID**)&psSGXDeviceMap); + if (eError != PVRSRV_OK) + { + PVR_DPF((PVR_DBG_ERROR,"DevDeInitSGX: Failed to get device memory map!")); + return eError; + } + + + if (!psSGXDeviceMap->pvRegsCpuVBase) + { + + if (psDevInfo->pvRegsBaseKM != IMG_NULL) + { + OSUnMapPhysToLin(psDevInfo->pvRegsBaseKM, + psDevInfo->ui32RegSize, + PVRSRV_HAP_KERNEL_ONLY|PVRSRV_HAP_UNCACHED, + IMG_NULL); + } + } + +#if defined(SGX_FEATURE_HOST_PORT) + if (psSGXDeviceMap->ui32Flags & SGX_HOSTPORT_PRESENT) + { + + if (psDevInfo->pvHostPortBaseKM != IMG_NULL) + { + OSUnMapPhysToLin(psDevInfo->pvHostPortBaseKM, + psDevInfo->ui32HPSize, + PVRSRV_HAP_KERNEL_ONLY|PVRSRV_HAP_UNCACHED, + IMG_NULL); + } + } +#endif + + + + OSFreeMem(PVRSRV_OS_NON_PAGEABLE_HEAP, + sizeof(PVRSRV_SGXDEV_INFO), + psDevInfo, + 0); + + psDeviceNode->pvDevice = IMG_NULL; + + if (psDeviceMemoryHeap != IMG_NULL) + { + + OSFreeMem(PVRSRV_OS_NON_PAGEABLE_HEAP, + sizeof(DEVICE_MEMORY_HEAP_INFO) * psDeviceNode->sDevMemoryInfo.ui32HeapCount, + psDeviceMemoryHeap, + 0); + } + + return PVRSRV_OK; +} + + + + +#if defined(SYS_USING_INTERRUPTS) || defined(SUPPORT_HW_RECOVERY) +static +IMG_VOID HWRecoveryResetSGX (PVRSRV_DEVICE_NODE *psDeviceNode, + IMG_UINT32 ui32Component, + IMG_UINT32 ui32CallerID) +{ + PVRSRV_ERROR eError; + PVRSRV_SGXDEV_INFO *psDevInfo = (PVRSRV_SGXDEV_INFO*)psDeviceNode->pvDevice; + SGXMKIF_HOST_CTL *psSGXHostCtl = (SGXMKIF_HOST_CTL *)psDevInfo->psSGXHostCtl; + + PVR_UNREFERENCED_PARAMETER(ui32Component); + + + + eError = PVRSRVPowerLock(ui32CallerID, IMG_FALSE); + if(eError != PVRSRV_OK) + { + + + + PVR_DPF((PVR_DBG_WARNING,"HWRecoveryResetSGX: Power transition in progress")); + return; + } + + psSGXHostCtl->ui32InterruptClearFlags |= PVRSRV_USSE_EDM_INTERRUPT_HWR; + + PVR_DPF((PVR_DBG_ERROR, "HWRecoveryResetSGX: SGX Hardware Recovery triggered")); + + + + PDUMPSUSPEND(); + + + do + { + eError = SGXInitialise(psDevInfo, IMG_TRUE); + } + while (eError == PVRSRV_ERROR_RETRY); + if (eError != PVRSRV_OK) + { + PVR_DPF((PVR_DBG_ERROR,"HWRecoveryResetSGX: SGXInitialise failed (%d)", eError)); + } + + + PDUMPRESUME(); + + PVRSRVPowerUnlock(ui32CallerID); + + + SGXScheduleProcessQueuesKM(psDeviceNode); + + + + PVRSRVProcessQueues(ui32CallerID, IMG_TRUE); +} +#endif + + +#if defined(SUPPORT_HW_RECOVERY) +IMG_VOID SGXOSTimer(IMG_VOID *pvData) +{ + PVRSRV_DEVICE_NODE *psDeviceNode = pvData; + PVRSRV_SGXDEV_INFO *psDevInfo = psDeviceNode->pvDevice; + static IMG_UINT32 ui32EDMTasks = 0; + static IMG_UINT32 ui32LockupCounter = 0; + static IMG_UINT32 ui32NumResets = 0; + IMG_UINT32 ui32CurrentEDMTasks; + IMG_BOOL bLockup = IMG_FALSE; + IMG_BOOL bPoweredDown; + + + psDevInfo->ui32TimeStamp++; + +#if defined(NO_HARDWARE) + bPoweredDown = IMG_TRUE; +#else + bPoweredDown = (IMG_BOOL)!SGXIsDevicePowered(psDeviceNode); +#endif + + + + if (bPoweredDown) + { + ui32LockupCounter = 0; + } + else + { + + ui32CurrentEDMTasks = OSReadHWReg(psDevInfo->pvRegsBaseKM, psDevInfo->ui32EDMTaskReg0); + if (psDevInfo->ui32EDMTaskReg1 != 0) + { + ui32CurrentEDMTasks ^= OSReadHWReg(psDevInfo->pvRegsBaseKM, psDevInfo->ui32EDMTaskReg1); + } + if ((ui32CurrentEDMTasks == ui32EDMTasks) && + (psDevInfo->ui32NumResets == ui32NumResets)) + { + ui32LockupCounter++; + if (ui32LockupCounter == 3) + { + ui32LockupCounter = 0; + PVR_DPF((PVR_DBG_ERROR, "SGXOSTimer() detected SGX lockup (0x%x tasks)", ui32EDMTasks)); + + bLockup = IMG_TRUE; + } + } + else + { + ui32LockupCounter = 0; + ui32EDMTasks = ui32CurrentEDMTasks; + ui32NumResets = psDevInfo->ui32NumResets; + } + } + + if (bLockup) + { + SGXMKIF_HOST_CTL *psSGXHostCtl = (SGXMKIF_HOST_CTL *)psDevInfo->psSGXHostCtl; + + + psSGXHostCtl->ui32HostDetectedLockups ++; + + + HWRecoveryResetSGX(psDeviceNode, 0, KERNEL_ID); + } +} +#endif + + +#if defined(SYS_USING_INTERRUPTS) + + +IMG_BOOL SGX_ISRHandler (IMG_VOID *pvData) +{ + IMG_BOOL bInterruptProcessed = IMG_FALSE; + + + { + IMG_UINT32 ui32EventStatus, ui32EventEnable; + IMG_UINT32 ui32EventClear = 0; + PVRSRV_DEVICE_NODE *psDeviceNode; + PVRSRV_SGXDEV_INFO *psDevInfo; + + + if(pvData == IMG_NULL) + { + PVR_DPF((PVR_DBG_ERROR, "SGX_ISRHandler: Invalid params\n")); + return bInterruptProcessed; + } + + psDeviceNode = (PVRSRV_DEVICE_NODE *)pvData; + psDevInfo = (PVRSRV_SGXDEV_INFO *)psDeviceNode->pvDevice; + + ui32EventStatus = OSReadHWReg(psDevInfo->pvRegsBaseKM, EUR_CR_EVENT_STATUS); + ui32EventEnable = OSReadHWReg(psDevInfo->pvRegsBaseKM, EUR_CR_EVENT_HOST_ENABLE); + + + + gui32EventStatusServicesByISR = ui32EventStatus; + + + ui32EventStatus &= ui32EventEnable; + + if (ui32EventStatus & EUR_CR_EVENT_STATUS_SW_EVENT_MASK) + { + ui32EventClear |= EUR_CR_EVENT_HOST_CLEAR_SW_EVENT_MASK; + } + + if (ui32EventClear) + { + bInterruptProcessed = IMG_TRUE; + + + ui32EventClear |= EUR_CR_EVENT_HOST_CLEAR_MASTER_INTERRUPT_MASK; + + + OSWriteHWReg(psDevInfo->pvRegsBaseKM, EUR_CR_EVENT_HOST_CLEAR, ui32EventClear); + } + } + + return bInterruptProcessed; +} + + +IMG_VOID SGX_MISRHandler (IMG_VOID *pvData) +{ + PVRSRV_DEVICE_NODE *psDeviceNode = (PVRSRV_DEVICE_NODE *)pvData; + PVRSRV_SGXDEV_INFO *psDevInfo = (PVRSRV_SGXDEV_INFO*)psDeviceNode->pvDevice; + SGXMKIF_HOST_CTL *psSGXHostCtl = (SGXMKIF_HOST_CTL *)psDevInfo->psSGXHostCtl; + + if (((psSGXHostCtl->ui32InterruptFlags & PVRSRV_USSE_EDM_INTERRUPT_HWR) != 0UL) && + ((psSGXHostCtl->ui32InterruptClearFlags & PVRSRV_USSE_EDM_INTERRUPT_HWR) == 0UL)) + { + HWRecoveryResetSGX(psDeviceNode, 0, ISR_ID); + } + +#if defined(OS_SUPPORTS_IN_LISR) + if (psDeviceNode->bReProcessDeviceCommandComplete) + { + SGXScheduleProcessQueuesKM(psDeviceNode); + } +#endif + +#if defined(SUPPORT_ACTIVE_POWER_MANAGEMENT) + SGXTestActivePowerEvent(psDeviceNode, ISR_ID); +#endif +} +#endif + + +PVRSRV_ERROR SGXRegisterDevice (PVRSRV_DEVICE_NODE *psDeviceNode) +{ + DEVICE_MEMORY_INFO *psDevMemoryInfo; + DEVICE_MEMORY_HEAP_INFO *psDeviceMemoryHeap; + + + psDeviceNode->sDevId.eDeviceType = DEV_DEVICE_TYPE; + psDeviceNode->sDevId.eDeviceClass = DEV_DEVICE_CLASS; + + psDeviceNode->pfnInitDevice = DevInitSGXPart1; + psDeviceNode->pfnDeInitDevice = DevDeInitSGX; + + psDeviceNode->pfnInitDeviceCompatCheck = SGXDevInitCompatCheck; + + + + psDeviceNode->pfnMMUInitialise = MMU_Initialise; + psDeviceNode->pfnMMUFinalise = MMU_Finalise; + psDeviceNode->pfnMMUInsertHeap = MMU_InsertHeap; + psDeviceNode->pfnMMUCreate = MMU_Create; + psDeviceNode->pfnMMUDelete = MMU_Delete; + psDeviceNode->pfnMMUAlloc = MMU_Alloc; + psDeviceNode->pfnMMUFree = MMU_Free; + psDeviceNode->pfnMMUMapPages = MMU_MapPages; + psDeviceNode->pfnMMUMapShadow = MMU_MapShadow; + psDeviceNode->pfnMMUUnmapPages = MMU_UnmapPages; + psDeviceNode->pfnMMUMapScatter = MMU_MapScatter; + psDeviceNode->pfnMMUGetPhysPageAddr = MMU_GetPhysPageAddr; + psDeviceNode->pfnMMUGetPDDevPAddr = MMU_GetPDDevPAddr; + +#if defined (SYS_USING_INTERRUPTS) + + + psDeviceNode->pfnDeviceISR = SGX_ISRHandler; + psDeviceNode->pfnDeviceMISR = SGX_MISRHandler; +#endif + + + + psDeviceNode->pfnDeviceCommandComplete = SGXCommandComplete; + + + + psDevMemoryInfo = &psDeviceNode->sDevMemoryInfo; + + psDevMemoryInfo->ui32AddressSpaceSizeLog2 = SGX_FEATURE_ADDRESS_SPACE_SIZE; + + + psDevMemoryInfo->ui32Flags = 0; + + + psDevMemoryInfo->ui32HeapCount = SGX_MAX_HEAP_ID; + + + psDevMemoryInfo->ui32SyncHeapID = SGX_SYNCINFO_HEAP_ID; + + +#if defined(SUPPORT_SGX_GENERAL_MAPPING_HEAP) + psDevMemoryInfo->ui32MappingHeapID = SGX_GENERAL_MAPPING_HEAP_ID; +#else + psDevMemoryInfo->ui32MappingHeapID = SGX_GENERAL_HEAP_ID; +#endif + + + if(OSAllocMem( PVRSRV_OS_PAGEABLE_HEAP, + sizeof(DEVICE_MEMORY_HEAP_INFO) * psDevMemoryInfo->ui32HeapCount, + (IMG_VOID **)&psDevMemoryInfo->psDeviceMemoryHeap, 0) != PVRSRV_OK) + { + PVR_DPF((PVR_DBG_ERROR,"SGXRegisterDevice : Failed to alloc memory for DEVICE_MEMORY_HEAP_INFO")); + return (PVRSRV_ERROR_OUT_OF_MEMORY); + } + OSMemSet(psDevMemoryInfo->psDeviceMemoryHeap, 0, sizeof(DEVICE_MEMORY_HEAP_INFO) * psDevMemoryInfo->ui32HeapCount); + + psDeviceMemoryHeap = psDevMemoryInfo->psDeviceMemoryHeap; + + + + + + psDeviceMemoryHeap[SGX_GENERAL_HEAP_ID].ui32HeapID = HEAP_ID( PVRSRV_DEVICE_TYPE_SGX , SGX_GENERAL_HEAP_ID); + psDeviceMemoryHeap[SGX_GENERAL_HEAP_ID].sDevVAddrBase.uiAddr = SGX_GENERAL_HEAP_BASE; + psDeviceMemoryHeap[SGX_GENERAL_HEAP_ID].ui32HeapSize = SGX_GENERAL_HEAP_SIZE; + psDeviceMemoryHeap[SGX_GENERAL_HEAP_ID].ui32Attribs = PVRSRV_HAP_WRITECOMBINE + | PVRSRV_MEM_RAM_BACKED_ALLOCATION + | PVRSRV_HAP_SINGLE_PROCESS; + psDeviceMemoryHeap[SGX_GENERAL_HEAP_ID].pszName = "General"; + psDeviceMemoryHeap[SGX_GENERAL_HEAP_ID].pszBSName = "General BS"; + psDeviceMemoryHeap[SGX_GENERAL_HEAP_ID].DevMemHeapType = DEVICE_MEMORY_HEAP_PERCONTEXT; + + psDeviceMemoryHeap[SGX_GENERAL_HEAP_ID].ui32DataPageSize = SGX_MMU_PAGE_SIZE; + + + psDeviceMemoryHeap[SGX_TADATA_HEAP_ID].ui32HeapID = HEAP_ID( PVRSRV_DEVICE_TYPE_SGX , SGX_TADATA_HEAP_ID); + psDeviceMemoryHeap[SGX_TADATA_HEAP_ID].sDevVAddrBase.uiAddr = SGX_TADATA_HEAP_BASE; + psDeviceMemoryHeap[SGX_TADATA_HEAP_ID].ui32HeapSize = SGX_TADATA_HEAP_SIZE; + psDeviceMemoryHeap[SGX_TADATA_HEAP_ID].ui32Attribs = PVRSRV_HAP_WRITECOMBINE + | PVRSRV_MEM_RAM_BACKED_ALLOCATION + | PVRSRV_HAP_MULTI_PROCESS; + psDeviceMemoryHeap[SGX_TADATA_HEAP_ID].pszName = "TA Data"; + psDeviceMemoryHeap[SGX_TADATA_HEAP_ID].pszBSName = "TA Data BS"; + psDeviceMemoryHeap[SGX_TADATA_HEAP_ID].DevMemHeapType = DEVICE_MEMORY_HEAP_PERCONTEXT; + + psDeviceMemoryHeap[SGX_TADATA_HEAP_ID].ui32DataPageSize = SGX_MMU_PAGE_SIZE; + + + psDeviceMemoryHeap[SGX_KERNEL_CODE_HEAP_ID].ui32HeapID = HEAP_ID( PVRSRV_DEVICE_TYPE_SGX ,SGX_KERNEL_CODE_HEAP_ID); + psDeviceMemoryHeap[SGX_KERNEL_CODE_HEAP_ID].sDevVAddrBase.uiAddr = SGX_KERNEL_CODE_HEAP_BASE; + psDeviceMemoryHeap[SGX_KERNEL_CODE_HEAP_ID].ui32HeapSize = SGX_KERNEL_CODE_HEAP_SIZE; + psDeviceMemoryHeap[SGX_KERNEL_CODE_HEAP_ID].ui32Attribs = PVRSRV_HAP_WRITECOMBINE + | PVRSRV_MEM_RAM_BACKED_ALLOCATION + | PVRSRV_HAP_MULTI_PROCESS; + psDeviceMemoryHeap[SGX_KERNEL_CODE_HEAP_ID].pszName = "Kernel Code"; + psDeviceMemoryHeap[SGX_KERNEL_CODE_HEAP_ID].pszBSName = "Kernel Code BS"; + psDeviceMemoryHeap[SGX_KERNEL_CODE_HEAP_ID].DevMemHeapType = DEVICE_MEMORY_HEAP_SHARED_EXPORTED; + + psDeviceMemoryHeap[SGX_KERNEL_CODE_HEAP_ID].ui32DataPageSize = SGX_MMU_PAGE_SIZE; + + + psDeviceMemoryHeap[SGX_KERNEL_DATA_HEAP_ID].ui32HeapID = HEAP_ID( PVRSRV_DEVICE_TYPE_SGX ,SGX_KERNEL_DATA_HEAP_ID); + psDeviceMemoryHeap[SGX_KERNEL_DATA_HEAP_ID].sDevVAddrBase.uiAddr = SGX_KERNEL_DATA_HEAP_BASE; + psDeviceMemoryHeap[SGX_KERNEL_DATA_HEAP_ID].ui32HeapSize = SGX_KERNEL_DATA_HEAP_SIZE; + psDeviceMemoryHeap[SGX_KERNEL_DATA_HEAP_ID].ui32Attribs = PVRSRV_HAP_WRITECOMBINE + | PVRSRV_MEM_RAM_BACKED_ALLOCATION + | PVRSRV_HAP_MULTI_PROCESS; + psDeviceMemoryHeap[SGX_KERNEL_DATA_HEAP_ID].pszName = "KernelData"; + psDeviceMemoryHeap[SGX_KERNEL_DATA_HEAP_ID].pszBSName = "KernelData BS"; + psDeviceMemoryHeap[SGX_KERNEL_DATA_HEAP_ID].DevMemHeapType = DEVICE_MEMORY_HEAP_SHARED_EXPORTED; + + psDeviceMemoryHeap[SGX_KERNEL_DATA_HEAP_ID].ui32DataPageSize = SGX_MMU_PAGE_SIZE; + + + psDeviceMemoryHeap[SGX_PIXELSHADER_HEAP_ID].ui32HeapID = HEAP_ID( PVRSRV_DEVICE_TYPE_SGX ,SGX_PIXELSHADER_HEAP_ID); + psDeviceMemoryHeap[SGX_PIXELSHADER_HEAP_ID].sDevVAddrBase.uiAddr = SGX_PIXELSHADER_HEAP_BASE; + psDeviceMemoryHeap[SGX_PIXELSHADER_HEAP_ID].ui32HeapSize = SGX_PIXELSHADER_HEAP_SIZE; + psDeviceMemoryHeap[SGX_PIXELSHADER_HEAP_ID].ui32Attribs = PVRSRV_HAP_WRITECOMBINE + | PVRSRV_MEM_RAM_BACKED_ALLOCATION + | PVRSRV_HAP_SINGLE_PROCESS; + psDeviceMemoryHeap[SGX_PIXELSHADER_HEAP_ID].pszName = "PixelShaderUSSE"; + psDeviceMemoryHeap[SGX_PIXELSHADER_HEAP_ID].pszBSName = "PixelShaderUSSE BS"; + psDeviceMemoryHeap[SGX_PIXELSHADER_HEAP_ID].DevMemHeapType = DEVICE_MEMORY_HEAP_PERCONTEXT; + + psDeviceMemoryHeap[SGX_PIXELSHADER_HEAP_ID].ui32DataPageSize = SGX_MMU_PAGE_SIZE; + + + psDeviceMemoryHeap[SGX_VERTEXSHADER_HEAP_ID].ui32HeapID = HEAP_ID( PVRSRV_DEVICE_TYPE_SGX ,SGX_VERTEXSHADER_HEAP_ID); + psDeviceMemoryHeap[SGX_VERTEXSHADER_HEAP_ID].sDevVAddrBase.uiAddr = SGX_VERTEXSHADER_HEAP_BASE; + psDeviceMemoryHeap[SGX_VERTEXSHADER_HEAP_ID].ui32HeapSize = SGX_VERTEXSHADER_HEAP_SIZE; + psDeviceMemoryHeap[SGX_VERTEXSHADER_HEAP_ID].ui32Attribs = PVRSRV_HAP_WRITECOMBINE + | PVRSRV_MEM_RAM_BACKED_ALLOCATION + | PVRSRV_HAP_SINGLE_PROCESS; + psDeviceMemoryHeap[SGX_VERTEXSHADER_HEAP_ID].pszName = "VertexShaderUSSE"; + psDeviceMemoryHeap[SGX_VERTEXSHADER_HEAP_ID].pszBSName = "VertexShaderUSSE BS"; + psDeviceMemoryHeap[SGX_VERTEXSHADER_HEAP_ID].DevMemHeapType = DEVICE_MEMORY_HEAP_PERCONTEXT; + + psDeviceMemoryHeap[SGX_VERTEXSHADER_HEAP_ID].ui32DataPageSize = SGX_MMU_PAGE_SIZE; + + + psDeviceMemoryHeap[SGX_PDSPIXEL_CODEDATA_HEAP_ID].ui32HeapID = HEAP_ID( PVRSRV_DEVICE_TYPE_SGX ,SGX_PDSPIXEL_CODEDATA_HEAP_ID); + psDeviceMemoryHeap[SGX_PDSPIXEL_CODEDATA_HEAP_ID].sDevVAddrBase.uiAddr = SGX_PDSPIXEL_CODEDATA_HEAP_BASE; + psDeviceMemoryHeap[SGX_PDSPIXEL_CODEDATA_HEAP_ID].ui32HeapSize = SGX_PDSPIXEL_CODEDATA_HEAP_SIZE; + psDeviceMemoryHeap[SGX_PDSPIXEL_CODEDATA_HEAP_ID].ui32Attribs = PVRSRV_HAP_WRITECOMBINE + | PVRSRV_MEM_RAM_BACKED_ALLOCATION + | PVRSRV_HAP_SINGLE_PROCESS; + psDeviceMemoryHeap[SGX_PDSPIXEL_CODEDATA_HEAP_ID].pszName = "PDSPixelCodeData"; + psDeviceMemoryHeap[SGX_PDSPIXEL_CODEDATA_HEAP_ID].pszBSName = "PDSPixelCodeData BS"; + psDeviceMemoryHeap[SGX_PDSPIXEL_CODEDATA_HEAP_ID].DevMemHeapType = DEVICE_MEMORY_HEAP_PERCONTEXT; + + psDeviceMemoryHeap[SGX_PDSPIXEL_CODEDATA_HEAP_ID].ui32DataPageSize = SGX_MMU_PAGE_SIZE; + + + psDeviceMemoryHeap[SGX_PDSVERTEX_CODEDATA_HEAP_ID].ui32HeapID = HEAP_ID( PVRSRV_DEVICE_TYPE_SGX ,SGX_PDSVERTEX_CODEDATA_HEAP_ID); + psDeviceMemoryHeap[SGX_PDSVERTEX_CODEDATA_HEAP_ID].sDevVAddrBase.uiAddr = SGX_PDSVERTEX_CODEDATA_HEAP_BASE; + psDeviceMemoryHeap[SGX_PDSVERTEX_CODEDATA_HEAP_ID].ui32HeapSize = SGX_PDSVERTEX_CODEDATA_HEAP_SIZE; + psDeviceMemoryHeap[SGX_PDSVERTEX_CODEDATA_HEAP_ID].ui32Attribs = PVRSRV_HAP_WRITECOMBINE + | PVRSRV_MEM_RAM_BACKED_ALLOCATION + | PVRSRV_HAP_SINGLE_PROCESS; + psDeviceMemoryHeap[SGX_PDSVERTEX_CODEDATA_HEAP_ID].pszName = "PDSVertexCodeData"; + psDeviceMemoryHeap[SGX_PDSVERTEX_CODEDATA_HEAP_ID].pszBSName = "PDSVertexCodeData BS"; + psDeviceMemoryHeap[SGX_PDSVERTEX_CODEDATA_HEAP_ID].DevMemHeapType = DEVICE_MEMORY_HEAP_PERCONTEXT; + + psDeviceMemoryHeap[SGX_PDSVERTEX_CODEDATA_HEAP_ID].ui32DataPageSize = SGX_MMU_PAGE_SIZE; + + + psDeviceMemoryHeap[SGX_SYNCINFO_HEAP_ID].ui32HeapID = HEAP_ID( PVRSRV_DEVICE_TYPE_SGX ,SGX_SYNCINFO_HEAP_ID); + psDeviceMemoryHeap[SGX_SYNCINFO_HEAP_ID].sDevVAddrBase.uiAddr = SGX_SYNCINFO_HEAP_BASE; + psDeviceMemoryHeap[SGX_SYNCINFO_HEAP_ID].ui32HeapSize = SGX_SYNCINFO_HEAP_SIZE; + psDeviceMemoryHeap[SGX_SYNCINFO_HEAP_ID].ui32Attribs = PVRSRV_HAP_WRITECOMBINE + | PVRSRV_MEM_RAM_BACKED_ALLOCATION + | PVRSRV_HAP_MULTI_PROCESS; + psDeviceMemoryHeap[SGX_SYNCINFO_HEAP_ID].pszName = "CacheCoherent"; + psDeviceMemoryHeap[SGX_SYNCINFO_HEAP_ID].pszBSName = "CacheCoherent BS"; + + psDeviceMemoryHeap[SGX_SYNCINFO_HEAP_ID].DevMemHeapType = DEVICE_MEMORY_HEAP_SHARED_EXPORTED; + + psDeviceMemoryHeap[SGX_SYNCINFO_HEAP_ID].ui32DataPageSize = SGX_MMU_PAGE_SIZE; + + + psDeviceMemoryHeap[SGX_3DPARAMETERS_HEAP_ID].ui32HeapID = HEAP_ID(PVRSRV_DEVICE_TYPE_SGX, SGX_3DPARAMETERS_HEAP_ID); + psDeviceMemoryHeap[SGX_3DPARAMETERS_HEAP_ID].sDevVAddrBase.uiAddr = SGX_3DPARAMETERS_HEAP_BASE; + psDeviceMemoryHeap[SGX_3DPARAMETERS_HEAP_ID].ui32HeapSize = SGX_3DPARAMETERS_HEAP_SIZE; + psDeviceMemoryHeap[SGX_3DPARAMETERS_HEAP_ID].pszName = "3DParameters"; + psDeviceMemoryHeap[SGX_3DPARAMETERS_HEAP_ID].pszBSName = "3DParameters BS"; +#if defined(SUPPORT_PERCONTEXT_PB) + psDeviceMemoryHeap[SGX_3DPARAMETERS_HEAP_ID].ui32Attribs = PVRSRV_HAP_WRITECOMBINE + | PVRSRV_MEM_RAM_BACKED_ALLOCATION + | PVRSRV_HAP_SINGLE_PROCESS; + psDeviceMemoryHeap[SGX_3DPARAMETERS_HEAP_ID].DevMemHeapType = DEVICE_MEMORY_HEAP_PERCONTEXT; +#else + psDeviceMemoryHeap[SGX_3DPARAMETERS_HEAP_ID].ui32Attribs = PVRSRV_HAP_WRITECOMBINE + | PVRSRV_MEM_RAM_BACKED_ALLOCATION + | PVRSRV_HAP_MULTI_PROCESS; + psDeviceMemoryHeap[SGX_3DPARAMETERS_HEAP_ID].DevMemHeapType = DEVICE_MEMORY_HEAP_SHARED_EXPORTED; +#endif + + psDeviceMemoryHeap[SGX_3DPARAMETERS_HEAP_ID].ui32DataPageSize = SGX_MMU_PAGE_SIZE; + +#if defined(SUPPORT_SGX_GENERAL_MAPPING_HEAP) + + psDeviceMemoryHeap[SGX_GENERAL_MAPPING_HEAP_ID].ui32HeapID = HEAP_ID( PVRSRV_DEVICE_TYPE_SGX , SGX_GENERAL_MAPPING_HEAP_ID); + psDeviceMemoryHeap[SGX_GENERAL_MAPPING_HEAP_ID].sDevVAddrBase.uiAddr = SGX_GENERAL_MAPPING_HEAP_BASE; + psDeviceMemoryHeap[SGX_GENERAL_MAPPING_HEAP_ID].ui32HeapSize = SGX_GENERAL_MAPPING_HEAP_SIZE; + psDeviceMemoryHeap[SGX_GENERAL_MAPPING_HEAP_ID].ui32Attribs = PVRSRV_HAP_WRITECOMBINE | PVRSRV_HAP_MULTI_PROCESS; + psDeviceMemoryHeap[SGX_GENERAL_MAPPING_HEAP_ID].pszName = "GeneralMapping"; + psDeviceMemoryHeap[SGX_GENERAL_MAPPING_HEAP_ID].pszBSName = "GeneralMapping BS"; +#if defined(SGX_FEATURE_2D_HARDWARE) && defined(SGX_FEATURE_MULTIPLE_MEM_CONTEXTS) && defined(FIX_HW_BRN_23410) + + + + + + + + psDeviceMemoryHeap[SGX_GENERAL_MAPPING_HEAP_ID].DevMemHeapType = DEVICE_MEMORY_HEAP_SHARED_EXPORTED; +#else + psDeviceMemoryHeap[SGX_GENERAL_MAPPING_HEAP_ID].DevMemHeapType = DEVICE_MEMORY_HEAP_PERCONTEXT; +#endif + + psDeviceMemoryHeap[SGX_GENERAL_MAPPING_HEAP_ID].ui32DataPageSize = SGX_MMU_PAGE_SIZE; +#endif + +#if defined(SGX_FEATURE_2D_HARDWARE) + + + psDeviceMemoryHeap[SGX_2D_HEAP_ID].ui32HeapID = HEAP_ID( PVRSRV_DEVICE_TYPE_SGX ,SGX_2D_HEAP_ID); + psDeviceMemoryHeap[SGX_2D_HEAP_ID].sDevVAddrBase.uiAddr = SGX_2D_HEAP_BASE; + psDeviceMemoryHeap[SGX_2D_HEAP_ID].ui32HeapSize = SGX_2D_HEAP_SIZE; + psDeviceMemoryHeap[SGX_2D_HEAP_ID].ui32Attribs = PVRSRV_HAP_WRITECOMBINE + | PVRSRV_MEM_RAM_BACKED_ALLOCATION + | PVRSRV_HAP_SINGLE_PROCESS; + psDeviceMemoryHeap[SGX_2D_HEAP_ID].pszName = "2D"; + psDeviceMemoryHeap[SGX_2D_HEAP_ID].pszBSName = "2D BS"; + + psDeviceMemoryHeap[SGX_2D_HEAP_ID].DevMemHeapType = DEVICE_MEMORY_HEAP_SHARED_EXPORTED; + + psDeviceMemoryHeap[SGX_2D_HEAP_ID].ui32DataPageSize = SGX_MMU_PAGE_SIZE; +#endif + + + return PVRSRV_OK; +} + +IMG_EXPORT +PVRSRV_ERROR SGXGetClientInfoKM(IMG_HANDLE hDevCookie, + SGX_CLIENT_INFO* psClientInfo) +{ + PVRSRV_SGXDEV_INFO *psDevInfo = (PVRSRV_SGXDEV_INFO *)((PVRSRV_DEVICE_NODE *)hDevCookie)->pvDevice; + + + + psDevInfo->ui32ClientRefCount++; +#ifdef PDUMP + + + if(psDevInfo->ui32ClientRefCount == 1) + { + psDevInfo->psKernelCCBInfo->ui32CCBDumpWOff = 0; + } + +#endif + + + psClientInfo->ui32ProcessID = OSGetCurrentProcessIDKM(); + + + + OSMemCopy(&psClientInfo->asDevData, &psDevInfo->asSGXDevData, sizeof(psClientInfo->asDevData)); + + + return PVRSRV_OK; +} + +PVRSRV_ERROR SGXDevInitCompatCheck(PVRSRV_DEVICE_NODE *psDeviceNode) +{ + PVRSRV_SGXDEV_INFO *psDevInfo; + PPVRSRV_KERNEL_MEM_INFO psMemInfo; + PVRSRV_ERROR eError; +#if !defined(NO_HARDWARE) + IMG_UINT32 ui32BuildOptions, ui32BuildOptionsMismatch; + PVRSRV_SGX_MISCINFO_FEATURES *psSGXFeatures; +#endif + + + if(psDeviceNode->sDevId.eDeviceType != PVRSRV_DEVICE_TYPE_SGX) + { + PVR_DPF((PVR_DBG_ERROR, "SGXDevInitCompatCheck: Device not of type SGX")); + eError = PVRSRV_ERROR_INVALID_PARAMS; + goto exit; + } + psDevInfo = psDeviceNode->pvDevice; + psMemInfo = psDevInfo->psKernelSGXMiscMemInfo; + +#if !defined (NO_HARDWARE) + + eError = SGXGetBuildInfoKM(psDevInfo, psDeviceNode); + if(eError != PVRSRV_OK) + { + PVR_DPF((PVR_DBG_ERROR, "SGXDevInitCompatCheck: Unable to validate device DDK version")); + goto exit; + } + psSGXFeatures = &((PVRSRV_SGX_MISCINFO_INFO*)(psMemInfo->pvLinAddrKM))->sSGXFeatures; + if( (psSGXFeatures->ui32DDKVersion != + ((PVRVERSION_MAJ << 16) | + (PVRVERSION_MIN << 8) | + PVRVERSION_BRANCH) ) || + (psSGXFeatures->ui32DDKBuild != PVRVERSION_BUILD) ) + { + PVR_DPF((PVR_DBG_ERROR, "SGXDevInitCompatCheck: Incompatible driver DDK revision (%ld)/device DDK revision (%ld).", + PVRVERSION_BUILD, psSGXFeatures->ui32DDKBuild)); + eError = PVRSRV_ERROR_DDK_VERSION_MISMATCH; + goto exit; + } + else + { + PVR_DPF((PVR_DBG_WARNING, "(Success) SGXInit: driver DDK (%ld) and device DDK (%ld) match", + PVRVERSION_BUILD, psSGXFeatures->ui32DDKBuild)); + } + + + + ui32BuildOptions = psSGXFeatures->ui32BuildOptions; + if (ui32BuildOptions != (SGX_BUILD_OPTIONS)) + { + ui32BuildOptionsMismatch = ui32BuildOptions ^ (SGX_BUILD_OPTIONS); + if ( ((SGX_BUILD_OPTIONS) & ui32BuildOptionsMismatch) != 0) + { + PVR_DPF((PVR_DBG_ERROR, "SGXInit: Mismatch in driver and microkernel build options; " + "extra options present in driver: (0x%lx)", + (SGX_BUILD_OPTIONS) & ui32BuildOptionsMismatch )); + } + + if ( (ui32BuildOptions & ui32BuildOptionsMismatch) != 0) + { + PVR_DPF((PVR_DBG_ERROR, "SGXInit: Mismatch in driver and microkernel build options; " + "extra options present in microkernel: (0x%lx)", + ui32BuildOptions & ui32BuildOptionsMismatch )); + } + eError = PVRSRV_ERROR_BUILD_MISMATCH; + goto exit; + } + else + { + PVR_DPF((PVR_DBG_WARNING, "(Success) SGXInit: Driver and microkernel build options match.")); + } + +#endif + eError = PVRSRV_OK; +exit: +#if defined(IGNORE_SGX_INIT_COMPATIBILITY_CHECK) + return PVRSRV_OK; +#else + return eError; +#endif +} + +static +PVRSRV_ERROR SGXGetBuildInfoKM(PVRSRV_SGXDEV_INFO *psDevInfo, + PVRSRV_DEVICE_NODE *psDeviceNode) +{ + PVRSRV_ERROR eError; + SGXMKIF_COMMAND sCommandData; + PVRSRV_SGX_MISCINFO_INFO *psSGXMiscInfoInt; + PVRSRV_SGX_MISCINFO_FEATURES *psSGXFeatures; + + PPVRSRV_KERNEL_MEM_INFO psMemInfo = psDevInfo->psKernelSGXMiscMemInfo; + + if (! psMemInfo->pvLinAddrKM) + { + PVR_DPF((PVR_DBG_ERROR, "SGXGetMiscInfoKM: Invalid address.")); + return PVRSRV_ERROR_INVALID_PARAMS; + } + psSGXMiscInfoInt = psMemInfo->pvLinAddrKM; + psSGXMiscInfoInt->ui32MiscInfoFlags &= ~PVRSRV_USSE_MISCINFO_READY; + psSGXFeatures = &psSGXMiscInfoInt->sSGXFeatures; + + + OSMemSet(psMemInfo->pvLinAddrKM, 0, + sizeof(PVRSRV_SGX_MISCINFO_INFO)); + + + sCommandData.ui32Data[1] = psMemInfo->sDevVAddr.uiAddr; + + eError = SGXScheduleCCBCommandKM(psDeviceNode, + SGXMKIF_COMMAND_REQUEST_SGXMISCINFO, + &sCommandData, + KERNEL_ID, + 0); + + if (eError != PVRSRV_OK) + { + PVR_DPF((PVR_DBG_ERROR, "SGXGetMiscInfoKM: SGXScheduleCCBCommandKM failed.")); + return eError; + } + + +#if !defined(NO_HARDWARE) + { + IMG_BOOL bTimeout = IMG_TRUE; + + LOOP_UNTIL_TIMEOUT(MAX_HW_TIME_US) + { + if ((psSGXMiscInfoInt->ui32MiscInfoFlags & PVRSRV_USSE_MISCINFO_READY) != 0) + { + bTimeout = IMG_FALSE; + break; + } + } END_LOOP_UNTIL_TIMEOUT(); + + if(bTimeout) + { + return PVRSRV_ERROR_TIMEOUT; + } + } +#endif + + return PVRSRV_OK; +} + +IMG_EXPORT +PVRSRV_ERROR SGXGetMiscInfoKM(PVRSRV_SGXDEV_INFO *psDevInfo, + SGX_MISC_INFO *psMiscInfo, + PVRSRV_DEVICE_NODE *psDeviceNode) +{ + switch(psMiscInfo->eRequest) + { + case SGX_MISC_INFO_REQUEST_CLOCKSPEED: + { + psMiscInfo->uData.ui32SGXClockSpeed = psDevInfo->ui32CoreClockSpeed; + return PVRSRV_OK; + } + + case SGX_MISC_INFO_REQUEST_SGXREV: + { + PVRSRV_SGX_MISCINFO_FEATURES *psSGXFeatures; + PPVRSRV_KERNEL_MEM_INFO psMemInfo = psDevInfo->psKernelSGXMiscMemInfo; + + SGXGetBuildInfoKM(psDevInfo, psDeviceNode); + psSGXFeatures = &((PVRSRV_SGX_MISCINFO_INFO*)(psMemInfo->pvLinAddrKM))->sSGXFeatures; + + + psMiscInfo->uData.sSGXFeatures = *psSGXFeatures; + + + PVR_DPF((PVR_DBG_MESSAGE, "SGXGetMiscInfoKM: Core 0x%lx, sw ID 0x%lx, sw Rev 0x%lx\n", + psSGXFeatures->ui32CoreRev, + psSGXFeatures->ui32CoreIdSW, + psSGXFeatures->ui32CoreRevSW)); + PVR_DPF((PVR_DBG_MESSAGE, "SGXGetMiscInfoKM: DDK version 0x%lx, DDK build 0x%lx\n", + psSGXFeatures->ui32DDKVersion, + psSGXFeatures->ui32DDKBuild)); + + + return PVRSRV_OK; + } + + case SGX_MISC_INFO_REQUEST_DRIVER_SGXREV: + { + PPVRSRV_KERNEL_MEM_INFO psMemInfo = psDevInfo->psKernelSGXMiscMemInfo; + PVRSRV_SGX_MISCINFO_FEATURES *psSGXFeatures; + + psSGXFeatures = &((PVRSRV_SGX_MISCINFO_INFO*)(psMemInfo->pvLinAddrKM))->sSGXFeatures; + + + OSMemSet(psMemInfo->pvLinAddrKM, 0, + sizeof(PVRSRV_SGX_MISCINFO_INFO)); + + psSGXFeatures->ui32DDKVersion = + (PVRVERSION_MAJ << 16) | + (PVRVERSION_MIN << 8) | + PVRVERSION_BRANCH; + psSGXFeatures->ui32DDKBuild = PVRVERSION_BUILD; + + + psMiscInfo->uData.sSGXFeatures = *psSGXFeatures; + return PVRSRV_OK; + } + +#ifdef SUPPORT_SGX_HWPERF + case SGX_MISC_INFO_REQUEST_SET_HWPERF_STATUS: + { + SGXMKIF_HWPERF_CB *psHWPerfCB = psDevInfo->psKernelHWPerfCBMemInfo->pvLinAddrKM; + IMG_UINT ui32MatchingFlags; + + + if ((psMiscInfo->uData.ui32NewHWPerfStatus & ~(PVRSRV_SGX_HWPERF_GRAPHICS_ON | PVRSRV_SGX_HWPERF_MK_EXECUTION_ON)) != 0) + { + return PVRSRV_ERROR_INVALID_PARAMS; + } + + + ui32MatchingFlags = psMiscInfo->uData.ui32NewHWPerfStatus & psDevInfo->psSGXHostCtl->ui32HWPerfFlags; + if((ui32MatchingFlags & PVRSRV_SGX_HWPERF_GRAPHICS_ON) == 0UL) + { + psHWPerfCB->ui32OrdinalGRAPHICS = 0xffffffff; + } + if((ui32MatchingFlags & PVRSRV_SGX_HWPERF_MK_EXECUTION_ON) == 0UL) + { + psHWPerfCB->ui32OrdinalMK_EXECUTION = 0xffffffffUL; + } + + + psDevInfo->psSGXHostCtl->ui32HWPerfFlags = psMiscInfo->uData.ui32NewHWPerfStatus; + #if defined(PDUMP) + PDUMPCOMMENTWITHFLAGS(PDUMP_FLAGS_CONTINUOUS, "SGX ukernel HWPerf status %lu\n", + psDevInfo->psSGXHostCtl->ui32HWPerfFlags); + PDUMPMEM(IMG_NULL, psDevInfo->psKernelSGXHostCtlMemInfo, + offsetof(SGXMKIF_HOST_CTL, ui32HWPerfFlags), + sizeof(psDevInfo->psSGXHostCtl->ui32HWPerfFlags), PDUMP_FLAGS_CONTINUOUS, + MAKEUNIQUETAG(psDevInfo->psKernelSGXHostCtlMemInfo)); + #endif + + return PVRSRV_OK; + } + case SGX_MISC_INFO_REQUEST_HWPERF_CB_ON: + { + + SGXMKIF_HWPERF_CB *psHWPerfCB = psDevInfo->psKernelHWPerfCBMemInfo->pvLinAddrKM; + psHWPerfCB->ui32OrdinalGRAPHICS = 0xffffffffUL; + + psDevInfo->psSGXHostCtl->ui32HWPerfFlags |= PVRSRV_SGX_HWPERF_GRAPHICS_ON; + return PVRSRV_OK; + } + case SGX_MISC_INFO_REQUEST_HWPERF_CB_OFF: + { + + psDevInfo->psSGXHostCtl->ui32HWPerfFlags = 0; + return PVRSRV_OK; + } + case SGX_MISC_INFO_REQUEST_HWPERF_RETRIEVE_CB: + { + + SGX_MISC_INFO_HWPERF_RETRIEVE_CB *psRetrieve = &psMiscInfo->uData.sRetrieveCB; + SGXMKIF_HWPERF_CB *psHWPerfCB = psDevInfo->psKernelHWPerfCBMemInfo->pvLinAddrKM; + IMG_UINT i; + + for (i = 0; psHWPerfCB->ui32Woff != psHWPerfCB->ui32Roff && i < psRetrieve->ui32ArraySize; i++) + { + SGXMKIF_HWPERF_CB_ENTRY *psData = &psHWPerfCB->psHWPerfCBData[psHWPerfCB->ui32Roff]; + + + + psRetrieve->psHWPerfData[i].ui32FrameNo = psData->ui32FrameNo; + psRetrieve->psHWPerfData[i].ui32Type = (psData->ui32Type & PVRSRV_SGX_HWPERF_TYPE_OP_MASK); + psRetrieve->psHWPerfData[i].ui32StartTime = psData->ui32Time; + psRetrieve->psHWPerfData[i].ui32StartTimeWraps = psData->ui32TimeWraps; + psRetrieve->psHWPerfData[i].ui32EndTime = psData->ui32Time; + psRetrieve->psHWPerfData[i].ui32EndTimeWraps = psData->ui32TimeWraps; + psRetrieve->psHWPerfData[i].ui32ClockSpeed = psDevInfo->ui32CoreClockSpeed; + psRetrieve->psHWPerfData[i].ui32TimeMax = psDevInfo->ui32uKernelTimerClock; + psHWPerfCB->ui32Roff = (psHWPerfCB->ui32Roff + 1) & (SGXMKIF_HWPERF_CB_SIZE - 1); + } + psRetrieve->ui32DataCount = i; + psRetrieve->ui32Time = OSClockus(); + return PVRSRV_OK; + } +#endif + default: + { + + return PVRSRV_ERROR_INVALID_PARAMS; + } + } +} + +#if defined(SUPPORT_SGX_HWPERF) +IMG_EXPORT +PVRSRV_ERROR SGXReadDiffCountersKM(IMG_HANDLE hDevHandle, + IMG_UINT32 ui32Reg, + IMG_UINT32 *pui32Old, + IMG_BOOL bNew, + IMG_UINT32 ui32New, + IMG_UINT32 ui32NewReset, + IMG_UINT32 ui32CountersReg, + IMG_UINT32 *pui32Time, + IMG_BOOL *pbActive, + PVRSRV_SGXDEV_DIFF_INFO *psDiffs) +{ + PVRSRV_ERROR eError; + SYS_DATA *psSysData; + PVRSRV_POWER_DEV *psPowerDevice; + IMG_BOOL bPowered = IMG_FALSE; + PVRSRV_DEVICE_NODE *psDeviceNode = hDevHandle; + PVRSRV_SGXDEV_INFO *psDevInfo = psDeviceNode->pvDevice; + + + if(bNew) + { + psDevInfo->ui32HWGroupRequested = ui32New; + } + psDevInfo->ui32HWReset |= ui32NewReset; + + + eError = PVRSRVPowerLock(KERNEL_ID, IMG_FALSE); + if (eError != PVRSRV_OK) + { + return eError; + } + + SysAcquireData(&psSysData); + + + psPowerDevice = psSysData->psPowerDeviceList; + while (psPowerDevice) + { + if (psPowerDevice->ui32DeviceIndex == psDeviceNode->sDevId.ui32DeviceIndex) + { + bPowered = (IMG_BOOL)(psPowerDevice->eCurrentPowerState == PVRSRV_POWER_STATE_D0); + break; + } + + psPowerDevice = psPowerDevice->psNext; + } + + + *pbActive = bPowered; + + + + { + PVRSRV_SGXDEV_DIFF_INFO sNew, *psPrev = &psDevInfo->sDiffInfo; + IMG_UINT32 i; + + sNew.ui32Time[0] = OSClockus(); + + + *pui32Time = sNew.ui32Time[0]; + + + if(sNew.ui32Time[0] != psPrev->ui32Time[0] && bPowered) + { + + *pui32Old = OSReadHWReg(psDevInfo->pvRegsBaseKM, ui32Reg); + + for (i = 0; i < PVRSRV_SGX_DIFF_NUM_COUNTERS; ++i) + { + sNew.aui32Counters[i] = OSReadHWReg(psDevInfo->pvRegsBaseKM, ui32CountersReg + (i * 4)); + } + + + + if (psDevInfo->ui32HWGroupRequested != *pui32Old) + { + + if(psDevInfo->ui32HWReset != 0) + { + OSWriteHWReg(psDevInfo->pvRegsBaseKM, ui32Reg, psDevInfo->ui32HWGroupRequested | psDevInfo->ui32HWReset); + psDevInfo->ui32HWReset = 0; + } + + OSWriteHWReg(psDevInfo->pvRegsBaseKM, ui32Reg, psDevInfo->ui32HWGroupRequested); + } + + sNew.ui32Marker[0] = psDevInfo->ui32KickTACounter; + sNew.ui32Marker[1] = psDevInfo->ui32KickTARenderCounter; + + sNew.ui32Time[1] = psDevInfo->psSGXHostCtl->ui32TimeWraps; + + + for (i = 0; i < PVRSRV_SGX_DIFF_NUM_COUNTERS; ++i) + { + psDiffs->aui32Counters[i] = sNew.aui32Counters[i] - psPrev->aui32Counters[i]; + } + + psDiffs->ui32Marker[0] = sNew.ui32Marker[0] - psPrev->ui32Marker[0]; + psDiffs->ui32Marker[1] = sNew.ui32Marker[1] - psPrev->ui32Marker[1]; + + psDiffs->ui32Time[0] = sNew.ui32Time[0] - psPrev->ui32Time[0]; + psDiffs->ui32Time[1] = sNew.ui32Time[1] - psPrev->ui32Time[1]; + + + *psPrev = sNew; + } + else + { + + for (i = 0; i < PVRSRV_SGX_DIFF_NUM_COUNTERS; ++i) + { + psDiffs->aui32Counters[i] = 0; + } + + psDiffs->ui32Marker[0] = 0; + psDiffs->ui32Marker[1] = 0; + + psDiffs->ui32Time[0] = 0; + psDiffs->ui32Time[1] = 0; + } + } + + + PVRSRVPowerUnlock(KERNEL_ID); + +#if defined(SUPPORT_ACTIVE_POWER_MANAGEMENT) + SGXTestActivePowerEvent(psDeviceNode, KERNEL_ID); +#endif + + return eError; +} + + +IMG_EXPORT +PVRSRV_ERROR SGXReadHWPerfCBKM(IMG_HANDLE hDevHandle, + IMG_UINT32 ui32ArraySize, + PVRSRV_SGX_HWPERF_CB_ENTRY *psClientHWPerfEntry, + IMG_UINT32 *pui32DataCount, + IMG_UINT32 *pui32ClockSpeed, + IMG_UINT32 *pui32HostTimeStamp) +{ + PVRSRV_ERROR eError = PVRSRV_OK; + PVRSRV_DEVICE_NODE *psDeviceNode = hDevHandle; + PVRSRV_SGXDEV_INFO *psDevInfo = psDeviceNode->pvDevice; + SGXMKIF_HWPERF_CB *psHWPerfCB = psDevInfo->psKernelHWPerfCBMemInfo->pvLinAddrKM; + IMG_UINT i; + + for (i = 0; + psHWPerfCB->ui32Woff != psHWPerfCB->ui32Roff && i < ui32ArraySize; + i++) + { + SGXMKIF_HWPERF_CB_ENTRY *psMKPerfEntry = &psHWPerfCB->psHWPerfCBData[psHWPerfCB->ui32Roff]; + + psClientHWPerfEntry[i].ui32FrameNo = psMKPerfEntry->ui32FrameNo; + psClientHWPerfEntry[i].ui32Type = psMKPerfEntry->ui32Type; + psClientHWPerfEntry[i].ui32Ordinal = psMKPerfEntry->ui32Ordinal; + psClientHWPerfEntry[i].ui32Clocksx16 = SGXConvertTimeStamp(psDevInfo, + psMKPerfEntry->ui32TimeWraps, + psMKPerfEntry->ui32Time); + OSMemCopy(&psClientHWPerfEntry[i].ui32Counters[0], + &psMKPerfEntry->ui32Counters[0], + sizeof(psMKPerfEntry->ui32Counters)); + + psHWPerfCB->ui32Roff = (psHWPerfCB->ui32Roff + 1) & (SGXMKIF_HWPERF_CB_SIZE - 1); + } + + *pui32DataCount = i; + *pui32ClockSpeed = psDevInfo->ui32CoreClockSpeed; + *pui32HostTimeStamp = OSClockus(); + + return eError; +} +#else +#endif + + diff --git a/services4/srvkm/devices/sgx/sgxkick.c b/services4/srvkm/devices/sgx/sgxkick.c new file mode 100644 index 0000000..0d5cf4f --- /dev/null +++ b/services4/srvkm/devices/sgx/sgxkick.c @@ -0,0 +1,522 @@ +/********************************************************************** + * + * Copyright(c) 2008 Imagination Technologies Ltd. All rights reserved. + * + * This program is free software; you can redistribute it and/or modify it + * under the terms and conditions of the GNU General Public License, + * version 2, as published by the Free Software Foundation. + * + * This program is distributed in the hope it will be useful but, except + * as otherwise stated in writing, without any warranty; without even the + * implied warranty of merchantability or fitness for a particular purpose. + * See the GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License along with + * this program; if not, write to the Free Software Foundation, Inc., + * 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA. + * + * The full GNU General Public License is included in this distribution in + * the file called "COPYING". + * + * Contact Information: + * Imagination Technologies Ltd. + * Home Park Estate, Kings Langley, Herts, WD4 8LZ, UK + * + ******************************************************************************/ + +#include +#include "services_headers.h" +#include "sgxinfo.h" +#include "sgxinfokm.h" +#if defined (PDUMP) +#include "sgxapi_km.h" +#include "pdump_km.h" +#endif +#include "sgx_bridge_km.h" +#include "osfunc.h" +#include "pvr_debug.h" +#include "sgxutils.h" + +IMG_EXPORT +PVRSRV_ERROR SGXDoKickKM(IMG_HANDLE hDevHandle, SGX_CCB_KICK *psCCBKick) +{ + PVRSRV_ERROR eError; + PVRSRV_KERNEL_SYNC_INFO *psSyncInfo; + PVRSRV_KERNEL_MEM_INFO *psCCBMemInfo = (PVRSRV_KERNEL_MEM_INFO *) psCCBKick->hCCBKernelMemInfo; + SGXMKIF_CMDTA_SHARED *psTACmd; + IMG_UINT32 i; +#if defined(SUPPORT_SGX_HWPERF) + PVRSRV_DEVICE_NODE *psDeviceNode; + PVRSRV_SGXDEV_INFO *psDevInfo; + + psDeviceNode = (PVRSRV_DEVICE_NODE *)hDevHandle; + psDevInfo = (PVRSRV_SGXDEV_INFO *)psDeviceNode->pvDevice; +#endif + +#if defined(SUPPORT_SGX_HWPERF) + if (psCCBKick->bKickRender) + { + ++psDevInfo->ui32KickTARenderCounter; + } + ++psDevInfo->ui32KickTACounter; +#endif + + if (!CCB_OFFSET_IS_VALID(SGXMKIF_CMDTA_SHARED, psCCBMemInfo, psCCBKick, ui32CCBOffset)) + { + PVR_DPF((PVR_DBG_ERROR, "SGXDoKickKM: Invalid CCB offset")); + return PVRSRV_ERROR_INVALID_PARAMS; + } + + + psTACmd = CCB_DATA_FROM_OFFSET(SGXMKIF_CMDTA_SHARED, psCCBMemInfo, psCCBKick, ui32CCBOffset); + + + if (psCCBKick->hTA3DSyncInfo) + { + psSyncInfo = (PVRSRV_KERNEL_SYNC_INFO *)psCCBKick->hTA3DSyncInfo; + psTACmd->sTA3DDependency.sWriteOpsCompleteDevVAddr = psSyncInfo->sWriteOpsCompleteDevVAddr; + + psTACmd->sTA3DDependency.ui32WriteOpsPendingVal = psSyncInfo->psSyncData->ui32WriteOpsPending; + + if (psCCBKick->bTADependency) + { + psSyncInfo->psSyncData->ui32WriteOpsPending++; + } + } + + if (psCCBKick->hTASyncInfo != IMG_NULL) + { + psSyncInfo = (PVRSRV_KERNEL_SYNC_INFO *)psCCBKick->hTASyncInfo; + + psTACmd->sTATQSyncReadOpsCompleteDevVAddr = psSyncInfo->sReadOpsCompleteDevVAddr; + psTACmd->sTATQSyncWriteOpsCompleteDevVAddr = psSyncInfo->sWriteOpsCompleteDevVAddr; + + psTACmd->ui32TATQSyncReadOpsPendingVal = psSyncInfo->psSyncData->ui32ReadOpsPending++; + psTACmd->ui32TATQSyncWriteOpsPendingVal = psSyncInfo->psSyncData->ui32WriteOpsPending; + } + + if (psCCBKick->h3DSyncInfo != IMG_NULL) + { + psSyncInfo = (PVRSRV_KERNEL_SYNC_INFO *)psCCBKick->h3DSyncInfo; + + psTACmd->s3DTQSyncReadOpsCompleteDevVAddr = psSyncInfo->sReadOpsCompleteDevVAddr; + psTACmd->s3DTQSyncWriteOpsCompleteDevVAddr = psSyncInfo->sWriteOpsCompleteDevVAddr; + + psTACmd->ui323DTQSyncReadOpsPendingVal = psSyncInfo->psSyncData->ui32ReadOpsPending++; + psTACmd->ui323DTQSyncWriteOpsPendingVal = psSyncInfo->psSyncData->ui32WriteOpsPending; + } + + psTACmd->ui32NumTAStatusVals = psCCBKick->ui32NumTAStatusVals; + if (psCCBKick->ui32NumTAStatusVals != 0) + { + + for (i = 0; i < psCCBKick->ui32NumTAStatusVals; i++) + { +#if defined(SUPPORT_SGX_NEW_STATUS_VALS) + psTACmd->sCtlTAStatusInfo[i] = psCCBKick->asTAStatusUpdate[i].sCtlStatus; +#else + psSyncInfo = (PVRSRV_KERNEL_SYNC_INFO *)psCCBKick->ahTAStatusSyncInfo[i]; + psTACmd->sCtlTAStatusInfo[i].sStatusDevAddr = psSyncInfo->sReadOpsCompleteDevVAddr; + psTACmd->sCtlTAStatusInfo[i].ui32StatusValue = psSyncInfo->psSyncData->ui32ReadOpsPending; +#endif + } + } + + psTACmd->ui32Num3DStatusVals = psCCBKick->ui32Num3DStatusVals; + if (psCCBKick->ui32Num3DStatusVals != 0) + { + + for (i = 0; i < psCCBKick->ui32Num3DStatusVals; i++) + { +#if defined(SUPPORT_SGX_NEW_STATUS_VALS) + psTACmd->sCtl3DStatusInfo[i] = psCCBKick->as3DStatusUpdate[i].sCtlStatus; +#else + psSyncInfo = (PVRSRV_KERNEL_SYNC_INFO *)psCCBKick->ah3DStatusSyncInfo[i]; + psTACmd->sCtl3DStatusInfo[i].sStatusDevAddr = psSyncInfo->sReadOpsCompleteDevVAddr; + psTACmd->sCtl3DStatusInfo[i].ui32StatusValue = psSyncInfo->psSyncData->ui32ReadOpsPending; +#endif + } + } + + + + psTACmd->ui32NumSrcSyncs = psCCBKick->ui32NumSrcSyncs; + for (i=0; iui32NumSrcSyncs; i++) + { + psSyncInfo = (PVRSRV_KERNEL_SYNC_INFO *) psCCBKick->ahSrcKernelSyncInfo[i]; + + psTACmd->asSrcSyncs[i].sWriteOpsCompleteDevVAddr = psSyncInfo->sWriteOpsCompleteDevVAddr; + psTACmd->asSrcSyncs[i].sReadOpsCompleteDevVAddr = psSyncInfo->sReadOpsCompleteDevVAddr; + + + psTACmd->asSrcSyncs[i].ui32ReadOpsPendingVal = psSyncInfo->psSyncData->ui32ReadOpsPending++; + + psTACmd->asSrcSyncs[i].ui32WriteOpsPendingVal = psSyncInfo->psSyncData->ui32WriteOpsPending; + + } + + if (psCCBKick->bFirstKickOrResume && psCCBKick->ui32NumDstSyncObjects > 0) + { + PVRSRV_KERNEL_MEM_INFO *psHWDstSyncListMemInfo = + (PVRSRV_KERNEL_MEM_INFO *)psCCBKick->hKernelHWSyncListMemInfo; + SGXMKIF_HWDEVICE_SYNC_LIST *psHWDeviceSyncList = psHWDstSyncListMemInfo->pvLinAddrKM; + IMG_UINT32 ui32NumDstSyncs = psCCBKick->ui32NumDstSyncObjects; + + PVR_ASSERT(((PVRSRV_KERNEL_MEM_INFO *)psCCBKick->hKernelHWSyncListMemInfo)->ui32AllocSize >= (sizeof(SGXMKIF_HWDEVICE_SYNC_LIST) + + (sizeof(PVRSRV_DEVICE_SYNC_OBJECT) * ui32NumDstSyncs))); + + psHWDeviceSyncList->ui32NumSyncObjects = ui32NumDstSyncs; +#if defined(PDUMP) + if (PDumpIsCaptureFrameKM()) + { + PDUMPCOMMENT("HWDeviceSyncList for TACmd\r\n"); + PDUMPMEM(IMG_NULL, + psHWDstSyncListMemInfo, + 0, + sizeof(SGXMKIF_HWDEVICE_SYNC_LIST), + 0, + MAKEUNIQUETAG(psHWDstSyncListMemInfo)); + } +#endif +#if defined(SGX_FEATURE_RENDER_TARGET_ARRAYS) + for (i=0; ipasDstSyncHandles[i]; +#else + psSyncInfo = (PVRSRV_KERNEL_SYNC_INFO *)psCCBKick->sDstSyncHandle; + i = 0; +#endif + if (psSyncInfo) + { + psHWDeviceSyncList->asSyncData[i].sWriteOpsCompleteDevVAddr = psSyncInfo->sWriteOpsCompleteDevVAddr; + psHWDeviceSyncList->asSyncData[i].sReadOpsCompleteDevVAddr = psSyncInfo->sReadOpsCompleteDevVAddr; + + psHWDeviceSyncList->asSyncData[i].ui32ReadOpsPendingVal = psSyncInfo->psSyncData->ui32ReadOpsPending; + psHWDeviceSyncList->asSyncData[i].ui32WriteOpsPendingVal = psSyncInfo->psSyncData->ui32WriteOpsPending++; + + #if defined(PDUMP) + if (PDumpIsCaptureFrameKM()) + { + IMG_UINT32 ui32ModifiedValue; + IMG_UINT32 ui32SyncOffset = offsetof(SGXMKIF_HWDEVICE_SYNC_LIST, asSyncData) + + (i * sizeof(PVRSRV_DEVICE_SYNC_OBJECT)); + IMG_UINT32 ui32WOpsOffset = ui32SyncOffset + + offsetof(PVRSRV_DEVICE_SYNC_OBJECT, ui32WriteOpsPendingVal); + IMG_UINT32 ui32ROpsOffset = ui32SyncOffset + + offsetof(PVRSRV_DEVICE_SYNC_OBJECT, ui32ReadOpsPendingVal); + + PDUMPCOMMENT("HWDeviceSyncObject for RT: %i\r\n", i); + + PDUMPMEM(IMG_NULL, + psHWDstSyncListMemInfo, + ui32SyncOffset, + sizeof(PVRSRV_DEVICE_SYNC_OBJECT), + 0, + MAKEUNIQUETAG(psHWDstSyncListMemInfo)); + + if ((psSyncInfo->psSyncData->ui32LastOpDumpVal == 0) && + (psSyncInfo->psSyncData->ui32LastReadOpDumpVal == 0)) + { + + PDUMPCOMMENT("Init RT ROpsComplete\r\n", i); + PDUMPMEM(&psSyncInfo->psSyncData->ui32LastReadOpDumpVal, + psSyncInfo->psSyncDataMemInfoKM, + offsetof(PVRSRV_SYNC_DATA, ui32ReadOpsComplete), + sizeof(psSyncInfo->psSyncData->ui32ReadOpsComplete), + 0, + MAKEUNIQUETAG(psSyncInfo->psSyncDataMemInfoKM)); + + PDUMPCOMMENT("Init RT WOpsComplete\r\n"); + PDUMPMEM(&psSyncInfo->psSyncData->ui32LastOpDumpVal, + psSyncInfo->psSyncDataMemInfoKM, + offsetof(PVRSRV_SYNC_DATA, ui32WriteOpsComplete), + sizeof(psSyncInfo->psSyncData->ui32WriteOpsComplete), + 0, + MAKEUNIQUETAG(psSyncInfo->psSyncDataMemInfoKM)); + } + + psSyncInfo->psSyncData->ui32LastOpDumpVal++; + + ui32ModifiedValue = psSyncInfo->psSyncData->ui32LastOpDumpVal - 1; + + PDUMPCOMMENT("Modify RT %d WOpPendingVal in HWDevSyncList\r\n", i); + + PDUMPMEM(&ui32ModifiedValue, + psHWDstSyncListMemInfo, + ui32WOpsOffset, + sizeof(IMG_UINT32), + 0, + MAKEUNIQUETAG(psHWDstSyncListMemInfo)); + + PDUMPCOMMENT("Modify RT %d ROpsPendingVal in HWDevSyncList\r\n", i); + + PDUMPMEM(&psSyncInfo->psSyncData->ui32LastReadOpDumpVal, + psHWDstSyncListMemInfo, + ui32ROpsOffset, + sizeof(IMG_UINT32), + 0, + MAKEUNIQUETAG(psHWDstSyncListMemInfo)); + } + #endif + } + else + { + psHWDeviceSyncList->asSyncData[i].sWriteOpsCompleteDevVAddr.uiAddr = 0; + psHWDeviceSyncList->asSyncData[i].sReadOpsCompleteDevVAddr.uiAddr = 0; + + psHWDeviceSyncList->asSyncData[i].ui32ReadOpsPendingVal = 0; + psHWDeviceSyncList->asSyncData[i].ui32WriteOpsPendingVal = 0; + } + } + } + +#if defined(PDUMP) + if (PDumpIsCaptureFrameKM()) + { + PDUMPCOMMENT("Shared part of TA command\r\n"); + + PDUMPMEM(psTACmd, + psCCBMemInfo, + psCCBKick->ui32CCBDumpWOff, + sizeof(SGXMKIF_CMDTA_SHARED), + 0, + MAKEUNIQUETAG(psCCBMemInfo)); + + for (i=0; iui32NumSrcSyncs; i++) + { + IMG_UINT32 ui32ModifiedValue; + psSyncInfo = (PVRSRV_KERNEL_SYNC_INFO *) psCCBKick->ahSrcKernelSyncInfo[i]; + + if ((psSyncInfo->psSyncData->ui32LastOpDumpVal == 0) && + (psSyncInfo->psSyncData->ui32LastReadOpDumpVal == 0)) + { + + PDUMPCOMMENT("Init RT ROpsComplete\r\n", i); + PDUMPMEM(&psSyncInfo->psSyncData->ui32LastReadOpDumpVal, + psSyncInfo->psSyncDataMemInfoKM, + offsetof(PVRSRV_SYNC_DATA, ui32ReadOpsComplete), + sizeof(psSyncInfo->psSyncData->ui32ReadOpsComplete), + 0, + MAKEUNIQUETAG(psSyncInfo->psSyncDataMemInfoKM)); + + PDUMPCOMMENT("Init RT WOpsComplete\r\n"); + PDUMPMEM(&psSyncInfo->psSyncData->ui32LastOpDumpVal, + psSyncInfo->psSyncDataMemInfoKM, + offsetof(PVRSRV_SYNC_DATA, ui32WriteOpsComplete), + sizeof(psSyncInfo->psSyncData->ui32WriteOpsComplete), + 0, + MAKEUNIQUETAG(psSyncInfo->psSyncDataMemInfoKM)); + } + + psSyncInfo->psSyncData->ui32LastReadOpDumpVal++; + + ui32ModifiedValue = psSyncInfo->psSyncData->ui32LastReadOpDumpVal - 1; + + PDUMPCOMMENT("Modify SrcSync %d ROpsPendingVal\r\n", i); + + PDUMPMEM(&ui32ModifiedValue, + psCCBMemInfo, + psCCBKick->ui32CCBDumpWOff + offsetof(SGXMKIF_CMDTA_SHARED, asSrcSyncs) + + (i * sizeof(PVRSRV_DEVICE_SYNC_OBJECT)) + offsetof(PVRSRV_DEVICE_SYNC_OBJECT, ui32ReadOpsPendingVal), + sizeof(IMG_UINT32), + 0, + MAKEUNIQUETAG(psCCBMemInfo)); + + PDUMPCOMMENT("Modify SrcSync %d WOpPendingVal\r\n", i); + + PDUMPMEM(&psSyncInfo->psSyncData->ui32LastOpDumpVal, + psCCBMemInfo, + psCCBKick->ui32CCBDumpWOff + offsetof(SGXMKIF_CMDTA_SHARED, asSrcSyncs) + + (i * sizeof(PVRSRV_DEVICE_SYNC_OBJECT)) + offsetof(PVRSRV_DEVICE_SYNC_OBJECT, ui32WriteOpsPendingVal), + sizeof(IMG_UINT32), + 0, + MAKEUNIQUETAG(psCCBMemInfo)); + + } + + for (i = 0; i < psCCBKick->ui32NumTAStatusVals; i++) + { +#if defined(SUPPORT_SGX_NEW_STATUS_VALS) + PDUMPCOMMENT("Modify TA status value in TA cmd\r\n"); + PDUMPMEM(&psCCBKick->asTAStatusUpdate[i].ui32LastStatusUpdateDumpVal, + psCCBMemInfo, + psCCBKick->ui32CCBDumpWOff + offsetof(SGXMKIF_CMDTA_SHARED, sCtlTAStatusInfo[i].ui32StatusValue), + sizeof(IMG_UINT32), + 0, + MAKEUNIQUETAG(psCCBMemInfo)); +#else + psSyncInfo = (PVRSRV_KERNEL_SYNC_INFO *)psCCBKick->ahTAStatusSyncInfo[i]; + PDUMPCOMMENT("Modify TA status value in TA cmd\r\n"); + PDUMPMEM(&psSyncInfo->psSyncData->ui32LastOpDumpVal, + psCCBMemInfo, + psCCBKick->ui32CCBDumpWOff + offsetof(SGXMKIF_CMDTA_SHARED, sCtlTAStatusInfo[i].ui32StatusValue), + sizeof(IMG_UINT32), + 0, + MAKEUNIQUETAG(psCCBMemInfo)); +#endif + } + + for (i = 0; i < psCCBKick->ui32Num3DStatusVals; i++) + { +#if defined(SUPPORT_SGX_NEW_STATUS_VALS) + PDUMPCOMMENT("Modify 3D status value in TA cmd\r\n"); + PDUMPMEM(&psCCBKick->as3DStatusUpdate[i].ui32LastStatusUpdateDumpVal, + psCCBMemInfo, + psCCBKick->ui32CCBDumpWOff + offsetof(SGXMKIF_CMDTA_SHARED, sCtl3DStatusInfo[i].ui32StatusValue), + sizeof(IMG_UINT32), + 0, + MAKEUNIQUETAG(psCCBMemInfo)); +#else + psSyncInfo = (PVRSRV_KERNEL_SYNC_INFO *)psCCBKick->ah3DStatusSyncInfo[i]; + PDUMPCOMMENT("Modify 3D status value in TA cmd\r\n"); + PDUMPMEM(&psSyncInfo->psSyncData->ui32LastOpDumpVal, + psCCBMemInfo, + psCCBKick->ui32CCBDumpWOff + offsetof(SGXMKIF_CMDTA_SHARED, sCtl3DStatusInfo[i].ui32StatusValue), + sizeof(IMG_UINT32), + 0, + MAKEUNIQUETAG(psCCBMemInfo)); +#endif + } + } +#endif + + eError = SGXScheduleCCBCommandKM(hDevHandle, psCCBKick->eCommand, &psCCBKick->sCommand, KERNEL_ID, 0); + if (eError == PVRSRV_ERROR_RETRY) + { + if (psCCBKick->bFirstKickOrResume && psCCBKick->ui32NumDstSyncObjects > 0) + { +#if defined(SGX_FEATURE_RENDER_TARGET_ARRAYS) + for (i=0; i < psCCBKick->ui32NumDstSyncObjects; i++) +#endif + { +#if defined(SGX_FEATURE_RENDER_TARGET_ARRAYS) + + psSyncInfo = (PVRSRV_KERNEL_SYNC_INFO *)psCCBKick->pasDstSyncHandles[i]; +#else + + psSyncInfo = (PVRSRV_KERNEL_SYNC_INFO *)psCCBKick->sDstSyncHandle; +#endif + if (psSyncInfo) + { + psSyncInfo->psSyncData->ui32WriteOpsPending--; +#if defined(PDUMP) + if (PDumpIsCaptureFrameKM()) + { + psSyncInfo->psSyncData->ui32LastOpDumpVal--; + } +#endif + } + } + } + + for (i=0; iui32NumSrcSyncs; i++) + { + psSyncInfo = (PVRSRV_KERNEL_SYNC_INFO *) psCCBKick->ahSrcKernelSyncInfo[i]; + psSyncInfo->psSyncData->ui32ReadOpsPending--; + } + + return eError; + } + else if (PVRSRV_OK != eError) + { + PVR_DPF((PVR_DBG_ERROR, "SGXDoKickKM: SGXScheduleCCBCommandKM failed.")); + return eError; + } + + +#if defined(NO_HARDWARE) + + + + if (psCCBKick->hTA3DSyncInfo) + { + psSyncInfo = (PVRSRV_KERNEL_SYNC_INFO *)psCCBKick->hTA3DSyncInfo; + + if (psCCBKick->bTADependency) + { + psSyncInfo->psSyncData->ui32WriteOpsComplete = psSyncInfo->psSyncData->ui32WriteOpsPending; + } + } + + if (psCCBKick->hTASyncInfo != IMG_NULL) + { + psSyncInfo = (PVRSRV_KERNEL_SYNC_INFO *)psCCBKick->hTASyncInfo; + + psSyncInfo->psSyncData->ui32ReadOpsComplete = psSyncInfo->psSyncData->ui32ReadOpsPending; + } + + if (psCCBKick->h3DSyncInfo != IMG_NULL) + { + psSyncInfo = (PVRSRV_KERNEL_SYNC_INFO *)psCCBKick->h3DSyncInfo; + + psSyncInfo->psSyncData->ui32ReadOpsComplete = psSyncInfo->psSyncData->ui32ReadOpsPending; + } + + + for (i = 0; i < psCCBKick->ui32NumTAStatusVals; i++) + { +#if defined(SUPPORT_SGX_NEW_STATUS_VALS) + PVRSRV_KERNEL_MEM_INFO *psKernelMemInfo = (PVRSRV_KERNEL_MEM_INFO*)psCCBKick->asTAStatusUpdate[i].hKernelMemInfo; + + *(IMG_UINT32*)((IMG_UINTPTR_T)psKernelMemInfo->pvLinAddrKM + + (psTACmd->sCtlTAStatusInfo[i].sStatusDevAddr.uiAddr + - psKernelMemInfo->sDevVAddr.uiAddr)) = psTACmd->sCtlTAStatusInfo[i].ui32StatusValue; +#else + psSyncInfo = (PVRSRV_KERNEL_SYNC_INFO *)psCCBKick->ahTAStatusSyncInfo[i]; + psSyncInfo->psSyncData->ui32ReadOpsComplete = psTACmd->sCtlTAStatusInfo[i].ui32StatusValue; +#endif + } + + + for (i=0; iui32NumSrcSyncs; i++) + { + psSyncInfo = (PVRSRV_KERNEL_SYNC_INFO *) psCCBKick->ahSrcKernelSyncInfo[i]; + + psSyncInfo->psSyncData->ui32ReadOpsComplete = psSyncInfo->psSyncData->ui32ReadOpsPending; + + } + + if (psCCBKick->bTerminateOrAbort) + { + if (psCCBKick->ui32NumDstSyncObjects > 0) + { + PVRSRV_KERNEL_MEM_INFO *psHWDstSyncListMemInfo = + (PVRSRV_KERNEL_MEM_INFO *)psCCBKick->hKernelHWSyncListMemInfo; + SGXMKIF_HWDEVICE_SYNC_LIST *psHWDeviceSyncList = psHWDstSyncListMemInfo->pvLinAddrKM; + + #if defined(SGX_FEATURE_RENDER_TARGET_ARRAYS) + for (i=0; iui32NumDstSyncObjects; i++) + { + psSyncInfo = (PVRSRV_KERNEL_SYNC_INFO *)psCCBKick->pasDstSyncHandles[i]; + if (psSyncInfo) + psSyncInfo->psSyncData->ui32WriteOpsComplete = psHWDeviceSyncList->asSyncData[i].ui32WriteOpsPendingVal+1; + } + #else + psSyncInfo = (PVRSRV_KERNEL_SYNC_INFO *)psCCBKick->sDstSyncHandle; + if (psSyncInfo) + psSyncInfo->psSyncData->ui32WriteOpsComplete = psHWDeviceSyncList->asSyncData[0].ui32WriteOpsPendingVal+1; + #endif + } + + + for (i = 0; i < psCCBKick->ui32Num3DStatusVals; i++) + { +#if defined(SUPPORT_SGX_NEW_STATUS_VALS) + PVRSRV_KERNEL_MEM_INFO *psKernelMemInfo = (PVRSRV_KERNEL_MEM_INFO*)psCCBKick->as3DStatusUpdate[i].hKernelMemInfo; + + *(IMG_UINT32*)((IMG_UINTPTR_T)psKernelMemInfo->pvLinAddrKM + + (psTACmd->sCtl3DStatusInfo[i].sStatusDevAddr.uiAddr + - psKernelMemInfo->sDevVAddr.uiAddr)) = psTACmd->sCtl3DStatusInfo[i].ui32StatusValue; +#else + psSyncInfo = (PVRSRV_KERNEL_SYNC_INFO *)psCCBKick->ah3DStatusSyncInfo[i]; + psSyncInfo->psSyncData->ui32ReadOpsComplete = psTACmd->sCtl3DStatusInfo[i].ui32StatusValue; +#endif + } + } +#endif + + return eError; +} + diff --git a/services4/srvkm/devices/sgx/sgxpower.c b/services4/srvkm/devices/sgx/sgxpower.c new file mode 100644 index 0000000..69c0a8f --- /dev/null +++ b/services4/srvkm/devices/sgx/sgxpower.c @@ -0,0 +1,491 @@ +/********************************************************************** + * + * Copyright(c) 2008 Imagination Technologies Ltd. All rights reserved. + * + * This program is free software; you can redistribute it and/or modify it + * under the terms and conditions of the GNU General Public License, + * version 2, as published by the Free Software Foundation. + * + * This program is distributed in the hope it will be useful but, except + * as otherwise stated in writing, without any warranty; without even the + * implied warranty of merchantability or fitness for a particular purpose. + * See the GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License along with + * this program; if not, write to the Free Software Foundation, Inc., + * 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA. + * + * The full GNU General Public License is included in this distribution in + * the file called "COPYING". + * + * Contact Information: + * Imagination Technologies Ltd. + * Home Park Estate, Kings Langley, Herts, WD4 8LZ, UK + * + ******************************************************************************/ + +#include + +#include "sgxdefs.h" +#include "services_headers.h" +#include "sgxapi_km.h" +#include "sgxinfokm.h" +#include "sgxutils.h" +#include "pdump_km.h" + + +typedef enum _PVR_DEVICE_POWER_STATE_ +{ + + PVR_DEVICE_POWER_STATE_ON = 0, + PVR_DEVICE_POWER_STATE_IDLE = 1, + PVR_DEVICE_POWER_STATE_OFF = 2, + + PVR_DEVICE_POWER_STATE_FORCE_I32 = 0x7fffffff + +} PVR_DEVICE_POWER_STATE, *PPVR_DEVICE_POWER_STATE; + + +static PVR_DEVICE_POWER_STATE MapDevicePowerState(PVR_POWER_STATE ePowerState) +{ + PVR_DEVICE_POWER_STATE eDevicePowerState; + + switch (ePowerState) + { + case PVRSRV_POWER_STATE_D0: + { + eDevicePowerState = PVR_DEVICE_POWER_STATE_ON; + break; + } + case PVRSRV_POWER_STATE_D3: + { + eDevicePowerState = PVR_DEVICE_POWER_STATE_OFF; + break; + } + default: + { + PVR_DPF((PVR_DBG_ERROR,"MapDevicePowerState: Invalid state: %ld", ePowerState)); + eDevicePowerState = PVR_DEVICE_POWER_STATE_FORCE_I32; + PVR_DBG_BREAK; + } + } + + return eDevicePowerState; +} + + +static IMG_VOID SGXGetTimingInfo(PVRSRV_DEVICE_NODE *psDeviceNode) +{ + PVRSRV_SGXDEV_INFO *psDevInfo = psDeviceNode->pvDevice; +#if defined(SGX_DYNAMIC_TIMING_INFO) + SGX_TIMING_INFORMATION sSGXTimingInfo = {0}; +#else + SGX_DEVICE_MAP *psSGXDeviceMap; +#endif + IMG_UINT32 ui32ActivePowManSampleRate; + SGX_TIMING_INFORMATION *psSGXTimingInfo; + + +#if defined(SGX_DYNAMIC_TIMING_INFO) + psSGXTimingInfo = &sSGXTimingInfo; + SysGetSGXTimingInformation(psSGXTimingInfo); +#else + SysGetDeviceMemoryMap(PVRSRV_DEVICE_TYPE_SGX, + (IMG_VOID**)&psSGXDeviceMap); + psSGXTimingInfo = &psSGXDeviceMap->sTimingInfo; +#endif + +#if defined(SUPPORT_HW_RECOVERY) + { + PVRSRV_ERROR eError; + IMG_UINT32 ui32OlduKernelFreq; + + if (psDevInfo->hTimer != IMG_NULL) + { + ui32OlduKernelFreq = psDevInfo->ui32CoreClockSpeed / psDevInfo->ui32uKernelTimerClock; + if (ui32OlduKernelFreq != psSGXTimingInfo->ui32uKernelFreq) + { + + + eError = OSRemoveTimer(psDevInfo->hTimer); + if (eError != PVRSRV_OK) + { + PVR_DPF((PVR_DBG_ERROR,"SGXGetTimingInfo: Failed to remove timer")); + } + psDevInfo->hTimer = IMG_NULL; + } + } + + if (psDevInfo->hTimer == IMG_NULL) + { + + + + psDevInfo->hTimer = OSAddTimer(SGXOSTimer, psDeviceNode, + 1000 * 50 / psSGXTimingInfo->ui32uKernelFreq); + if(psDevInfo->hTimer == IMG_NULL) + { + PVR_DPF((PVR_DBG_ERROR,"SGXGetTimingInfo : Failed to register timer callback function")); + } + } + + psDevInfo->psSGXHostCtl->ui32HWRecoverySampleRate = + psSGXTimingInfo->ui32uKernelFreq / psSGXTimingInfo->ui32HWRecoveryFreq; + } +#endif + + + psDevInfo->ui32CoreClockSpeed = psSGXTimingInfo->ui32CoreClockSpeed; + psDevInfo->ui32uKernelTimerClock = psSGXTimingInfo->ui32CoreClockSpeed / psSGXTimingInfo->ui32uKernelFreq; + + ui32ActivePowManSampleRate = + psSGXTimingInfo->ui32uKernelFreq * psSGXTimingInfo->ui32ActivePowManLatencyms / 1000; + + + + + + + + + ui32ActivePowManSampleRate += 1; + + psDevInfo->psSGXHostCtl->ui32ActivePowManSampleRate = ui32ActivePowManSampleRate; +} + + +IMG_VOID SGXStartTimer(PVRSRV_SGXDEV_INFO *psDevInfo, + IMG_BOOL bStartOSTimer) +{ + IMG_UINT32 ui32RegVal; + + #if !defined(SUPPORT_HW_RECOVERY) + PVR_UNREFERENCED_PARAMETER(bStartOSTimer); + #endif + + + + ui32RegVal = EUR_CR_EVENT_TIMER_ENABLE_MASK | psDevInfo->ui32uKernelTimerClock; + OSWriteHWReg(psDevInfo->pvRegsBaseKM, EUR_CR_EVENT_TIMER, ui32RegVal); + PDUMPREGWITHFLAGS(EUR_CR_EVENT_TIMER, ui32RegVal, PDUMP_FLAGS_CONTINUOUS); + + #if defined(SUPPORT_HW_RECOVERY) + if (bStartOSTimer) + { + PVRSRV_ERROR eError; + + eError = OSEnableTimer(psDevInfo->hTimer); + if (eError != PVRSRV_OK) + { + PVR_DPF((PVR_DBG_ERROR,"SGXStartTimer : Failed to enable host timer")); + } + } + #endif +} + + +static IMG_VOID SGXPollForClockGating (PVRSRV_SGXDEV_INFO *psDevInfo, + IMG_UINT32 ui32Register, + IMG_UINT32 ui32RegisterValue, + IMG_CHAR *pszComment) +{ + PVR_UNREFERENCED_PARAMETER(psDevInfo); + PVR_UNREFERENCED_PARAMETER(ui32Register); + PVR_UNREFERENCED_PARAMETER(ui32RegisterValue); + PVR_UNREFERENCED_PARAMETER(pszComment); + + #if !defined(NO_HARDWARE) + if (psDevInfo != IMG_NULL) + { + if (PollForValueKM((IMG_UINT32 *)psDevInfo->pvRegsBaseKM + (ui32Register >> 2), + 0, + ui32RegisterValue, + MAX_HW_TIME_US/WAIT_TRY_COUNT, + WAIT_TRY_COUNT) != PVRSRV_OK) + { + PVR_DPF((PVR_DBG_ERROR,"SGXPrePowerState: %s failed.", pszComment)); + } + } + #endif + + PDUMPCOMMENT(pszComment); + PDUMPREGPOL(ui32Register, 0, ui32RegisterValue); +} + + +static PVRSRV_ERROR SGXPrePowerState (IMG_HANDLE hDevHandle, + PVR_DEVICE_POWER_STATE eNewPowerState, + PVR_DEVICE_POWER_STATE eCurrentPowerState) +{ + if ((eNewPowerState != eCurrentPowerState) && + (eNewPowerState != PVR_DEVICE_POWER_STATE_ON)) + { + PVRSRV_ERROR eError; + PVRSRV_DEVICE_NODE *psDeviceNode = hDevHandle; + PVRSRV_SGXDEV_INFO *psDevInfo = psDeviceNode->pvDevice; + IMG_UINT32 ui32PowerCmd, ui32CompleteStatus; + SGXMKIF_COMMAND sCommand = {0}; + + #if defined(SUPPORT_HW_RECOVERY) + + eError = OSDisableTimer(psDevInfo->hTimer); + if (eError != PVRSRV_OK) + { + PVR_DPF((PVR_DBG_ERROR,"SGXPrePowerState: Failed to disable timer")); + return eError; + } + #endif + + if (eNewPowerState == PVR_DEVICE_POWER_STATE_OFF) + { + + ui32PowerCmd = PVRSRV_POWERCMD_POWEROFF; + ui32CompleteStatus = PVRSRV_USSE_EDM_POWMAN_POWEROFF_COMPLETE; + PDUMPCOMMENT("SGX power off request"); + } + else + { + + ui32PowerCmd = PVRSRV_POWERCMD_IDLE; + ui32CompleteStatus = PVRSRV_USSE_EDM_POWMAN_IDLE_COMPLETE; + PDUMPCOMMENT("SGX idle request"); + } + + sCommand.ui32Data[0] = PVRSRV_CCBFLAGS_POWERCMD; + sCommand.ui32Data[1] = ui32PowerCmd; + + eError = SGXScheduleCCBCommand(psDevInfo, SGXMKIF_COMMAND_EDM_KICK, &sCommand, KERNEL_ID, 0); + if (eError != PVRSRV_OK) + { + PVR_DPF((PVR_DBG_ERROR,"SGXPrePowerState: Failed to submit power down command")); + return eError; + } + + + #if !defined(NO_HARDWARE) + if (PollForValueKM(&psDevInfo->psSGXHostCtl->ui32PowerStatus, + ui32CompleteStatus, + ui32CompleteStatus, + MAX_HW_TIME_US/WAIT_TRY_COUNT, + WAIT_TRY_COUNT) != PVRSRV_OK) + { + PVR_DPF((PVR_DBG_ERROR,"SGXPrePowerState: Wait for SGX ukernel power transition failed.")); + PVR_DBG_BREAK; + } + #endif + + #if defined(PDUMP) + PDUMPCOMMENT("TA/3D CCB Control - Wait for power event on uKernel."); + PDUMPMEMPOL(psDevInfo->psKernelSGXHostCtlMemInfo, + offsetof(SGXMKIF_HOST_CTL, ui32PowerStatus), + ui32CompleteStatus, + ui32CompleteStatus, + PDUMP_POLL_OPERATOR_EQUAL, + IMG_FALSE, IMG_FALSE, + MAKEUNIQUETAG(psDevInfo->psKernelSGXHostCtlMemInfo)); + #endif + + + SGXPollForClockGating(psDevInfo, + psDevInfo->ui32ClkGateStatusReg, + psDevInfo->ui32ClkGateStatusMask, + "Wait for SGX clock gating"); + + #if defined(SGX_FEATURE_MP) + + SGXPollForClockGating(psDevInfo, + psDevInfo->ui32MasterClkGateStatusReg, + psDevInfo->ui32MasterClkGateStatusMask, + "Wait for SGX master clock gating"); + #endif + + if (eNewPowerState == PVR_DEVICE_POWER_STATE_OFF) + { + + eError = SGXDeinitialise(psDevInfo); + if (eError != PVRSRV_OK) + { + PVR_DPF((PVR_DBG_ERROR,"SGXPrePowerState: SGXDeinitialise failed: %lu", eError)); + return eError; + } + } + } + + return PVRSRV_OK; +} + + +static PVRSRV_ERROR SGXPostPowerState (IMG_HANDLE hDevHandle, + PVR_DEVICE_POWER_STATE eNewPowerState, + PVR_DEVICE_POWER_STATE eCurrentPowerState) +{ + if ((eNewPowerState != eCurrentPowerState) && + (eCurrentPowerState != PVR_DEVICE_POWER_STATE_ON)) + { + PVRSRV_ERROR eError; + PVRSRV_DEVICE_NODE *psDeviceNode = hDevHandle; + PVRSRV_SGXDEV_INFO *psDevInfo = psDeviceNode->pvDevice; + SGXMKIF_HOST_CTL *psSGXHostCtl = psDevInfo->psSGXHostCtl; + + + psSGXHostCtl->ui32PowerStatus = 0; + PDUMPCOMMENT("TA/3D CCB Control - Reset power status"); + #if defined(PDUMP) + PDUMPMEM(IMG_NULL, psDevInfo->psKernelSGXHostCtlMemInfo, + offsetof(SGXMKIF_HOST_CTL, ui32PowerStatus), + sizeof(IMG_UINT32), PDUMP_FLAGS_CONTINUOUS, + MAKEUNIQUETAG(psDevInfo->psKernelSGXHostCtlMemInfo)); + #endif + + if (eCurrentPowerState == PVR_DEVICE_POWER_STATE_OFF) + { + + + + + + SGXGetTimingInfo(psDeviceNode); + + + + eError = SGXInitialise(psDevInfo, IMG_FALSE); + if (eError != PVRSRV_OK) + { + PVR_DPF((PVR_DBG_ERROR,"SGXPostPowerState: SGXInitialise failed")); + return eError; + } + } + else + { + + + SGXMKIF_COMMAND sCommand = {0}; + + SGXStartTimer(psDevInfo, IMG_TRUE); + + sCommand.ui32Data[0] = PVRSRV_CCBFLAGS_PROCESS_QUEUESCMD; + eError = SGXScheduleCCBCommand(psDevInfo, SGXMKIF_COMMAND_EDM_KICK, &sCommand, ISR_ID, 0); + if (eError != PVRSRV_OK) + { + PVR_DPF((PVR_DBG_ERROR,"SGXPostPowerState failed to schedule CCB command: %lu", eError)); + return PVRSRV_ERROR_GENERIC; + } + } + } + + return PVRSRV_OK; +} + + +PVRSRV_ERROR SGXPrePowerStateExt (IMG_HANDLE hDevHandle, + PVR_POWER_STATE eNewPowerState, + PVR_POWER_STATE eCurrentPowerState) +{ + PVR_DEVICE_POWER_STATE eNewDevicePowerState = MapDevicePowerState(eNewPowerState); + PVR_DEVICE_POWER_STATE eCurrentDevicePowerState = MapDevicePowerState(eCurrentPowerState); + + return SGXPrePowerState(hDevHandle, eNewDevicePowerState, eCurrentDevicePowerState); +} + + +PVRSRV_ERROR SGXPostPowerStateExt (IMG_HANDLE hDevHandle, + PVR_POWER_STATE eNewPowerState, + PVR_POWER_STATE eCurrentPowerState) +{ + PVRSRV_ERROR eError; + PVR_DEVICE_POWER_STATE eNewDevicePowerState = MapDevicePowerState(eNewPowerState); + PVR_DEVICE_POWER_STATE eCurrentDevicePowerState = MapDevicePowerState(eCurrentPowerState); + + eError = SGXPostPowerState(hDevHandle, eNewDevicePowerState, eCurrentDevicePowerState); + if (eError != PVRSRV_OK) + { + return eError; + } + + PVR_DPF((PVR_DBG_MESSAGE, + "SGXPostPowerState : SGX Power Transition from %d to %d OK", + eCurrentPowerState, eNewPowerState)); + + return eError; +} + + +PVRSRV_ERROR SGXPreClockSpeedChange (IMG_HANDLE hDevHandle, + IMG_BOOL bIdleDevice, + PVR_POWER_STATE eCurrentPowerState) +{ + PVRSRV_ERROR eError; + PVRSRV_DEVICE_NODE *psDeviceNode = hDevHandle; + PVRSRV_SGXDEV_INFO *psDevInfo = psDeviceNode->pvDevice; + + PVR_UNREFERENCED_PARAMETER(psDevInfo); + + if (eCurrentPowerState == PVRSRV_POWER_STATE_D0) + { + if (bIdleDevice) + { + + PDUMPSUSPEND(); + + eError = SGXPrePowerState(hDevHandle, PVR_DEVICE_POWER_STATE_IDLE, + PVR_DEVICE_POWER_STATE_ON); + + if (eError != PVRSRV_OK) + { + PDUMPRESUME(); + return eError; + } + } + } + + PVR_DPF((PVR_DBG_MESSAGE,"SGXPreClockSpeedChange: SGX clock speed was %luHz", + psDevInfo->ui32CoreClockSpeed)); + + return PVRSRV_OK; +} + + +PVRSRV_ERROR SGXPostClockSpeedChange (IMG_HANDLE hDevHandle, + IMG_BOOL bIdleDevice, + PVR_POWER_STATE eCurrentPowerState) +{ + PVRSRV_DEVICE_NODE *psDeviceNode = hDevHandle; + PVRSRV_SGXDEV_INFO *psDevInfo = psDeviceNode->pvDevice; + IMG_UINT32 ui32OldClockSpeed = psDevInfo->ui32CoreClockSpeed; + + PVR_UNREFERENCED_PARAMETER(ui32OldClockSpeed); + + if (eCurrentPowerState == PVRSRV_POWER_STATE_D0) + { + + + SGXGetTimingInfo(psDeviceNode); + + if (bIdleDevice) + { + PVRSRV_ERROR eError; + + eError = SGXPostPowerState(hDevHandle, PVR_DEVICE_POWER_STATE_ON, + PVR_DEVICE_POWER_STATE_IDLE); + + PDUMPRESUME(); + + if (eError != PVRSRV_OK) + { + return eError; + } + } + else + { + SGXStartTimer(psDevInfo, IMG_TRUE); + } + + } + + PVR_DPF((PVR_DBG_MESSAGE,"SGXPostClockSpeedChange: SGX clock speed changed from %luHz to %luHz", + ui32OldClockSpeed, psDevInfo->ui32CoreClockSpeed)); + + return PVRSRV_OK; +} + + diff --git a/services4/srvkm/devices/sgx/sgxreset.c b/services4/srvkm/devices/sgx/sgxreset.c new file mode 100644 index 0000000..b630552 --- /dev/null +++ b/services4/srvkm/devices/sgx/sgxreset.c @@ -0,0 +1,408 @@ +/********************************************************************** + * + * Copyright(c) 2008 Imagination Technologies Ltd. All rights reserved. + * + * This program is free software; you can redistribute it and/or modify it + * under the terms and conditions of the GNU General Public License, + * version 2, as published by the Free Software Foundation. + * + * This program is distributed in the hope it will be useful but, except + * as otherwise stated in writing, without any warranty; without even the + * implied warranty of merchantability or fitness for a particular purpose. + * See the GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License along with + * this program; if not, write to the Free Software Foundation, Inc., + * 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA. + * + * The full GNU General Public License is included in this distribution in + * the file called "COPYING". + * + * Contact Information: + * Imagination Technologies Ltd. + * Home Park Estate, Kings Langley, Herts, WD4 8LZ, UK + * + ******************************************************************************/ + +#include "sgxdefs.h" +#include "sgxmmu.h" +#include "services_headers.h" +#include "sgxinfokm.h" +#include "sgxconfig.h" + +#include "pdump_km.h" + + +static IMG_VOID SGXResetSoftReset(PVRSRV_SGXDEV_INFO *psDevInfo, + IMG_BOOL bResetBIF, + IMG_UINT32 ui32PDUMPFlags, + IMG_BOOL bPDump) +{ + IMG_UINT32 ui32SoftResetRegVal = + + EUR_CR_SOFT_RESET_DPM_RESET_MASK | + EUR_CR_SOFT_RESET_TA_RESET_MASK | + EUR_CR_SOFT_RESET_USE_RESET_MASK | + EUR_CR_SOFT_RESET_ISP_RESET_MASK | + EUR_CR_SOFT_RESET_TSP_RESET_MASK; + + +#ifdef EUR_CR_SOFT_RESET_TWOD_RESET_MASK + ui32SoftResetRegVal |= EUR_CR_SOFT_RESET_TWOD_RESET_MASK; +#endif +#if defined(EUR_CR_SOFT_RESET_TE_RESET_MASK) + ui32SoftResetRegVal |= EUR_CR_SOFT_RESET_TE_RESET_MASK; +#endif +#if defined(EUR_CR_SOFT_RESET_MTE_RESET_MASK) + ui32SoftResetRegVal |= EUR_CR_SOFT_RESET_MTE_RESET_MASK; +#endif +#if defined(EUR_CR_SOFT_RESET_ISP2_RESET_MASK) + ui32SoftResetRegVal |= EUR_CR_SOFT_RESET_ISP2_RESET_MASK; +#endif +#if defined(EUR_CR_SOFT_RESET_PDS_RESET_MASK) + ui32SoftResetRegVal |= EUR_CR_SOFT_RESET_PDS_RESET_MASK; +#endif +#if defined(EUR_CR_SOFT_RESET_PBE_RESET_MASK) + ui32SoftResetRegVal |= EUR_CR_SOFT_RESET_PBE_RESET_MASK; +#endif +#if defined(EUR_CR_SOFT_RESET_CACHEL2_RESET_MASK) + ui32SoftResetRegVal |= EUR_CR_SOFT_RESET_CACHEL2_RESET_MASK; +#endif +#if defined(EUR_CR_SOFT_RESET_UCACHEL2_RESET_MASK) + ui32SoftResetRegVal |= EUR_CR_SOFT_RESET_UCACHEL2_RESET_MASK; +#endif +#if defined(EUR_CR_SOFT_RESET_MADD_RESET_MASK) + ui32SoftResetRegVal |= EUR_CR_SOFT_RESET_MADD_RESET_MASK; +#endif +#if defined(EUR_CR_SOFT_RESET_ITR_RESET_MASK) + ui32SoftResetRegVal |= EUR_CR_SOFT_RESET_ITR_RESET_MASK; +#endif +#if defined(EUR_CR_SOFT_RESET_TEX_RESET_MASK) + ui32SoftResetRegVal |= EUR_CR_SOFT_RESET_TEX_RESET_MASK; +#endif +#if defined(EUR_CR_SOFT_RESET_IDXFIFO_RESET_MASK) + ui32SoftResetRegVal |= EUR_CR_SOFT_RESET_IDXFIFO_RESET_MASK; +#endif +#if defined(EUR_CR_SOFT_RESET_VDM_RESET_MASK) + ui32SoftResetRegVal |= EUR_CR_SOFT_RESET_VDM_RESET_MASK; +#endif + +#if !defined(PDUMP) + PVR_UNREFERENCED_PARAMETER(ui32PDUMPFlags); +#endif + + if (bResetBIF) + { + ui32SoftResetRegVal |= EUR_CR_SOFT_RESET_BIF_RESET_MASK; + } + + OSWriteHWReg(psDevInfo->pvRegsBaseKM, EUR_CR_SOFT_RESET, ui32SoftResetRegVal); + if (bPDump) + { + PDUMPREGWITHFLAGS(EUR_CR_SOFT_RESET, ui32SoftResetRegVal, ui32PDUMPFlags); + } +} + + +static IMG_VOID SGXResetSleep(PVRSRV_SGXDEV_INFO *psDevInfo, + IMG_UINT32 ui32PDUMPFlags, + IMG_BOOL bPDump) +{ +#if !defined(PDUMP) + PVR_UNREFERENCED_PARAMETER(ui32PDUMPFlags); +#endif + + + OSWaitus(1000 * 1000000 / psDevInfo->ui32CoreClockSpeed); + if (bPDump) + { + PDUMPIDLWITHFLAGS(30, ui32PDUMPFlags); +#if defined(PDUMP) + PDumpRegRead(EUR_CR_SOFT_RESET, ui32PDUMPFlags); +#endif + } + + + +} + + +static IMG_VOID SGXResetInvalDC(PVRSRV_SGXDEV_INFO *psDevInfo, + IMG_UINT32 ui32PDUMPFlags, + IMG_BOOL bPDump) +{ + IMG_UINT32 ui32RegVal; + + + ui32RegVal = EUR_CR_BIF_CTRL_INVALDC_MASK; + OSWriteHWReg(psDevInfo->pvRegsBaseKM, EUR_CR_BIF_CTRL, ui32RegVal); + if (bPDump) + { + PDUMPREGWITHFLAGS(EUR_CR_BIF_CTRL, ui32RegVal, ui32PDUMPFlags); + } + SGXResetSleep(psDevInfo, ui32PDUMPFlags, bPDump); + + ui32RegVal = 0; + OSWriteHWReg(psDevInfo->pvRegsBaseKM, EUR_CR_BIF_CTRL, ui32RegVal); + if (bPDump) + { + PDUMPREGWITHFLAGS(EUR_CR_BIF_CTRL, ui32RegVal, ui32PDUMPFlags); + } + SGXResetSleep(psDevInfo, ui32PDUMPFlags, bPDump); + +#if !defined(SGX_FEATURE_MULTIPLE_MEM_CONTEXTS) + { + + + + if (PollForValueKM((IMG_UINT32 *)((IMG_UINT8*)psDevInfo->pvRegsBaseKM + EUR_CR_BIF_MEM_REQ_STAT), + 0, + EUR_CR_BIF_MEM_REQ_STAT_READS_MASK, + MAX_HW_TIME_US/WAIT_TRY_COUNT, + WAIT_TRY_COUNT) != PVRSRV_OK) + { + PVR_DPF((PVR_DBG_ERROR,"Wait for DC invalidate failed.")); + PVR_DBG_BREAK; + } + + if (bPDump) + { + PDUMPREGPOLWITHFLAGS(EUR_CR_BIF_MEM_REQ_STAT, 0, EUR_CR_BIF_MEM_REQ_STAT_READS_MASK, ui32PDUMPFlags); + } + } +#endif +} + + +IMG_VOID SGXReset(PVRSRV_SGXDEV_INFO *psDevInfo, + IMG_UINT32 ui32PDUMPFlags) +{ + IMG_UINT32 ui32RegVal; +#if defined(EUR_CR_BIF_INT_STAT_FAULT_REQ_MASK) + const IMG_UINT32 ui32BifFaultMask = EUR_CR_BIF_INT_STAT_FAULT_REQ_MASK; +#else + const IMG_UINT32 ui32BifFaultMask = EUR_CR_BIF_INT_STAT_FAULT_MASK; +#endif + +#if defined(SGX_FEATURE_MULTIPLE_MEM_CONTEXTS) + IMG_UINT32 ui32BIFCtrl; +#if defined(EUR_CR_BIF_MEM_ARB_CONFIG) + IMG_UINT32 ui32BIFMemArb; +#endif +#endif + +#ifndef PDUMP + PVR_UNREFERENCED_PARAMETER(ui32PDUMPFlags); +#endif + + psDevInfo->ui32NumResets++; + + PDUMPCOMMENTWITHFLAGS(ui32PDUMPFlags, "Start of SGX reset sequence\r\n"); + +#if defined(FIX_HW_BRN_23944) + + ui32RegVal = EUR_CR_BIF_CTRL_PAUSE_MASK; + OSWriteHWReg(psDevInfo->pvRegsBaseKM, EUR_CR_BIF_CTRL, ui32RegVal); + PDUMPREGWITHFLAGS(EUR_CR_BIF_CTRL, ui32RegVal, ui32PDUMPFlags); + + SGXResetSleep(psDevInfo, ui32PDUMPFlags, IMG_TRUE); + + ui32RegVal = OSReadHWReg(psDevInfo->pvRegsBaseKM, EUR_CR_BIF_INT_STAT); + if (ui32RegVal & ui32BifFaultMask) + { + + ui32RegVal = EUR_CR_BIF_CTRL_PAUSE_MASK | EUR_CR_BIF_CTRL_CLEAR_FAULT_MASK; + OSWriteHWReg(psDevInfo->pvRegsBaseKM, EUR_CR_BIF_CTRL, ui32RegVal); + PDUMPREGWITHFLAGS(EUR_CR_BIF_CTRL, ui32RegVal, ui32PDUMPFlags); + + SGXResetSleep(psDevInfo, ui32PDUMPFlags, IMG_TRUE); + + ui32RegVal = EUR_CR_BIF_CTRL_PAUSE_MASK; + OSWriteHWReg(psDevInfo->pvRegsBaseKM, EUR_CR_BIF_CTRL, ui32RegVal); + PDUMPREGWITHFLAGS(EUR_CR_BIF_CTRL, ui32RegVal, ui32PDUMPFlags); + + SGXResetSleep(psDevInfo, ui32PDUMPFlags, IMG_TRUE); + } +#endif + + + SGXResetSoftReset(psDevInfo, IMG_TRUE, ui32PDUMPFlags, IMG_TRUE); + + SGXResetSleep(psDevInfo, ui32PDUMPFlags, IMG_TRUE); + + + +#if defined(SGX_FEATURE_MULTIPLE_MEM_CONTEXTS) + ui32RegVal = 0; + OSWriteHWReg(psDevInfo->pvRegsBaseKM, EUR_CR_BIF_BANK_SET, ui32RegVal); + PDUMPREGWITHFLAGS(EUR_CR_BIF_BANK_SET, ui32RegVal, ui32PDUMPFlags); + OSWriteHWReg(psDevInfo->pvRegsBaseKM, EUR_CR_BIF_BANK0, ui32RegVal); + PDUMPREGWITHFLAGS(EUR_CR_BIF_BANK0, ui32RegVal, ui32PDUMPFlags); + +#if defined(EUR_CR_BIF_MEM_ARB_CONFIG) + + + ui32BIFMemArb = (12UL << EUR_CR_BIF_MEM_ARB_CONFIG_PAGE_SIZE_SHIFT) | + (7UL << EUR_CR_BIF_MEM_ARB_CONFIG_BEST_CNT_SHIFT) | + (12UL << EUR_CR_BIF_MEM_ARB_CONFIG_TTE_THRESH_SHIFT); + OSWriteHWReg(psDevInfo->pvRegsBaseKM, EUR_CR_BIF_MEM_ARB_CONFIG, ui32BIFMemArb); + PDUMPREGWITHFLAGS(EUR_CR_BIF_MEM_ARB_CONFIG, ui32BIFMemArb, ui32PDUMPFlags); +#endif +#endif + +#if defined(SGX_FEATURE_SYSTEM_CACHE) +#if defined(SGX_FEATURE_MP) + #if defined(SGX_BYPASS_SYSTEM_CACHE) + #error SGX_BYPASS_SYSTEM_CACHE not supported + #else + ui32RegVal = EUR_CR_MASTER_SLC_CTRL_USSE_INVAL_REQ0_MASK | + (0xC << EUR_CR_MASTER_SLC_CTRL_ARB_PAGE_SIZE_SHIFT); + OSWriteHWReg(psDevInfo->pvRegsBaseKM, EUR_CR_MASTER_SLC_CTRL, ui32RegVal); + PDUMPREG(EUR_CR_MASTER_SLC_CTRL, ui32RegVal); + + ui32RegVal = EUR_CR_MASTER_SLC_CTRL_BYPASS_BYP_CC_MASK; + OSWriteHWReg(psDevInfo->pvRegsBaseKM, EUR_CR_MASTER_SLC_CTRL_BYPASS, ui32RegVal); + PDUMPREG(EUR_CR_MASTER_SLC_CTRL_BYPASS, ui32RegVal); + #endif +#else + #if defined(SGX_BYPASS_SYSTEM_CACHE) + + ui32RegVal = EUR_CR_MNE_CR_CTRL_BYPASS_ALL_MASK; + #else + #if defined(FIX_HW_BRN_26620) + ui32RegVal = 0; + #else + + ui32RegVal = EUR_CR_MNE_CR_CTRL_BYP_CC_MASK; + #endif + #endif + OSWriteHWReg(psDevInfo->pvRegsBaseKM, EUR_CR_MNE_CR_CTRL, ui32RegVal); + PDUMPREG(EUR_CR_MNE_CR_CTRL, ui32RegVal); +#endif +#endif + + + + + + + ui32RegVal = psDevInfo->sBIFResetPDDevPAddr.uiAddr; + OSWriteHWReg(psDevInfo->pvRegsBaseKM, EUR_CR_BIF_DIR_LIST_BASE0, ui32RegVal); + + SGXResetSleep(psDevInfo, ui32PDUMPFlags, IMG_FALSE); + + + SGXResetSoftReset(psDevInfo, IMG_FALSE, ui32PDUMPFlags, IMG_TRUE); + SGXResetSleep(psDevInfo, ui32PDUMPFlags, IMG_FALSE); + + SGXResetInvalDC(psDevInfo, ui32PDUMPFlags, IMG_FALSE); + + + + for (;;) + { + IMG_UINT32 ui32BifIntStat = OSReadHWReg(psDevInfo->pvRegsBaseKM, EUR_CR_BIF_INT_STAT); + IMG_DEV_VIRTADDR sBifFault; + IMG_UINT32 ui32PDIndex, ui32PTIndex; + + if ((ui32BifIntStat & ui32BifFaultMask) == 0) + { + break; + } + + + + + sBifFault.uiAddr = OSReadHWReg(psDevInfo->pvRegsBaseKM, EUR_CR_BIF_FAULT); + PVR_DPF((PVR_DBG_WARNING, "SGXReset: Page fault 0x%x/0x%x", ui32BifIntStat, sBifFault.uiAddr)); + ui32PDIndex = sBifFault.uiAddr >> (SGX_MMU_PAGE_SHIFT + SGX_MMU_PT_SHIFT); + ui32PTIndex = (sBifFault.uiAddr & SGX_MMU_PT_MASK) >> SGX_MMU_PAGE_SHIFT; + + + SGXResetSoftReset(psDevInfo, IMG_TRUE, ui32PDUMPFlags, IMG_FALSE); + + + psDevInfo->pui32BIFResetPD[ui32PDIndex] = psDevInfo->sBIFResetPTDevPAddr.uiAddr + | SGX_MMU_PDE_PAGE_SIZE_4K + | SGX_MMU_PDE_VALID; + psDevInfo->pui32BIFResetPT[ui32PTIndex] = psDevInfo->sBIFResetPageDevPAddr.uiAddr + | SGX_MMU_PTE_VALID; + + + ui32RegVal = OSReadHWReg(psDevInfo->pvRegsBaseKM, EUR_CR_EVENT_STATUS); + OSWriteHWReg(psDevInfo->pvRegsBaseKM, EUR_CR_EVENT_HOST_CLEAR, ui32RegVal); + ui32RegVal = OSReadHWReg(psDevInfo->pvRegsBaseKM, EUR_CR_EVENT_STATUS2); + OSWriteHWReg(psDevInfo->pvRegsBaseKM, EUR_CR_EVENT_HOST_CLEAR2, ui32RegVal); + + SGXResetSleep(psDevInfo, ui32PDUMPFlags, IMG_FALSE); + + + SGXResetSoftReset(psDevInfo, IMG_FALSE, ui32PDUMPFlags, IMG_FALSE); + SGXResetSleep(psDevInfo, ui32PDUMPFlags, IMG_FALSE); + + + SGXResetInvalDC(psDevInfo, ui32PDUMPFlags, IMG_FALSE); + + + psDevInfo->pui32BIFResetPD[ui32PDIndex] = 0; + psDevInfo->pui32BIFResetPT[ui32PTIndex] = 0; + } + + + + +#if defined(SGX_FEATURE_MULTIPLE_MEM_CONTEXTS) + + ui32BIFCtrl = (SGX_BIF_DIR_LIST_INDEX_EDM << EUR_CR_BIF_BANK0_INDEX_EDM_SHIFT); +#ifdef SGX_FEATURE_2D_HARDWARE + + ui32BIFCtrl |= (SGX_BIF_DIR_LIST_INDEX_EDM << EUR_CR_BIF_BANK0_INDEX_2D_SHIFT); +#endif +#if defined(FIX_HW_BRN_23410) + + ui32BIFCtrl |= (SGX_BIF_DIR_LIST_INDEX_EDM << EUR_CR_BIF_BANK0_INDEX_TA_SHIFT); +#endif + + OSWriteHWReg(psDevInfo->pvRegsBaseKM, EUR_CR_BIF_BANK0, ui32BIFCtrl); + PDUMPREGWITHFLAGS(EUR_CR_BIF_BANK0, ui32BIFCtrl, ui32PDUMPFlags); +#endif + + { + IMG_UINT32 ui32EDMDirListReg; + + + #if (SGX_BIF_DIR_LIST_INDEX_EDM == 0) + ui32EDMDirListReg = EUR_CR_BIF_DIR_LIST_BASE0; + #else + + ui32EDMDirListReg = EUR_CR_BIF_DIR_LIST_BASE1 + 4 * (SGX_BIF_DIR_LIST_INDEX_EDM - 1); + #endif + + OSWriteHWReg(psDevInfo->pvRegsBaseKM, ui32EDMDirListReg, psDevInfo->sKernelPDDevPAddr.uiAddr); + PDUMPPDREGWITHFLAGS(ui32EDMDirListReg, psDevInfo->sKernelPDDevPAddr.uiAddr, ui32PDUMPFlags, PDUMP_PD_UNIQUETAG); + } + +#ifdef SGX_FEATURE_2D_HARDWARE + + OSWriteHWReg(psDevInfo->pvRegsBaseKM, EUR_CR_BIF_TWOD_REQ_BASE, SGX_2D_HEAP_BASE); + PDUMPREGWITHFLAGS(EUR_CR_BIF_TWOD_REQ_BASE, SGX_2D_HEAP_BASE, ui32PDUMPFlags); +#endif + + + SGXResetInvalDC(psDevInfo, ui32PDUMPFlags, IMG_TRUE); + + PVR_DPF((PVR_DBG_MESSAGE,"Soft Reset of SGX")); + SGXResetSleep(psDevInfo, ui32PDUMPFlags, IMG_TRUE); + + + ui32RegVal = 0; + OSWriteHWReg(psDevInfo->pvRegsBaseKM, EUR_CR_SOFT_RESET, ui32RegVal); + PDUMPREGWITHFLAGS(EUR_CR_SOFT_RESET, ui32RegVal, ui32PDUMPFlags); + + + SGXResetSleep(psDevInfo, ui32PDUMPFlags, IMG_TRUE); + + PDUMPCOMMENTWITHFLAGS(ui32PDUMPFlags, "End of SGX reset sequence\r\n"); +} + + diff --git a/services4/srvkm/devices/sgx/sgxtransfer.c b/services4/srvkm/devices/sgx/sgxtransfer.c new file mode 100644 index 0000000..b6f9ab2 --- /dev/null +++ b/services4/srvkm/devices/sgx/sgxtransfer.c @@ -0,0 +1,445 @@ +/********************************************************************** + * + * Copyright(c) 2008 Imagination Technologies Ltd. All rights reserved. + * + * This program is free software; you can redistribute it and/or modify it + * under the terms and conditions of the GNU General Public License, + * version 2, as published by the Free Software Foundation. + * + * This program is distributed in the hope it will be useful but, except + * as otherwise stated in writing, without any warranty; without even the + * implied warranty of merchantability or fitness for a particular purpose. + * See the GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License along with + * this program; if not, write to the Free Software Foundation, Inc., + * 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA. + * + * The full GNU General Public License is included in this distribution in + * the file called "COPYING". + * + * Contact Information: + * Imagination Technologies Ltd. + * Home Park Estate, Kings Langley, Herts, WD4 8LZ, UK + * + ******************************************************************************/ + +#if defined(TRANSFER_QUEUE) + +#include + +#include "sgxdefs.h" +#include "services_headers.h" +#include "buffer_manager.h" +#include "sgxinfo.h" +#include "sysconfig.h" +#include "regpaths.h" +#include "pdump_km.h" +#include "mmu.h" +#include "pvr_bridge.h" +#include "sgx_bridge_km.h" +#include "sgxinfokm.h" +#include "osfunc.h" +#include "pvr_debug.h" +#include "sgxutils.h" + +IMG_EXPORT PVRSRV_ERROR SGXSubmitTransferKM(IMG_HANDLE hDevHandle, PVRSRV_TRANSFER_SGX_KICK *psKick) +{ + PVRSRV_KERNEL_MEM_INFO *psCCBMemInfo = (PVRSRV_KERNEL_MEM_INFO *)psKick->hCCBMemInfo; + SGXMKIF_COMMAND sCommand = {0}; + SGXMKIF_TRANSFERCMD_SHARED *psSharedTransferCmd; + PVRSRV_KERNEL_SYNC_INFO *psSyncInfo; + PVRSRV_ERROR eError; + + + if (!CCB_OFFSET_IS_VALID(SGXMKIF_TRANSFERCMD_SHARED, psCCBMemInfo, psKick, ui32SharedCmdCCBOffset)) + { + PVR_DPF((PVR_DBG_ERROR, "SGXSubmitTransferKM: Invalid CCB offset")); + return PVRSRV_ERROR_INVALID_PARAMS; + } + + + psSharedTransferCmd = CCB_DATA_FROM_OFFSET(SGXMKIF_TRANSFERCMD_SHARED, psCCBMemInfo, psKick, ui32SharedCmdCCBOffset); + + if (psKick->hTASyncInfo != IMG_NULL) + { + psSyncInfo = (PVRSRV_KERNEL_SYNC_INFO *)psKick->hTASyncInfo; + + psSharedTransferCmd->ui32TASyncWriteOpsPendingVal = psSyncInfo->psSyncData->ui32WriteOpsPending++; + psSharedTransferCmd->ui32TASyncReadOpsPendingVal = psSyncInfo->psSyncData->ui32ReadOpsPending; + + psSharedTransferCmd->sTASyncWriteOpsCompleteDevVAddr = psSyncInfo->sWriteOpsCompleteDevVAddr; + psSharedTransferCmd->sTASyncReadOpsCompleteDevVAddr = psSyncInfo->sReadOpsCompleteDevVAddr; + } + else + { + psSharedTransferCmd->sTASyncWriteOpsCompleteDevVAddr.uiAddr = 0; + psSharedTransferCmd->sTASyncReadOpsCompleteDevVAddr.uiAddr = 0; + } + + if (psKick->h3DSyncInfo != IMG_NULL) + { + psSyncInfo = (PVRSRV_KERNEL_SYNC_INFO *)psKick->h3DSyncInfo; + + psSharedTransferCmd->ui323DSyncWriteOpsPendingVal = psSyncInfo->psSyncData->ui32WriteOpsPending++; + psSharedTransferCmd->ui323DSyncReadOpsPendingVal = psSyncInfo->psSyncData->ui32ReadOpsPending; + + psSharedTransferCmd->s3DSyncWriteOpsCompleteDevVAddr = psSyncInfo->sWriteOpsCompleteDevVAddr; + psSharedTransferCmd->s3DSyncReadOpsCompleteDevVAddr = psSyncInfo->sReadOpsCompleteDevVAddr; + } + else + { + psSharedTransferCmd->s3DSyncWriteOpsCompleteDevVAddr.uiAddr = 0; + psSharedTransferCmd->s3DSyncReadOpsCompleteDevVAddr.uiAddr = 0; + } + + if ((psKick->ui32Flags & SGXMKIF_TQFLAGS_KEEPPENDING) == 0UL) + { + if (psKick->ui32NumSrcSync > 0) + { + psSyncInfo = (PVRSRV_KERNEL_SYNC_INFO *)psKick->ahSrcSyncInfo[0]; + + psSharedTransferCmd->ui32SrcWriteOpPendingVal = psSyncInfo->psSyncData->ui32WriteOpsPending; + psSharedTransferCmd->ui32SrcReadOpPendingVal = psSyncInfo->psSyncData->ui32ReadOpsPending; + + psSharedTransferCmd->sSrcWriteOpsCompleteDevAddr = psSyncInfo->sWriteOpsCompleteDevVAddr; + psSharedTransferCmd->sSrcReadOpsCompleteDevAddr = psSyncInfo->sReadOpsCompleteDevVAddr; + + } + + if (psKick->ui32NumDstSync > 0) + { + psSyncInfo = (PVRSRV_KERNEL_SYNC_INFO *)psKick->ahDstSyncInfo[0]; + + psSharedTransferCmd->ui32DstWriteOpPendingVal = psSyncInfo->psSyncData->ui32WriteOpsPending; + psSharedTransferCmd->ui32DstReadOpPendingVal = psSyncInfo->psSyncData->ui32ReadOpsPending; + + psSharedTransferCmd->sDstWriteOpsCompleteDevAddr = psSyncInfo->sWriteOpsCompleteDevVAddr; + psSharedTransferCmd->sDstReadOpsCompleteDevAddr = psSyncInfo->sReadOpsCompleteDevVAddr; + + } + + + if (psKick->ui32NumSrcSync > 0) + { + psSyncInfo = (PVRSRV_KERNEL_SYNC_INFO *)psKick->ahSrcSyncInfo[0]; + psSyncInfo->psSyncData->ui32ReadOpsPending++; + } + if (psKick->ui32NumDstSync > 0) + { + psSyncInfo = (PVRSRV_KERNEL_SYNC_INFO *)psKick->ahDstSyncInfo[0]; + psSyncInfo->psSyncData->ui32WriteOpsPending++; + } + } + + + if (psKick->ui32NumDstSync > 1 || psKick->ui32NumSrcSync > 1) + { + PVR_DPF((PVR_DBG_ERROR, + "Transfer command doesn't support more than 1 sync object per src/dst\ndst: %d, src: %d", + psKick->ui32NumDstSync, psKick->ui32NumSrcSync)); + } + +#if defined(PDUMP) + if (PDumpIsCaptureFrameKM() + || ((psKick->ui32PDumpFlags & PDUMP_FLAGS_CONTINUOUS) != 0)) + { + PDUMPCOMMENT("Shared part of transfer command\r\n"); + PDUMPMEM(psSharedTransferCmd, + psCCBMemInfo, + psKick->ui32CCBDumpWOff, + sizeof(SGXMKIF_TRANSFERCMD_SHARED), + psKick->ui32PDumpFlags, + MAKEUNIQUETAG(psCCBMemInfo)); + + if((psKick->ui32NumSrcSync > 0) && ((psKick->ui32Flags & SGXMKIF_TQFLAGS_KEEPPENDING) == 0UL)) + { + psSyncInfo = psKick->ahSrcSyncInfo[0]; + + PDUMPCOMMENT("Hack src surface write op in transfer cmd\r\n"); + PDUMPMEM(&psSyncInfo->psSyncData->ui32LastOpDumpVal, + psCCBMemInfo, + psKick->ui32CCBDumpWOff + offsetof(SGXMKIF_TRANSFERCMD_SHARED, ui32SrcWriteOpPendingVal), + sizeof(psSyncInfo->psSyncData->ui32LastOpDumpVal), + psKick->ui32PDumpFlags, + MAKEUNIQUETAG(psCCBMemInfo)); + + PDUMPCOMMENT("Hack src surface read op in transfer cmd\r\n"); + PDUMPMEM(&psSyncInfo->psSyncData->ui32LastReadOpDumpVal, + psCCBMemInfo, + psKick->ui32CCBDumpWOff + offsetof(SGXMKIF_TRANSFERCMD_SHARED, ui32SrcReadOpPendingVal), + sizeof(psSyncInfo->psSyncData->ui32LastReadOpDumpVal), + psKick->ui32PDumpFlags, + MAKEUNIQUETAG(psCCBMemInfo)); + + } + if((psKick->ui32NumDstSync > 0) && ((psKick->ui32Flags & SGXMKIF_TQFLAGS_KEEPPENDING) == 0UL)) + { + psSyncInfo = psKick->ahDstSyncInfo[0]; + + PDUMPCOMMENT("Hack dest surface write op in transfer cmd\r\n"); + PDUMPMEM(&psSyncInfo->psSyncData->ui32LastOpDumpVal, + psCCBMemInfo, + psKick->ui32CCBDumpWOff + offsetof(SGXMKIF_TRANSFERCMD_SHARED, ui32DstWriteOpPendingVal), + sizeof(psSyncInfo->psSyncData->ui32LastOpDumpVal), + psKick->ui32PDumpFlags, + MAKEUNIQUETAG(psCCBMemInfo)); + + PDUMPCOMMENT("Hack dest surface read op in transfer cmd\r\n"); + PDUMPMEM(&psSyncInfo->psSyncData->ui32LastReadOpDumpVal, + psCCBMemInfo, + psKick->ui32CCBDumpWOff + offsetof(SGXMKIF_TRANSFERCMD_SHARED, ui32DstReadOpPendingVal), + sizeof(psSyncInfo->psSyncData->ui32LastReadOpDumpVal), + psKick->ui32PDumpFlags, + MAKEUNIQUETAG(psCCBMemInfo)); + + } + + + if((psKick->ui32NumSrcSync > 0) && ((psKick->ui32Flags & SGXMKIF_TQFLAGS_KEEPPENDING)== 0UL)) + { + psSyncInfo = (PVRSRV_KERNEL_SYNC_INFO *)psKick->ahSrcSyncInfo[0]; + psSyncInfo->psSyncData->ui32LastReadOpDumpVal++; + } + + if((psKick->ui32NumDstSync > 0) && ((psKick->ui32Flags & SGXMKIF_TQFLAGS_KEEPPENDING) == 0UL)) + { + psSyncInfo = (PVRSRV_KERNEL_SYNC_INFO *)psKick->ahDstSyncInfo[0]; + psSyncInfo->psSyncData->ui32LastOpDumpVal++; + } + } +#endif + + sCommand.ui32Data[0] = PVRSRV_CCBFLAGS_TRANSFERCMD; + sCommand.ui32Data[1] = psKick->sHWTransferContextDevVAddr.uiAddr; + + eError = SGXScheduleCCBCommandKM(hDevHandle, SGXMKIF_COMMAND_EDM_KICK, &sCommand, KERNEL_ID, psKick->ui32PDumpFlags); + + +#if defined(NO_HARDWARE) + if (! (psKick->ui32Flags & SGXMKIF_TQFLAGS_NOSYNCUPDATE)) + { + IMG_UINT32 i; + + + for(i = 0; i < psKick->ui32NumSrcSync; i++) + { + psSyncInfo = (PVRSRV_KERNEL_SYNC_INFO *)psKick->ahSrcSyncInfo[i]; + psSyncInfo->psSyncData->ui32ReadOpsComplete = psSyncInfo->psSyncData->ui32ReadOpsPending; + } + + for(i = 0; i < psKick->ui32NumDstSync; i++) + { + psSyncInfo = (PVRSRV_KERNEL_SYNC_INFO *)psKick->ahDstSyncInfo[i]; + psSyncInfo->psSyncData->ui32WriteOpsComplete = psSyncInfo->psSyncData->ui32WriteOpsPending; + + } + + if (psKick->hTASyncInfo != IMG_NULL) + { + psSyncInfo = (PVRSRV_KERNEL_SYNC_INFO *)psKick->hTASyncInfo; + + psSyncInfo->psSyncData->ui32WriteOpsComplete = psSyncInfo->psSyncData->ui32WriteOpsPending; + } + + if (psKick->h3DSyncInfo != IMG_NULL) + { + psSyncInfo = (PVRSRV_KERNEL_SYNC_INFO *)psKick->h3DSyncInfo; + + psSyncInfo->psSyncData->ui32WriteOpsComplete = psSyncInfo->psSyncData->ui32WriteOpsPending; + } + } +#endif + + return eError; +} + +#if defined(SGX_FEATURE_2D_HARDWARE) +IMG_EXPORT PVRSRV_ERROR SGXSubmit2DKM(IMG_HANDLE hDevHandle, PVRSRV_2D_SGX_KICK *psKick) + +{ + PVRSRV_KERNEL_MEM_INFO *psCCBMemInfo = (PVRSRV_KERNEL_MEM_INFO *)psKick->hCCBMemInfo; + SGXMKIF_COMMAND sCommand = {0}; + SGXMKIF_2DCMD_SHARED *ps2DCmd; + PVRSRV_KERNEL_SYNC_INFO *psSyncInfo; + PVRSRV_ERROR eError; + IMG_UINT32 i; + + if (!CCB_OFFSET_IS_VALID(SGXMKIF_2DCMD_SHARED, psCCBMemInfo, psKick, ui32SharedCmdCCBOffset)) + { + PVR_DPF((PVR_DBG_ERROR, "SGXSubmit2DKM: Invalid CCB offset")); + return PVRSRV_ERROR_INVALID_PARAMS; + } + + + ps2DCmd = CCB_DATA_FROM_OFFSET(SGXMKIF_2DCMD_SHARED, psCCBMemInfo, psKick, ui32SharedCmdCCBOffset); + + OSMemSet(ps2DCmd, 0, sizeof(*ps2DCmd)); + + + if (psKick->hTASyncInfo != IMG_NULL) + { + psSyncInfo = (PVRSRV_KERNEL_SYNC_INFO *)psKick->hTASyncInfo; + + ps2DCmd->sTASyncData.ui32WriteOpsPendingVal = psSyncInfo->psSyncData->ui32WriteOpsPending++; + ps2DCmd->sTASyncData.ui32ReadOpsPendingVal = psSyncInfo->psSyncData->ui32ReadOpsPending; + + ps2DCmd->sTASyncData.sWriteOpsCompleteDevVAddr = psSyncInfo->sWriteOpsCompleteDevVAddr; + ps2DCmd->sTASyncData.sReadOpsCompleteDevVAddr = psSyncInfo->sReadOpsCompleteDevVAddr; + } + + + if (psKick->h3DSyncInfo != IMG_NULL) + { + psSyncInfo = (PVRSRV_KERNEL_SYNC_INFO *)psKick->h3DSyncInfo; + + ps2DCmd->s3DSyncData.ui32WriteOpsPendingVal = psSyncInfo->psSyncData->ui32WriteOpsPending++; + ps2DCmd->s3DSyncData.ui32ReadOpsPendingVal = psSyncInfo->psSyncData->ui32ReadOpsPending; + + ps2DCmd->s3DSyncData.sWriteOpsCompleteDevVAddr = psSyncInfo->sWriteOpsCompleteDevVAddr; + ps2DCmd->s3DSyncData.sReadOpsCompleteDevVAddr = psSyncInfo->sReadOpsCompleteDevVAddr; + } + + + ps2DCmd->ui32NumSrcSync = psKick->ui32NumSrcSync; + for (i = 0; i < psKick->ui32NumSrcSync; i++) + { + psSyncInfo = psKick->ahSrcSyncInfo[i]; + + ps2DCmd->sSrcSyncData[i].ui32WriteOpsPendingVal = psSyncInfo->psSyncData->ui32WriteOpsPending; + ps2DCmd->sSrcSyncData[i].ui32ReadOpsPendingVal = psSyncInfo->psSyncData->ui32ReadOpsPending; + + ps2DCmd->sSrcSyncData[i].sWriteOpsCompleteDevVAddr = psSyncInfo->sWriteOpsCompleteDevVAddr; + ps2DCmd->sSrcSyncData[i].sReadOpsCompleteDevVAddr = psSyncInfo->sReadOpsCompleteDevVAddr; + } + + if (psKick->hDstSyncInfo != IMG_NULL) + { + psSyncInfo = psKick->hDstSyncInfo; + + ps2DCmd->sDstSyncData.ui32WriteOpsPendingVal = psSyncInfo->psSyncData->ui32WriteOpsPending; + ps2DCmd->sDstSyncData.ui32ReadOpsPendingVal = psSyncInfo->psSyncData->ui32ReadOpsPending; + + ps2DCmd->sDstSyncData.sWriteOpsCompleteDevVAddr = psSyncInfo->sWriteOpsCompleteDevVAddr; + ps2DCmd->sDstSyncData.sReadOpsCompleteDevVAddr = psSyncInfo->sReadOpsCompleteDevVAddr; + } + + + for (i = 0; i < psKick->ui32NumSrcSync; i++) + { + psSyncInfo = psKick->ahSrcSyncInfo[i]; + psSyncInfo->psSyncData->ui32ReadOpsPending++; + } + + if (psKick->hDstSyncInfo != IMG_NULL) + { + psSyncInfo = psKick->hDstSyncInfo; + psSyncInfo->psSyncData->ui32WriteOpsPending++; + } + +#if defined(PDUMP) + if (PDumpIsCaptureFrameKM() + || ((psKick->ui32PDumpFlags & PDUMP_FLAGS_CONTINUOUS) != 0)) + { + + PDUMPCOMMENT("Shared part of 2D command\r\n"); + PDUMPMEM(ps2DCmd, + psCCBMemInfo, + psKick->ui32CCBDumpWOff, + sizeof(SGXMKIF_2DCMD_SHARED), + psKick->ui32PDumpFlags, + MAKEUNIQUETAG(psCCBMemInfo)); + + for (i = 0; i < psKick->ui32NumSrcSync; i++) + { + psSyncInfo = psKick->ahSrcSyncInfo[i]; + + PDUMPCOMMENT("Hack src surface write op in 2D cmd\r\n"); + PDUMPMEM(&psSyncInfo->psSyncData->ui32LastOpDumpVal, + psCCBMemInfo, + psKick->ui32CCBDumpWOff + offsetof(SGXMKIF_2DCMD_SHARED, sSrcSyncData[i].ui32WriteOpsPendingVal), + sizeof(psSyncInfo->psSyncData->ui32LastOpDumpVal), + psKick->ui32PDumpFlags, + MAKEUNIQUETAG(psCCBMemInfo)); + + PDUMPCOMMENT("Hack src surface read op in 2D cmd\r\n"); + PDUMPMEM(&psSyncInfo->psSyncData->ui32LastReadOpDumpVal, + psCCBMemInfo, + psKick->ui32CCBDumpWOff + offsetof(SGXMKIF_2DCMD_SHARED, sSrcSyncData[i].ui32ReadOpsPendingVal), + sizeof(psSyncInfo->psSyncData->ui32LastReadOpDumpVal), + psKick->ui32PDumpFlags, + MAKEUNIQUETAG(psCCBMemInfo)); + } + + if (psKick->hDstSyncInfo != IMG_NULL) + { + psSyncInfo = psKick->hDstSyncInfo; + + PDUMPCOMMENT("Hack dest surface write op in 2D cmd\r\n"); + PDUMPMEM(&psSyncInfo->psSyncData->ui32LastOpDumpVal, + psCCBMemInfo, + psKick->ui32CCBDumpWOff + offsetof(SGXMKIF_2DCMD_SHARED, sDstSyncData.ui32WriteOpsPendingVal), + sizeof(psSyncInfo->psSyncData->ui32LastOpDumpVal), + psKick->ui32PDumpFlags, + MAKEUNIQUETAG(psCCBMemInfo)); + + PDUMPCOMMENT("Hack dest surface read op in 2D cmd\r\n"); + PDUMPMEM(&psSyncInfo->psSyncData->ui32LastReadOpDumpVal, + psCCBMemInfo, + psKick->ui32CCBDumpWOff + offsetof(SGXMKIF_2DCMD_SHARED, sDstSyncData.ui32ReadOpsPendingVal), + sizeof(psSyncInfo->psSyncData->ui32LastReadOpDumpVal), + psKick->ui32PDumpFlags, + MAKEUNIQUETAG(psCCBMemInfo)); + } + + + for (i = 0; i < psKick->ui32NumSrcSync; i++) + { + psSyncInfo = psKick->ahSrcSyncInfo[i]; + psSyncInfo->psSyncData->ui32LastReadOpDumpVal++; + } + + if (psKick->hDstSyncInfo != IMG_NULL) + { + psSyncInfo = psKick->hDstSyncInfo; + psSyncInfo->psSyncData->ui32LastOpDumpVal++; + } + } +#endif + + sCommand.ui32Data[0] = PVRSRV_CCBFLAGS_2DCMD; + sCommand.ui32Data[1] = psKick->sHW2DContextDevVAddr.uiAddr; + + eError = SGXScheduleCCBCommandKM(hDevHandle, SGXMKIF_COMMAND_EDM_KICK, &sCommand, KERNEL_ID, psKick->ui32PDumpFlags); + + +#if defined(NO_HARDWARE) + + for(i = 0; i < psKick->ui32NumSrcSync; i++) + { + psSyncInfo = (PVRSRV_KERNEL_SYNC_INFO *)psKick->ahSrcSyncInfo[i]; + psSyncInfo->psSyncData->ui32ReadOpsComplete = psSyncInfo->psSyncData->ui32ReadOpsPending; + } + + psSyncInfo = (PVRSRV_KERNEL_SYNC_INFO *)psKick->hDstSyncInfo; + psSyncInfo->psSyncData->ui32WriteOpsComplete = psSyncInfo->psSyncData->ui32WriteOpsPending; + + if (psKick->hTASyncInfo != IMG_NULL) + { + psSyncInfo = (PVRSRV_KERNEL_SYNC_INFO *)psKick->hTASyncInfo; + + psSyncInfo->psSyncData->ui32WriteOpsComplete = psSyncInfo->psSyncData->ui32WriteOpsPending; + } + + if (psKick->h3DSyncInfo != IMG_NULL) + { + psSyncInfo = (PVRSRV_KERNEL_SYNC_INFO *)psKick->h3DSyncInfo; + + psSyncInfo->psSyncData->ui32WriteOpsComplete = psSyncInfo->psSyncData->ui32WriteOpsPending; + } +#endif + + return eError; +} +#endif +#endif diff --git a/services4/srvkm/devices/sgx/sgxutils.c b/services4/srvkm/devices/sgx/sgxutils.c new file mode 100644 index 0000000..c09cf44 --- /dev/null +++ b/services4/srvkm/devices/sgx/sgxutils.c @@ -0,0 +1,922 @@ +/********************************************************************** + * + * Copyright(c) 2008 Imagination Technologies Ltd. All rights reserved. + * + * This program is free software; you can redistribute it and/or modify it + * under the terms and conditions of the GNU General Public License, + * version 2, as published by the Free Software Foundation. + * + * This program is distributed in the hope it will be useful but, except + * as otherwise stated in writing, without any warranty; without even the + * implied warranty of merchantability or fitness for a particular purpose. + * See the GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License along with + * this program; if not, write to the Free Software Foundation, Inc., + * 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA. + * + * The full GNU General Public License is included in this distribution in + * the file called "COPYING". + * + * Contact Information: + * Imagination Technologies Ltd. + * Home Park Estate, Kings Langley, Herts, WD4 8LZ, UK + * + ******************************************************************************/ + +#include + +#include "sgxdefs.h" +#include "services_headers.h" +#include "buffer_manager.h" +#include "sgxapi_km.h" +#include "sgxinfo.h" +#include "sgxinfokm.h" +#include "sysconfig.h" +#include "pdump_km.h" +#include "mmu.h" +#include "pvr_bridge_km.h" +#include "osfunc.h" +#include "pvr_debug.h" +#include "sgxutils.h" + +#ifdef __linux__ +#include +#else +#include +#endif + + +#if defined(SYS_CUSTOM_POWERDOWN) +PVRSRV_ERROR SysPowerDownMISR(PVRSRV_DEVICE_NODE * psDeviceNode, IMG_UINT32 ui32CallerID); +#endif + + +#if defined(SUPPORT_ACTIVE_POWER_MANAGEMENT) + +IMG_VOID SGXPostActivePowerEvent(PVRSRV_DEVICE_NODE * psDeviceNode, + IMG_UINT32 ui32CallerID) +{ + PVRSRV_SGXDEV_INFO *psDevInfo = psDeviceNode->pvDevice; + SGXMKIF_HOST_CTL *psSGXHostCtl = psDevInfo->psSGXHostCtl; + + + psSGXHostCtl->ui32NumActivePowerEvents++; + + if ((psSGXHostCtl->ui32PowerStatus & PVRSRV_USSE_EDM_POWMAN_POWEROFF_RESTART_IMMEDIATE) != 0) + { + + + + if (ui32CallerID == ISR_ID) + { + psDeviceNode->bReProcessDeviceCommandComplete = IMG_TRUE; + } + else + { + SGXScheduleProcessQueuesKM(psDeviceNode); + } + } +} + + +IMG_VOID SGXTestActivePowerEvent (PVRSRV_DEVICE_NODE *psDeviceNode, + IMG_UINT32 ui32CallerID) +{ + PVRSRV_ERROR eError = PVRSRV_OK; + PVRSRV_SGXDEV_INFO *psDevInfo = psDeviceNode->pvDevice; + SGXMKIF_HOST_CTL *psSGXHostCtl = psDevInfo->psSGXHostCtl; + + if (((psSGXHostCtl->ui32InterruptFlags & PVRSRV_USSE_EDM_INTERRUPT_ACTIVE_POWER) != 0) && + ((psSGXHostCtl->ui32InterruptClearFlags & PVRSRV_USSE_EDM_INTERRUPT_ACTIVE_POWER) == 0)) + { + + psSGXHostCtl->ui32InterruptClearFlags |= PVRSRV_USSE_EDM_INTERRUPT_ACTIVE_POWER; + + + PDUMPSUSPEND(); + +#if defined(SYS_CUSTOM_POWERDOWN) + + + + eError = SysPowerDownMISR(psDeviceNode, ui32CallerID); +#else + eError = PVRSRVSetDevicePowerStateKM(psDeviceNode->sDevId.ui32DeviceIndex, + PVRSRV_POWER_STATE_D3, + ui32CallerID, IMG_FALSE); + if (eError == PVRSRV_OK) + { + SGXPostActivePowerEvent(psDeviceNode, ui32CallerID); + } +#endif + if (eError == PVRSRV_ERROR_RETRY) + { + + + psSGXHostCtl->ui32InterruptClearFlags &= ~PVRSRV_USSE_EDM_INTERRUPT_ACTIVE_POWER; + eError = PVRSRV_OK; + } + + + PDUMPRESUME(); + } + + if (eError != PVRSRV_OK) + { + PVR_DPF((PVR_DBG_ERROR, "SGXTestActivePowerEvent error:%lu", eError)); + } +} +#endif + + +#ifdef INLINE_IS_PRAGMA +#pragma inline(SGXAcquireKernelCCBSlot) +#endif +static INLINE SGXMKIF_COMMAND * SGXAcquireKernelCCBSlot(PVRSRV_SGX_CCB_INFO *psCCB) +{ + + + LOOP_UNTIL_TIMEOUT(MAX_HW_TIME_US) + { + if(((*psCCB->pui32WriteOffset + 1) & 255) != *psCCB->pui32ReadOffset) + { + return &psCCB->psCommands[*psCCB->pui32WriteOffset]; + } + } END_LOOP_UNTIL_TIMEOUT(); + + + return IMG_NULL; +} + +PVRSRV_ERROR SGXScheduleCCBCommand(PVRSRV_SGXDEV_INFO *psDevInfo, + SGXMKIF_COMMAND_TYPE eCommandType, + SGXMKIF_COMMAND *psCommandData, + IMG_UINT32 ui32CallerID, + IMG_UINT32 ui32PDumpFlags) +{ + PVRSRV_SGX_CCB_INFO *psKernelCCB; + PVRSRV_ERROR eError = PVRSRV_OK; + SGXMKIF_COMMAND *psSGXCommand; +#if defined(PDUMP) + IMG_VOID *pvDumpCommand; +#else + PVR_UNREFERENCED_PARAMETER(ui32CallerID); + PVR_UNREFERENCED_PARAMETER(ui32PDumpFlags); +#endif + + psKernelCCB = psDevInfo->psKernelCCBInfo; + + psSGXCommand = SGXAcquireKernelCCBSlot(psKernelCCB); + + + if(!psSGXCommand) + { + eError = PVRSRV_ERROR_TIMEOUT; + goto Exit; + } + + + psCommandData->ui32Data[2] = psDevInfo->ui32CacheControl; + +#if defined(PDUMP) + + psDevInfo->sPDContext.ui32CacheControl |= psDevInfo->ui32CacheControl; +#endif + + + psDevInfo->ui32CacheControl = 0; + + + *psSGXCommand = *psCommandData; + + switch(eCommandType) + { + case SGXMKIF_COMMAND_EDM_KICK: + psSGXCommand->ui32ServiceAddress = psDevInfo->ui32HostKickAddress; + break; + case SGXMKIF_COMMAND_REQUEST_SGXMISCINFO: + psSGXCommand->ui32ServiceAddress = psDevInfo->ui32GetMiscInfoAddress; + break; + case SGXMKIF_COMMAND_VIDEO_KICK: + default: + PVR_DPF((PVR_DBG_ERROR,"SGXScheduleCCBCommandKM: Unknown command type: %d", eCommandType)) ; + eError = PVRSRV_ERROR_GENERIC; + goto Exit; + } + +#if defined(PDUMP) + if (ui32CallerID != ISR_ID) + { + + PDUMPCOMMENTWITHFLAGS(0, "Poll for space in the Kernel CCB\r\n"); + PDUMPMEMPOL(psKernelCCB->psCCBCtlMemInfo, offsetof(PVRSRV_SGX_CCB_CTL, ui32ReadOffset), (psKernelCCB->ui32CCBDumpWOff + 1) & 0xff, 0xff, PDUMP_POLL_OPERATOR_NOTEQUAL, IMG_FALSE, IMG_FALSE, MAKEUNIQUETAG(psKernelCCB->psCCBCtlMemInfo)); + + PDUMPCOMMENTWITHFLAGS(0, "Kernel CCB command\r\n"); + pvDumpCommand = (IMG_VOID *)((IMG_UINT8 *)psKernelCCB->psCCBMemInfo->pvLinAddrKM + (*psKernelCCB->pui32WriteOffset * sizeof(SGXMKIF_COMMAND))); + + PDUMPMEM(pvDumpCommand, + psKernelCCB->psCCBMemInfo, + psKernelCCB->ui32CCBDumpWOff * sizeof(SGXMKIF_COMMAND), + sizeof(SGXMKIF_COMMAND), + ui32PDumpFlags, + MAKEUNIQUETAG(psKernelCCB->psCCBMemInfo)); + + + PDUMPMEM(&psDevInfo->sPDContext.ui32CacheControl, + psKernelCCB->psCCBMemInfo, + psKernelCCB->ui32CCBDumpWOff * sizeof(SGXMKIF_COMMAND) + + offsetof(SGXMKIF_COMMAND, ui32Data[2]), + sizeof(IMG_UINT32), + ui32PDumpFlags, + MAKEUNIQUETAG(psKernelCCB->psCCBMemInfo)); + + if (PDumpIsCaptureFrameKM() + || ((ui32PDumpFlags & PDUMP_FLAGS_CONTINUOUS) != 0)) + { + + psDevInfo->sPDContext.ui32CacheControl = 0; + } + } +#endif + +#if defined(FIX_HW_BRN_26620) && defined(SGX_FEATURE_SYSTEM_CACHE) && !defined(SGX_BYPASS_SYSTEM_CACHE) + + eError = PollForValueKM (psKernelCCB->pui32ReadOffset, + *psKernelCCB->pui32WriteOffset, + 0xFF, + MAX_HW_TIME_US/WAIT_TRY_COUNT, + WAIT_TRY_COUNT); + if (eError != PVRSRV_OK) + { + eError = PVRSRV_ERROR_TIMEOUT; + goto Exit; + } +#endif + + + + *psKernelCCB->pui32WriteOffset = (*psKernelCCB->pui32WriteOffset + 1) & 255; + +#if defined(PDUMP) + if (ui32CallerID != ISR_ID) + { + #if defined(FIX_HW_BRN_26620) && defined(SGX_FEATURE_SYSTEM_CACHE) && !defined(SGX_BYPASS_SYSTEM_CACHE) + PDUMPCOMMENTWITHFLAGS(0, "Poll for previous Kernel CCB CMD to be read\r\n"); + PDUMPMEMPOL(psKernelCCB->psCCBCtlMemInfo, + offsetof(PVRSRV_SGX_CCB_CTL, ui32ReadOffset), + (psKernelCCB->ui32CCBDumpWOff), + 0xFF, + PDUMP_POLL_OPERATOR_EQUAL, + IMG_FALSE, IMG_FALSE, + MAKEUNIQUETAG(psKernelCCB->psCCBCtlMemInfo)); + #endif + + if (PDumpIsCaptureFrameKM() + || ((ui32PDumpFlags & PDUMP_FLAGS_CONTINUOUS) != 0)) + { + psKernelCCB->ui32CCBDumpWOff = (psKernelCCB->ui32CCBDumpWOff + 1) & 0xFF; + } + + PDUMPCOMMENTWITHFLAGS(0, "Kernel CCB write offset\r\n"); + PDUMPMEM(&psKernelCCB->ui32CCBDumpWOff, + psKernelCCB->psCCBCtlMemInfo, + offsetof(PVRSRV_SGX_CCB_CTL, ui32WriteOffset), + sizeof(IMG_UINT32), + ui32PDumpFlags, + MAKEUNIQUETAG(psKernelCCB->psCCBCtlMemInfo)); + PDUMPCOMMENTWITHFLAGS(0, "Kernel CCB event kicker\r\n"); + PDUMPMEM(&psKernelCCB->ui32CCBDumpWOff, + psDevInfo->psKernelCCBEventKickerMemInfo, + 0, + sizeof(IMG_UINT32), + ui32PDumpFlags, + MAKEUNIQUETAG(psDevInfo->psKernelCCBEventKickerMemInfo)); + PDUMPCOMMENTWITHFLAGS(0, "Event kick\r\n"); + #if defined(FIX_HW_BRN_26620) && defined(SGX_FEATURE_SYSTEM_CACHE) && !defined(SGX_BYPASS_SYSTEM_CACHE) + PDUMPREGWITHFLAGS(SGX_MP_CORE_SELECT(EUR_CR_EVENT_KICK2, 0), EUR_CR_EVENT_KICK2_NOW_MASK, 0); + #else + PDUMPREGWITHFLAGS(SGX_MP_CORE_SELECT(EUR_CR_EVENT_KICK, 0), EUR_CR_EVENT_KICK_NOW_MASK, 0); + #endif + } +#endif + + *psDevInfo->pui32KernelCCBEventKicker = (*psDevInfo->pui32KernelCCBEventKicker + 1) & 0xFF; +#if defined(FIX_HW_BRN_26620) && defined(SGX_FEATURE_SYSTEM_CACHE) && !defined(SGX_BYPASS_SYSTEM_CACHE) + OSWriteHWReg(psDevInfo->pvRegsBaseKM, + SGX_MP_CORE_SELECT(EUR_CR_EVENT_KICK2, 0), + EUR_CR_EVENT_KICK2_NOW_MASK); +#else + OSWriteHWReg(psDevInfo->pvRegsBaseKM, + SGX_MP_CORE_SELECT(EUR_CR_EVENT_KICK, 0), + EUR_CR_EVENT_KICK_NOW_MASK); +#endif + +#if defined(NO_HARDWARE) + + *psKernelCCB->pui32ReadOffset = (*psKernelCCB->pui32ReadOffset + 1) & 255; +#endif + +Exit: + return eError; +} + + +PVRSRV_ERROR SGXScheduleCCBCommandKM(PVRSRV_DEVICE_NODE *psDeviceNode, + SGXMKIF_COMMAND_TYPE eCommandType, + SGXMKIF_COMMAND *psCommandData, + IMG_UINT32 ui32CallerID, + IMG_UINT32 ui32PDumpFlags) +{ + PVRSRV_ERROR eError; + PVRSRV_SGXDEV_INFO *psDevInfo = psDeviceNode->pvDevice; + + + PDUMPSUSPEND(); + + + eError = PVRSRVSetDevicePowerStateKM(psDeviceNode->sDevId.ui32DeviceIndex, + PVRSRV_POWER_STATE_D0, + ui32CallerID, + IMG_TRUE); + + PDUMPRESUME(); + + if (eError == PVRSRV_OK) + { + psDeviceNode->bReProcessDeviceCommandComplete = IMG_FALSE; + } + else + { + if (eError == PVRSRV_ERROR_RETRY) + { + if (ui32CallerID == ISR_ID) + { + + + + psDeviceNode->bReProcessDeviceCommandComplete = IMG_TRUE; + eError = PVRSRV_OK; + } + else + { + + + } + } + else + { + PVR_DPF((PVR_DBG_ERROR,"SGXScheduleCCBCommandKM failed to acquire lock - " + "ui32CallerID:%ld eError:%lu", ui32CallerID, eError)); + } + + return eError; + } + + eError = SGXScheduleCCBCommand(psDevInfo, eCommandType, psCommandData, ui32CallerID, ui32PDumpFlags); + + PVRSRVPowerUnlock(ui32CallerID); + +#if defined(SUPPORT_ACTIVE_POWER_MANAGEMENT) + if (ui32CallerID != ISR_ID) + { + + + + SGXTestActivePowerEvent(psDeviceNode, ui32CallerID); + } +#endif + + return eError; +} + + +PVRSRV_ERROR SGXScheduleProcessQueuesKM(PVRSRV_DEVICE_NODE *psDeviceNode) +{ + PVRSRV_ERROR eError; + PVRSRV_SGXDEV_INFO *psDevInfo = psDeviceNode->pvDevice; + SGXMKIF_HOST_CTL *psHostCtl = psDevInfo->psKernelSGXHostCtlMemInfo->pvLinAddrKM; + IMG_UINT32 ui32PowerStatus; + SGXMKIF_COMMAND sCommand = {0}; + + ui32PowerStatus = psHostCtl->ui32PowerStatus; + if ((ui32PowerStatus & PVRSRV_USSE_EDM_POWMAN_NO_WORK) != 0) + { + + return PVRSRV_OK; + } + + sCommand.ui32Data[0] = PVRSRV_CCBFLAGS_PROCESS_QUEUESCMD; + eError = SGXScheduleCCBCommandKM(psDeviceNode, SGXMKIF_COMMAND_EDM_KICK, &sCommand, ISR_ID, 0); + if (eError != PVRSRV_OK) + { + PVR_DPF((PVR_DBG_ERROR,"SGXScheduleProcessQueuesKM failed to schedule CCB command: %lu", eError)); + return PVRSRV_ERROR_GENERIC; + } + + return PVRSRV_OK; +} + + +IMG_BOOL SGXIsDevicePowered(PVRSRV_DEVICE_NODE *psDeviceNode) +{ + return PVRSRVIsDevicePowered(psDeviceNode->sDevId.ui32DeviceIndex); +} + +IMG_EXPORT +PVRSRV_ERROR SGXGetInternalDevInfoKM(IMG_HANDLE hDevCookie, + SGX_INTERNAL_DEVINFO *psSGXInternalDevInfo) +{ + PVRSRV_SGXDEV_INFO *psDevInfo = (PVRSRV_SGXDEV_INFO *)((PVRSRV_DEVICE_NODE *)hDevCookie)->pvDevice; + + psSGXInternalDevInfo->ui32Flags = psDevInfo->ui32Flags; + psSGXInternalDevInfo->bForcePTOff = (IMG_BOOL)psDevInfo->bForcePTOff; + + + psSGXInternalDevInfo->hHostCtlKernelMemInfoHandle = + (IMG_HANDLE)psDevInfo->psKernelSGXHostCtlMemInfo; + + return PVRSRV_OK; +} + + +#if defined (PDUMP) && !defined(EDM_USSE_HWDEBUG) +#define PDUMP_SGX_CLEANUP +#endif + +IMG_VOID SGXCleanupRequest(PVRSRV_DEVICE_NODE *psDeviceNode, + IMG_DEV_VIRTADDR *psHWDataDevVAddr, + IMG_UINT32 ui32ResManRequestFlag) +{ + PVRSRV_SGXDEV_INFO *psSGXDevInfo = (PVRSRV_SGXDEV_INFO *)psDeviceNode->pvDevice; + PVRSRV_KERNEL_MEM_INFO *psSGXHostCtlMemInfo = psSGXDevInfo->psKernelSGXHostCtlMemInfo; + SGXMKIF_HOST_CTL *psSGXHostCtl = (SGXMKIF_HOST_CTL *)psSGXHostCtlMemInfo->pvLinAddrKM; +#if defined(PDUMP_SGX_CLEANUP) + IMG_HANDLE hUniqueTag = MAKEUNIQUETAG(psSGXHostCtlMemInfo); +#endif + + if ((psSGXHostCtl->ui32PowerStatus & PVRSRV_USSE_EDM_POWMAN_NO_WORK) != 0) + { + + } + else + { + + if (psSGXDevInfo->ui32CacheControl & SGX_BIF_INVALIDATE_PDCACHE) + { + psSGXHostCtl->ui32ResManFlags |= PVRSRV_USSE_EDM_RESMAN_CLEANUP_INVALPD; + psSGXDevInfo->ui32CacheControl ^= SGX_BIF_INVALIDATE_PDCACHE; + } + if (psSGXDevInfo->ui32CacheControl & SGX_BIF_INVALIDATE_PTCACHE) + { + psSGXHostCtl->ui32ResManFlags |= PVRSRV_USSE_EDM_RESMAN_CLEANUP_INVALPT; + psSGXDevInfo->ui32CacheControl ^= SGX_BIF_INVALIDATE_PTCACHE; + } + + if(psHWDataDevVAddr == IMG_NULL) + { + psSGXHostCtl->sResManCleanupData.uiAddr = 0; + } + else + { + + psSGXHostCtl->sResManCleanupData.uiAddr = psHWDataDevVAddr->uiAddr; + } + + + psSGXHostCtl->ui32ResManFlags |= ui32ResManRequestFlag; + +#if defined(PDUMP_SGX_CLEANUP) + + PDUMPCOMMENTWITHFLAGS(0, "TA/3D CCB Control - Request clean-up event on uKernel..."); + PDUMPMEM(IMG_NULL, psSGXHostCtlMemInfo, offsetof(SGXMKIF_HOST_CTL, sResManCleanupData.uiAddr), sizeof(IMG_UINT32), 0, hUniqueTag); + PDUMPMEM(&ui32ResManRequestFlag, psSGXHostCtlMemInfo, offsetof(SGXMKIF_HOST_CTL, ui32ResManFlags), sizeof(IMG_UINT32), 0, hUniqueTag); +#else + PDUMPCOMMENTWITHFLAGS(0, "Clean-up event on uKernel disabled"); +#endif + + + SGXScheduleProcessQueuesKM(psDeviceNode); + + + #if !defined(NO_HARDWARE) + if(PollForValueKM ((volatile IMG_UINT32 *)(&psSGXHostCtl->ui32ResManFlags), + PVRSRV_USSE_EDM_RESMAN_CLEANUP_COMPLETE, + PVRSRV_USSE_EDM_RESMAN_CLEANUP_COMPLETE, + MAX_HW_TIME_US/WAIT_TRY_COUNT, + WAIT_TRY_COUNT) != PVRSRV_OK) + { + PVR_DPF((PVR_DBG_ERROR,"SGXCleanupRequest: Wait for uKernel to clean up failed")); + PVR_DBG_BREAK; + } + #endif + + #if defined(PDUMP_SGX_CLEANUP) + + PDUMPCOMMENTWITHFLAGS(0, "TA/3D CCB Control - Wait for clean-up request to complete..."); + PDUMPMEMPOL(psSGXHostCtlMemInfo, + offsetof(SGXMKIF_HOST_CTL, ui32ResManFlags), + PVRSRV_USSE_EDM_RESMAN_CLEANUP_COMPLETE, + PVRSRV_USSE_EDM_RESMAN_CLEANUP_COMPLETE, + PDUMP_POLL_OPERATOR_EQUAL, + IMG_FALSE, IMG_FALSE, + hUniqueTag); + #endif + + psSGXHostCtl->ui32ResManFlags &= ~(ui32ResManRequestFlag); + psSGXHostCtl->ui32ResManFlags &= ~(PVRSRV_USSE_EDM_RESMAN_CLEANUP_COMPLETE); +#if defined(PDUMP_SGX_CLEANUP) + PDUMPMEM(IMG_NULL, psSGXHostCtlMemInfo, offsetof(SGXMKIF_HOST_CTL, ui32ResManFlags), sizeof(IMG_UINT32), 0, hUniqueTag); +#endif + } +} + +typedef struct _SGX_HW_RENDER_CONTEXT_CLEANUP_ +{ + PVRSRV_DEVICE_NODE *psDeviceNode; + IMG_DEV_VIRTADDR sHWRenderContextDevVAddr; + IMG_HANDLE hBlockAlloc; + PRESMAN_ITEM psResItem; +} SGX_HW_RENDER_CONTEXT_CLEANUP; + + +static PVRSRV_ERROR SGXCleanupHWRenderContextCallback(IMG_PVOID pvParam, + IMG_UINT32 ui32Param) +{ + SGX_HW_RENDER_CONTEXT_CLEANUP *psCleanup = pvParam; + + PVR_UNREFERENCED_PARAMETER(ui32Param); + + SGXCleanupRequest(psCleanup->psDeviceNode, + &psCleanup->sHWRenderContextDevVAddr, + PVRSRV_USSE_EDM_RESMAN_CLEANUP_RC_REQUEST); + + OSFreeMem(PVRSRV_OS_PAGEABLE_HEAP, + sizeof(SGX_HW_RENDER_CONTEXT_CLEANUP), + psCleanup, + psCleanup->hBlockAlloc); + + return PVRSRV_OK; +} + +typedef struct _SGX_HW_TRANSFER_CONTEXT_CLEANUP_ +{ + PVRSRV_DEVICE_NODE *psDeviceNode; + IMG_DEV_VIRTADDR sHWTransferContextDevVAddr; + IMG_HANDLE hBlockAlloc; + PRESMAN_ITEM psResItem; +} SGX_HW_TRANSFER_CONTEXT_CLEANUP; + + +static PVRSRV_ERROR SGXCleanupHWTransferContextCallback(IMG_PVOID pvParam, + IMG_UINT32 ui32Param) +{ + SGX_HW_TRANSFER_CONTEXT_CLEANUP *psCleanup = (SGX_HW_TRANSFER_CONTEXT_CLEANUP *)pvParam; + + PVR_UNREFERENCED_PARAMETER(ui32Param); + + SGXCleanupRequest(psCleanup->psDeviceNode, + &psCleanup->sHWTransferContextDevVAddr, PVRSRV_USSE_EDM_RESMAN_CLEANUP_TC_REQUEST); + + OSFreeMem(PVRSRV_OS_PAGEABLE_HEAP, + sizeof(SGX_HW_TRANSFER_CONTEXT_CLEANUP), + psCleanup, + psCleanup->hBlockAlloc); + + return PVRSRV_OK; +} + +IMG_EXPORT +IMG_HANDLE SGXRegisterHWRenderContextKM(IMG_HANDLE psDeviceNode, + IMG_DEV_VIRTADDR *psHWRenderContextDevVAddr, + PVRSRV_PER_PROCESS_DATA *psPerProc) +{ + PVRSRV_ERROR eError; + IMG_HANDLE hBlockAlloc; + SGX_HW_RENDER_CONTEXT_CLEANUP *psCleanup; + PRESMAN_ITEM psResItem; + + eError = OSAllocMem(PVRSRV_OS_PAGEABLE_HEAP, + sizeof(SGX_HW_RENDER_CONTEXT_CLEANUP), + (IMG_VOID **)&psCleanup, + &hBlockAlloc); + + if (eError != PVRSRV_OK) + { + PVR_DPF((PVR_DBG_ERROR, "SGXRegisterHWRenderContextKM: Couldn't allocate memory for SGX_HW_RENDER_CONTEXT_CLEANUP structure")); + return IMG_NULL; + } + + psCleanup->hBlockAlloc = hBlockAlloc; + psCleanup->psDeviceNode = psDeviceNode; + psCleanup->sHWRenderContextDevVAddr = *psHWRenderContextDevVAddr; + + psResItem = ResManRegisterRes(psPerProc->hResManContext, + RESMAN_TYPE_HW_RENDER_CONTEXT, + (IMG_VOID *)psCleanup, + 0, + &SGXCleanupHWRenderContextCallback); + + if (psResItem == IMG_NULL) + { + PVR_DPF((PVR_DBG_ERROR, "SGXRegisterHWRenderContextKM: ResManRegisterRes failed")); + OSFreeMem(PVRSRV_OS_PAGEABLE_HEAP, + sizeof(SGX_HW_RENDER_CONTEXT_CLEANUP), + psCleanup, + psCleanup->hBlockAlloc); + + return IMG_NULL; + } + + psCleanup->psResItem = psResItem; + + return (IMG_HANDLE)psCleanup; +} + +IMG_EXPORT +PVRSRV_ERROR SGXUnregisterHWRenderContextKM(IMG_HANDLE hHWRenderContext) +{ + PVRSRV_ERROR eError; + SGX_HW_RENDER_CONTEXT_CLEANUP *psCleanup; + + PVR_ASSERT(hHWRenderContext != IMG_NULL); + + psCleanup = (SGX_HW_RENDER_CONTEXT_CLEANUP *)hHWRenderContext; + + if (psCleanup == IMG_NULL) + { + PVR_DPF((PVR_DBG_ERROR, "SGXUnregisterHWRenderContextKM: invalid parameter")); + return PVRSRV_ERROR_INVALID_PARAMS; + } + + eError = ResManFreeResByPtr(psCleanup->psResItem); + + return eError; +} + + +IMG_EXPORT +IMG_HANDLE SGXRegisterHWTransferContextKM(IMG_HANDLE psDeviceNode, + IMG_DEV_VIRTADDR *psHWTransferContextDevVAddr, + PVRSRV_PER_PROCESS_DATA *psPerProc) +{ + PVRSRV_ERROR eError; + IMG_HANDLE hBlockAlloc; + SGX_HW_TRANSFER_CONTEXT_CLEANUP *psCleanup; + PRESMAN_ITEM psResItem; + + eError = OSAllocMem(PVRSRV_OS_PAGEABLE_HEAP, + sizeof(SGX_HW_TRANSFER_CONTEXT_CLEANUP), + (IMG_VOID **)&psCleanup, + &hBlockAlloc); + + if (eError != PVRSRV_OK) + { + PVR_DPF((PVR_DBG_ERROR, "SGXRegisterHWTransferContextKM: Couldn't allocate memory for SGX_HW_TRANSFER_CONTEXT_CLEANUP structure")); + return IMG_NULL; + } + + psCleanup->hBlockAlloc = hBlockAlloc; + psCleanup->psDeviceNode = psDeviceNode; + psCleanup->sHWTransferContextDevVAddr = *psHWTransferContextDevVAddr; + + psResItem = ResManRegisterRes(psPerProc->hResManContext, + RESMAN_TYPE_HW_TRANSFER_CONTEXT, + psCleanup, + 0, + &SGXCleanupHWTransferContextCallback); + + if (psResItem == IMG_NULL) + { + PVR_DPF((PVR_DBG_ERROR, "SGXRegisterHWTransferContextKM: ResManRegisterRes failed")); + OSFreeMem(PVRSRV_OS_PAGEABLE_HEAP, + sizeof(SGX_HW_TRANSFER_CONTEXT_CLEANUP), + psCleanup, + psCleanup->hBlockAlloc); + + return IMG_NULL; + } + + psCleanup->psResItem = psResItem; + + return (IMG_HANDLE)psCleanup; +} + +IMG_EXPORT +PVRSRV_ERROR SGXUnregisterHWTransferContextKM(IMG_HANDLE hHWTransferContext) +{ + PVRSRV_ERROR eError; + SGX_HW_TRANSFER_CONTEXT_CLEANUP *psCleanup; + + PVR_ASSERT(hHWTransferContext != IMG_NULL); + + psCleanup = (SGX_HW_TRANSFER_CONTEXT_CLEANUP *)hHWTransferContext; + + if (psCleanup == IMG_NULL) + { + PVR_DPF((PVR_DBG_ERROR, "SGXUnregisterHWTransferContextKM: invalid parameter")); + return PVRSRV_ERROR_INVALID_PARAMS; + } + + eError = ResManFreeResByPtr(psCleanup->psResItem); + + return eError; +} + +#if defined(SGX_FEATURE_2D_HARDWARE) +typedef struct _SGX_HW_2D_CONTEXT_CLEANUP_ +{ + PVRSRV_DEVICE_NODE *psDeviceNode; + IMG_DEV_VIRTADDR sHW2DContextDevVAddr; + IMG_HANDLE hBlockAlloc; + PRESMAN_ITEM psResItem; +} SGX_HW_2D_CONTEXT_CLEANUP; + +static PVRSRV_ERROR SGXCleanupHW2DContextCallback(IMG_PVOID pvParam, IMG_UINT32 ui32Param) +{ + SGX_HW_2D_CONTEXT_CLEANUP *psCleanup = (SGX_HW_2D_CONTEXT_CLEANUP *)pvParam; + + PVR_UNREFERENCED_PARAMETER(ui32Param); + + SGXCleanupRequest(psCleanup->psDeviceNode, + &psCleanup->sHW2DContextDevVAddr, PVRSRV_USSE_EDM_RESMAN_CLEANUP_2DC_REQUEST); + + OSFreeMem(PVRSRV_OS_PAGEABLE_HEAP, + sizeof(SGX_HW_2D_CONTEXT_CLEANUP), + psCleanup, + psCleanup->hBlockAlloc); + + return PVRSRV_OK; +} + +IMG_EXPORT +IMG_HANDLE SGXRegisterHW2DContextKM(IMG_HANDLE psDeviceNode, + IMG_DEV_VIRTADDR *psHW2DContextDevVAddr, + PVRSRV_PER_PROCESS_DATA *psPerProc) +{ + PVRSRV_ERROR eError; + IMG_HANDLE hBlockAlloc; + SGX_HW_2D_CONTEXT_CLEANUP *psCleanup; + PRESMAN_ITEM psResItem; + + eError = OSAllocMem(PVRSRV_OS_PAGEABLE_HEAP, + sizeof(SGX_HW_2D_CONTEXT_CLEANUP), + (IMG_VOID **)&psCleanup, + &hBlockAlloc); + + if (eError != PVRSRV_OK) + { + PVR_DPF((PVR_DBG_ERROR, "SGXRegisterHW2DContextKM: Couldn't allocate memory for SGX_HW_2D_CONTEXT_CLEANUP structure")); + return IMG_NULL; + } + + psCleanup->hBlockAlloc = hBlockAlloc; + psCleanup->psDeviceNode = psDeviceNode; + psCleanup->sHW2DContextDevVAddr = *psHW2DContextDevVAddr; + + psResItem = ResManRegisterRes(psPerProc->hResManContext, + RESMAN_TYPE_HW_2D_CONTEXT, + psCleanup, + 0, + &SGXCleanupHW2DContextCallback); + + if (psResItem == IMG_NULL) + { + PVR_DPF((PVR_DBG_ERROR, "SGXRegisterHW2DContextKM: ResManRegisterRes failed")); + OSFreeMem(PVRSRV_OS_PAGEABLE_HEAP, + sizeof(SGX_HW_2D_CONTEXT_CLEANUP), + psCleanup, + psCleanup->hBlockAlloc); + + return IMG_NULL; + } + + psCleanup->psResItem = psResItem; + + return (IMG_HANDLE)psCleanup; +} + +IMG_EXPORT +PVRSRV_ERROR SGXUnregisterHW2DContextKM(IMG_HANDLE hHW2DContext) +{ + PVRSRV_ERROR eError; + SGX_HW_2D_CONTEXT_CLEANUP *psCleanup; + + PVR_ASSERT(hHW2DContext != IMG_NULL); + + if (hHW2DContext == IMG_NULL) + { + return (PVRSRV_ERROR_INVALID_PARAMS); + } + + psCleanup = (SGX_HW_2D_CONTEXT_CLEANUP *)hHW2DContext; + + eError = ResManFreeResByPtr(psCleanup->psResItem); + + return eError; +} +#endif + +#ifdef INLINE_IS_PRAGMA +#pragma inline(SGX2DQuerySyncOpsComplete) +#endif +static INLINE +IMG_BOOL SGX2DQuerySyncOpsComplete(PVRSRV_KERNEL_SYNC_INFO *psSyncInfo, + IMG_UINT32 ui32ReadOpsPending, + IMG_UINT32 ui32WriteOpsPending) +{ + PVRSRV_SYNC_DATA *psSyncData = psSyncInfo->psSyncData; + + return (IMG_BOOL)( + (psSyncData->ui32ReadOpsComplete >= ui32ReadOpsPending) && + (psSyncData->ui32WriteOpsComplete >= ui32WriteOpsPending) + ); +} + +IMG_EXPORT +PVRSRV_ERROR SGX2DQueryBlitsCompleteKM(PVRSRV_SGXDEV_INFO *psDevInfo, + PVRSRV_KERNEL_SYNC_INFO *psSyncInfo, + IMG_BOOL bWaitForComplete) +{ + IMG_UINT32 ui32ReadOpsPending, ui32WriteOpsPending; + + PVR_UNREFERENCED_PARAMETER(psDevInfo); + + PVR_DPF((PVR_DBG_CALLTRACE, "SGX2DQueryBlitsCompleteKM: Start")); + + ui32ReadOpsPending = psSyncInfo->psSyncData->ui32ReadOpsPending; + ui32WriteOpsPending = psSyncInfo->psSyncData->ui32WriteOpsPending; + + if(SGX2DQuerySyncOpsComplete(psSyncInfo, ui32ReadOpsPending, ui32WriteOpsPending)) + { + + PVR_DPF((PVR_DBG_CALLTRACE, "SGX2DQueryBlitsCompleteKM: No wait. Blits complete.")); + return PVRSRV_OK; + } + + + if (!bWaitForComplete) + { + + PVR_DPF((PVR_DBG_CALLTRACE, "SGX2DQueryBlitsCompleteKM: No wait. Ops pending.")); + return PVRSRV_ERROR_CMD_NOT_PROCESSED; + } + + + PVR_DPF((PVR_DBG_MESSAGE, "SGX2DQueryBlitsCompleteKM: Ops pending. Start polling.")); + LOOP_UNTIL_TIMEOUT(MAX_HW_TIME_US) + { + OSWaitus(MAX_HW_TIME_US/WAIT_TRY_COUNT); + + if(SGX2DQuerySyncOpsComplete(psSyncInfo, ui32ReadOpsPending, ui32WriteOpsPending)) + { + + PVR_DPF((PVR_DBG_CALLTRACE, "SGX2DQueryBlitsCompleteKM: Wait over. Blits complete.")); + return PVRSRV_OK; + } + } END_LOOP_UNTIL_TIMEOUT(); + + + PVR_DPF((PVR_DBG_ERROR,"SGX2DQueryBlitsCompleteKM: Timed out. Ops pending.")); + +#if defined(DEBUG) + { + PVRSRV_SYNC_DATA *psSyncData = psSyncInfo->psSyncData; + + PVR_TRACE(("SGX2DQueryBlitsCompleteKM: Syncinfo: %p, Syncdata: %p", psSyncInfo, psSyncData)); + + PVR_TRACE(("SGX2DQueryBlitsCompleteKM: Read ops complete: %d, Read ops pending: %d", psSyncData->ui32ReadOpsComplete, psSyncData->ui32ReadOpsPending)); + PVR_TRACE(("SGX2DQueryBlitsCompleteKM: Write ops complete: %d, Write ops pending: %d", psSyncData->ui32WriteOpsComplete, psSyncData->ui32WriteOpsPending)); + + } +#endif + + return PVRSRV_ERROR_TIMEOUT; +} + + +IMG_EXPORT +IMG_VOID SGXFlushHWRenderTargetKM(IMG_HANDLE psDeviceNode, IMG_DEV_VIRTADDR sHWRTDataSetDevVAddr) +{ + PVR_ASSERT(sHWRTDataSetDevVAddr.uiAddr != IMG_NULL); + + SGXCleanupRequest((PVRSRV_DEVICE_NODE *)psDeviceNode, &sHWRTDataSetDevVAddr, PVRSRV_USSE_EDM_RESMAN_CLEANUP_RT_REQUEST); +} + + +IMG_UINT32 SGXConvertTimeStamp(PVRSRV_SGXDEV_INFO *psDevInfo, + IMG_UINT32 ui32TimeWraps, + IMG_UINT32 ui32Time) +{ + IMG_UINT64 ui64Clocks; + IMG_UINT32 ui32Clocksx16; + + ui64Clocks = ((IMG_UINT64)ui32TimeWraps * psDevInfo->ui32uKernelTimerClock) + + (psDevInfo->ui32uKernelTimerClock - (ui32Time & EUR_CR_EVENT_TIMER_VALUE_MASK)); + ui32Clocksx16 = (IMG_UINT32)(ui64Clocks / 16); + + return ui32Clocksx16; +} + + + diff --git a/services4/srvkm/devices/sgx/sgxutils.h b/services4/srvkm/devices/sgx/sgxutils.h new file mode 100644 index 0000000..9fa69bd --- /dev/null +++ b/services4/srvkm/devices/sgx/sgxutils.h @@ -0,0 +1,100 @@ +/********************************************************************** + * + * Copyright(c) 2008 Imagination Technologies Ltd. All rights reserved. + * + * This program is free software; you can redistribute it and/or modify it + * under the terms and conditions of the GNU General Public License, + * version 2, as published by the Free Software Foundation. + * + * This program is distributed in the hope it will be useful but, except + * as otherwise stated in writing, without any warranty; without even the + * implied warranty of merchantability or fitness for a particular purpose. + * See the GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License along with + * this program; if not, write to the Free Software Foundation, Inc., + * 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA. + * + * The full GNU General Public License is included in this distribution in + * the file called "COPYING". + * + * Contact Information: + * Imagination Technologies Ltd. + * Home Park Estate, Kings Langley, Herts, WD4 8LZ, UK + * + ******************************************************************************/ + +#include "perproc.h" + +#define CCB_OFFSET_IS_VALID(type, psCCBMemInfo, psCCBKick, offset) \ + ((sizeof(type) <= (psCCBMemInfo)->ui32AllocSize) && \ + ((psCCBKick)->offset <= (psCCBMemInfo)->ui32AllocSize - sizeof(type))) + +#define CCB_DATA_FROM_OFFSET(type, psCCBMemInfo, psCCBKick, offset) \ + ((type *)(((IMG_CHAR *)(psCCBMemInfo)->pvLinAddrKM) + \ + (psCCBKick)->offset)) + + +#if defined(SUPPORT_ACTIVE_POWER_MANAGEMENT) +IMG_IMPORT +IMG_VOID SGXTestActivePowerEvent(PVRSRV_DEVICE_NODE *psDeviceNode, + IMG_UINT32 ui32CallerID); +#endif + +IMG_IMPORT +PVRSRV_ERROR SGXScheduleCCBCommand(PVRSRV_SGXDEV_INFO *psDevInfo, + SGXMKIF_COMMAND_TYPE eCommandType, + SGXMKIF_COMMAND *psCommandData, + IMG_UINT32 ui32CallerID, + IMG_UINT32 ui32PDumpFlags); +IMG_IMPORT +PVRSRV_ERROR SGXScheduleCCBCommandKM(PVRSRV_DEVICE_NODE *psDeviceNode, + SGXMKIF_COMMAND_TYPE eCommandType, + SGXMKIF_COMMAND *psCommandData, + IMG_UINT32 ui32CallerID, + IMG_UINT32 ui32PDumpFlags); + +IMG_IMPORT +PVRSRV_ERROR SGXScheduleProcessQueuesKM(PVRSRV_DEVICE_NODE *psDeviceNode); + +IMG_IMPORT +IMG_BOOL SGXIsDevicePowered(PVRSRV_DEVICE_NODE *psDeviceNode); + +IMG_IMPORT +IMG_HANDLE SGXRegisterHWRenderContextKM(IMG_HANDLE psDeviceNode, + IMG_DEV_VIRTADDR *psHWRenderContextDevVAddr, + PVRSRV_PER_PROCESS_DATA *psPerProc); + +IMG_IMPORT +IMG_HANDLE SGXRegisterHWTransferContextKM(IMG_HANDLE psDeviceNode, + IMG_DEV_VIRTADDR *psHWTransferContextDevVAddr, + PVRSRV_PER_PROCESS_DATA *psPerProc); + +IMG_IMPORT +IMG_VOID SGXFlushHWRenderTargetKM(IMG_HANDLE psSGXDevInfo, IMG_DEV_VIRTADDR psHWRTDataSetDevVAddr); + +IMG_IMPORT +PVRSRV_ERROR SGXUnregisterHWRenderContextKM(IMG_HANDLE hHWRenderContext); + +IMG_IMPORT +PVRSRV_ERROR SGXUnregisterHWTransferContextKM(IMG_HANDLE hHWTransferContext); + +#if defined(SGX_FEATURE_2D_HARDWARE) +IMG_IMPORT +IMG_HANDLE SGXRegisterHW2DContextKM(IMG_HANDLE psDeviceNode, + IMG_DEV_VIRTADDR *psHW2DContextDevVAddr, + PVRSRV_PER_PROCESS_DATA *psPerProc); + +IMG_IMPORT +PVRSRV_ERROR SGXUnregisterHW2DContextKM(IMG_HANDLE hHW2DContext); +#endif + +IMG_UINT32 SGXConvertTimeStamp(PVRSRV_SGXDEV_INFO *psDevInfo, + IMG_UINT32 ui32TimeWraps, + IMG_UINT32 ui32Time); + +IMG_VOID SGXCleanupRequest(PVRSRV_DEVICE_NODE *psDeviceNode, + IMG_DEV_VIRTADDR *psHWDataDevVAddr, + IMG_UINT32 ui32ResManRequestFlag); + + diff --git a/services4/srvkm/env/linux/env_data.h b/services4/srvkm/env/linux/env_data.h new file mode 100644 index 0000000..2d7d30b --- /dev/null +++ b/services4/srvkm/env/linux/env_data.h @@ -0,0 +1,54 @@ +/********************************************************************** + * + * Copyright(c) 2008 Imagination Technologies Ltd. All rights reserved. + * + * This program is free software; you can redistribute it and/or modify it + * under the terms and conditions of the GNU General Public License, + * version 2, as published by the Free Software Foundation. + * + * This program is distributed in the hope it will be useful but, except + * as otherwise stated in writing, without any warranty; without even the + * implied warranty of merchantability or fitness for a particular purpose. + * See the GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License along with + * this program; if not, write to the Free Software Foundation, Inc., + * 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA. + * + * The full GNU General Public License is included in this distribution in + * the file called "COPYING". + * + * Contact Information: + * Imagination Technologies Ltd. + * Home Park Estate, Kings Langley, Herts, WD4 8LZ, UK + * + ******************************************************************************/ + +#ifndef _ENV_DATA_ +#define _ENV_DATA_ + +#include +#include + +#define PVRSRV_MAX_BRIDGE_IN_SIZE 0x1000 +#define PVRSRV_MAX_BRIDGE_OUT_SIZE 0x1000 + +typedef struct _PVR_PCI_DEV_TAG +{ + struct pci_dev *psPCIDev; + HOST_PCI_INIT_FLAGS ePCIFlags; + IMG_BOOL abPCIResourceInUse[DEVICE_COUNT_RESOURCE]; +} PVR_PCI_DEV; + +typedef struct _ENV_DATA_TAG +{ + IMG_VOID *pvBridgeData; + struct pm_dev *psPowerDevice; + IMG_BOOL bLISRInstalled; + IMG_BOOL bMISRInstalled; + IMG_UINT32 ui32IRQ; + IMG_VOID *pvISRCookie; + struct tasklet_struct sMISRTasklet; +} ENV_DATA; + +#endif diff --git a/services4/srvkm/env/linux/env_perproc.h b/services4/srvkm/env/linux/env_perproc.h new file mode 100644 index 0000000..40404f5 --- /dev/null +++ b/services4/srvkm/env/linux/env_perproc.h @@ -0,0 +1,50 @@ +/********************************************************************** + * + * Copyright(c) 2008 Imagination Technologies Ltd. All rights reserved. + * + * This program is free software; you can redistribute it and/or modify it + * under the terms and conditions of the GNU General Public License, + * version 2, as published by the Free Software Foundation. + * + * This program is distributed in the hope it will be useful but, except + * as otherwise stated in writing, without any warranty; without even the + * implied warranty of merchantability or fitness for a particular purpose. + * See the GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License along with + * this program; if not, write to the Free Software Foundation, Inc., + * 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA. + * + * The full GNU General Public License is included in this distribution in + * the file called "COPYING". + * + * Contact Information: + * Imagination Technologies Ltd. + * Home Park Estate, Kings Langley, Herts, WD4 8LZ, UK + * + ******************************************************************************/ + +#ifndef __ENV_PERPROC_H__ +#define __ENV_PERPROC_H__ + +#include "linux/list.h" +#include "linux/proc_fs.h" + +#include "img_types.h" + +typedef struct _PVRSRV_ENV_PER_PROCESS_DATA_ +{ + IMG_HANDLE hBlockAlloc; + struct proc_dir_entry *psProcDir; +} PVRSRV_ENV_PER_PROCESS_DATA; + +IMG_VOID RemovePerProcessProcDir(PVRSRV_ENV_PER_PROCESS_DATA *psEnvPerProc); + +PVRSRV_ERROR LinuxMMapPerProcessConnect(PVRSRV_ENV_PER_PROCESS_DATA *psEnvPerProc); + +IMG_VOID LinuxMMapPerProcessDisconnect(PVRSRV_ENV_PER_PROCESS_DATA *psEnvPerProc); + +PVRSRV_ERROR LinuxMMapPerProcessHandleOptions(PVRSRV_HANDLE_BASE *psHandleBase); + +#endif + diff --git a/services4/srvkm/env/linux/event.c b/services4/srvkm/env/linux/event.c new file mode 100644 index 0000000..a10f874 --- /dev/null +++ b/services4/srvkm/env/linux/event.c @@ -0,0 +1,269 @@ +/********************************************************************** + * + * Copyright(c) 2008 Imagination Technologies Ltd. All rights reserved. + * + * This program is free software; you can redistribute it and/or modify it + * under the terms and conditions of the GNU General Public License, + * version 2, as published by the Free Software Foundation. + * + * This program is distributed in the hope it will be useful but, except + * as otherwise stated in writing, without any warranty; without even the + * implied warranty of merchantability or fitness for a particular purpose. + * See the GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License along with + * this program; if not, write to the Free Software Foundation, Inc., + * 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA. + * + * The full GNU General Public License is included in this distribution in + * the file called "COPYING". + * + * Contact Information: + * Imagination Technologies Ltd. + * Home Park Estate, Kings Langley, Herts, WD4 8LZ, UK + * + ******************************************************************************/ + +#ifndef AUTOCONF_INCLUDED + #include +#endif + +#include +#include +#include +#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,22)) +#include +#endif +#include +#include +#include +#include +#include + +#include +#include +#include +#include +#include +#include +#include +#include + +#include "img_types.h" +#include "services_headers.h" +#include "mm.h" +#include "pvrmmap.h" +#include "mmap.h" +#include "env_data.h" +#include "proc.h" +#include "mutex.h" +#include "lock.h" + +typedef struct PVRSRV_LINUX_EVENT_OBJECT_LIST_TAG +{ + rwlock_t sLock; + struct list_head sList; + +} PVRSRV_LINUX_EVENT_OBJECT_LIST; + + +typedef struct PVRSRV_LINUX_EVENT_OBJECT_TAG +{ + atomic_t sTimeStamp; + IMG_UINT32 ui32TimeStampPrevious; +#if defined(DEBUG) + IMG_UINT ui32Stats; +#endif + wait_queue_head_t sWait; + struct list_head sList; + IMG_HANDLE hResItem; + PVRSRV_LINUX_EVENT_OBJECT_LIST *psLinuxEventObjectList; +} PVRSRV_LINUX_EVENT_OBJECT; + +PVRSRV_ERROR LinuxEventObjectListCreate(IMG_HANDLE *phEventObjectList) +{ + PVRSRV_LINUX_EVENT_OBJECT_LIST *psEvenObjectList; + + if(OSAllocMem(PVRSRV_OS_NON_PAGEABLE_HEAP, sizeof(PVRSRV_LINUX_EVENT_OBJECT_LIST), + (IMG_VOID **)&psEvenObjectList, IMG_NULL) != PVRSRV_OK) + { + PVR_DPF((PVR_DBG_ERROR, "LinuxEventObjectCreate: failed to allocate memory for event list")); + return PVRSRV_ERROR_OUT_OF_MEMORY; + } + + INIT_LIST_HEAD(&psEvenObjectList->sList); + + rwlock_init(&psEvenObjectList->sLock); + + *phEventObjectList = (IMG_HANDLE *) psEvenObjectList; + + return PVRSRV_OK; +} + +PVRSRV_ERROR LinuxEventObjectListDestroy(IMG_HANDLE hEventObjectList) +{ + + PVRSRV_LINUX_EVENT_OBJECT_LIST *psEvenObjectList = (PVRSRV_LINUX_EVENT_OBJECT_LIST *) hEventObjectList ; + + if(psEvenObjectList) + { + if (!list_empty(&psEvenObjectList->sList)) + { + PVR_DPF((PVR_DBG_ERROR, "LinuxEventObjectListDestroy: Event List is not empty")); + return PVRSRV_ERROR_GENERIC; + } + OSFreeMem(PVRSRV_OS_NON_PAGEABLE_HEAP, sizeof(PVRSRV_LINUX_EVENT_OBJECT_LIST), psEvenObjectList, IMG_NULL); + } + return PVRSRV_OK; +} + + +PVRSRV_ERROR LinuxEventObjectDelete(IMG_HANDLE hOSEventObjectList, IMG_HANDLE hOSEventObject) +{ + if(hOSEventObjectList) + { + if(hOSEventObject) + { + PVRSRV_LINUX_EVENT_OBJECT *psLinuxEventObject = (PVRSRV_LINUX_EVENT_OBJECT *)hOSEventObject; +#if defined(DEBUG) + PVR_DPF((PVR_DBG_MESSAGE, "LinuxEventObjectListDelete: Event object waits: %lu", psLinuxEventObject->ui32Stats)); +#endif + if(ResManFreeResByPtr(psLinuxEventObject->hResItem) != PVRSRV_OK) + { + return PVRSRV_ERROR_GENERIC; + } + + return PVRSRV_OK; + } + } + return PVRSRV_ERROR_GENERIC; + +} + +static PVRSRV_ERROR LinuxEventObjectDeleteCallback(IMG_PVOID pvParam, IMG_UINT32 ui32Param) +{ + PVRSRV_LINUX_EVENT_OBJECT *psLinuxEventObject = pvParam; + PVRSRV_LINUX_EVENT_OBJECT_LIST *psLinuxEventObjectList = psLinuxEventObject->psLinuxEventObjectList; + + PVR_UNREFERENCED_PARAMETER(ui32Param); + + write_lock_bh(&psLinuxEventObjectList->sLock); + list_del(&psLinuxEventObject->sList); + write_unlock_bh(&psLinuxEventObjectList->sLock); + +#if defined(DEBUG) + PVR_DPF((PVR_DBG_MESSAGE, "LinuxEventObjectDeleteCallback: Event object waits: %lu", psLinuxEventObject->ui32Stats)); +#endif + + OSFreeMem(PVRSRV_OS_NON_PAGEABLE_HEAP, sizeof(PVRSRV_LINUX_EVENT_OBJECT), psLinuxEventObject, IMG_NULL); + + return PVRSRV_OK; +} +PVRSRV_ERROR LinuxEventObjectAdd(IMG_HANDLE hOSEventObjectList, IMG_HANDLE *phOSEventObject) + { + PVRSRV_LINUX_EVENT_OBJECT *psLinuxEventObject; + PVRSRV_LINUX_EVENT_OBJECT_LIST *psLinuxEventObjectList = (PVRSRV_LINUX_EVENT_OBJECT_LIST*)hOSEventObjectList; + IMG_UINT32 ui32PID = OSGetCurrentProcessIDKM(); + PVRSRV_PER_PROCESS_DATA *psPerProc; + + psPerProc = PVRSRVPerProcessData(ui32PID); + if (psPerProc == IMG_NULL) + { + PVR_DPF((PVR_DBG_ERROR, "LinuxEventObjectAdd: Couldn't find per-process data")); + return PVRSRV_ERROR_OUT_OF_MEMORY; + } + + + if(OSAllocMem(PVRSRV_OS_NON_PAGEABLE_HEAP, sizeof(PVRSRV_LINUX_EVENT_OBJECT), + (IMG_VOID **)&psLinuxEventObject, IMG_NULL) != PVRSRV_OK) + { + PVR_DPF((PVR_DBG_ERROR, "LinuxEventObjectAdd: failed to allocate memory ")); + return PVRSRV_ERROR_OUT_OF_MEMORY; + } + + INIT_LIST_HEAD(&psLinuxEventObject->sList); + + atomic_set(&psLinuxEventObject->sTimeStamp, 0); + psLinuxEventObject->ui32TimeStampPrevious = 0; + +#if defined(DEBUG) + psLinuxEventObject->ui32Stats = 0; +#endif + init_waitqueue_head(&psLinuxEventObject->sWait); + + psLinuxEventObject->psLinuxEventObjectList = psLinuxEventObjectList; + + psLinuxEventObject->hResItem = ResManRegisterRes(psPerProc->hResManContext, + RESMAN_TYPE_EVENT_OBJECT, + psLinuxEventObject, + 0, + &LinuxEventObjectDeleteCallback); + + write_lock_bh(&psLinuxEventObjectList->sLock); + list_add(&psLinuxEventObject->sList, &psLinuxEventObjectList->sList); + write_unlock_bh(&psLinuxEventObjectList->sLock); + + *phOSEventObject = psLinuxEventObject; + + return PVRSRV_OK; +} + +PVRSRV_ERROR LinuxEventObjectSignal(IMG_HANDLE hOSEventObjectList) +{ + PVRSRV_LINUX_EVENT_OBJECT *psLinuxEventObject; + PVRSRV_LINUX_EVENT_OBJECT_LIST *psLinuxEventObjectList = (PVRSRV_LINUX_EVENT_OBJECT_LIST*)hOSEventObjectList; + struct list_head *psListEntry, *psListEntryTemp, *psList; + psList = &psLinuxEventObjectList->sList; + + list_for_each_safe(psListEntry, psListEntryTemp, psList) + { + + psLinuxEventObject = (PVRSRV_LINUX_EVENT_OBJECT *)list_entry(psListEntry, PVRSRV_LINUX_EVENT_OBJECT, sList); + + atomic_inc(&psLinuxEventObject->sTimeStamp); + wake_up_interruptible(&psLinuxEventObject->sWait); + } + + return PVRSRV_OK; + +} + +PVRSRV_ERROR LinuxEventObjectWait(IMG_HANDLE hOSEventObject, IMG_UINT32 ui32MSTimeout) +{ + IMG_UINT32 ui32TimeStamp; + DEFINE_WAIT(sWait); + + PVRSRV_LINUX_EVENT_OBJECT *psLinuxEventObject = (PVRSRV_LINUX_EVENT_OBJECT *) hOSEventObject; + + IMG_UINT32 ui32TimeOutJiffies = msecs_to_jiffies(ui32MSTimeout); + + do + { + prepare_to_wait(&psLinuxEventObject->sWait, &sWait, TASK_INTERRUPTIBLE); + ui32TimeStamp = atomic_read(&psLinuxEventObject->sTimeStamp); + + if(psLinuxEventObject->ui32TimeStampPrevious != ui32TimeStamp) + { + break; + } + + LinuxUnLockMutex(&gPVRSRVLock); + + ui32TimeOutJiffies = (IMG_UINT32)schedule_timeout((IMG_INT32)ui32TimeOutJiffies); + + LinuxLockMutex(&gPVRSRVLock); +#if defined(DEBUG) + psLinuxEventObject->ui32Stats++; +#endif + + + } while (ui32TimeOutJiffies); + + finish_wait(&psLinuxEventObject->sWait, &sWait); + + psLinuxEventObject->ui32TimeStampPrevious = ui32TimeStamp; + + return ui32TimeOutJiffies ? PVRSRV_OK : PVRSRV_ERROR_TIMEOUT; + +} + diff --git a/services4/srvkm/env/linux/event.h b/services4/srvkm/env/linux/event.h new file mode 100644 index 0000000..d07bc97 --- /dev/null +++ b/services4/srvkm/env/linux/event.h @@ -0,0 +1,32 @@ +/********************************************************************** + * + * Copyright(c) 2008 Imagination Technologies Ltd. All rights reserved. + * + * This program is free software; you can redistribute it and/or modify it + * under the terms and conditions of the GNU General Public License, + * version 2, as published by the Free Software Foundation. + * + * This program is distributed in the hope it will be useful but, except + * as otherwise stated in writing, without any warranty; without even the + * implied warranty of merchantability or fitness for a particular purpose. + * See the GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License along with + * this program; if not, write to the Free Software Foundation, Inc., + * 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA. + * + * The full GNU General Public License is included in this distribution in + * the file called "COPYING". + * + * Contact Information: + * Imagination Technologies Ltd. + * Home Park Estate, Kings Langley, Herts, WD4 8LZ, UK + * + ******************************************************************************/ + +PVRSRV_ERROR LinuxEventObjectListCreate(IMG_HANDLE *phEventObjectList); +PVRSRV_ERROR LinuxEventObjectListDestroy(IMG_HANDLE hEventObjectList); +PVRSRV_ERROR LinuxEventObjectAdd(IMG_HANDLE hOSEventObjectList, IMG_HANDLE *phOSEventObject); +PVRSRV_ERROR LinuxEventObjectDelete(IMG_HANDLE hOSEventObjectList, IMG_HANDLE hOSEventObject); +PVRSRV_ERROR LinuxEventObjectSignal(IMG_HANDLE hOSEventObjectList); +PVRSRV_ERROR LinuxEventObjectWait(IMG_HANDLE hOSEventObject, IMG_UINT32 ui32MSTimeout); diff --git a/services4/srvkm/env/linux/kbuild/Makefile b/services4/srvkm/env/linux/kbuild/Makefile new file mode 100644 index 0000000..7001d9e --- /dev/null +++ b/services4/srvkm/env/linux/kbuild/Makefile @@ -0,0 +1,129 @@ +# +# Copyright(c) 2008 Imagination Technologies Ltd. All rights reserved. +# +# This program is free software; you can redistribute it and/or modify it +# under the terms and conditions of the GNU General Public License, +# version 2, as published by the Free Software Foundation. +# +# This program is distributed in the hope it will be useful but, except +# as otherwise stated in writing, without any warranty; without even the +# implied warranty of merchantability or fitness for a particular purpose. +# See the GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License along with +# this program; if not, write to the Free Software Foundation, Inc., +# 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA. +# +# The full GNU General Public License is included in this distribution in +# the file called "COPYING". +# +# Contact Information: +# Imagination Technologies Ltd. +# Home Park Estate, Kings Langley, Herts, WD4 8LZ, UK +# +# + +include $(EURASIAROOT)/eurasiacon/build/linux/kbuild/Makefile.kbuild_subdir_common + +MODULE = pvrsrvkm + +#MODULE_CFLAGS = -E + +KBUILDROOT = ../../../.. + +INCLUDES = -I$(EURASIAROOT)/include4 \ + -I$(EURASIAROOT)/services4/include \ + -I$(EURASIAROOT)/services4/srvkm/env/linux \ + -I$(EURASIAROOT)/services4/srvkm/include \ + -I$(EURASIAROOT)/services4/srvkm/bridged \ + -I$(EURASIAROOT)/services4/system/$(PVR_SYSTEM) \ + -I$(EURASIAROOT)/services4/system/include + + +SOURCES = $(KBUILDROOT)/srvkm/env/linux/osfunc.c \ + $(KBUILDROOT)/srvkm/env/linux/mutils.c \ + $(KBUILDROOT)/srvkm/env/linux/mmap.c \ + $(KBUILDROOT)/srvkm/env/linux/module.c \ + $(KBUILDROOT)/srvkm/env/linux/pdump.c \ + $(KBUILDROOT)/srvkm/env/linux/proc.c \ + $(KBUILDROOT)/srvkm/env/linux/pvr_bridge_k.c \ + $(KBUILDROOT)/srvkm/env/linux/pvr_debug.c \ + $(KBUILDROOT)/srvkm/env/linux/mm.c \ + $(KBUILDROOT)/srvkm/env/linux/mutex.c \ + $(KBUILDROOT)/srvkm/env/linux/event.c \ + $(KBUILDROOT)/srvkm/env/linux/osperproc.c + +SOURCES += $(KBUILDROOT)/srvkm/common/buffer_manager.c \ + $(KBUILDROOT)/srvkm/common/devicemem.c \ + $(KBUILDROOT)/srvkm/common/deviceclass.c \ + $(KBUILDROOT)/srvkm/common/handle.c \ + $(KBUILDROOT)/srvkm/common/hash.c \ + $(KBUILDROOT)/srvkm/common/metrics.c \ + $(KBUILDROOT)/srvkm/common/pvrsrv.c \ + $(KBUILDROOT)/srvkm/common/queue.c \ + $(KBUILDROOT)/srvkm/common/ra.c \ + $(KBUILDROOT)/srvkm/common/resman.c \ + $(KBUILDROOT)/srvkm/common/power.c \ + $(KBUILDROOT)/srvkm/common/mem.c \ + $(KBUILDROOT)/srvkm/common/pdump_common.c \ + $(KBUILDROOT)/srvkm/bridged/bridged_support.c \ + $(KBUILDROOT)/srvkm/bridged/bridged_pvr_bridge.c \ + $(KBUILDROOT)/srvkm/common/perproc.c \ + $(KBUILDROOT)/../services4/system/$(PVR_SYSTEM)/sysconfig.c \ + $(KBUILDROOT)/../services4/system/$(PVR_SYSTEM)/sysutils.c + +INCLUDES += -I$(EURASIAROOT)/services4/srvkm/hwdefs + +SYM_VERS_DEPS = $(EURASIAROOT)/tools/intern/debug/dbgdriv/linux + + +# +# Device dependent +# + +ifeq ($(SUPPORT_SGX), 1) + +INCLUDES += -I$(EURASIAROOT)/services4/srvkm/bridged/sgx \ + -I$(EURASIAROOT)/services4/srvkm/devices/sgx + +SOURCES += $(KBUILDROOT)/srvkm/bridged/sgx/bridged_sgx_bridge.c \ + $(KBUILDROOT)/srvkm/devices/sgx/sgxinit.c \ + $(KBUILDROOT)/srvkm/devices/sgx/sgxpower.c \ + $(KBUILDROOT)/srvkm/devices/sgx/sgxreset.c \ + $(KBUILDROOT)/srvkm/devices/sgx/sgxutils.c \ + $(KBUILDROOT)/srvkm/devices/sgx/sgxkick.c \ + $(KBUILDROOT)/srvkm/devices/sgx/sgxtransfer.c \ + $(KBUILDROOT)/srvkm/devices/sgx/mmu.c \ + $(KBUILDROOT)/srvkm/devices/sgx/pb.c + +else + +ifeq ($(SUPPORT_VGX), 1) + +INCLUDES += -I$(EURASIAROOT)/services4/srvkm/bridged/vgx \ + -I$(EURASIAROOT)/services4/srvkm/devices/vgx + +#FIXME: We need to cerate a subset of vgxdefs.h from $(EURASIAROOT)/hwdefs +# and put it into srvkm/hwdefs for GPL compliance +INCLUDES += -I$(EURASIAROOT)/hwdefs + +SOURCES += $(KBUILDROOT)/srvkm/bridged/vgx/bridged_vgx_bridge.c \ + $(KBUILDROOT)/srvkm/devices/vgx/vgxinit.c \ + $(KBUILDROOT)/srvkm/devices/vgx/vgxreset.c \ + $(KBUILDROOT)/srvkm/devices/vgx/mmu.c \ + $(KBUILDROOT)/srvkm/devices/vgx/pb.c \ + $(KBUILDROOT)/srvkm/env/linux/pdump_vgx.c +endif + +endif # SUPPORT_SGX + +ifeq ($(SUPPORT_DRI_DRM),1) + SOURCES += $(KBUILDROOT)/srvkm/env/linux/pvr_drm.c + INCLUDES += -I$(KERNELDIR)/drivers/char/drm -I$(KERNELDIR)/include/drm +endif + +ifeq ($(PVR_MODULE_TEST),1) +INCLUDES += -I$(EURASIAROOT)/moduletests/include +SOURCES += $(KBUILDROOT)/../moduletests/services_test/kern_test.c +SYS_CFLAGS += -DMODULE_TEST +endif diff --git a/services4/srvkm/env/linux/linkage.h b/services4/srvkm/env/linux/linkage.h new file mode 100644 index 0000000..5c0bb0e --- /dev/null +++ b/services4/srvkm/env/linux/linkage.h @@ -0,0 +1,44 @@ +/********************************************************************** + * + * Copyright(c) 2008 Imagination Technologies Ltd. All rights reserved. + * + * This program is free software; you can redistribute it and/or modify it + * under the terms and conditions of the GNU General Public License, + * version 2, as published by the Free Software Foundation. + * + * This program is distributed in the hope it will be useful but, except + * as otherwise stated in writing, without any warranty; without even the + * implied warranty of merchantability or fitness for a particular purpose. + * See the GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License along with + * this program; if not, write to the Free Software Foundation, Inc., + * 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA. + * + * The full GNU General Public License is included in this distribution in + * the file called "COPYING". + * + * Contact Information: + * Imagination Technologies Ltd. + * Home Park Estate, Kings Langley, Herts, WD4 8LZ, UK + * + ******************************************************************************/ + +#ifndef __LINKAGE_H__ +#define __LINKAGE_H__ + +IMG_INT32 PVRSRV_BridgeDispatchKM(struct file *file, IMG_UINT cmd, IMG_UINT32 arg); +IMG_VOID PVRDPFInit(IMG_VOID); + +#ifdef DEBUG +IMG_INT PVRDebugProcSetLevel(struct file *file, const IMG_CHAR *buffer, IMG_UINT32 count, IMG_VOID *data); +IMG_INT PVRDebugProcGetLevel(IMG_CHAR *page, IMG_CHAR **start, off_t off, IMG_INT count, IMG_INT *eof, IMG_VOID *data); +IMG_VOID PVRDebugSetLevel(IMG_UINT32 uDebugLevel); + +#ifdef PVR_MANUAL_POWER_CONTROL +IMG_INT PVRProcSetPowerLevel(struct file *file, const IMG_CHAR *buffer, IMG_UINT32 count, IMG_VOID *data); +IMG_INT PVRProcGetPowerLevel(IMG_CHAR *page, IMG_CHAR **start, off_t off, IMG_INT count, IMG_INT *eof, IMG_VOID *data); +#endif +#endif + +#endif diff --git a/services4/srvkm/env/linux/lock.h b/services4/srvkm/env/linux/lock.h new file mode 100644 index 0000000..e0bf5ee --- /dev/null +++ b/services4/srvkm/env/linux/lock.h @@ -0,0 +1,32 @@ +/********************************************************************** + * + * Copyright(c) 2008 Imagination Technologies Ltd. All rights reserved. + * + * This program is free software; you can redistribute it and/or modify it + * under the terms and conditions of the GNU General Public License, + * version 2, as published by the Free Software Foundation. + * + * This program is distributed in the hope it will be useful but, except + * as otherwise stated in writing, without any warranty; without even the + * implied warranty of merchantability or fitness for a particular purpose. + * See the GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License along with + * this program; if not, write to the Free Software Foundation, Inc., + * 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA. + * + * The full GNU General Public License is included in this distribution in + * the file called "COPYING". + * + * Contact Information: + * Imagination Technologies Ltd. + * Home Park Estate, Kings Langley, Herts, WD4 8LZ, UK + * + ******************************************************************************/ + +#ifndef __LOCK_H__ +#define __LOCK_H__ + +extern PVRSRV_LINUX_MUTEX gPVRSRVLock; + +#endif diff --git a/services4/srvkm/env/linux/mm.c b/services4/srvkm/env/linux/mm.c new file mode 100644 index 0000000..179dd48 --- /dev/null +++ b/services4/srvkm/env/linux/mm.c @@ -0,0 +1,1830 @@ +/********************************************************************** + * + * Copyright(c) 2008 Imagination Technologies Ltd. All rights reserved. + * + * This program is free software; you can redistribute it and/or modify it + * under the terms and conditions of the GNU General Public License, + * version 2, as published by the Free Software Foundation. + * + * This program is distributed in the hope it will be useful but, except + * as otherwise stated in writing, without any warranty; without even the + * implied warranty of merchantability or fitness for a particular purpose. + * See the GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License along with + * this program; if not, write to the Free Software Foundation, Inc., + * 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA. + * + * The full GNU General Public License is included in this distribution in + * the file called "COPYING". + * + * Contact Information: + * Imagination Technologies Ltd. + * Home Park Estate, Kings Langley, Herts, WD4 8LZ, UK + * + ******************************************************************************/ + +#ifndef AUTOCONF_INCLUDED + #include +#endif + +#include +#include +#include +#include +#if (LINUX_VERSION_CODE < KERNEL_VERSION(2,6,0)) +#include +#endif +#include +#include +#include + +#include "img_defs.h" +#include "services.h" +#include "servicesint.h" +#include "syscommon.h" +#include "mutils.h" +#include "mm.h" +#include "pvrmmap.h" +#include "mmap.h" +#include "osfunc.h" +#include "pvr_debug.h" +#include "proc.h" +#include "mutex.h" +#include "lock.h" + +#if defined(DEBUG_LINUX_MEMORY_ALLOCATIONS) +typedef enum { + DEBUG_MEM_ALLOC_TYPE_KMALLOC, + DEBUG_MEM_ALLOC_TYPE_VMALLOC, + DEBUG_MEM_ALLOC_TYPE_ALLOC_PAGES, + DEBUG_MEM_ALLOC_TYPE_IOREMAP, + DEBUG_MEM_ALLOC_TYPE_IO, + DEBUG_MEM_ALLOC_TYPE_KMEM_CACHE, + DEBUG_MEM_ALLOC_TYPE_COUNT +}DEBUG_MEM_ALLOC_TYPE; + +typedef struct _DEBUG_MEM_ALLOC_REC +{ + DEBUG_MEM_ALLOC_TYPE eAllocType; + IMG_VOID *pvKey; + IMG_VOID *pvCpuVAddr; + IMG_UINT32 ulCpuPAddr; + IMG_VOID *pvPrivateData; + IMG_UINT32 ui32Bytes; + pid_t pid; + IMG_CHAR *pszFileName; + IMG_UINT32 ui32Line; + + struct _DEBUG_MEM_ALLOC_REC *psNext; +}DEBUG_MEM_ALLOC_REC; + +static DEBUG_MEM_ALLOC_REC *g_MemoryRecords; + +static IMG_UINT32 g_WaterMarkData[DEBUG_MEM_ALLOC_TYPE_COUNT]; +static IMG_UINT32 g_HighWaterMarkData[DEBUG_MEM_ALLOC_TYPE_COUNT]; + +static IMG_UINT32 g_SysRAMWaterMark; +static IMG_UINT32 g_SysRAMHighWaterMark; + +static IMG_UINT32 g_IOMemWaterMark; +static IMG_UINT32 g_IOMemHighWaterMark; + +static IMG_VOID DebugMemAllocRecordAdd(DEBUG_MEM_ALLOC_TYPE eAllocType, + IMG_VOID *pvKey, + IMG_VOID *pvCpuVAddr, + IMG_UINT32 ulCpuPAddr, + IMG_VOID *pvPrivateData, + IMG_UINT32 ui32Bytes, + IMG_CHAR *pszFileName, + IMG_UINT32 ui32Line); + +static IMG_VOID DebugMemAllocRecordRemove(DEBUG_MEM_ALLOC_TYPE eAllocType, IMG_VOID *pvKey, IMG_CHAR *pszFileName, IMG_UINT32 ui32Line); + +static IMG_CHAR *DebugMemAllocRecordTypeToString(DEBUG_MEM_ALLOC_TYPE eAllocType); + +static off_t printMemoryRecords(IMG_CHAR * buffer, size_t size, off_t off); +#endif + + +#if defined(DEBUG_LINUX_MEM_AREAS) +typedef struct _DEBUG_LINUX_MEM_AREA_REC +{ + LinuxMemArea *psLinuxMemArea; + IMG_UINT32 ui32Flags; + pid_t pid; + + struct _DEBUG_LINUX_MEM_AREA_REC *psNext; +}DEBUG_LINUX_MEM_AREA_REC; + +#if defined(DEBUG_LINUX_MEM_AREAS) || defined(DEBUG_LINUX_MEMORY_ALLOCATIONS) +static PVRSRV_LINUX_MUTEX g_sDebugMutex; +#endif + +static DEBUG_LINUX_MEM_AREA_REC *g_LinuxMemAreaRecords; +static IMG_UINT32 g_LinuxMemAreaCount; +static IMG_UINT32 g_LinuxMemAreaWaterMark; +static IMG_UINT32 g_LinuxMemAreaHighWaterMark; + +static off_t printLinuxMemAreaRecords(IMG_CHAR * buffer, size_t size, off_t off); +#endif + +static LinuxKMemCache *psLinuxMemAreaCache; + + +#if (LINUX_VERSION_CODE < KERNEL_VERSION(2,6,15)) +static IMG_VOID ReservePages(IMG_VOID *pvAddress, IMG_UINT32 ui32Length); +static IMG_VOID UnreservePages(IMG_VOID *pvAddress, IMG_UINT32 ui32Length); +#endif + +static LinuxMemArea *LinuxMemAreaStructAlloc(IMG_VOID); +static IMG_VOID LinuxMemAreaStructFree(LinuxMemArea *psLinuxMemArea); +#if defined(DEBUG_LINUX_MEM_AREAS) +static IMG_VOID DebugLinuxMemAreaRecordAdd(LinuxMemArea *psLinuxMemArea, IMG_UINT32 ui32Flags); +static DEBUG_LINUX_MEM_AREA_REC *DebugLinuxMemAreaRecordFind(LinuxMemArea *psLinuxMemArea); +static IMG_VOID DebugLinuxMemAreaRecordRemove(LinuxMemArea *psLinuxMemArea); +#endif + +PVRSRV_ERROR +LinuxMMInit(IMG_VOID) +{ +#if defined(DEBUG_LINUX_MEM_AREAS) || defined(DEBUG_LINUX_MEMORY_ALLOCATIONS) + LinuxInitMutex(&g_sDebugMutex); +#endif + +#if defined(DEBUG_LINUX_MEM_AREAS) + { + IMG_INT iStatus; + iStatus = CreateProcReadEntry("mem_areas", printLinuxMemAreaRecords); + if(iStatus!=0) + { + return PVRSRV_ERROR_OUT_OF_MEMORY; + } + } +#endif + + +#if defined(DEBUG_LINUX_MEMORY_ALLOCATIONS) + { + IMG_INT iStatus; + iStatus = CreateProcReadEntry("meminfo", printMemoryRecords); + if(iStatus!=0) + { + return PVRSRV_ERROR_OUT_OF_MEMORY; + } + } +#endif + + psLinuxMemAreaCache = KMemCacheCreateWrapper("img-mm", sizeof(LinuxMemArea), 0, 0); + if(!psLinuxMemAreaCache) + { + PVR_DPF((PVR_DBG_ERROR,"%s: failed to allocate kmem_cache", __FUNCTION__)); + return PVRSRV_ERROR_OUT_OF_MEMORY; + } + + return PVRSRV_OK; +} + + +IMG_VOID +LinuxMMCleanup(IMG_VOID) +{ + +#if defined(DEBUG_LINUX_MEM_AREAS) + { + DEBUG_LINUX_MEM_AREA_REC *psCurrentRecord = g_LinuxMemAreaRecords, *psNextRecord; + + if(g_LinuxMemAreaCount) + { + PVR_DPF((PVR_DBG_ERROR, "%s: BUG!: There are %d LinuxMemArea allocation unfreed (%ld bytes)", + __FUNCTION__, g_LinuxMemAreaCount, g_LinuxMemAreaWaterMark)); + } + + while(psCurrentRecord) + { + LinuxMemArea *psLinuxMemArea; + + psNextRecord = psCurrentRecord->psNext; + psLinuxMemArea = psCurrentRecord->psLinuxMemArea; + PVR_DPF((PVR_DBG_ERROR, "%s: BUG!: Cleaning up Linux memory area (%p), type=%s, size=%ld bytes", + __FUNCTION__, + psCurrentRecord->psLinuxMemArea, + LinuxMemAreaTypeToString(psCurrentRecord->psLinuxMemArea->eAreaType), + psCurrentRecord->psLinuxMemArea->ui32ByteSize)); + + LinuxMemAreaDeepFree(psLinuxMemArea); + + psCurrentRecord = psNextRecord; + } + RemoveProcEntry("mem_areas"); + } +#endif + + +#if defined(DEBUG_LINUX_MEMORY_ALLOCATIONS) + { + DEBUG_MEM_ALLOC_REC *psCurrentRecord = g_MemoryRecords, *psNextRecord; + + + while(psCurrentRecord) + { + psNextRecord = psCurrentRecord->psNext; + PVR_DPF((PVR_DBG_ERROR, "%s: BUG!: Cleaning up memory: " + "type=%s " + "CpuVAddr=%p " + "CpuPAddr=0x%08lx, " + "allocated @ file=%s,line=%d", + __FUNCTION__, + DebugMemAllocRecordTypeToString(psCurrentRecord->eAllocType), + psCurrentRecord->pvCpuVAddr, + psCurrentRecord->ulCpuPAddr, + psCurrentRecord->pszFileName, + psCurrentRecord->ui32Line)); + switch(psCurrentRecord->eAllocType) + { + case DEBUG_MEM_ALLOC_TYPE_KMALLOC: + KFreeWrapper(psCurrentRecord->pvCpuVAddr); + break; + case DEBUG_MEM_ALLOC_TYPE_IOREMAP: + IOUnmapWrapper(psCurrentRecord->pvCpuVAddr); + break; + case DEBUG_MEM_ALLOC_TYPE_IO: + + DebugMemAllocRecordRemove(DEBUG_MEM_ALLOC_TYPE_IO, psCurrentRecord->pvKey, __FILE__, __LINE__); + break; + case DEBUG_MEM_ALLOC_TYPE_VMALLOC: + VFreeWrapper(psCurrentRecord->pvCpuVAddr); + break; + case DEBUG_MEM_ALLOC_TYPE_ALLOC_PAGES: + + DebugMemAllocRecordRemove(DEBUG_MEM_ALLOC_TYPE_ALLOC_PAGES, psCurrentRecord->pvKey, __FILE__, __LINE__); + break; + case DEBUG_MEM_ALLOC_TYPE_KMEM_CACHE: + KMemCacheFreeWrapper(psCurrentRecord->pvPrivateData, psCurrentRecord->pvCpuVAddr); + break; + default: + PVR_ASSERT(0); + } + psCurrentRecord = psNextRecord; + } + RemoveProcEntry("meminfo"); + } +#endif + + if(psLinuxMemAreaCache) + { + KMemCacheDestroyWrapper(psLinuxMemAreaCache); + psLinuxMemAreaCache=NULL; + } +} + + +IMG_VOID * +_KMallocWrapper(IMG_UINT32 ui32ByteSize, IMG_CHAR *pszFileName, IMG_UINT32 ui32Line) +{ + IMG_VOID *pvRet; + pvRet = kmalloc(ui32ByteSize, GFP_KERNEL); +#if defined(DEBUG_LINUX_MEMORY_ALLOCATIONS) + if(pvRet) + { + DebugMemAllocRecordAdd(DEBUG_MEM_ALLOC_TYPE_KMALLOC, + pvRet, + pvRet, + 0, + NULL, + ui32ByteSize, + pszFileName, + ui32Line + ); + } +#endif + return pvRet; +} + + +IMG_VOID +_KFreeWrapper(IMG_VOID *pvCpuVAddr, IMG_CHAR *pszFileName, IMG_UINT32 ui32Line) +{ +#if defined(DEBUG_LINUX_MEMORY_ALLOCATIONS) + DebugMemAllocRecordRemove(DEBUG_MEM_ALLOC_TYPE_KMALLOC, pvCpuVAddr, pszFileName, ui32Line); +#endif + kfree(pvCpuVAddr); +} + + +#if defined(DEBUG_LINUX_MEMORY_ALLOCATIONS) +static IMG_VOID +DebugMemAllocRecordAdd(DEBUG_MEM_ALLOC_TYPE eAllocType, + IMG_VOID *pvKey, + IMG_VOID *pvCpuVAddr, + IMG_UINT32 ulCpuPAddr, + IMG_VOID *pvPrivateData, + IMG_UINT32 ui32Bytes, + IMG_CHAR *pszFileName, + IMG_UINT32 ui32Line) +{ + DEBUG_MEM_ALLOC_REC *psRecord; + + LinuxLockMutex(&g_sDebugMutex); + + psRecord = kmalloc(sizeof(DEBUG_MEM_ALLOC_REC), GFP_KERNEL); + + psRecord->eAllocType = eAllocType; + psRecord->pvKey = pvKey; + psRecord->pvCpuVAddr = pvCpuVAddr; + psRecord->ulCpuPAddr = ulCpuPAddr; + psRecord->pvPrivateData = pvPrivateData; + psRecord->pid = current->pid; + psRecord->ui32Bytes = ui32Bytes; + psRecord->pszFileName = pszFileName; + psRecord->ui32Line = ui32Line; + + psRecord->psNext = g_MemoryRecords; + g_MemoryRecords = psRecord; + + g_WaterMarkData[eAllocType] += ui32Bytes; + if(g_WaterMarkData[eAllocType] > g_HighWaterMarkData[eAllocType]) + { + g_HighWaterMarkData[eAllocType] = g_WaterMarkData[eAllocType]; + } + + if(eAllocType == DEBUG_MEM_ALLOC_TYPE_KMALLOC + || eAllocType == DEBUG_MEM_ALLOC_TYPE_VMALLOC + || eAllocType == DEBUG_MEM_ALLOC_TYPE_ALLOC_PAGES + || eAllocType == DEBUG_MEM_ALLOC_TYPE_KMEM_CACHE) + { + g_SysRAMWaterMark += ui32Bytes; + if(g_SysRAMWaterMark > g_SysRAMHighWaterMark) + { + g_SysRAMHighWaterMark = g_SysRAMWaterMark; + } + } + else if(eAllocType == DEBUG_MEM_ALLOC_TYPE_IOREMAP + || eAllocType == DEBUG_MEM_ALLOC_TYPE_IO) + { + g_IOMemWaterMark += ui32Bytes; + if(g_IOMemWaterMark > g_IOMemHighWaterMark) + { + g_IOMemHighWaterMark = g_IOMemWaterMark; + } + } + + LinuxUnLockMutex(&g_sDebugMutex); +} + + + +static IMG_VOID +DebugMemAllocRecordRemove(DEBUG_MEM_ALLOC_TYPE eAllocType, IMG_VOID *pvKey, IMG_CHAR *pszFileName, IMG_UINT32 ui32Line) +{ + DEBUG_MEM_ALLOC_REC **ppsCurrentRecord; + + LinuxLockMutex(&g_sDebugMutex); + + + for(ppsCurrentRecord = &g_MemoryRecords; + *ppsCurrentRecord; + ppsCurrentRecord = &((*ppsCurrentRecord)->psNext)) + { + if((*ppsCurrentRecord)->eAllocType == eAllocType + && (*ppsCurrentRecord)->pvKey == pvKey) + { + DEBUG_MEM_ALLOC_REC *psNextRecord; + DEBUG_MEM_ALLOC_TYPE eAllocType; + + psNextRecord = (*ppsCurrentRecord)->psNext; + eAllocType = (*ppsCurrentRecord)->eAllocType; + g_WaterMarkData[eAllocType] -= (*ppsCurrentRecord)->ui32Bytes; + + if(eAllocType == DEBUG_MEM_ALLOC_TYPE_KMALLOC + || eAllocType == DEBUG_MEM_ALLOC_TYPE_VMALLOC + || eAllocType == DEBUG_MEM_ALLOC_TYPE_ALLOC_PAGES + || eAllocType == DEBUG_MEM_ALLOC_TYPE_KMEM_CACHE) + { + g_SysRAMWaterMark -= (*ppsCurrentRecord)->ui32Bytes; + } + else if(eAllocType == DEBUG_MEM_ALLOC_TYPE_IOREMAP + || eAllocType == DEBUG_MEM_ALLOC_TYPE_IO) + { + g_IOMemWaterMark -= (*ppsCurrentRecord)->ui32Bytes; + } + + kfree(*ppsCurrentRecord); + *ppsCurrentRecord = psNextRecord; + goto exit_unlock; + } + } + + PVR_DPF((PVR_DBG_ERROR, "%s: couldn't find an entry for type=%s with pvKey=%p (called from %s, line %d\n", + __FUNCTION__, DebugMemAllocRecordTypeToString(eAllocType), pvKey, + pszFileName, ui32Line)); + +exit_unlock: + LinuxUnLockMutex(&g_sDebugMutex); +} + + +static IMG_CHAR * +DebugMemAllocRecordTypeToString(DEBUG_MEM_ALLOC_TYPE eAllocType) +{ + IMG_CHAR *apszDebugMemoryRecordTypes[] = { + "KMALLOC", + "VMALLOC", + "ALLOC_PAGES", + "IOREMAP", + "IO", + "KMEM_CACHE_ALLOC" + }; + return apszDebugMemoryRecordTypes[eAllocType]; +} +#endif + + + +IMG_VOID * +_VMallocWrapper(IMG_UINT32 ui32Bytes, + IMG_UINT32 ui32AllocFlags, + IMG_CHAR *pszFileName, + IMG_UINT32 ui32Line) +{ + pgprot_t PGProtFlags; + IMG_VOID *pvRet; + + switch(ui32AllocFlags & PVRSRV_HAP_CACHETYPE_MASK) + { + case PVRSRV_HAP_CACHED: + PGProtFlags = PAGE_KERNEL; + break; + case PVRSRV_HAP_WRITECOMBINE: + PGProtFlags = PGPROT_WC(PAGE_KERNEL); + break; + case PVRSRV_HAP_UNCACHED: + PGProtFlags = PGPROT_UC(PAGE_KERNEL); + break; + default: + PVR_DPF((PVR_DBG_ERROR, + "VMAllocWrapper: unknown mapping flags=0x%08lx", + ui32AllocFlags)); + dump_stack(); + return NULL; + } + + + pvRet = __vmalloc(ui32Bytes, GFP_KERNEL | __GFP_HIGHMEM, PGProtFlags); + +#if defined(DEBUG_LINUX_MEMORY_ALLOCATIONS) + if(pvRet) + { + DebugMemAllocRecordAdd(DEBUG_MEM_ALLOC_TYPE_VMALLOC, + pvRet, + pvRet, + 0, + NULL, + PAGE_ALIGN(ui32Bytes), + pszFileName, + ui32Line + ); + } +#endif + + return pvRet; +} + + +IMG_VOID +_VFreeWrapper(IMG_VOID *pvCpuVAddr, IMG_CHAR *pszFileName, IMG_UINT32 ui32Line) +{ +#if defined(DEBUG_LINUX_MEMORY_ALLOCATIONS) + DebugMemAllocRecordRemove(DEBUG_MEM_ALLOC_TYPE_VMALLOC, pvCpuVAddr, pszFileName, ui32Line); +#endif + vfree(pvCpuVAddr); +} + + +LinuxMemArea * +NewVMallocLinuxMemArea(IMG_UINT32 ui32Bytes, IMG_UINT32 ui32AreaFlags) +{ + LinuxMemArea *psLinuxMemArea; + IMG_VOID *pvCpuVAddr; + + psLinuxMemArea = LinuxMemAreaStructAlloc(); + if(!psLinuxMemArea) + { + goto failed; + } + + pvCpuVAddr = VMallocWrapper(ui32Bytes, ui32AreaFlags); + if(!pvCpuVAddr) + { + goto failed; + } + +#if (LINUX_VERSION_CODE < KERNEL_VERSION(2,6,15)) + + ReservePages(pvCpuVAddr, ui32Bytes); +#endif + + psLinuxMemArea->eAreaType = LINUX_MEM_AREA_VMALLOC; + psLinuxMemArea->uData.sVmalloc.pvVmallocAddress = pvCpuVAddr; + psLinuxMemArea->ui32ByteSize = ui32Bytes; + psLinuxMemArea->ui32AreaFlags = ui32AreaFlags; + psLinuxMemArea->bMMapRegistered = IMG_FALSE; + INIT_LIST_HEAD(&psLinuxMemArea->sMMapOffsetStructList); + +#if defined(DEBUG_LINUX_MEM_AREAS) + DebugLinuxMemAreaRecordAdd(psLinuxMemArea, ui32AreaFlags); +#endif + + return psLinuxMemArea; + +failed: + PVR_DPF((PVR_DBG_ERROR, "%s: failed!", __FUNCTION__)); + if(psLinuxMemArea) + LinuxMemAreaStructFree(psLinuxMemArea); + return NULL; +} + + +IMG_VOID +FreeVMallocLinuxMemArea(LinuxMemArea *psLinuxMemArea) +{ + PVR_ASSERT(psLinuxMemArea); + PVR_ASSERT(psLinuxMemArea->eAreaType == LINUX_MEM_AREA_VMALLOC); + PVR_ASSERT(psLinuxMemArea->uData.sVmalloc.pvVmallocAddress); + +#if defined(DEBUG_LINUX_MEM_AREAS) + DebugLinuxMemAreaRecordRemove(psLinuxMemArea); +#endif + +#if (LINUX_VERSION_CODE < KERNEL_VERSION(2,6,15)) + UnreservePages(psLinuxMemArea->uData.sVmalloc.pvVmallocAddress, + psLinuxMemArea->ui32ByteSize); +#endif + + PVR_DPF((PVR_DBG_MESSAGE,"%s: pvCpuVAddr: %p", + __FUNCTION__, psLinuxMemArea->uData.sVmalloc.pvVmallocAddress)); + VFreeWrapper(psLinuxMemArea->uData.sVmalloc.pvVmallocAddress); + + LinuxMemAreaStructFree(psLinuxMemArea); +} + + +#if (LINUX_VERSION_CODE < KERNEL_VERSION(2,6,15)) +static IMG_VOID +ReservePages(IMG_VOID *pvAddress, IMG_UINT32 ui32Length) +{ + IMG_VOID *pvPage; + IMG_VOID *pvEnd = pvAddress + ui32Length; + + for(pvPage = pvAddress; pvPage < pvEnd; pvPage += PAGE_SIZE) + { +#if (LINUX_VERSION_CODE > KERNEL_VERSION(2,6,0)) + SetPageReserved(vmalloc_to_page(pvPage)); +#else + mem_map_reserve(vmalloc_to_page(pvPage)); +#endif + } +} + + +static IMG_VOID +UnreservePages(IMG_VOID *pvAddress, IMG_UINT32 ui32Length) +{ + IMG_VOID *pvPage; + IMG_VOID *pvEnd = pvAddress + ui32Length; + + for(pvPage = pvAddress; pvPage < pvEnd; pvPage += PAGE_SIZE) + { +#if (LINUX_VERSION_CODE > KERNEL_VERSION(2,6,0)) + ClearPageReserved(vmalloc_to_page(pvPage)); +#else + mem_map_unreserve(vmalloc_to_page(pvPage)); +#endif + } +} +#endif + + +IMG_VOID * +_IORemapWrapper(IMG_CPU_PHYADDR BasePAddr, + IMG_UINT32 ui32Bytes, + IMG_UINT32 ui32MappingFlags, + IMG_CHAR *pszFileName, + IMG_UINT32 ui32Line) +{ + IMG_VOID *pvIORemapCookie = IMG_NULL; + + switch(ui32MappingFlags & PVRSRV_HAP_CACHETYPE_MASK) + { + case PVRSRV_HAP_CACHED: + pvIORemapCookie = (IMG_VOID *)IOREMAP(BasePAddr.uiAddr, ui32Bytes); + break; + case PVRSRV_HAP_WRITECOMBINE: + pvIORemapCookie = (IMG_VOID *)IOREMAP_WC(BasePAddr.uiAddr, ui32Bytes); + break; + case PVRSRV_HAP_UNCACHED: + pvIORemapCookie = (IMG_VOID *)IOREMAP_UC(BasePAddr.uiAddr, ui32Bytes); + break; + default: + PVR_DPF((PVR_DBG_ERROR, "IORemapWrapper: unknown mapping flags")); + return NULL; + } + +#if defined(DEBUG_LINUX_MEMORY_ALLOCATIONS) + if(pvIORemapCookie) + { + DebugMemAllocRecordAdd(DEBUG_MEM_ALLOC_TYPE_IOREMAP, + pvIORemapCookie, + pvIORemapCookie, + BasePAddr.uiAddr, + NULL, + ui32Bytes, + pszFileName, + ui32Line + ); + } +#endif + + return pvIORemapCookie; +} + + +IMG_VOID +_IOUnmapWrapper(IMG_VOID *pvIORemapCookie, IMG_CHAR *pszFileName, IMG_UINT32 ui32Line) +{ +#if defined(DEBUG_LINUX_MEMORY_ALLOCATIONS) + DebugMemAllocRecordRemove(DEBUG_MEM_ALLOC_TYPE_IOREMAP, pvIORemapCookie, pszFileName, ui32Line); +#endif + iounmap(pvIORemapCookie); +} + + +LinuxMemArea * +NewIORemapLinuxMemArea(IMG_CPU_PHYADDR BasePAddr, + IMG_UINT32 ui32Bytes, + IMG_UINT32 ui32AreaFlags) +{ + LinuxMemArea *psLinuxMemArea; + IMG_VOID *pvIORemapCookie; + + psLinuxMemArea = LinuxMemAreaStructAlloc(); + if(!psLinuxMemArea) + { + return NULL; + } + + pvIORemapCookie = IORemapWrapper(BasePAddr, ui32Bytes, ui32AreaFlags); + if(!pvIORemapCookie) + { + LinuxMemAreaStructFree(psLinuxMemArea); + return NULL; + } + + psLinuxMemArea->eAreaType = LINUX_MEM_AREA_IOREMAP; + psLinuxMemArea->uData.sIORemap.pvIORemapCookie = pvIORemapCookie; + psLinuxMemArea->uData.sIORemap.CPUPhysAddr = BasePAddr; + psLinuxMemArea->ui32ByteSize = ui32Bytes; + psLinuxMemArea->ui32AreaFlags = ui32AreaFlags; + psLinuxMemArea->bMMapRegistered = IMG_FALSE; + INIT_LIST_HEAD(&psLinuxMemArea->sMMapOffsetStructList); + +#if defined(DEBUG_LINUX_MEM_AREAS) + DebugLinuxMemAreaRecordAdd(psLinuxMemArea, ui32AreaFlags); +#endif + + return psLinuxMemArea; +} + + +IMG_VOID +FreeIORemapLinuxMemArea(LinuxMemArea *psLinuxMemArea) +{ + PVR_ASSERT(psLinuxMemArea->eAreaType == LINUX_MEM_AREA_IOREMAP); + +#if defined(DEBUG_LINUX_MEM_AREAS) + DebugLinuxMemAreaRecordRemove(psLinuxMemArea); +#endif + + IOUnmapWrapper(psLinuxMemArea->uData.sIORemap.pvIORemapCookie); + + LinuxMemAreaStructFree(psLinuxMemArea); +} + + +static IMG_BOOL +PagesAreContiguous(IMG_SYS_PHYADDR *psSysPhysAddr, IMG_UINT32 ui32Bytes) +{ + IMG_UINT32 ui32; + IMG_UINT32 ui32AddrChk; + IMG_UINT32 ui32NumPages = RANGE_TO_PAGES(ui32Bytes); + + for (ui32 = 0, ui32AddrChk = psSysPhysAddr[0].uiAddr; + ui32 < ui32NumPages; + ui32++, ui32AddrChk += PAGE_SIZE) + { + if (psSysPhysAddr[ui32].uiAddr != ui32AddrChk) + { + return IMG_FALSE; + } + } + + return IMG_TRUE; +} + +LinuxMemArea *NewExternalKVLinuxMemArea(IMG_SYS_PHYADDR *pBasePAddr, IMG_VOID *pvCPUVAddr, IMG_UINT32 ui32Bytes, IMG_BOOL bPhysContig, IMG_UINT32 ui32AreaFlags) +{ + LinuxMemArea *psLinuxMemArea; + + psLinuxMemArea = LinuxMemAreaStructAlloc(); + if(!psLinuxMemArea) + { + return NULL; + } + + psLinuxMemArea->eAreaType = LINUX_MEM_AREA_EXTERNAL_KV; + psLinuxMemArea->uData.sExternalKV.pvExternalKV = pvCPUVAddr; + psLinuxMemArea->uData.sExternalKV.bPhysContig = bPhysContig || PagesAreContiguous(pBasePAddr, ui32Bytes); + + if (psLinuxMemArea->uData.sExternalKV.bPhysContig) + { + psLinuxMemArea->uData.sExternalKV.uPhysAddr.SysPhysAddr = *pBasePAddr; + } + else + { + psLinuxMemArea->uData.sExternalKV.uPhysAddr.pSysPhysAddr = pBasePAddr; + } + psLinuxMemArea->ui32ByteSize = ui32Bytes; + psLinuxMemArea->ui32AreaFlags = ui32AreaFlags; + psLinuxMemArea->bMMapRegistered = IMG_FALSE; + INIT_LIST_HEAD(&psLinuxMemArea->sMMapOffsetStructList); + +#if defined(DEBUG_LINUX_MEM_AREAS) + DebugLinuxMemAreaRecordAdd(psLinuxMemArea, ui32AreaFlags); +#endif + + return psLinuxMemArea; +} + + +IMG_VOID +FreeExternalKVLinuxMemArea(LinuxMemArea *psLinuxMemArea) +{ + PVR_ASSERT(psLinuxMemArea->eAreaType == LINUX_MEM_AREA_EXTERNAL_KV); + +#if defined(DEBUG_LINUX_MEM_AREAS) + DebugLinuxMemAreaRecordRemove(psLinuxMemArea); +#endif + + LinuxMemAreaStructFree(psLinuxMemArea); +} + + +LinuxMemArea * +NewIOLinuxMemArea(IMG_CPU_PHYADDR BasePAddr, + IMG_UINT32 ui32Bytes, + IMG_UINT32 ui32AreaFlags) +{ + LinuxMemArea *psLinuxMemArea = LinuxMemAreaStructAlloc(); + if(!psLinuxMemArea) + { + return NULL; + } + + + psLinuxMemArea->eAreaType = LINUX_MEM_AREA_IO; + psLinuxMemArea->uData.sIO.CPUPhysAddr.uiAddr = BasePAddr.uiAddr; + psLinuxMemArea->ui32ByteSize = ui32Bytes; + psLinuxMemArea->ui32AreaFlags = ui32AreaFlags; + psLinuxMemArea->bMMapRegistered = IMG_FALSE; + INIT_LIST_HEAD(&psLinuxMemArea->sMMapOffsetStructList); + +#if defined(DEBUG_LINUX_MEMORY_ALLOCATIONS) + DebugMemAllocRecordAdd(DEBUG_MEM_ALLOC_TYPE_IO, + (IMG_VOID *)BasePAddr.uiAddr, + 0, + BasePAddr.uiAddr, + NULL, + ui32Bytes, + "unknown", + 0 + ); +#endif + +#if defined(DEBUG_LINUX_MEM_AREAS) + DebugLinuxMemAreaRecordAdd(psLinuxMemArea, ui32AreaFlags); +#endif + + return psLinuxMemArea; +} + + +IMG_VOID +FreeIOLinuxMemArea(LinuxMemArea *psLinuxMemArea) +{ + PVR_ASSERT(psLinuxMemArea->eAreaType == LINUX_MEM_AREA_IO); + +#if defined(DEBUG_LINUX_MEM_AREAS) + DebugLinuxMemAreaRecordRemove(psLinuxMemArea); +#endif + +#if defined(DEBUG_LINUX_MEMORY_ALLOCATIONS) + DebugMemAllocRecordRemove(DEBUG_MEM_ALLOC_TYPE_IO, + (IMG_VOID *)psLinuxMemArea->uData.sIO.CPUPhysAddr.uiAddr, __FILE__, __LINE__); +#endif + + + + LinuxMemAreaStructFree(psLinuxMemArea); +} + + +LinuxMemArea * +NewAllocPagesLinuxMemArea(IMG_UINT32 ui32Bytes, IMG_UINT32 ui32AreaFlags) +{ + LinuxMemArea *psLinuxMemArea; + IMG_UINT32 ui32PageCount; + struct page **pvPageList; + IMG_HANDLE hBlockPageList; + IMG_INT32 i; + PVRSRV_ERROR eError; + + psLinuxMemArea = LinuxMemAreaStructAlloc(); + if(!psLinuxMemArea) + { + goto failed_area_alloc; + } + + ui32PageCount = RANGE_TO_PAGES(ui32Bytes); + eError = OSAllocMem(0, sizeof(*pvPageList) * ui32PageCount, (IMG_VOID **)&pvPageList, &hBlockPageList); + if(eError != PVRSRV_OK) + { + goto failed_page_list_alloc; + } + + for(i=0; i KERNEL_VERSION(2,6,0)) + SetPageReserved(pvPageList[i]); +#else + mem_map_reserve(pvPageList[i]); +#endif +#endif + + } + +#if defined(DEBUG_LINUX_MEMORY_ALLOCATIONS) + DebugMemAllocRecordAdd(DEBUG_MEM_ALLOC_TYPE_ALLOC_PAGES, + pvPageList, + 0, + 0, + NULL, + PAGE_ALIGN(ui32Bytes), + "unknown", + 0 + ); +#endif + + psLinuxMemArea->eAreaType = LINUX_MEM_AREA_ALLOC_PAGES; + psLinuxMemArea->uData.sPageList.pvPageList = pvPageList; + psLinuxMemArea->uData.sPageList.hBlockPageList = hBlockPageList; + psLinuxMemArea->ui32ByteSize = ui32Bytes; + psLinuxMemArea->ui32AreaFlags = ui32AreaFlags; + psLinuxMemArea->bMMapRegistered = IMG_FALSE; + INIT_LIST_HEAD(&psLinuxMemArea->sMMapOffsetStructList); + +#if defined(DEBUG_LINUX_MEM_AREAS) + DebugLinuxMemAreaRecordAdd(psLinuxMemArea, ui32AreaFlags); +#endif + + return psLinuxMemArea; + +failed_alloc_pages: + for(i--; i >= 0; i--) + { + __free_pages(pvPageList[i], 0); + } + (IMG_VOID) OSFreeMem(0, sizeof(*pvPageList) * ui32PageCount, pvPageList, hBlockPageList); +failed_page_list_alloc: + LinuxMemAreaStructFree(psLinuxMemArea); +failed_area_alloc: + PVR_DPF((PVR_DBG_ERROR, "%s: failed", __FUNCTION__)); + + return NULL; +} + + +IMG_VOID +FreeAllocPagesLinuxMemArea(LinuxMemArea *psLinuxMemArea) +{ + IMG_UINT32 ui32PageCount; + struct page **pvPageList; + IMG_HANDLE hBlockPageList; + IMG_UINT32 i; + + PVR_ASSERT(psLinuxMemArea); + PVR_ASSERT(psLinuxMemArea->eAreaType == LINUX_MEM_AREA_ALLOC_PAGES); + +#if defined(DEBUG_LINUX_MEM_AREAS) + DebugLinuxMemAreaRecordRemove(psLinuxMemArea); +#endif + + ui32PageCount = RANGE_TO_PAGES(psLinuxMemArea->ui32ByteSize); + pvPageList = psLinuxMemArea->uData.sPageList.pvPageList; + hBlockPageList = psLinuxMemArea->uData.sPageList.hBlockPageList; + +#if defined(DEBUG_LINUX_MEMORY_ALLOCATIONS) + DebugMemAllocRecordRemove(DEBUG_MEM_ALLOC_TYPE_ALLOC_PAGES, pvPageList, __FILE__, __LINE__); +#endif + + for(i=0;i KERNEL_VERSION(2,6,0)) + ClearPageReserved(pvPageList[i]); +#else + mem_map_reserve(pvPageList[i]); +#endif +#endif + __free_pages(pvPageList[i], 0); + } + + (IMG_VOID) OSFreeMem(0, sizeof(*pvPageList) * ui32PageCount, pvPageList, hBlockPageList); + + LinuxMemAreaStructFree(psLinuxMemArea); +} + + +struct page* +LinuxMemAreaOffsetToPage(LinuxMemArea *psLinuxMemArea, + IMG_UINT32 ui32ByteOffset) +{ + IMG_UINT32 ui32PageIndex; + IMG_CHAR *pui8Addr; + + switch(psLinuxMemArea->eAreaType) + { + case LINUX_MEM_AREA_ALLOC_PAGES: + ui32PageIndex = PHYS_TO_PFN(ui32ByteOffset); + return psLinuxMemArea->uData.sPageList.pvPageList[ui32PageIndex]; + break; + case LINUX_MEM_AREA_VMALLOC: + pui8Addr = psLinuxMemArea->uData.sVmalloc.pvVmallocAddress; + pui8Addr += ui32ByteOffset; + return vmalloc_to_page(pui8Addr); + break; + case LINUX_MEM_AREA_SUB_ALLOC: + return LinuxMemAreaOffsetToPage(psLinuxMemArea->uData.sSubAlloc.psParentLinuxMemArea, + psLinuxMemArea->uData.sSubAlloc.ui32ByteOffset + + ui32ByteOffset); + default: + PVR_DPF((PVR_DBG_ERROR, + "%s: Unsupported request for struct page from LinuxMemArea with type=%s", + LinuxMemAreaTypeToString(psLinuxMemArea->eAreaType))); + return NULL; + } +} + + +LinuxKMemCache * +KMemCacheCreateWrapper(IMG_CHAR *pszName, + size_t Size, + size_t Align, + IMG_UINT32 ui32Flags) +{ +#if defined(DEBUG_LINUX_SLAB_ALLOCATIONS) + ui32Flags |= SLAB_POISON|SLAB_RED_ZONE; +#endif + return kmem_cache_create(pszName, Size, Align, ui32Flags, NULL +#if (LINUX_VERSION_CODE <= KERNEL_VERSION(2,6,22)) + , NULL +#endif + ); +} + + +IMG_VOID +KMemCacheDestroyWrapper(LinuxKMemCache *psCache) +{ + kmem_cache_destroy(psCache); +} + + +IMG_VOID * +_KMemCacheAllocWrapper(LinuxKMemCache *psCache, +#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,14)) + gfp_t Flags, +#else + IMG_INT Flags, +#endif + IMG_CHAR *pszFileName, + IMG_UINT32 ui32Line) +{ + IMG_VOID *pvRet; + + pvRet = kmem_cache_alloc(psCache, Flags); + +#if defined(DEBUG_LINUX_MEMORY_ALLOCATIONS) + DebugMemAllocRecordAdd(DEBUG_MEM_ALLOC_TYPE_KMEM_CACHE, + pvRet, + pvRet, + 0, + psCache, + kmem_cache_size(psCache), + pszFileName, + ui32Line + ); +#endif + + return pvRet; +} + + +IMG_VOID +_KMemCacheFreeWrapper(LinuxKMemCache *psCache, IMG_VOID *pvObject, IMG_CHAR *pszFileName, IMG_UINT32 ui32Line) +{ +#if defined(DEBUG_LINUX_MEMORY_ALLOCATIONS) + DebugMemAllocRecordRemove(DEBUG_MEM_ALLOC_TYPE_KMEM_CACHE, pvObject, pszFileName, ui32Line); +#endif + + kmem_cache_free(psCache, pvObject); +} + + +const IMG_CHAR * +KMemCacheNameWrapper(LinuxKMemCache *psCache) +{ + + return ""; +} + + +LinuxMemArea * +NewSubLinuxMemArea(LinuxMemArea *psParentLinuxMemArea, + IMG_UINT32 ui32ByteOffset, + IMG_UINT32 ui32Bytes) +{ + LinuxMemArea *psLinuxMemArea; + + PVR_ASSERT((ui32ByteOffset+ui32Bytes) <= psParentLinuxMemArea->ui32ByteSize); + + psLinuxMemArea = LinuxMemAreaStructAlloc(); + if(!psLinuxMemArea) + { + return NULL; + } + + psLinuxMemArea->eAreaType = LINUX_MEM_AREA_SUB_ALLOC; + psLinuxMemArea->uData.sSubAlloc.psParentLinuxMemArea = psParentLinuxMemArea; + psLinuxMemArea->uData.sSubAlloc.ui32ByteOffset = ui32ByteOffset; + psLinuxMemArea->ui32ByteSize = ui32Bytes; + psLinuxMemArea->ui32AreaFlags = psParentLinuxMemArea->ui32AreaFlags; + psLinuxMemArea->bMMapRegistered = IMG_FALSE; + INIT_LIST_HEAD(&psLinuxMemArea->sMMapOffsetStructList); + +#if defined(DEBUG_LINUX_MEM_AREAS) + { + DEBUG_LINUX_MEM_AREA_REC *psParentRecord; + psParentRecord = DebugLinuxMemAreaRecordFind(psParentLinuxMemArea); + DebugLinuxMemAreaRecordAdd(psLinuxMemArea, psParentRecord->ui32Flags); + } +#endif + + return psLinuxMemArea; +} + + +IMG_VOID +FreeSubLinuxMemArea(LinuxMemArea *psLinuxMemArea) +{ + PVR_ASSERT(psLinuxMemArea->eAreaType == LINUX_MEM_AREA_SUB_ALLOC); + +#if defined(DEBUG_LINUX_MEM_AREAS) + DebugLinuxMemAreaRecordRemove(psLinuxMemArea); +#endif + + + + LinuxMemAreaStructFree(psLinuxMemArea); +} + + +static LinuxMemArea * +LinuxMemAreaStructAlloc(IMG_VOID) +{ +#if 0 + LinuxMemArea *psLinuxMemArea; + psLinuxMemArea = kmem_cache_alloc(psLinuxMemAreaCache, GFP_KERNEL); + printk(KERN_ERR "%s: psLinuxMemArea=%p\n", __FUNCTION__, psLinuxMemArea); + dump_stack(); + return psLinuxMemArea; +#else + return KMemCacheAllocWrapper(psLinuxMemAreaCache, GFP_KERNEL); +#endif +} + + +static IMG_VOID +LinuxMemAreaStructFree(LinuxMemArea *psLinuxMemArea) +{ + KMemCacheFreeWrapper(psLinuxMemAreaCache, psLinuxMemArea); + + +} + + +IMG_VOID +LinuxMemAreaDeepFree(LinuxMemArea *psLinuxMemArea) +{ + switch(psLinuxMemArea->eAreaType) + { + case LINUX_MEM_AREA_VMALLOC: + FreeVMallocLinuxMemArea(psLinuxMemArea); + break; + case LINUX_MEM_AREA_ALLOC_PAGES: + FreeAllocPagesLinuxMemArea(psLinuxMemArea); + break; + case LINUX_MEM_AREA_IOREMAP: + FreeIORemapLinuxMemArea(psLinuxMemArea); + break; + case LINUX_MEM_AREA_EXTERNAL_KV: + FreeExternalKVLinuxMemArea(psLinuxMemArea); + break; + case LINUX_MEM_AREA_IO: + FreeIOLinuxMemArea(psLinuxMemArea); + break; + case LINUX_MEM_AREA_SUB_ALLOC: + FreeSubLinuxMemArea(psLinuxMemArea); + break; + default: + PVR_DPF((PVR_DBG_ERROR, "%s: Unknown are type (%d)\n", + __FUNCTION__, psLinuxMemArea->eAreaType)); + } +} + + +#if defined(DEBUG_LINUX_MEM_AREAS) +static IMG_VOID +DebugLinuxMemAreaRecordAdd(LinuxMemArea *psLinuxMemArea, IMG_UINT32 ui32Flags) +{ + DEBUG_LINUX_MEM_AREA_REC *psNewRecord; + const IMG_CHAR *pi8FlagsString; + + LinuxLockMutex(&g_sDebugMutex); + + if(psLinuxMemArea->eAreaType != LINUX_MEM_AREA_SUB_ALLOC) + { + g_LinuxMemAreaWaterMark += psLinuxMemArea->ui32ByteSize; + if(g_LinuxMemAreaWaterMark > g_LinuxMemAreaHighWaterMark) + { + g_LinuxMemAreaHighWaterMark = g_LinuxMemAreaWaterMark; + } + } + g_LinuxMemAreaCount++; + + + psNewRecord = kmalloc(sizeof(DEBUG_LINUX_MEM_AREA_REC), GFP_KERNEL); + if(psNewRecord) + { + + psNewRecord->psLinuxMemArea = psLinuxMemArea; + psNewRecord->ui32Flags = ui32Flags; + psNewRecord->pid = current->pid; + psNewRecord->psNext = g_LinuxMemAreaRecords; + g_LinuxMemAreaRecords = psNewRecord; + } + else + { + PVR_DPF((PVR_DBG_ERROR, + "%s: failed to allocate linux memory area record.", + __FUNCTION__)); + } + + + pi8FlagsString = HAPFlagsToString(ui32Flags); + if(strstr(pi8FlagsString, "UNKNOWN")) + { + PVR_DPF((PVR_DBG_ERROR, + "%s: Unexpected flags (0x%08lx) associated with psLinuxMemArea @ 0x%08lx", + __FUNCTION__, + ui32Flags, + psLinuxMemArea)); + + } + + LinuxUnLockMutex(&g_sDebugMutex); +} + + +static DEBUG_LINUX_MEM_AREA_REC * +DebugLinuxMemAreaRecordFind(LinuxMemArea *psLinuxMemArea) +{ + DEBUG_LINUX_MEM_AREA_REC *psCurrentRecord; + + LinuxLockMutex(&g_sDebugMutex); + + for(psCurrentRecord = g_LinuxMemAreaRecords; + psCurrentRecord; + psCurrentRecord = psCurrentRecord->psNext) + { + if(psCurrentRecord->psLinuxMemArea == psLinuxMemArea) + { + goto exit_unlock; + } + } + +exit_unlock: + LinuxUnLockMutex(&g_sDebugMutex); + + return psCurrentRecord; +} + + +static IMG_VOID +DebugLinuxMemAreaRecordRemove(LinuxMemArea *psLinuxMemArea) +{ + DEBUG_LINUX_MEM_AREA_REC **ppsCurrentRecord; + + LinuxLockMutex(&g_sDebugMutex); + + if(psLinuxMemArea->eAreaType != LINUX_MEM_AREA_SUB_ALLOC) + { + g_LinuxMemAreaWaterMark -= psLinuxMemArea->ui32ByteSize; + } + g_LinuxMemAreaCount--; + + + for(ppsCurrentRecord = &g_LinuxMemAreaRecords; + *ppsCurrentRecord; + ppsCurrentRecord = &((*ppsCurrentRecord)->psNext)) + { + if((*ppsCurrentRecord)->psLinuxMemArea == psLinuxMemArea) + { + DEBUG_LINUX_MEM_AREA_REC *psNextRecord; + + psNextRecord = (*ppsCurrentRecord)->psNext; + kfree(*ppsCurrentRecord); + *ppsCurrentRecord = psNextRecord; + goto exit_unlock; + } + } + + PVR_DPF((PVR_DBG_ERROR, "%s: couldn't find an entry for psLinuxMemArea=%p\n", + __FUNCTION__, psLinuxMemArea)); + +exit_unlock: + LinuxUnLockMutex(&g_sDebugMutex); +} +#endif + + +IMG_VOID * +LinuxMemAreaToCpuVAddr(LinuxMemArea *psLinuxMemArea) +{ + switch(psLinuxMemArea->eAreaType) + { + case LINUX_MEM_AREA_VMALLOC: + return psLinuxMemArea->uData.sVmalloc.pvVmallocAddress; + case LINUX_MEM_AREA_IOREMAP: + return psLinuxMemArea->uData.sIORemap.pvIORemapCookie; + case LINUX_MEM_AREA_EXTERNAL_KV: + return psLinuxMemArea->uData.sExternalKV.pvExternalKV; + case LINUX_MEM_AREA_SUB_ALLOC: + { + IMG_CHAR *pAddr = + LinuxMemAreaToCpuVAddr(psLinuxMemArea->uData.sSubAlloc.psParentLinuxMemArea); + if(!pAddr) + { + return NULL; + } + return pAddr + psLinuxMemArea->uData.sSubAlloc.ui32ByteOffset; + } + default: + return NULL; + } +} + + +IMG_CPU_PHYADDR +LinuxMemAreaToCpuPAddr(LinuxMemArea *psLinuxMemArea, IMG_UINT32 ui32ByteOffset) +{ + IMG_CPU_PHYADDR CpuPAddr; + + CpuPAddr.uiAddr = 0; + + switch(psLinuxMemArea->eAreaType) + { + case LINUX_MEM_AREA_IOREMAP: + { + CpuPAddr = psLinuxMemArea->uData.sIORemap.CPUPhysAddr; + CpuPAddr.uiAddr += ui32ByteOffset; + break; + } + case LINUX_MEM_AREA_EXTERNAL_KV: + { + if (psLinuxMemArea->uData.sExternalKV.bPhysContig) + { + CpuPAddr = SysSysPAddrToCpuPAddr(psLinuxMemArea->uData.sExternalKV.uPhysAddr.SysPhysAddr); + CpuPAddr.uiAddr += ui32ByteOffset; + } + else + { + IMG_UINT32 ui32PageIndex = PHYS_TO_PFN(ui32ByteOffset); + IMG_SYS_PHYADDR SysPAddr = psLinuxMemArea->uData.sExternalKV.uPhysAddr.pSysPhysAddr[ui32PageIndex]; + + CpuPAddr = SysSysPAddrToCpuPAddr(SysPAddr); + CpuPAddr.uiAddr += ADDR_TO_PAGE_OFFSET(ui32ByteOffset); + } + break; + } + case LINUX_MEM_AREA_IO: + { + CpuPAddr = psLinuxMemArea->uData.sIO.CPUPhysAddr; + CpuPAddr.uiAddr += ui32ByteOffset; + break; + } + case LINUX_MEM_AREA_VMALLOC: + { + IMG_CHAR *pCpuVAddr; + pCpuVAddr = + (IMG_CHAR *)psLinuxMemArea->uData.sVmalloc.pvVmallocAddress; + pCpuVAddr += ui32ByteOffset; + CpuPAddr.uiAddr = VMallocToPhys(pCpuVAddr); + break; + } + case LINUX_MEM_AREA_ALLOC_PAGES: + { + struct page *page; + IMG_UINT32 ui32PageIndex = PHYS_TO_PFN(ui32ByteOffset); + page = psLinuxMemArea->uData.sPageList.pvPageList[ui32PageIndex]; + CpuPAddr.uiAddr = page_to_phys(page); + CpuPAddr.uiAddr += ADDR_TO_PAGE_OFFSET(ui32ByteOffset); + break; + } + case LINUX_MEM_AREA_SUB_ALLOC: + { + CpuPAddr = + OSMemHandleToCpuPAddr(psLinuxMemArea->uData.sSubAlloc.psParentLinuxMemArea, + psLinuxMemArea->uData.sSubAlloc.ui32ByteOffset + + ui32ByteOffset); + break; + } + default: + PVR_DPF((PVR_DBG_ERROR, "%s: Unknown LinuxMemArea type (%d)\n", + __FUNCTION__, psLinuxMemArea->eAreaType)); + } + + PVR_ASSERT(CpuPAddr.uiAddr); + return CpuPAddr; +} + + +IMG_BOOL +LinuxMemAreaPhysIsContig(LinuxMemArea *psLinuxMemArea) +{ + switch(psLinuxMemArea->eAreaType) + { + case LINUX_MEM_AREA_IOREMAP: + case LINUX_MEM_AREA_IO: + return IMG_TRUE; + + case LINUX_MEM_AREA_EXTERNAL_KV: + return psLinuxMemArea->uData.sExternalKV.bPhysContig; + + case LINUX_MEM_AREA_VMALLOC: + case LINUX_MEM_AREA_ALLOC_PAGES: + return IMG_FALSE; + + case LINUX_MEM_AREA_SUB_ALLOC: + return LinuxMemAreaPhysIsContig(psLinuxMemArea->uData.sSubAlloc.psParentLinuxMemArea); + + default: + PVR_DPF((PVR_DBG_ERROR, "%s: Unknown LinuxMemArea type (%d)\n", + __FUNCTION__, psLinuxMemArea->eAreaType)); + break; + } + return IMG_FALSE; +} + + +const IMG_CHAR * +LinuxMemAreaTypeToString(LINUX_MEM_AREA_TYPE eMemAreaType) +{ + + switch(eMemAreaType) + { + case LINUX_MEM_AREA_IOREMAP: + return "LINUX_MEM_AREA_IOREMAP"; + case LINUX_MEM_AREA_EXTERNAL_KV: + return "LINUX_MEM_AREA_EXTERNAL_KV"; + case LINUX_MEM_AREA_IO: + return "LINUX_MEM_AREA_IO"; + case LINUX_MEM_AREA_VMALLOC: + return "LINUX_MEM_AREA_VMALLOC"; + case LINUX_MEM_AREA_SUB_ALLOC: + return "LINUX_MEM_AREA_SUB_ALLOC"; + case LINUX_MEM_AREA_ALLOC_PAGES: + return "LINUX_MEM_AREA_ALLOC_PAGES"; + default: + PVR_ASSERT(0); + } + + return ""; +} + + +#if defined(DEBUG_LINUX_MEM_AREAS) +static off_t +printLinuxMemAreaRecords(IMG_CHAR * buffer, size_t count, off_t off) +{ + DEBUG_LINUX_MEM_AREA_REC *psRecord; + off_t Ret; + + LinuxLockMutex(&g_sDebugMutex); + + if(!off) + { + if(count < 500) + { + Ret = 0; + goto unlock_and_return; + } +#if !defined(DEBUG_LINUX_XML_PROC_FILES) + Ret = printAppend(buffer, count, 0, + "Number of Linux Memory Areas: %lu\n" + "At the current water mark these areas correspond to %lu bytes (excluding SUB areas)\n" + "At the highest water mark these areas corresponded to %lu bytes (excluding SUB areas)\n" + "\nDetails for all Linux Memory Areas:\n" + "%s %-24s %s %s %-8s %-5s %s\n", + g_LinuxMemAreaCount, + g_LinuxMemAreaWaterMark, + g_LinuxMemAreaHighWaterMark, + "psLinuxMemArea", + "LinuxMemType", + "CpuVAddr", + "CpuPAddr", + "Bytes", + "Pid", + "Flags" + ); +#else + Ret = printAppend(buffer, count, 0, + "\n" + "\t%lu\n" + "\t\n" + "\t\n" + "\n", + g_LinuxMemAreaCount, + g_LinuxMemAreaWaterMark, + g_LinuxMemAreaHighWaterMark + ); +#endif + goto unlock_and_return; + } + + for(psRecord=g_LinuxMemAreaRecords; --off && psRecord; psRecord=psRecord->psNext) + ; + if(!psRecord) + { + Ret = END_OF_FILE; + goto unlock_and_return; + } + + if(count < 500) + { + Ret = 0; + goto unlock_and_return; + } + + Ret = printAppend(buffer, count, 0, +#if !defined(DEBUG_LINUX_XML_PROC_FILES) + "%8p %-24s %8p %08lx %-8ld %-5u %08lx=(%s)\n", +#else + "\n" + "\t%8p\n" + "\t%s\n" + "\t%8p\n" + "\t%08lx\n" + "\t%ld\n" + "\t%u\n" + "\t%08lx\n" + "\t%s\n" + "\n", +#endif + psRecord->psLinuxMemArea, + LinuxMemAreaTypeToString(psRecord->psLinuxMemArea->eAreaType), + LinuxMemAreaToCpuVAddr(psRecord->psLinuxMemArea), + LinuxMemAreaToCpuPAddr(psRecord->psLinuxMemArea,0).uiAddr, + psRecord->psLinuxMemArea->ui32ByteSize, + psRecord->pid, + psRecord->ui32Flags, + HAPFlagsToString(psRecord->ui32Flags) + ); + +unlock_and_return: + LinuxUnLockMutex(&g_sDebugMutex); + return Ret; +} +#endif + + +#if defined(DEBUG_LINUX_MEMORY_ALLOCATIONS) +static off_t +printMemoryRecords(IMG_CHAR * buffer, size_t count, off_t off) +{ + DEBUG_MEM_ALLOC_REC *psRecord; + off_t Ret; + + LinuxLockMutex(&g_sDebugMutex); + + if(!off) + { + if(count < 1000) + { + Ret = 0; + goto unlock_and_return; + } + +#if !defined(DEBUG_LINUX_XML_PROC_FILES) + + Ret = printAppend(buffer, count, 0, "%-60s: %ld bytes\n", + "Current Water Mark of bytes allocated via kmalloc", + g_WaterMarkData[DEBUG_MEM_ALLOC_TYPE_KMALLOC]); + Ret = printAppend(buffer, count, Ret, "%-60s: %ld bytes\n", + "Highest Water Mark of bytes allocated via kmalloc", + g_HighWaterMarkData[DEBUG_MEM_ALLOC_TYPE_KMALLOC]); + Ret = printAppend(buffer, count, Ret, "%-60s: %ld bytes\n", + "Current Water Mark of bytes allocated via vmalloc", + g_WaterMarkData[DEBUG_MEM_ALLOC_TYPE_VMALLOC]); + Ret = printAppend(buffer, count, Ret, "%-60s: %ld bytes\n", + "Highest Water Mark of bytes allocated via vmalloc", + g_HighWaterMarkData[DEBUG_MEM_ALLOC_TYPE_VMALLOC]); + Ret = printAppend(buffer, count, Ret, "%-60s: %ld bytes\n", + "Current Water Mark of bytes allocated via alloc_pages", + g_WaterMarkData[DEBUG_MEM_ALLOC_TYPE_ALLOC_PAGES]); + Ret = printAppend(buffer, count, Ret, "%-60s: %ld bytes\n", + "Highest Water Mark of bytes allocated via alloc_pages", + g_HighWaterMarkData[DEBUG_MEM_ALLOC_TYPE_ALLOC_PAGES]); + Ret = printAppend(buffer, count, Ret, "%-60s: %ld bytes\n", + "Current Water Mark of bytes allocated via ioremap", + g_WaterMarkData[DEBUG_MEM_ALLOC_TYPE_IOREMAP]); + Ret = printAppend(buffer, count, Ret, "%-60s: %ld bytes\n", + "Highest Water Mark of bytes allocated via ioremap", + g_HighWaterMarkData[DEBUG_MEM_ALLOC_TYPE_IOREMAP]); + Ret = printAppend(buffer, count, Ret, "%-60s: %ld bytes\n", + "Current Water Mark of bytes reserved for \"IO\" memory areas", + g_WaterMarkData[DEBUG_MEM_ALLOC_TYPE_IO]); + Ret = printAppend(buffer, count, Ret, "%-60s: %ld bytes\n", + "Highest Water Mark of bytes allocated for \"IO\" memory areas", + g_HighWaterMarkData[DEBUG_MEM_ALLOC_TYPE_IO]); + Ret = printAppend(buffer, count, Ret, "%-60s: %ld bytes\n", + "Current Water Mark of bytes allocated via kmem_cache_alloc", + g_WaterMarkData[DEBUG_MEM_ALLOC_TYPE_KMEM_CACHE]); + Ret = printAppend(buffer, count, Ret, "%-60s: %ld bytes\n", + "Highest Water Mark of bytes allocated via kmem_cache_alloc", + g_HighWaterMarkData[DEBUG_MEM_ALLOC_TYPE_KMEM_CACHE]); + Ret = printAppend(buffer, count, Ret, "\n"); + + Ret = printAppend(buffer, count, Ret, "%-60s: %ld bytes\n", + "The Current Water Mark for memory allocated from system RAM", + g_SysRAMWaterMark); + Ret = printAppend(buffer, count, Ret, "%-60s: %ld bytes\n", + "The Highest Water Mark for memory allocated from system RAM", + g_SysRAMHighWaterMark); + Ret = printAppend(buffer, count, Ret, "%-60s: %ld bytes\n", + "The Current Water Mark for memory allocated from IO memory", + g_IOMemWaterMark); + Ret = printAppend(buffer, count, Ret, "%-60s: %ld bytes\n", + "The Highest Water Mark for memory allocated from IO memory", + g_IOMemHighWaterMark); + + Ret = printAppend(buffer, count, Ret, "\n"); + + Ret = printAppend(buffer, count, Ret, "Details for all known allocations:\n" + "%-16s %-8s %-8s %-10s %-5s %-10s %s\n", + "Type", + "CpuVAddr", + "CpuPAddr", + "Bytes", + "PID", + "PrivateData", + "Filename:Line"); + +#else + + + Ret = printAppend(buffer, count, 0, "\n\n"); + Ret = printAppend(buffer, count, Ret, + "\n", + g_WaterMarkData[DEBUG_MEM_ALLOC_TYPE_KMALLOC]); + Ret = printAppend(buffer, count, Ret, + "\n", + g_HighWaterMarkData[DEBUG_MEM_ALLOC_TYPE_KMALLOC]); + Ret = printAppend(buffer, count, Ret, + "\n", + g_WaterMarkData[DEBUG_MEM_ALLOC_TYPE_VMALLOC]); + Ret = printAppend(buffer, count, Ret, + "\n", + g_HighWaterMarkData[DEBUG_MEM_ALLOC_TYPE_VMALLOC]); + Ret = printAppend(buffer, count, Ret, + "\n", + g_WaterMarkData[DEBUG_MEM_ALLOC_TYPE_ALLOC_PAGES]); + Ret = printAppend(buffer, count, Ret, + "\n", + g_HighWaterMarkData[DEBUG_MEM_ALLOC_TYPE_ALLOC_PAGES]); + Ret = printAppend(buffer, count, Ret, + "\n", + g_WaterMarkData[DEBUG_MEM_ALLOC_TYPE_IOREMAP]); + Ret = printAppend(buffer, count, Ret, + "\n", + g_HighWaterMarkData[DEBUG_MEM_ALLOC_TYPE_IOREMAP]); + Ret = printAppend(buffer, count, Ret, + "\n", + g_WaterMarkData[DEBUG_MEM_ALLOC_TYPE_IO]); + Ret = printAppend(buffer, count, Ret, + "\n", + g_HighWaterMarkData[DEBUG_MEM_ALLOC_TYPE_IO]); + Ret = printAppend(buffer, count, Ret, + "\n", + g_WaterMarkData[DEBUG_MEM_ALLOC_TYPE_KMEM_CACHE]); + Ret = printAppend(buffer, count, Ret, + "\n", + g_HighWaterMarkData[DEBUG_MEM_ALLOC_TYPE_KMEM_CACHE]); + Ret = printAppend(buffer, count, Ret, "\n"); + + Ret = printAppend(buffer, count, Ret, + "\n", + g_SysRAMWaterMark); + Ret = printAppend(buffer, count, Ret, + "\n", + g_SysRAMHighWaterMark); + Ret = printAppend(buffer, count, Ret, + "\n", + g_IOMemWaterMark); + Ret = printAppend(buffer, count, Ret, + "\n", + g_IOMemHighWaterMark); + + Ret = printAppend(buffer, count, Ret, "\n"); + +#endif + + goto unlock_and_return; + } + + if(count < 1000) + { + Ret = 0; + goto unlock_and_return; + } + + for(psRecord=g_MemoryRecords; --off && psRecord; psRecord=psRecord->psNext) + ; + if(!psRecord) + { +#if defined(DEBUG_LINUX_XML_PROC_FILES) + if(off == 0) + { + Ret = printAppend(buffer, count, 0, "\n"); + goto unlock_and_return; + } +#endif + Ret = END_OF_FILE; + goto unlock_and_return; + } + + if(psRecord->eAllocType != DEBUG_MEM_ALLOC_TYPE_KMEM_CACHE) + { + Ret = printAppend(buffer, count, 0, +#if !defined(DEBUG_LINUX_XML_PROC_FILES) + "%-16s %-8p %08lx %-10ld %-5d %-10s %s:%ld\n", +#else + "\n" + "\t%s\n" + "\t%-8p\n" + "\t%08lx\n" + "\t%ld\n" + "\t%d\n" + "\t%s\n" + "\t%s\n" + "\t%ld\n" + "\n", +#endif + DebugMemAllocRecordTypeToString(psRecord->eAllocType), + psRecord->pvCpuVAddr, + psRecord->ulCpuPAddr, + psRecord->ui32Bytes, + psRecord->pid, + "NULL", + psRecord->pszFileName, + psRecord->ui32Line); + } + else + { + Ret = printAppend(buffer, count, 0, +#if !defined(DEBUG_LINUX_XML_PROC_FILES) + "%-16s %-8p %08lx %-10ld %-5d %-10s %s:%ld\n", +#else + "\n" + "\t%s\n" + "\t%-8p\n" + "\t%08lx\n" + "\t%ld\n" + "\t%d\n" + "\t%s\n" + "\t%s\n" + "\t%ld\n" + "\n", +#endif + DebugMemAllocRecordTypeToString(psRecord->eAllocType), + psRecord->pvCpuVAddr, + psRecord->ulCpuPAddr, + psRecord->ui32Bytes, + psRecord->pid, + KMemCacheNameWrapper(psRecord->pvPrivateData), + psRecord->pszFileName, + psRecord->ui32Line); + } + +unlock_and_return: + LinuxUnLockMutex(&g_sDebugMutex); + return Ret; +} +#endif + + +#if defined(DEBUG_LINUX_MEM_AREAS) || defined(DEBUG_LINUX_MMAP_AREAS) +const IMG_CHAR * +HAPFlagsToString(IMG_UINT32 ui32Flags) +{ + static IMG_CHAR szFlags[50]; + IMG_INT32 i32Pos = 0; + IMG_UINT32 ui32CacheTypeIndex, ui32MapTypeIndex; + IMG_CHAR *apszCacheTypes[] = { + "UNCACHED", + "CACHED", + "WRITECOMBINE", + "UNKNOWN" + }; + IMG_CHAR *apszMapType[] = { + "KERNEL_ONLY", + "SINGLE_PROCESS", + "MULTI_PROCESS", + "FROM_EXISTING_PROCESS", + "NO_CPU_VIRTUAL", + "UNKNOWN" + }; + + + if(ui32Flags & PVRSRV_HAP_UNCACHED){ + ui32CacheTypeIndex=0; + }else if(ui32Flags & PVRSRV_HAP_CACHED){ + ui32CacheTypeIndex=1; + }else if(ui32Flags & PVRSRV_HAP_WRITECOMBINE){ + ui32CacheTypeIndex=2; + }else{ + ui32CacheTypeIndex=3; + PVR_DPF((PVR_DBG_ERROR, "%s: unknown cache type (%u)", + __FUNCTION__, (ui32Flags & PVRSRV_HAP_CACHETYPE_MASK))); + } + + + if(ui32Flags & PVRSRV_HAP_KERNEL_ONLY){ + ui32MapTypeIndex = 0; + }else if(ui32Flags & PVRSRV_HAP_SINGLE_PROCESS){ + ui32MapTypeIndex = 1; + }else if(ui32Flags & PVRSRV_HAP_MULTI_PROCESS){ + ui32MapTypeIndex = 2; + }else if(ui32Flags & PVRSRV_HAP_FROM_EXISTING_PROCESS){ + ui32MapTypeIndex = 3; + }else if(ui32Flags & PVRSRV_HAP_NO_CPU_VIRTUAL){ + ui32MapTypeIndex = 4; + }else{ + ui32MapTypeIndex = 5; + PVR_DPF((PVR_DBG_ERROR, "%s: unknown map type (%u)", + __FUNCTION__, (ui32Flags & PVRSRV_HAP_MAPTYPE_MASK))); + } + + i32Pos = sprintf(szFlags, "%s|", apszCacheTypes[ui32CacheTypeIndex]); + if (i32Pos <= 0) + { + PVR_DPF((PVR_DBG_ERROR, "%s: sprintf for cache type %u failed (%d)", + __FUNCTION__, ui32CacheTypeIndex, i32Pos)); + szFlags[0] = 0; + } + else + { + sprintf(szFlags + i32Pos, "%s", apszMapType[ui32MapTypeIndex]); + } + + return szFlags; +} +#endif + + diff --git a/services4/srvkm/env/linux/mm.h b/services4/srvkm/env/linux/mm.h new file mode 100644 index 0000000..7d2da4e --- /dev/null +++ b/services4/srvkm/env/linux/mm.h @@ -0,0 +1,331 @@ +/********************************************************************** + * + * Copyright(c) 2008 Imagination Technologies Ltd. All rights reserved. + * + * This program is free software; you can redistribute it and/or modify it + * under the terms and conditions of the GNU General Public License, + * version 2, as published by the Free Software Foundation. + * + * This program is distributed in the hope it will be useful but, except + * as otherwise stated in writing, without any warranty; without even the + * implied warranty of merchantability or fitness for a particular purpose. + * See the GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License along with + * this program; if not, write to the Free Software Foundation, Inc., + * 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA. + * + * The full GNU General Public License is included in this distribution in + * the file called "COPYING". + * + * Contact Information: + * Imagination Technologies Ltd. + * Home Park Estate, Kings Langley, Herts, WD4 8LZ, UK + * + ******************************************************************************/ + +#ifndef __IMG_LINUX_MM_H__ +#define __IMG_LINUX_MM_H__ + +#ifndef AUTOCONF_INCLUDED + #include +#endif + +#include +#include +#include +#include + +#include + +#define PHYS_TO_PFN(phys) ((phys) >> PAGE_SHIFT) +#define PFN_TO_PHYS(pfn) ((pfn) << PAGE_SHIFT) + +#define RANGE_TO_PAGES(range) (((range) + (PAGE_SIZE - 1)) >> PAGE_SHIFT) + +#define ADDR_TO_PAGE_OFFSET(addr) (((unsigned long)(addr)) & (PAGE_SIZE - 1)) + +#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,10)) +#define REMAP_PFN_RANGE(vma, addr, pfn, size, prot) remap_pfn_range(vma, addr, pfn, size, prot) +#else +#define REMAP_PFN_RANGE(vma, addr, pfn, size, prot) remap_page_range(vma, addr, PFN_TO_PHYS(pfn), size, prot) +#endif + +#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,12)) +#define IO_REMAP_PFN_RANGE(vma, addr, pfn, size, prot) io_remap_pfn_range(vma, addr, pfn, size, prot) +#else +#define IO_REMAP_PFN_RANGE(vma, addr, pfn, size, prot) io_remap_page_range(vma, addr, PFN_TO_PHYS(pfn), size, prot) +#endif + +#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,15)) +#define VM_INSERT_PAGE(vma, addr, page) vm_insert_page(vma, addr, page) +#else +#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,10)) +#define VM_INSERT_PAGE(vma, addr, page) remap_pfn_range(vma, addr, page_to_pfn(page), PAGE_SIZE, vma->vm_page_prot); +#else +#define VM_INSERT_PAGE(vma, addr, page) remap_page_range(vma, addr, page_to_phys(page), PAGE_SIZE, vma->vm_page_prot); +#endif +#endif + +static inline IMG_UINT32 VMallocToPhys(IMG_VOID *pCpuVAddr) +{ + return (page_to_phys(vmalloc_to_page(pCpuVAddr)) + ADDR_TO_PAGE_OFFSET(pCpuVAddr)); + +} + +typedef enum { + LINUX_MEM_AREA_IOREMAP, + LINUX_MEM_AREA_EXTERNAL_KV, + LINUX_MEM_AREA_IO, + LINUX_MEM_AREA_VMALLOC, + LINUX_MEM_AREA_ALLOC_PAGES, + LINUX_MEM_AREA_SUB_ALLOC, + LINUX_MEM_AREA_TYPE_COUNT +}LINUX_MEM_AREA_TYPE; + +typedef struct _LinuxMemArea LinuxMemArea; + + +struct _LinuxMemArea { + LINUX_MEM_AREA_TYPE eAreaType; + union _uData + { + struct _sIORemap + { + + IMG_CPU_PHYADDR CPUPhysAddr; + IMG_VOID *pvIORemapCookie; + }sIORemap; + struct _sExternalKV + { + + IMG_BOOL bPhysContig; + union { + + IMG_SYS_PHYADDR SysPhysAddr; + IMG_SYS_PHYADDR *pSysPhysAddr; + } uPhysAddr; + IMG_VOID *pvExternalKV; + }sExternalKV; + struct _sIO + { + + IMG_CPU_PHYADDR CPUPhysAddr; + }sIO; + struct _sVmalloc + { + + IMG_VOID *pvVmallocAddress; + }sVmalloc; + struct _sPageList + { + + struct page **pvPageList; + IMG_HANDLE hBlockPageList; + }sPageList; + struct _sSubAlloc + { + + LinuxMemArea *psParentLinuxMemArea; + IMG_UINT32 ui32ByteOffset; + }sSubAlloc; + }uData; + + IMG_UINT32 ui32ByteSize; + + IMG_UINT32 ui32AreaFlags; + + IMG_BOOL bMMapRegistered; + + + struct list_head sMMapItem; + + + struct list_head sMMapOffsetStructList; +}; + +#if (LINUX_VERSION_CODE < KERNEL_VERSION(2,6,17)) +typedef kmem_cache_t LinuxKMemCache; +#else +typedef struct kmem_cache LinuxKMemCache; +#endif + + +PVRSRV_ERROR LinuxMMInit(IMG_VOID); + + +IMG_VOID LinuxMMCleanup(IMG_VOID); + + +#if defined(DEBUG_LINUX_MEMORY_ALLOCATIONS) +#define KMallocWrapper(ui32ByteSize) _KMallocWrapper(ui32ByteSize, __FILE__, __LINE__) +#else +#define KMallocWrapper(ui32ByteSize) _KMallocWrapper(ui32ByteSize, NULL, 0) +#endif +IMG_VOID *_KMallocWrapper(IMG_UINT32 ui32ByteSize, IMG_CHAR *szFileName, IMG_UINT32 ui32Line); + + +#if defined(DEBUG_LINUX_MEMORY_ALLOCATIONS) +#define KFreeWrapper(pvCpuVAddr) _KFreeWrapper(pvCpuVAddr, __FILE__, __LINE__) +#else +#define KFreeWrapper(pvCpuVAddr) _KFreeWrapper(pvCpuVAddr, NULL, 0) +#endif +IMG_VOID _KFreeWrapper(IMG_VOID *pvCpuVAddr, IMG_CHAR *pszFileName, IMG_UINT32 ui32Line); + + +#if defined(DEBUG_LINUX_MEMORY_ALLOCATIONS) +#define VMallocWrapper(ui32Bytes, ui32AllocFlags) _VMallocWrapper(ui32Bytes, ui32AllocFlags, __FILE__, __LINE__) +#else +#define VMallocWrapper(ui32Bytes, ui32AllocFlags) _VMallocWrapper(ui32Bytes, ui32AllocFlags, NULL, 0) +#endif +IMG_VOID *_VMallocWrapper(IMG_UINT32 ui32Bytes, IMG_UINT32 ui32AllocFlags, IMG_CHAR *pszFileName, IMG_UINT32 ui32Line); + + +#if defined(DEBUG_LINUX_MEMORY_ALLOCATIONS) +#define VFreeWrapper(pvCpuVAddr) _VFreeWrapper(pvCpuVAddr, __FILE__, __LINE__) +#else +#define VFreeWrapper(pvCpuVAddr) _VFreeWrapper(pvCpuVAddr, NULL, 0) +#endif +IMG_VOID _VFreeWrapper(IMG_VOID *pvCpuVAddr, IMG_CHAR *pszFileName, IMG_UINT32 ui32Line); + + +LinuxMemArea *NewVMallocLinuxMemArea(IMG_UINT32 ui32Bytes, IMG_UINT32 ui32AreaFlags); + + +IMG_VOID FreeVMallocLinuxMemArea(LinuxMemArea *psLinuxMemArea); + + +#if defined(DEBUG_LINUX_MEMORY_ALLOCATIONS) +#define IORemapWrapper(BasePAddr, ui32Bytes, ui32MappingFlags) \ + _IORemapWrapper(BasePAddr, ui32Bytes, ui32MappingFlags, __FILE__, __LINE__) +#else +#define IORemapWrapper(BasePAddr, ui32Bytes, ui32MappingFlags) \ + _IORemapWrapper(BasePAddr, ui32Bytes, ui32MappingFlags, NULL, 0) +#endif +IMG_VOID *_IORemapWrapper(IMG_CPU_PHYADDR BasePAddr, + IMG_UINT32 ui32Bytes, + IMG_UINT32 ui32MappingFlags, + IMG_CHAR *pszFileName, + IMG_UINT32 ui32Line); + + +LinuxMemArea *NewIORemapLinuxMemArea(IMG_CPU_PHYADDR BasePAddr, IMG_UINT32 ui32Bytes, IMG_UINT32 ui32AreaFlags); + + +IMG_VOID FreeIORemapLinuxMemArea(LinuxMemArea *psLinuxMemArea); + +LinuxMemArea *NewExternalKVLinuxMemArea(IMG_SYS_PHYADDR *pBasePAddr, IMG_VOID *pvCPUVAddr, IMG_UINT32 ui32Bytes, IMG_BOOL bPhysContig, IMG_UINT32 ui32AreaFlags); + + +IMG_VOID FreeExternalKVLinuxMemArea(LinuxMemArea *psLinuxMemArea); + + +#if defined(DEBUG_LINUX_MEMORY_ALLOCATIONS) +#define IOUnmapWrapper(pvIORemapCookie) \ + _IOUnmapWrapper(pvIORemapCookie, __FILE__, __LINE__) +#else +#define IOUnmapWrapper(pvIORemapCookie) \ + _IOUnmapWrapper(pvIORemapCookie, NULL, 0) +#endif +IMG_VOID _IOUnmapWrapper(IMG_VOID *pvIORemapCookie, IMG_CHAR *pszFileName, IMG_UINT32 ui32Line); + + +struct page *LinuxMemAreaOffsetToPage(LinuxMemArea *psLinuxMemArea, IMG_UINT32 ui32ByteOffset); + + +LinuxKMemCache *KMemCacheCreateWrapper(IMG_CHAR *pszName, size_t Size, size_t Align, IMG_UINT32 ui32Flags); + + +IMG_VOID KMemCacheDestroyWrapper(LinuxKMemCache *psCache); + + +#if defined(DEBUG_LINUX_MEMORY_ALLOCATIONS) +#define KMemCacheAllocWrapper(psCache, Flags) _KMemCacheAllocWrapper(psCache, Flags, __FILE__, __LINE__) +#else +#define KMemCacheAllocWrapper(psCache, Flags) _KMemCacheAllocWrapper(psCache, Flags, NULL, 0) +#endif + +#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,14)) +IMG_VOID *_KMemCacheAllocWrapper(LinuxKMemCache *psCache, gfp_t Flags, IMG_CHAR *pszFileName, IMG_UINT32 ui32Line); +#else +IMG_VOID *_KMemCacheAllocWrapper(LinuxKMemCache *psCache, int Flags, IMG_CHAR *pszFileName, IMG_UINT32 ui32Line); +#endif + +#if defined(DEBUG_LINUX_MEMORY_ALLOCATIONS) +#define KMemCacheFreeWrapper(psCache, pvObject) _KMemCacheFreeWrapper(psCache, pvObject, __FILE__, __LINE__) +#else +#define KMemCacheFreeWrapper(psCache, pvObject) _KMemCacheFreeWrapper(psCache, pvObject, NULL, 0) +#endif +IMG_VOID _KMemCacheFreeWrapper(LinuxKMemCache *psCache, IMG_VOID *pvObject, IMG_CHAR *pszFileName, IMG_UINT32 ui32Line); + + +const IMG_CHAR *KMemCacheNameWrapper(LinuxKMemCache *psCache); + + +LinuxMemArea *NewIOLinuxMemArea(IMG_CPU_PHYADDR BasePAddr, IMG_UINT32 ui32Bytes, IMG_UINT32 ui32AreaFlags); + + +IMG_VOID FreeIOLinuxMemArea(LinuxMemArea *psLinuxMemArea); + + +LinuxMemArea *NewAllocPagesLinuxMemArea(IMG_UINT32 ui32Bytes, IMG_UINT32 ui32AreaFlags); + + +IMG_VOID FreeAllocPagesLinuxMemArea(LinuxMemArea *psLinuxMemArea); + + +LinuxMemArea *NewSubLinuxMemArea(LinuxMemArea *psParentLinuxMemArea, + IMG_UINT32 ui32ByteOffset, + IMG_UINT32 ui32Bytes); + + +IMG_VOID LinuxMemAreaDeepFree(LinuxMemArea *psLinuxMemArea); + + +#if defined(LINUX_MEM_AREAS_DEBUG) +IMG_VOID LinuxMemAreaRegister(LinuxMemArea *psLinuxMemArea); +#else +#define LinuxMemAreaRegister(X) +#endif + + +IMG_VOID *LinuxMemAreaToCpuVAddr(LinuxMemArea *psLinuxMemArea); + + +IMG_CPU_PHYADDR LinuxMemAreaToCpuPAddr(LinuxMemArea *psLinuxMemArea, IMG_UINT32 ui32ByteOffset); + + +#define LinuxMemAreaToCpuPFN(psLinuxMemArea, ui32ByteOffset) PHYS_TO_PFN(LinuxMemAreaToCpuPAddr(psLinuxMemArea, ui32ByteOffset).uiAddr) + +IMG_BOOL LinuxMemAreaPhysIsContig(LinuxMemArea *psLinuxMemArea); + +static inline LinuxMemArea * +LinuxMemAreaRoot(LinuxMemArea *psLinuxMemArea) +{ + if(psLinuxMemArea->eAreaType == LINUX_MEM_AREA_SUB_ALLOC) + { + return psLinuxMemArea->uData.sSubAlloc.psParentLinuxMemArea; + } + else + { + return psLinuxMemArea; + } +} + + +static inline LINUX_MEM_AREA_TYPE +LinuxMemAreaRootType(LinuxMemArea *psLinuxMemArea) +{ + return LinuxMemAreaRoot(psLinuxMemArea)->eAreaType; +} + + +const IMG_CHAR *LinuxMemAreaTypeToString(LINUX_MEM_AREA_TYPE eMemAreaType); + + +#if defined(DEBUG) || defined(DEBUG_LINUX_MEM_AREAS) +const IMG_CHAR *HAPFlagsToString(IMG_UINT32 ui32Flags); +#endif + +#endif + diff --git a/services4/srvkm/env/linux/mmap.c b/services4/srvkm/env/linux/mmap.c new file mode 100644 index 0000000..774d5ea --- /dev/null +++ b/services4/srvkm/env/linux/mmap.c @@ -0,0 +1,988 @@ +/********************************************************************** + * + * Copyright(c) 2008 Imagination Technologies Ltd. All rights reserved. + * + * This program is free software; you can redistribute it and/or modify it + * under the terms and conditions of the GNU General Public License, + * version 2, as published by the Free Software Foundation. + * + * This program is distributed in the hope it will be useful but, except + * as otherwise stated in writing, without any warranty; without even the + * implied warranty of merchantability or fitness for a particular purpose. + * See the GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License along with + * this program; if not, write to the Free Software Foundation, Inc., + * 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA. + * + * The full GNU General Public License is included in this distribution in + * the file called "COPYING". + * + * Contact Information: + * Imagination Technologies Ltd. + * Home Park Estate, Kings Langley, Herts, WD4 8LZ, UK + * + ******************************************************************************/ + +#ifndef AUTOCONF_INCLUDED + #include +#endif + +#include +#include +#include +#include +#if (LINUX_VERSION_CODE < KERNEL_VERSION(2,6,0)) +#include +#endif +#include +#include +#include +#include +#include +#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,22)) +#include +#include +#endif + +#include "img_defs.h" +#include "services.h" +#include "servicesint.h" +#include "pvrmmap.h" +#include "mutils.h" +#include "mmap.h" +#include "mm.h" +#include "pvr_debug.h" +#include "osfunc.h" +#include "proc.h" +#include "mutex.h" +#include "handle.h" +#include "perproc.h" +#include "env_perproc.h" +#include "bridged_support.h" + +#if !defined(PVR_SECURE_HANDLES) +#error "The mmap code requires PVR_SECURE_HANDLES" +#endif + +static PVRSRV_LINUX_MUTEX g_sMMapMutex; + +static LinuxKMemCache *g_psMemmapCache = NULL; +static LIST_HEAD(g_sMMapAreaList); +static LIST_HEAD(g_sMMapOffsetStructList); +#if defined(DEBUG_LINUX_MMAP_AREAS) +static IMG_UINT32 g_ui32RegisteredAreas = 0; +static IMG_UINT32 g_ui32TotalByteSize = 0; +#endif + +#define FIRST_PHYSICAL_PFN 0 +#define LAST_PHYSICAL_PFN 0x7ffffffful +#define FIRST_SPECIAL_PFN (LAST_PHYSICAL_PFN + 1) +#define LAST_SPECIAL_PFN 0xfffffffful + +#define MAX_MMAP_HANDLE 0x7ffffffful + +static inline IMG_BOOL +PFNIsPhysical(IMG_UINT32 pfn) +{ + return pfn >= FIRST_PHYSICAL_PFN && pfn <= LAST_PHYSICAL_PFN; +} + +static inline IMG_BOOL +PFNIsSpecial(IMG_UINT32 pfn) +{ + return pfn >= FIRST_SPECIAL_PFN && pfn <= LAST_SPECIAL_PFN; +} + +static inline IMG_HANDLE +MMapOffsetToHandle(IMG_UINT32 pfn) +{ + if (PFNIsPhysical(pfn)) + { + PVR_ASSERT(PFNIsPhysical(pfn)); + return IMG_NULL; + } + + return (IMG_HANDLE)(pfn - FIRST_SPECIAL_PFN); +} + +static inline IMG_UINT32 +HandleToMMapOffset(IMG_HANDLE hHandle) +{ + IMG_UINT32 ulHandle = (IMG_UINT32)hHandle; + + if (PFNIsSpecial(ulHandle)) + { + PVR_ASSERT(PFNIsSpecial(ulHandle)); + return 0; + } + + return ulHandle + FIRST_SPECIAL_PFN; +} + +static inline IMG_BOOL +LinuxMemAreaUsesPhysicalMap(LinuxMemArea *psLinuxMemArea) +{ + return LinuxMemAreaPhysIsContig(psLinuxMemArea); +} + +static inline IMG_UINT32 +GetCurrentThreadID(IMG_VOID) +{ + + return (IMG_UINT32)current->pid; +} + +static PKV_OFFSET_STRUCT +CreateOffsetStruct(LinuxMemArea *psLinuxMemArea, IMG_UINT32 ui32Offset, IMG_UINT32 ui32RealByteSize) +{ + PKV_OFFSET_STRUCT psOffsetStruct; +#if defined(DEBUG) || defined(DEBUG_LINUX_MMAP_AREAS) + const IMG_CHAR *pszName = LinuxMemAreaTypeToString(LinuxMemAreaRootType(psLinuxMemArea)); +#endif + + PVR_DPF((PVR_DBG_MESSAGE, + "%s(%s, psLinuxMemArea: 0x%p, ui32AllocFlags: 0x%8lx)", + __FUNCTION__, pszName, psLinuxMemArea, psLinuxMemArea->ui32AreaFlags)); + + PVR_ASSERT(psLinuxMemArea->eAreaType != LINUX_MEM_AREA_SUB_ALLOC || LinuxMemAreaRoot(psLinuxMemArea)->eAreaType != LINUX_MEM_AREA_SUB_ALLOC); + + PVR_ASSERT(psLinuxMemArea->bMMapRegistered); + + psOffsetStruct = KMemCacheAllocWrapper(g_psMemmapCache, GFP_KERNEL); + if(psOffsetStruct == IMG_NULL) + { + PVR_DPF((PVR_DBG_ERROR,"PVRMMapRegisterArea: Couldn't alloc another mapping record from cache")); + return IMG_NULL; + } + + psOffsetStruct->ui32MMapOffset = ui32Offset; + + psOffsetStruct->psLinuxMemArea = psLinuxMemArea; + + psOffsetStruct->ui32Mapped = 0; + + psOffsetStruct->ui32RealByteSize = ui32RealByteSize; + + + psOffsetStruct->ui32TID = GetCurrentThreadID(); + + psOffsetStruct->ui32PID = OSGetCurrentProcessIDKM(); + + psOffsetStruct->bOnMMapList = IMG_FALSE; + + psOffsetStruct->ui32RefCount = 0; + + psOffsetStruct->ui32UserVAddr = 0; + +#if defined(DEBUG_LINUX_MMAP_AREAS) + + psOffsetStruct->pszName = pszName; +#endif + + list_add_tail(&psOffsetStruct->sAreaItem, &psLinuxMemArea->sMMapOffsetStructList); + + return psOffsetStruct; +} + + +static IMG_VOID +DestroyOffsetStruct(PKV_OFFSET_STRUCT psOffsetStruct) +{ + list_del(&psOffsetStruct->sAreaItem); + + if (psOffsetStruct->bOnMMapList) + { + list_del(&psOffsetStruct->sMMapItem); + } + + PVR_DPF((PVR_DBG_MESSAGE, "%s: Table entry: " + "psLinuxMemArea=0x%08lX, CpuPAddr=0x%08lX", __FUNCTION__, + psOffsetStruct->psLinuxMemArea, + LinuxMemAreaToCpuPAddr(psOffsetStruct->psLinuxMemArea, 0))); + + KMemCacheFreeWrapper(g_psMemmapCache, psOffsetStruct); +} + + +static inline IMG_VOID +DetermineUsersSizeAndByteOffset(LinuxMemArea *psLinuxMemArea, + IMG_UINT32 *pui32RealByteSize, + IMG_UINT32 *pui32ByteOffset) +{ + IMG_UINT32 ui32PageAlignmentOffset; + IMG_CPU_PHYADDR CpuPAddr; + + CpuPAddr = LinuxMemAreaToCpuPAddr(psLinuxMemArea, 0); + ui32PageAlignmentOffset = ADDR_TO_PAGE_OFFSET(CpuPAddr.uiAddr); + + *pui32ByteOffset = ui32PageAlignmentOffset; + + *pui32RealByteSize = PAGE_ALIGN(psLinuxMemArea->ui32ByteSize + ui32PageAlignmentOffset); +} + + +PVRSRV_ERROR +PVRMMapOSMemHandleToMMapData(PVRSRV_PER_PROCESS_DATA *psPerProc, + IMG_HANDLE hMHandle, + IMG_UINT32 *pui32MMapOffset, + IMG_UINT32 *pui32ByteOffset, + IMG_UINT32 *pui32RealByteSize, + IMG_UINT32 *pui32UserVAddr) +{ + LinuxMemArea *psLinuxMemArea; + PKV_OFFSET_STRUCT psOffsetStruct; + IMG_HANDLE hOSMemHandle; + PVRSRV_ERROR eError = PVRSRV_ERROR_GENERIC; + + LinuxLockMutex(&g_sMMapMutex); + + PVR_ASSERT(PVRSRVGetMaxHandle(psPerProc->psHandleBase) <= MAX_MMAP_HANDLE); + + eError = PVRSRVLookupOSMemHandle(psPerProc->psHandleBase, &hOSMemHandle, hMHandle); + if (eError != PVRSRV_OK) + { + PVR_DPF((PVR_DBG_ERROR, "%s: Lookup of handle 0x%lx failed", __FUNCTION__, hMHandle)); + + goto exit_unlock; + } + + psLinuxMemArea = (LinuxMemArea *)hOSMemHandle; + + DetermineUsersSizeAndByteOffset(psLinuxMemArea, + pui32RealByteSize, + pui32ByteOffset); + + + list_for_each_entry(psOffsetStruct, &psLinuxMemArea->sMMapOffsetStructList, sAreaItem) + { + if (psPerProc->ui32PID == psOffsetStruct->ui32PID) + { + + PVR_ASSERT(*pui32RealByteSize == psOffsetStruct->ui32RealByteSize); + + *pui32MMapOffset = psOffsetStruct->ui32MMapOffset; + *pui32UserVAddr = psOffsetStruct->ui32UserVAddr; + psOffsetStruct->ui32RefCount++; + + eError = PVRSRV_OK; + goto exit_unlock; + } + } + + + *pui32UserVAddr = 0; + + if (LinuxMemAreaUsesPhysicalMap(psLinuxMemArea)) + { + *pui32MMapOffset = LinuxMemAreaToCpuPFN(psLinuxMemArea, 0); + PVR_ASSERT(PFNIsPhysical(*pui32MMapOffset)); + } + else + { + *pui32MMapOffset = HandleToMMapOffset(hMHandle); + PVR_ASSERT(PFNIsSpecial(*pui32MMapOffset)); + } + + psOffsetStruct = CreateOffsetStruct(psLinuxMemArea, *pui32MMapOffset, *pui32RealByteSize); + if (psOffsetStruct == IMG_NULL) + { + eError = PVRSRV_ERROR_OUT_OF_MEMORY; + goto exit_unlock; + } + + + list_add_tail(&psOffsetStruct->sMMapItem, &g_sMMapOffsetStructList); + + psOffsetStruct->bOnMMapList = IMG_TRUE; + + psOffsetStruct->ui32RefCount++; + + eError = PVRSRV_OK; + +exit_unlock: + LinuxUnLockMutex(&g_sMMapMutex); + + return eError; +} + + +PVRSRV_ERROR +PVRMMapReleaseMMapData(PVRSRV_PER_PROCESS_DATA *psPerProc, + IMG_HANDLE hMHandle, + IMG_BOOL *pbMUnmap, + IMG_UINT32 *pui32RealByteSize, + IMG_UINT32 *pui32UserVAddr) +{ + LinuxMemArea *psLinuxMemArea; + PKV_OFFSET_STRUCT psOffsetStruct; + IMG_HANDLE hOSMemHandle; + PVRSRV_ERROR eError = PVRSRV_ERROR_GENERIC; + IMG_UINT32 ui32PID = OSGetCurrentProcessIDKM(); + + LinuxLockMutex(&g_sMMapMutex); + + PVR_ASSERT(PVRSRVGetMaxHandle(psPerProc->psHandleBase) <= MAX_MMAP_HANDLE); + + eError = PVRSRVLookupOSMemHandle(psPerProc->psHandleBase, &hOSMemHandle, hMHandle); + if (eError != PVRSRV_OK) + { + PVR_DPF((PVR_DBG_ERROR, "%s: Lookup of handle 0x%lx failed", __FUNCTION__, hMHandle)); + + goto exit_unlock; + } + + psLinuxMemArea = (LinuxMemArea *)hOSMemHandle; + + + list_for_each_entry(psOffsetStruct, &psLinuxMemArea->sMMapOffsetStructList, sAreaItem) + { + if (psOffsetStruct->ui32PID == ui32PID) + { + if (psOffsetStruct->ui32RefCount == 0) + { + PVR_DPF((PVR_DBG_ERROR, "%s: Attempt to release mmap data with zero reference count for offset struct 0x%p, memory area 0x%p", __FUNCTION__, psOffsetStruct, psLinuxMemArea)); + eError = PVRSRV_ERROR_GENERIC; + goto exit_unlock; + } + + psOffsetStruct->ui32RefCount--; + + *pbMUnmap = (psOffsetStruct->ui32RefCount == 0) && (psOffsetStruct->ui32UserVAddr != 0); + + *pui32UserVAddr = (*pbMUnmap) ? psOffsetStruct->ui32UserVAddr : 0; + *pui32RealByteSize = (*pbMUnmap) ? psOffsetStruct->ui32RealByteSize : 0; + + eError = PVRSRV_OK; + goto exit_unlock; + } + } + + + PVR_DPF((PVR_DBG_ERROR, "%s: Mapping data not found for handle 0x%lx (memory area 0x%p)", __FUNCTION__, hMHandle, psLinuxMemArea)); + + eError = PVRSRV_ERROR_GENERIC; + +exit_unlock: + LinuxUnLockMutex(&g_sMMapMutex); + + return eError; +} + +static inline PKV_OFFSET_STRUCT +FindOffsetStructByOffset(IMG_UINT32 ui32Offset, IMG_UINT32 ui32RealByteSize) +{ + PKV_OFFSET_STRUCT psOffsetStruct; + IMG_UINT32 ui32TID = GetCurrentThreadID(); + IMG_UINT32 ui32PID = OSGetCurrentProcessIDKM(); + + list_for_each_entry(psOffsetStruct, &g_sMMapOffsetStructList, sMMapItem) + { + if (ui32Offset == psOffsetStruct->ui32MMapOffset && ui32RealByteSize == psOffsetStruct->ui32RealByteSize && psOffsetStruct->ui32PID == ui32PID) + { + + if (!PFNIsPhysical(ui32Offset) || psOffsetStruct->ui32TID == ui32TID) + { + return psOffsetStruct; + } + } + } + + return IMG_NULL; +} + + +static IMG_BOOL +DoMapToUser(LinuxMemArea *psLinuxMemArea, + struct vm_area_struct* ps_vma, + IMG_UINT32 ui32ByteOffset) +{ + IMG_UINT32 ui32ByteSize; + + if (psLinuxMemArea->eAreaType == LINUX_MEM_AREA_SUB_ALLOC) + { + return DoMapToUser(LinuxMemAreaRoot(psLinuxMemArea), + ps_vma, + psLinuxMemArea->uData.sSubAlloc.ui32ByteOffset + ui32ByteOffset); + } + + + ui32ByteSize = ps_vma->vm_end - ps_vma->vm_start; + PVR_ASSERT(ADDR_TO_PAGE_OFFSET(ui32ByteSize) == 0); + +#if defined (__sparc__) + +#error "SPARC not supported" +#endif + + if (PFNIsPhysical(ps_vma->vm_pgoff)) + { + IMG_INT result; + + PVR_ASSERT(LinuxMemAreaPhysIsContig(psLinuxMemArea)); + PVR_ASSERT(LinuxMemAreaToCpuPFN(psLinuxMemArea, ui32ByteOffset) == ps_vma->vm_pgoff); + + + result = IO_REMAP_PFN_RANGE(ps_vma, ps_vma->vm_start, ps_vma->vm_pgoff, ui32ByteSize, ps_vma->vm_page_prot); + + if(result == 0) + { + return IMG_TRUE; + } + + PVR_DPF((PVR_DBG_MESSAGE, "%s: Failed to map contiguous physical address range (%d), trying non-contiguous path", __FUNCTION__, result)); + } + + { + + IMG_UINT32 ulVMAPos; + IMG_UINT32 ui32ByteEnd = ui32ByteOffset + ui32ByteSize; + IMG_UINT32 ui32PA; + + + for(ui32PA = ui32ByteOffset; ui32PA < ui32ByteEnd; ui32PA += PAGE_SIZE) + { + IMG_UINT32 pfn = LinuxMemAreaToCpuPFN(psLinuxMemArea, ui32PA); + + if (!pfn_valid(pfn)) + { + PVR_DPF((PVR_DBG_ERROR,"%s: Error - PFN invalid: 0x%lx", __FUNCTION__, pfn)); + return IMG_FALSE; + } + } + + + ulVMAPos = ps_vma->vm_start; + for(ui32PA = ui32ByteOffset; ui32PA < ui32ByteEnd; ui32PA += PAGE_SIZE) + { + IMG_UINT32 pfn; + struct page *psPage; + IMG_INT result; + + pfn = LinuxMemAreaToCpuPFN(psLinuxMemArea, ui32PA); + PVR_ASSERT(pfn_valid(pfn)); + + psPage = pfn_to_page(pfn); + + result = VM_INSERT_PAGE(ps_vma, ulVMAPos, psPage); + if(result != 0) + { + PVR_DPF((PVR_DBG_ERROR,"%s: Error - VM_INSERT_PAGE failed (%d)", __FUNCTION__, result)); + return IMG_FALSE; + } + ulVMAPos += PAGE_SIZE; + } + } + + return IMG_TRUE; +} + + +static IMG_VOID +MMapVOpenNoLock(struct vm_area_struct* ps_vma) +{ + PKV_OFFSET_STRUCT psOffsetStruct = (PKV_OFFSET_STRUCT)ps_vma->vm_private_data; + PVR_ASSERT(psOffsetStruct != IMG_NULL) + psOffsetStruct->ui32Mapped++; + PVR_ASSERT(!psOffsetStruct->bOnMMapList); + + if (psOffsetStruct->ui32Mapped > 1) + { + PVR_DPF((PVR_DBG_WARNING, "%s: Offset structure 0x%p is being shared across processes (psOffsetStruct->ui32Mapped: %lu)", __FUNCTION__, psOffsetStruct, psOffsetStruct->ui32Mapped)); + PVR_ASSERT((ps_vma->vm_flags & VM_DONTCOPY) == 0); + } + +#if defined(DEBUG_LINUX_MMAP_AREAS) + + PVR_DPF((PVR_DBG_MESSAGE, + "%s: psLinuxMemArea 0x%p, KVAddress 0x%p MMapOffset %ld, ui32Mapped %d", + __FUNCTION__, + psOffsetStruct->psLinuxMemArea, + LinuxMemAreaToCpuVAddr(psOffsetStruct->psLinuxMemArea), + psOffsetStruct->ui32MMapOffset, + psOffsetStruct->ui32Mapped)); +#endif + +#if (LINUX_VERSION_CODE < KERNEL_VERSION(2,6,0)) + MOD_INC_USE_COUNT; +#endif +} + + +static void +MMapVOpen(struct vm_area_struct* ps_vma) +{ + LinuxLockMutex(&g_sMMapMutex); + + MMapVOpenNoLock(ps_vma); + + LinuxUnLockMutex(&g_sMMapMutex); +} + + +static IMG_VOID +MMapVCloseNoLock(struct vm_area_struct* ps_vma) +{ + PKV_OFFSET_STRUCT psOffsetStruct = (PKV_OFFSET_STRUCT)ps_vma->vm_private_data; + PVR_ASSERT(psOffsetStruct != IMG_NULL) + +#if defined(DEBUG_LINUX_MMAP_AREAS) + PVR_DPF((PVR_DBG_MESSAGE, + "%s: psLinuxMemArea 0x%p, CpuVAddr 0x%p ui32MMapOffset %ld, ui32Mapped %d", + __FUNCTION__, + psOffsetStruct->psLinuxMemArea, + LinuxMemAreaToCpuVAddr(psOffsetStruct->psLinuxMemArea), + psOffsetStruct->ui32MMapOffset, + psOffsetStruct->ui32Mapped)); +#endif + + PVR_ASSERT(!psOffsetStruct->bOnMMapList); + psOffsetStruct->ui32Mapped--; + if (psOffsetStruct->ui32Mapped == 0) + { + if (psOffsetStruct->ui32RefCount != 0) + { + PVR_DPF((PVR_DBG_MESSAGE, "%s: psOffsetStruct 0x%p has non-zero reference count (ui32RefCount = %lu). User mode address of start of mapping: 0x%lx", __FUNCTION__, psOffsetStruct, psOffsetStruct->ui32RefCount, psOffsetStruct->ui32UserVAddr)); + } + + DestroyOffsetStruct(psOffsetStruct); + } + + ps_vma->vm_private_data = NULL; + +#if (LINUX_VERSION_CODE < KERNEL_VERSION(2,6,0)) + MOD_DEC_USE_COUNT; +#endif +} + +static void +MMapVClose(struct vm_area_struct* ps_vma) +{ + LinuxLockMutex(&g_sMMapMutex); + + MMapVCloseNoLock(ps_vma); + + LinuxUnLockMutex(&g_sMMapMutex); +} + + +static struct vm_operations_struct MMapIOOps = +{ + open: MMapVOpen, + close: MMapVClose +}; + + +int +PVRMMap(struct file* pFile, struct vm_area_struct* ps_vma) +{ + IMG_UINT32 ui32ByteSize; + PKV_OFFSET_STRUCT psOffsetStruct = NULL; + int iRetVal = 0; + + PVR_UNREFERENCED_PARAMETER(pFile); + + LinuxLockMutex(&g_sMMapMutex); + + ui32ByteSize = ps_vma->vm_end - ps_vma->vm_start; + + PVR_DPF((PVR_DBG_MESSAGE, "%s: Received mmap(2) request with ui32MMapOffset 0x%08lx," + " and ui32ByteSize %ld(0x%08lx)", + __FUNCTION__, + ps_vma->vm_pgoff, + ui32ByteSize, ui32ByteSize)); + + + if ((ps_vma->vm_flags & VM_WRITE) && + !(ps_vma->vm_flags & VM_SHARED)) + { + PVR_DPF((PVR_DBG_ERROR, "%s: Cannot mmap non-shareable writable areas", __FUNCTION__)); + iRetVal = -EINVAL; + goto unlock_and_return; + } + + psOffsetStruct = FindOffsetStructByOffset(ps_vma->vm_pgoff, ui32ByteSize); + if (psOffsetStruct == IMG_NULL) + { + PVR_DPF((PVR_DBG_ERROR, + "%s: Attempted to mmap unregistered area at vm_pgoff %ld", + __FUNCTION__, ps_vma->vm_pgoff)); + iRetVal = -EINVAL; + goto unlock_and_return; + } + list_del(&psOffsetStruct->sMMapItem); + psOffsetStruct->bOnMMapList = IMG_FALSE; + + PVR_DPF((PVR_DBG_MESSAGE, "%s: Mapped psLinuxMemArea 0x%p\n", + __FUNCTION__, psOffsetStruct->psLinuxMemArea)); + + ps_vma->vm_flags |= VM_RESERVED; + ps_vma->vm_flags |= VM_IO; + + + ps_vma->vm_flags |= VM_DONTEXPAND; + + + ps_vma->vm_flags |= VM_DONTCOPY; + + ps_vma->vm_private_data = (void *)psOffsetStruct; + + switch(psOffsetStruct->psLinuxMemArea->ui32AreaFlags & PVRSRV_HAP_CACHETYPE_MASK) + { + case PVRSRV_HAP_CACHED: + + break; + case PVRSRV_HAP_WRITECOMBINE: + ps_vma->vm_page_prot = PGPROT_WC(ps_vma->vm_page_prot); + break; + case PVRSRV_HAP_UNCACHED: + ps_vma->vm_page_prot = PGPROT_UC(ps_vma->vm_page_prot); + break; + default: + PVR_DPF((PVR_DBG_ERROR, "%s: unknown cache type", __FUNCTION__)); + iRetVal = -EINVAL; + goto unlock_and_return; + } + + + ps_vma->vm_ops = &MMapIOOps; + + if(!DoMapToUser(psOffsetStruct->psLinuxMemArea, ps_vma, 0)) + { + iRetVal = -EAGAIN; + goto unlock_and_return; + } + + PVR_ASSERT(psOffsetStruct->ui32UserVAddr == 0) + + psOffsetStruct->ui32UserVAddr = ps_vma->vm_start; + + + MMapVOpenNoLock(ps_vma); + + PVR_DPF((PVR_DBG_MESSAGE, "%s: Mapped area at offset 0x%08lx\n", + __FUNCTION__, ps_vma->vm_pgoff)); + +unlock_and_return: + if (iRetVal != 0 && psOffsetStruct != IMG_NULL) + { + DestroyOffsetStruct(psOffsetStruct); + } + + LinuxUnLockMutex(&g_sMMapMutex); + + return iRetVal; +} + + +#if defined(DEBUG_LINUX_MMAP_AREAS) +static off_t +PrintMMapRegistrations(IMG_CHAR *buffer, size_t size, off_t off) +{ + LinuxMemArea *psLinuxMemArea; + off_t Ret; + + LinuxLockMutex(&g_sMMapMutex); + + if(!off) + { + Ret = printAppend(buffer, size, 0, +#if !defined(DEBUG_LINUX_XML_PROC_FILES) + "Allocations registered for mmap: %lu\n" + "In total these areas correspond to %lu bytes\n" + "psLinuxMemArea " + "UserVAddr " + "KernelVAddr " + "CpuPAddr " + "MMapOffset " + "ByteLength " + "LinuxMemType " + "Pid Name Flags\n", +#else + "\n" + "\t%lu\n" + "\t%lu\n" + "\n", +#endif + g_ui32RegisteredAreas, + g_ui32TotalByteSize + ); + + goto unlock_and_return; + } + + if (size < 135) + { + Ret = 0; + goto unlock_and_return; + } + + PVR_ASSERT(off != 0); + list_for_each_entry(psLinuxMemArea, &g_sMMapAreaList, sMMapItem) + { + PKV_OFFSET_STRUCT psOffsetStruct; + + list_for_each_entry(psOffsetStruct, &psLinuxMemArea->sMMapOffsetStructList, sAreaItem) + { + off--; + if (off == 0) + { + IMG_UINT32 ui32RealByteSize; + IMG_UINT32 ui32ByteOffset; + + PVR_ASSERT(psOffsetStruct->psLinuxMemArea == psLinuxMemArea); + + DetermineUsersSizeAndByteOffset(psLinuxMemArea, + &ui32RealByteSize, + &ui32ByteOffset); + + Ret = printAppend (buffer, size, 0, +#if !defined(DEBUG_LINUX_XML_PROC_FILES) + "%-8p %08lx %-8p %08lx %08lx %-8ld %-24s %-5lu %-8s %08lx(%s)\n", +#else + "\n" + "\t%-8p\n" + "\t%-8lx\n" + "\t%-8p\n" + "\t%08lx\n" + "\t%08lx\n" + "\t%-8ld\n" + "\t%-24s\n" + "\t%-5lu\n" + "\t%-8s\n" + "\t%08lx\n" + "\t%s\n" + "\n", +#endif + psLinuxMemArea, + psOffsetStruct->ui32UserVAddr + ui32ByteOffset, + LinuxMemAreaToCpuVAddr(psLinuxMemArea), + LinuxMemAreaToCpuPAddr(psLinuxMemArea,0).uiAddr, + psOffsetStruct->ui32MMapOffset, + psLinuxMemArea->ui32ByteSize, + LinuxMemAreaTypeToString(psLinuxMemArea->eAreaType), + psOffsetStruct->ui32PID, + psOffsetStruct->pszName, + psLinuxMemArea->ui32AreaFlags, + HAPFlagsToString(psLinuxMemArea->ui32AreaFlags)); + goto unlock_and_return; + } + } + } + Ret = END_OF_FILE; + +unlock_and_return: + LinuxUnLockMutex(&g_sMMapMutex); + return Ret; +} +#endif + + +PVRSRV_ERROR +PVRMMapRegisterArea(LinuxMemArea *psLinuxMemArea) +{ + PVRSRV_ERROR eError = PVRSRV_ERROR_GENERIC; +#if defined(DEBUG) || defined(DEBUG_LINUX_MMAP_AREAS) + const IMG_CHAR *pszName = LinuxMemAreaTypeToString(LinuxMemAreaRootType(psLinuxMemArea)); +#endif + + LinuxLockMutex(&g_sMMapMutex); + + PVR_DPF((PVR_DBG_MESSAGE, + "%s(%s, psLinuxMemArea 0x%p, ui32AllocFlags 0x%8lx)", + __FUNCTION__, pszName, psLinuxMemArea, psLinuxMemArea->ui32AreaFlags)); + + PVR_ASSERT(psLinuxMemArea->eAreaType != LINUX_MEM_AREA_SUB_ALLOC || LinuxMemAreaRoot(psLinuxMemArea)->eAreaType != LINUX_MEM_AREA_SUB_ALLOC); + + + if(psLinuxMemArea->bMMapRegistered) + { + PVR_DPF((PVR_DBG_ERROR, "%s: psLinuxMemArea 0x%p is already registered", + __FUNCTION__, psLinuxMemArea)); + eError = PVRSRV_ERROR_INVALID_PARAMS; + goto exit_unlock; + } + + list_add_tail(&psLinuxMemArea->sMMapItem, &g_sMMapAreaList); + + psLinuxMemArea->bMMapRegistered = IMG_TRUE; + +#if defined(DEBUG_LINUX_MMAP_AREAS) + g_ui32RegisteredAreas++; + + if (psLinuxMemArea->eAreaType != LINUX_MEM_AREA_SUB_ALLOC) + { + g_ui32TotalByteSize += psLinuxMemArea->ui32ByteSize; + } +#endif + + eError = PVRSRV_OK; + +exit_unlock: + LinuxUnLockMutex(&g_sMMapMutex); + + return eError; +} + + +PVRSRV_ERROR +PVRMMapRemoveRegisteredArea(LinuxMemArea *psLinuxMemArea) +{ + PVRSRV_ERROR eError = PVRSRV_ERROR_GENERIC; + PKV_OFFSET_STRUCT psOffsetStruct, psTmpOffsetStruct; + + LinuxLockMutex(&g_sMMapMutex); + + PVR_ASSERT(psLinuxMemArea->bMMapRegistered); + + list_for_each_entry_safe(psOffsetStruct, psTmpOffsetStruct, &psLinuxMemArea->sMMapOffsetStructList, sAreaItem) + { + if (psOffsetStruct->ui32Mapped != 0) + { + PVR_DPF((PVR_DBG_ERROR, "%s: psOffsetStruct 0x%p for memory area 0x0x%p is still mapped; psOffsetStruct->ui32Mapped %lu", __FUNCTION__, psOffsetStruct, psLinuxMemArea, psOffsetStruct->ui32Mapped)); + eError = PVRSRV_ERROR_GENERIC; + goto exit_unlock; + } + else + { + + PVR_DPF((PVR_DBG_WARNING, "%s: psOffsetStruct 0x%p was never mapped", __FUNCTION__, psOffsetStruct)); + } + + PVR_ASSERT((psOffsetStruct->ui32Mapped == 0) && psOffsetStruct->bOnMMapList); + + DestroyOffsetStruct(psOffsetStruct); + } + + list_del(&psLinuxMemArea->sMMapItem); + + psLinuxMemArea->bMMapRegistered = IMG_FALSE; + +#if defined(DEBUG_LINUX_MMAP_AREAS) + g_ui32RegisteredAreas--; + if (psLinuxMemArea->eAreaType != LINUX_MEM_AREA_SUB_ALLOC) + { + g_ui32TotalByteSize -= psLinuxMemArea->ui32ByteSize; + } +#endif + + eError = PVRSRV_OK; + +exit_unlock: + LinuxUnLockMutex(&g_sMMapMutex); + return eError; +} + + +PVRSRV_ERROR +LinuxMMapPerProcessConnect(PVRSRV_ENV_PER_PROCESS_DATA *psEnvPerProc) +{ + PVR_UNREFERENCED_PARAMETER(psEnvPerProc); + + return PVRSRV_OK; +} + +IMG_VOID +LinuxMMapPerProcessDisconnect(PVRSRV_ENV_PER_PROCESS_DATA *psEnvPerProc) +{ + PKV_OFFSET_STRUCT psOffsetStruct, psTmpOffsetStruct; + IMG_BOOL bWarn = IMG_FALSE; + IMG_UINT32 ui32PID = OSGetCurrentProcessIDKM(); + + PVR_UNREFERENCED_PARAMETER(psEnvPerProc); + + LinuxLockMutex(&g_sMMapMutex); + + list_for_each_entry_safe(psOffsetStruct, psTmpOffsetStruct, &g_sMMapOffsetStructList, sMMapItem) + { + if (psOffsetStruct->ui32PID == ui32PID) + { + if (!bWarn) + { + PVR_DPF((PVR_DBG_WARNING, "%s: process has unmapped offset structures. Removing them", __FUNCTION__)); + bWarn = IMG_TRUE; + } + PVR_ASSERT(psOffsetStruct->ui32Mapped == 0); + PVR_ASSERT(psOffsetStruct->bOnMMapList); + + DestroyOffsetStruct(psOffsetStruct); + } + } + + LinuxUnLockMutex(&g_sMMapMutex); +} + + +PVRSRV_ERROR LinuxMMapPerProcessHandleOptions(PVRSRV_HANDLE_BASE *psHandleBase) +{ + PVRSRV_ERROR eError = PVRSRV_OK; + + eError = PVRSRVSetMaxHandle(psHandleBase, MAX_MMAP_HANDLE); + if (eError != PVRSRV_OK) + { + PVR_DPF((PVR_DBG_ERROR,"%s: failed to set handle limit (%d)", __FUNCTION__, eError)); + return eError; + } + + return eError; +} + + +IMG_VOID +PVRMMapInit(IMG_VOID) +{ + LinuxInitMutex(&g_sMMapMutex); + + g_psMemmapCache = KMemCacheCreateWrapper("img-mmap", sizeof(KV_OFFSET_STRUCT), 0, 0); + if (!g_psMemmapCache) + { + PVR_DPF((PVR_DBG_ERROR,"%s: failed to allocate kmem_cache", __FUNCTION__)); + goto error; + } + +#if defined(DEBUG_LINUX_MMAP_AREAS) + CreateProcReadEntry("mmap", PrintMMapRegistrations); +#endif + + return; + +error: + PVRMMapCleanup(); + return; +} + + +IMG_VOID +PVRMMapCleanup(IMG_VOID) +{ + PVRSRV_ERROR eError; + + if (!list_empty(&g_sMMapAreaList)) + { + LinuxMemArea *psLinuxMemArea, *psTmpMemArea; + + PVR_DPF((PVR_DBG_ERROR, "%s: Memory areas are still registered with MMap", __FUNCTION__)); + + PVR_TRACE(("%s: Unregistering memory areas", __FUNCTION__)); + list_for_each_entry_safe(psLinuxMemArea, psTmpMemArea, &g_sMMapAreaList, sMMapItem) + { + eError = PVRMMapRemoveRegisteredArea(psLinuxMemArea); + if (eError != PVRSRV_OK) + { + PVR_DPF((PVR_DBG_ERROR, "%s: PVRMMapRemoveRegisteredArea failed (%d)", __FUNCTION__, eError)); + } + PVR_ASSERT(eError == PVRSRV_OK); + + LinuxMemAreaDeepFree(psLinuxMemArea); + } + } + PVR_ASSERT(list_empty((&g_sMMapAreaList))); + + RemoveProcEntry("mmap"); + + if(g_psMemmapCache) + { + KMemCacheDestroyWrapper(g_psMemmapCache); + g_psMemmapCache = NULL; + } +} diff --git a/services4/srvkm/env/linux/mmap.h b/services4/srvkm/env/linux/mmap.h new file mode 100644 index 0000000..5c9f2b2 --- /dev/null +++ b/services4/srvkm/env/linux/mmap.h @@ -0,0 +1,107 @@ +/********************************************************************** + * + * Copyright(c) 2008 Imagination Technologies Ltd. All rights reserved. + * + * This program is free software; you can redistribute it and/or modify it + * under the terms and conditions of the GNU General Public License, + * version 2, as published by the Free Software Foundation. + * + * This program is distributed in the hope it will be useful but, except + * as otherwise stated in writing, without any warranty; without even the + * implied warranty of merchantability or fitness for a particular purpose. + * See the GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License along with + * this program; if not, write to the Free Software Foundation, Inc., + * 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA. + * + * The full GNU General Public License is included in this distribution in + * the file called "COPYING". + * + * Contact Information: + * Imagination Technologies Ltd. + * Home Park Estate, Kings Langley, Herts, WD4 8LZ, UK + * + ******************************************************************************/ + +#if !defined(__MMAP_H__) +#define __MMAP_H__ + +#include +#include + +#include "perproc.h" +#include "mm.h" + +typedef struct KV_OFFSET_STRUCT_TAG +{ + + IMG_UINT32 ui32Mapped; + + + IMG_UINT32 ui32MMapOffset; + + IMG_UINT32 ui32RealByteSize; + + + LinuxMemArea *psLinuxMemArea; + + + IMG_UINT32 ui32TID; + + + IMG_UINT32 ui32PID; + + + IMG_BOOL bOnMMapList; + + + IMG_UINT32 ui32RefCount; + + + IMG_UINT32 ui32UserVAddr; + + +#if defined(DEBUG_LINUX_MMAP_AREAS) + const IMG_CHAR *pszName; +#endif + + + struct list_head sMMapItem; + + + struct list_head sAreaItem; +}KV_OFFSET_STRUCT, *PKV_OFFSET_STRUCT; + + + +IMG_VOID PVRMMapInit(IMG_VOID); + + +IMG_VOID PVRMMapCleanup(IMG_VOID); + + +PVRSRV_ERROR PVRMMapRegisterArea(LinuxMemArea *psLinuxMemArea); + + +PVRSRV_ERROR PVRMMapRemoveRegisteredArea(LinuxMemArea *psLinuxMemArea); + + +PVRSRV_ERROR PVRMMapOSMemHandleToMMapData(PVRSRV_PER_PROCESS_DATA *psPerProc, + IMG_HANDLE hMHandle, + IMG_UINT32 *pui32MMapOffset, + IMG_UINT32 *pui32ByteOffset, + IMG_UINT32 *pui32RealByteSize, IMG_UINT32 *pui32UserVAddr); + +PVRSRV_ERROR +PVRMMapReleaseMMapData(PVRSRV_PER_PROCESS_DATA *psPerProc, + IMG_HANDLE hMHandle, + IMG_BOOL *pbMUnmap, + IMG_UINT32 *pui32RealByteSize, + IMG_UINT32 *pui32UserVAddr); + +int PVRMMap(struct file* pFile, struct vm_area_struct* ps_vma); + + +#endif + diff --git a/services4/srvkm/env/linux/module.c b/services4/srvkm/env/linux/module.c new file mode 100644 index 0000000..b7ddda3 --- /dev/null +++ b/services4/srvkm/env/linux/module.c @@ -0,0 +1,661 @@ +/********************************************************************** + * + * Copyright(c) 2008 Imagination Technologies Ltd. All rights reserved. + * + * This program is free software; you can redistribute it and/or modify it + * under the terms and conditions of the GNU General Public License, + * version 2, as published by the Free Software Foundation. + * + * This program is distributed in the hope it will be useful but, except + * as otherwise stated in writing, without any warranty; without even the + * implied warranty of merchantability or fitness for a particular purpose. + * See the GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License along with + * this program; if not, write to the Free Software Foundation, Inc., + * 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA. + * + * The full GNU General Public License is included in this distribution in + * the file called "COPYING". + * + * Contact Information: + * Imagination Technologies Ltd. + * Home Park Estate, Kings Langley, Herts, WD4 8LZ, UK + * + ******************************************************************************/ + +#ifndef AUTOCONF_INCLUDED + #include +#endif + +#include +#include +#include +#include +#include +#include + +#if defined(LDM_PLATFORM) +#include +#endif + +#if defined(LDM_PCI) +#include +#endif + +#if defined(DEBUG) && defined(PVR_MANUAL_POWER_CONTROL) +#include +#endif + +#include "img_defs.h" +#include "services.h" +#include "kerneldisplay.h" +#include "kernelbuffer.h" +#include "syscommon.h" +#include "pvrmmap.h" +#include "mutils.h" +#include "mm.h" +#include "mmap.h" +#include "mutex.h" +#include "pvr_debug.h" +#include "srvkm.h" +#include "perproc.h" +#include "handle.h" +#include "pvr_bridge_km.h" +#include "proc.h" +#include "pvrmodule.h" +#include "private_data.h" +#include "lock.h" +#include "linkage.h" + +#if defined(SUPPORT_DRI_DRM) +#include "pvr_drm.h" +#endif +#define DRVNAME "pvrsrvkm" +#define DEVNAME "pvrsrvkm" + + +MODULE_SUPPORTED_DEVICE(DEVNAME); +#ifdef DEBUG +static IMG_INT debug = DBGPRIV_WARNING; +#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,0)) +#include +module_param(debug, int, 0); +#else +MODULE_PARM(debug, "i"); +MODULE_PARM_DESC(debug, "Sets the level of debug output (default=0x4)"); +#endif +#endif + + +extern IMG_BOOL PVRGetDisplayClassJTable(PVRSRV_DC_DISP2SRV_KMJTABLE *psJTable); +extern IMG_BOOL PVRGetBufferClassJTable(PVRSRV_BC_BUFFER2SRV_KMJTABLE *psJTable); +EXPORT_SYMBOL(PVRGetDisplayClassJTable); +EXPORT_SYMBOL(PVRGetBufferClassJTable); + + +static IMG_INT AssignedMajorNumber; + +#if defined(LDM_PLATFORM) || defined(LDM_PCI) +static struct class *psPvrClass; +#endif + +static IMG_INT PVRSRVOpen(struct inode* pInode, struct file* pFile); +static IMG_INT PVRSRVRelease(struct inode* pInode, struct file* pFile); + +PVRSRV_LINUX_MUTEX gPVRSRVLock; + +static struct file_operations pvrsrv_fops = { + owner:THIS_MODULE, + unlocked_ioctl:PVRSRV_BridgeDispatchKM, + open:PVRSRVOpen, + release:PVRSRVRelease, + mmap:PVRMMap, +}; + + +#if defined(DEBUG) && defined(PVR_MANUAL_POWER_CONTROL) +static IMG_UINT32 gPVRPowerLevel; +#endif + +#if defined(LDM_PLATFORM) || defined(LDM_PCI) + +#if defined(LDM_PLATFORM) +#define LDM_DEV struct platform_device +#define LDM_DRV struct platform_driver +#if defined(LDM_PCI) +#undef LDM_PCI +#endif +#endif + +#if defined(LDM_PCI) +#define LDM_DEV struct pci_dev +#define LDM_DRV struct pci_driver +#endif + +#if defined(LDM_PLATFORM) +static IMG_INT PVRSRVDriverRemove(LDM_DEV *device); +static IMG_INT PVRSRVDriverProbe(LDM_DEV *device); +#endif +#if defined(LDM_PCI) +static IMG_VOID PVRSRVDriverRemove(LDM_DEV *device); +static IMG_INT PVRSRVDriverProbe(LDM_DEV *device, const struct pci_device_id *id); +#endif +static IMG_INT PVRSRVDriverSuspend(LDM_DEV *device, pm_message_t state); +static IMG_VOID PVRSRVDriverShutdown(LDM_DEV *device); +static IMG_INT PVRSRVDriverResume(LDM_DEV *device); + +#if defined(LDM_PCI) +struct pci_device_id powervr_id_table[] __devinitdata = { + { PCI_DEVICE(SYS_SGX_DEV_VENDOR_ID, SYS_SGX_DEV_DEVICE_ID) }, + { 0 } +}; + +MODULE_DEVICE_TABLE(pci, powervr_id_table); +#endif + +static LDM_DRV powervr_driver = { +#if defined(LDM_PLATFORM) + .driver = { + .name = DRVNAME, + }, +#endif +#if defined(LDM_PCI) + .name = DRVNAME, + .id_table = powervr_id_table, +#endif + .probe = PVRSRVDriverProbe, +#if defined(LDM_PLATFORM) + .remove = PVRSRVDriverRemove, +#endif +#if defined(LDM_PCI) + .remove = __devexit_p(PVRSRVDriverRemove), +#endif + .suspend = PVRSRVDriverSuspend, + .resume = PVRSRVDriverResume, + .shutdown = PVRSRVDriverShutdown, +}; + +LDM_DEV *gpsPVRLDMDev; + +#if defined(LDM_PLATFORM) +static IMG_VOID PVRSRVDeviceRelease(struct device *device); + +static struct platform_device powervr_device = { + .name = DEVNAME, + .id = -1, + .dev = { + .release = PVRSRVDeviceRelease + } +}; +#endif + +#if defined(LDM_PLATFORM) +static IMG_INT PVRSRVDriverProbe(LDM_DEV *pDevice) +#endif +#if defined(LDM_PCI) +static IMG_INT __devinit PVRSRVDriverProbe(LDM_DEV *pDevice, const struct pci_device_id *id) +#endif +{ + SYS_DATA *psSysData; + + PVR_TRACE(("PVRSRVDriverProbe(pDevice=%p)", pDevice)); + +#if 0 + + if (PerDeviceSysInitialise((IMG_PVOID)pDevice) != PVRSRV_OK) + { + return -EINVAL; + } +#endif + + if (SysAcquireData(&psSysData) != PVRSRV_OK) + { + gpsPVRLDMDev = pDevice; + + if (SysInitialise() != PVRSRV_OK) + { + return -ENODEV; + } + } + + return 0; +} + + +#if defined (LDM_PLATFORM) +static IMG_INT PVRSRVDriverRemove(LDM_DEV *pDevice) +#endif +#if defined(LDM_PCI) +static IMG_VOID __devexit PVRSRVDriverRemove(LDM_DEV *pDevice) +#endif +{ + SYS_DATA *psSysData; + + PVR_TRACE(("PVRSRVDriverRemove(pDevice=%p)", pDevice)); + + if (SysAcquireData(&psSysData) == PVRSRV_OK) + { +#if defined(DEBUG) && defined(PVR_MANUAL_POWER_CONTROL) + if (gPVRPowerLevel != 0) + { + if (PVRSRVSetPowerStateKM(PVRSRV_POWER_STATE_D0) == PVRSRV_OK) + { + gPVRPowerLevel = 0; + } + } +#endif + SysDeinitialise(psSysData); + + gpsPVRLDMDev = IMG_NULL; + } + +#if 0 + if (PerDeviceSysDeInitialise((IMG_PVOID)pDevice) != PVRSRV_OK) + { + return -EINVAL; + } +#endif + +#if defined (LDM_PLATFORM) + return 0; +#endif +#if defined (LDM_PCI) + return; +#endif +} + + +static IMG_VOID PVRSRVDriverShutdown(LDM_DEV *pDevice) +{ + PVR_TRACE(("PVRSRVDriverShutdown(pDevice=%p)", pDevice)); + + (IMG_VOID) PVRSRVSetPowerStateKM(PVRSRV_POWER_STATE_D3); +} + + +static IMG_INT PVRSRVDriverSuspend(LDM_DEV *pDevice, pm_message_t state) +{ +#if !(defined(DEBUG) && defined(PVR_MANUAL_POWER_CONTROL)) + PVR_TRACE(( "PVRSRVDriverSuspend(pDevice=%p)", pDevice)); + + if (PVRSRVSetPowerStateKM(PVRSRV_POWER_STATE_D3) != PVRSRV_OK) + { + return -EINVAL; + } +#endif + return 0; +} + + +static IMG_INT PVRSRVDriverResume(LDM_DEV *pDevice) +{ +#if !(defined(DEBUG) && defined(PVR_MANUAL_POWER_CONTROL)) + PVR_TRACE(("PVRSRVDriverResume(pDevice=%p)", pDevice)); + + if (PVRSRVSetPowerStateKM(PVRSRV_POWER_STATE_D0) != PVRSRV_OK) + { + return -EINVAL; + } +#endif + return 0; +} + + +#if defined(LDM_PLATFORM) +static IMG_VOID PVRSRVDeviceRelease(struct device *pDevice) +{ + PVR_DPF((PVR_DBG_WARNING, "PVRSRVDeviceRelease(pDevice=%p)", pDevice)); +} +#endif +#endif + + +#if defined(DEBUG) && defined(PVR_MANUAL_POWER_CONTROL) +IMG_INT PVRProcSetPowerLevel(struct file *file, const IMG_CHAR *buffer, IMG_UINT32 count, IMG_VOID *data) +{ + IMG_CHAR data_buffer[2]; + IMG_UINT32 PVRPowerLevel; + + if (count != sizeof(data_buffer)) + { + return -EINVAL; + } + else + { + if (copy_from_user(data_buffer, buffer, count)) + return -EINVAL; + if (data_buffer[count - 1] != '\n') + return -EINVAL; + PVRPowerLevel = data_buffer[0] - '0'; + if (PVRPowerLevel != gPVRPowerLevel) + { + if (PVRPowerLevel != 0) + { + if (PVRSRVSetPowerStateKM(PVRSRV_POWER_STATE_D3) != PVRSRV_OK) + { + return -EINVAL; + } + } + else + { + if (PVRSRVSetPowerStateKM(PVRSRV_POWER_STATE_D0) != PVRSRV_OK) + { + return -EINVAL; + } + } + + gPVRPowerLevel = PVRPowerLevel; + } + } + return (count); +} + +IMG_INT PVRProcGetPowerLevel(IMG_CHAR *page, IMG_CHAR **start, off_t off, IMG_INT count, IMG_INT *eof, IMG_VOID *data) +{ + if (off == 0) { + *start = (IMG_CHAR *)1; + return printAppend(page, count, 0, "%lu\n", gPVRPowerLevel); + } + *eof = 1; + return 0; +} +#endif + +static IMG_INT PVRSRVOpen(struct inode unref__ * pInode, struct file *pFile) +{ + PVRSRV_FILE_PRIVATE_DATA *psPrivateData; + IMG_HANDLE hBlockAlloc; + IMG_INT iRet = -ENOMEM; + PVRSRV_ERROR eError; + IMG_UINT32 ui32PID; + + LinuxLockMutex(&gPVRSRVLock); + + ui32PID = OSGetCurrentProcessIDKM(); + + if (PVRSRVProcessConnect(ui32PID) != PVRSRV_OK) + goto err_unlock; + + eError = OSAllocMem(PVRSRV_OS_NON_PAGEABLE_HEAP, + sizeof(PVRSRV_FILE_PRIVATE_DATA), + (IMG_PVOID *)&psPrivateData, + &hBlockAlloc); + + if(eError != PVRSRV_OK) + goto err_unlock; + +#if defined(PVR_SECURE_FD_EXPORT) + psPrivateData->hKernelMemInfo = NULL; +#endif + psPrivateData->ui32OpenPID = ui32PID; + psPrivateData->hBlockAlloc = hBlockAlloc; + pFile->private_data = psPrivateData; + + iRet = 0; +err_unlock: + LinuxUnLockMutex(&gPVRSRVLock); + return iRet; +} + + +static IMG_INT PVRSRVRelease(struct inode unref__ * pInode, struct file *pFile) +{ + PVRSRV_FILE_PRIVATE_DATA *psPrivateData; + + LinuxLockMutex(&gPVRSRVLock); + + psPrivateData = pFile->private_data; + + + PVRSRVProcessDisconnect(psPrivateData->ui32OpenPID); + + OSFreeMem(PVRSRV_OS_NON_PAGEABLE_HEAP, + sizeof(PVRSRV_FILE_PRIVATE_DATA), + psPrivateData, psPrivateData->hBlockAlloc); + + LinuxUnLockMutex(&gPVRSRVLock); + return 0; +} + + +static IMG_INT __init PVRCore_Init(IMG_VOID) +{ + IMG_INT error; +#if !(defined(LDM_PLATFORM) || defined(LDM_PCI)) + PVRSRV_ERROR eError; +#else + struct device *psDev; +#endif + + + PVRDPFInit(); + + PVR_TRACE(("PVRCore_Init")); + + LinuxInitMutex(&gPVRSRVLock); + +#ifdef DEBUG + PVRDebugSetLevel(debug); +#endif + + if (CreateProcEntries ()) + { + error = -ENOMEM; + return error; + } + + PVRLinuxMUtilsInit(); + + if(LinuxMMInit() != PVRSRV_OK) + { + error = -ENOMEM; + goto init_failed; + } + + LinuxBridgeInit(); + + PVRMMapInit(); + +#if defined(LDM_PLATFORM) || defined(LDM_PCI) + +#if defined(LDM_PLATFORM) + if ((error = platform_driver_register(&powervr_driver)) != 0) + { + PVR_DPF((PVR_DBG_ERROR, "PVRCore_Init: unable to register platform driver (%d)", error)); + + goto init_failed; + } + + if ((error = platform_device_register(&powervr_device)) != 0) + { + platform_driver_unregister(&powervr_driver); + + PVR_DPF((PVR_DBG_ERROR, "PVRCore_Init: unable to register platform device (%d)", error)); + + goto init_failed; + } +#endif + +#if defined(LDM_PCI) + if ((error = pci_register_driver(&powervr_driver)) != 0) + { + PVR_DPF((PVR_DBG_ERROR, "PVRCore_Init: unable to register PCI driver (%d)", error)); + + goto init_failed; + } +#endif + +#else + + if ((eError = SysInitialise()) != PVRSRV_OK) + { + error = -ENODEV; +#if defined(TCF_REV) && (TCF_REV == 110) + if(eError == PVRSRV_ERROR_NOT_SUPPORTED) + { + printk("\nAtlas wrapper (FPGA image) version mismatch"); + error = -ENODEV; + } +#endif + goto init_failed; + } +#endif +#if defined(SUPPORT_DRI_DRM) + if(PVRSRVDrmInit() != PVRSRV_OK) + { + error = -ENODEV; + goto sys_deinit; + } +#endif + + AssignedMajorNumber = register_chrdev(0, DEVNAME, &pvrsrv_fops); + + if (AssignedMajorNumber <= 0) + { + PVR_DPF((PVR_DBG_ERROR, "PVRCore_Init: unable to get major number")); + + error = -EBUSY; + goto drm_deinit; + } + + PVR_TRACE(("PVRCore_Init: major device %d", AssignedMajorNumber)); + +#if defined(LDM_PLATFORM) || defined(LDM_PCI) + + psPvrClass = class_create(THIS_MODULE, "pvr"); + + if (IS_ERR(psPvrClass)) + { + PVR_DPF((PVR_DBG_ERROR, "PVRCore_Init: unable to create class (%ld)", PTR_ERR(psPvrClass))); + error = -EBUSY; + goto unregister_device; + } + + psDev = device_create(psPvrClass, NULL, MKDEV(AssignedMajorNumber, 0), +#if (LINUX_VERSION_CODE > KERNEL_VERSION(2,6,26)) + NULL, +#endif + DEVNAME); + if (IS_ERR(psDev)) + { + PVR_DPF((PVR_DBG_ERROR, "PVRCore_Init: unable to create device (%ld)", PTR_ERR(psDev))); + error = -EBUSY; + goto destroy_class; + } +#endif + + return 0; + +#if defined(LDM_PLATFORM) || defined(LDM_PCI) +destroy_class: + class_destroy(psPvrClass); +unregister_device: +#endif + unregister_chrdev(AssignedMajorNumber, DRVNAME); +drm_deinit: +#if defined(SUPPORT_DRI_DRM) + PVRSRVDrmExit(); +sys_deinit: +#endif +#if defined(LDM_PLATFORM) || defined(LDM_PCI) +#if defined(LDM_PCI) + pci_unregister_driver(&powervr_driver); +#endif + +#if defined (LDM_PLATFORM) + platform_device_unregister(&powervr_device); + platform_driver_unregister(&powervr_driver); +#endif + +#else + + { + SYS_DATA *psSysData; + + SysAcquireData(&psSysData); + if (psSysData != IMG_NULL) + { + SysDeinitialise(psSysData); + } + } +#endif +init_failed: + PVRMMapCleanup(); + LinuxMMCleanup(); + LinuxBridgeDeInit(); + RemoveProcEntries(); + + return error; + +} + + +static IMG_VOID __exit PVRCore_Cleanup(IMG_VOID) +{ + SYS_DATA *psSysData; + + PVR_TRACE(("PVRCore_Cleanup")); + + SysAcquireData(&psSysData); + +#if defined(LDM_PLATFORM) || defined(LDM_PCI) + device_destroy(psPvrClass, MKDEV(AssignedMajorNumber, 0)); + class_destroy(psPvrClass); +#endif + +#if (LINUX_VERSION_CODE <= KERNEL_VERSION(2,6,22)) + if ( +#endif + unregister_chrdev(AssignedMajorNumber, DRVNAME) +#if !(LINUX_VERSION_CODE <= KERNEL_VERSION(2,6,22)) + ; +#else + ) + { + PVR_DPF((PVR_DBG_ERROR," can't unregister device major %d", AssignedMajorNumber)); + } +#endif + +#if defined(LDM_PLATFORM) || defined(LDM_PCI) + +#if defined(LDM_PCI) + pci_unregister_driver(&powervr_driver); +#endif + +#if defined (LDM_PLATFORM) + platform_device_unregister(&powervr_device); + platform_driver_unregister(&powervr_driver); +#endif + +#else +#if defined(DEBUG) && defined(PVR_MANUAL_POWER_CONTROL) + if (gPVRPowerLevel != 0) + { + if (PVRSRVSetPowerStateKM(PVRSRV_POWER_STATE_D0) == PVRSRV_OK) + { + gPVRPowerLevel = 0; + } + } +#endif + + SysDeinitialise(psSysData); +#endif + + PVRMMapCleanup(); + + LinuxMMCleanup(); + + LinuxBridgeDeInit(); + + RemoveProcEntries(); + + PVR_TRACE(("PVRCore_Cleanup: unloading")); +#if defined(SUPPORT_DRI_DRM) + PVRSRVDrmExit(); +#endif +} + +module_init(PVRCore_Init); +module_exit(PVRCore_Cleanup); + diff --git a/services4/srvkm/env/linux/mutex.c b/services4/srvkm/env/linux/mutex.c new file mode 100644 index 0000000..1ff98b8 --- /dev/null +++ b/services4/srvkm/env/linux/mutex.c @@ -0,0 +1,134 @@ +/********************************************************************** + * + * Copyright(c) 2008 Imagination Technologies Ltd. All rights reserved. + * + * This program is free software; you can redistribute it and/or modify it + * under the terms and conditions of the GNU General Public License, + * version 2, as published by the Free Software Foundation. + * + * This program is distributed in the hope it will be useful but, except + * as otherwise stated in writing, without any warranty; without even the + * implied warranty of merchantability or fitness for a particular purpose. + * See the GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License along with + * this program; if not, write to the Free Software Foundation, Inc., + * 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA. + * + * The full GNU General Public License is included in this distribution in + * the file called "COPYING". + * + * Contact Information: + * Imagination Technologies Ltd. + * Home Park Estate, Kings Langley, Herts, WD4 8LZ, UK + * + ******************************************************************************/ + +#include +#include +#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,15)) +#include +#else +#include +#endif +#include + +#include +#include + +#include "mutex.h" + + +#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,15)) + +IMG_VOID LinuxInitMutex(PVRSRV_LINUX_MUTEX *psPVRSRVMutex) +{ + mutex_init(psPVRSRVMutex); +} + +IMG_VOID LinuxLockMutex(PVRSRV_LINUX_MUTEX *psPVRSRVMutex) +{ + mutex_lock(psPVRSRVMutex); +} + +PVRSRV_ERROR LinuxLockMutexInterruptible(PVRSRV_LINUX_MUTEX *psPVRSRVMutex) +{ + if(mutex_lock_interruptible(psPVRSRVMutex) == -EINTR) + { + return PVRSRV_ERROR_GENERIC; + }else{ + return PVRSRV_OK; + } +} + +IMG_INT32 LinuxTryLockMutex(PVRSRV_LINUX_MUTEX *psPVRSRVMutex) +{ + return mutex_trylock(psPVRSRVMutex); +} + +IMG_VOID LinuxUnLockMutex(PVRSRV_LINUX_MUTEX *psPVRSRVMutex) +{ + mutex_unlock(psPVRSRVMutex); +} + +IMG_BOOL LinuxIsLockedMutex(PVRSRV_LINUX_MUTEX *psPVRSRVMutex) +{ + return mutex_is_locked(psPVRSRVMutex); +} + + +#else + + +IMG_VOID LinuxInitMutex(PVRSRV_LINUX_MUTEX *psPVRSRVMutex) +{ + init_MUTEX(&psPVRSRVMutex->sSemaphore); + atomic_set(&psPVRSRVMutex->Count, 0); +} + +IMG_VOID LinuxLockMutex(PVRSRV_LINUX_MUTEX *psPVRSRVMutex) +{ + down(&psPVRSRVMutex->sSemaphore); + atomic_dec(&psPVRSRVMutex->Count); +} + +PVRSRV_ERROR LinuxLockMutexInterruptible(PVRSRV_LINUX_MUTEX *psPVRSRVMutex) +{ + if(down_interruptible(&psPVRSRVMutex->sSemaphore) == -EINTR) + { + + return PVRSRV_ERROR_GENERIC; + }else{ + atomic_dec(&psPVRSRVMutex->Count); + return PVRSRV_OK; + } +} + +IMG_INT32 LinuxTryLockMutex(PVRSRV_LINUX_MUTEX *psPVRSRVMutex) +{ + IMG_INT32 Status = down_trylock(&psPVRSRVMutex->sSemaphore); + if(Status == 0) + { + atomic_dec(&psPVRSRVMutex->Count); + } + + return Status; +} + +IMG_VOID LinuxUnLockMutex(PVRSRV_LINUX_MUTEX *psPVRSRVMutex) +{ + atomic_inc(&psPVRSRVMutex->Count); + up(&psPVRSRVMutex->sSemaphore); +} + +IMG_BOOL LinuxIsLockedMutex(PVRSRV_LINUX_MUTEX *psPVRSRVMutex) +{ + IMG_INT32 iCount; + + iCount = atomic_read(&psPVRSRVMutex->Count); + + return (IMG_BOOL)iCount; +} + +#endif + diff --git a/services4/srvkm/env/linux/mutex.h b/services4/srvkm/env/linux/mutex.h new file mode 100644 index 0000000..b24a599 --- /dev/null +++ b/services4/srvkm/env/linux/mutex.h @@ -0,0 +1,70 @@ +/********************************************************************** + * + * Copyright(c) 2008 Imagination Technologies Ltd. All rights reserved. + * + * This program is free software; you can redistribute it and/or modify it + * under the terms and conditions of the GNU General Public License, + * version 2, as published by the Free Software Foundation. + * + * This program is distributed in the hope it will be useful but, except + * as otherwise stated in writing, without any warranty; without even the + * implied warranty of merchantability or fitness for a particular purpose. + * See the GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License along with + * this program; if not, write to the Free Software Foundation, Inc., + * 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA. + * + * The full GNU General Public License is included in this distribution in + * the file called "COPYING". + * + * Contact Information: + * Imagination Technologies Ltd. + * Home Park Estate, Kings Langley, Herts, WD4 8LZ, UK + * + ******************************************************************************/ + +#ifndef __INCLUDED_LINUX_MUTEX_H_ +#define __INCLUDED_LINUX_MUTEX_H_ + +#include + +#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,15)) +#include +#else +#include +#endif + + + +#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,15)) + +typedef struct mutex PVRSRV_LINUX_MUTEX; + +#else + + +typedef struct { + struct semaphore sSemaphore; + + atomic_t Count; +}PVRSRV_LINUX_MUTEX; + +#endif + + +extern IMG_VOID LinuxInitMutex(PVRSRV_LINUX_MUTEX *psPVRSRVMutex); + +extern IMG_VOID LinuxLockMutex(PVRSRV_LINUX_MUTEX *psPVRSRVMutex); + +extern PVRSRV_ERROR LinuxLockMutexInterruptible(PVRSRV_LINUX_MUTEX *psPVRSRVMutex); + +extern IMG_INT32 LinuxTryLockMutex(PVRSRV_LINUX_MUTEX *psPVRSRVMutex); + +extern IMG_VOID LinuxUnLockMutex(PVRSRV_LINUX_MUTEX *psPVRSRVMutex); + +extern IMG_BOOL LinuxIsLockedMutex(PVRSRV_LINUX_MUTEX *psPVRSRVMutex); + + +#endif + diff --git a/services4/srvkm/env/linux/mutils.c b/services4/srvkm/env/linux/mutils.c new file mode 100644 index 0000000..9abff78 --- /dev/null +++ b/services4/srvkm/env/linux/mutils.c @@ -0,0 +1,132 @@ +/********************************************************************** + * + * Copyright(c) 2008 Imagination Technologies Ltd. All rights reserved. + * + * This program is free software; you can redistribute it and/or modify it + * under the terms and conditions of the GNU General Public License, + * version 2, as published by the Free Software Foundation. + * + * This program is distributed in the hope it will be useful but, except + * as otherwise stated in writing, without any warranty; without even the + * implied warranty of merchantability or fitness for a particular purpose. + * See the GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License along with + * this program; if not, write to the Free Software Foundation, Inc., + * 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA. + * + * The full GNU General Public License is included in this distribution in + * the file called "COPYING". + * + * Contact Information: + * Imagination Technologies Ltd. + * Home Park Estate, Kings Langley, Herts, WD4 8LZ, UK + * + ******************************************************************************/ + +#ifndef AUTOCONF_INCLUDED +#include +#endif +#include + +#include +#include +/* Compilation Error */ +/*#include */ + +#include "img_defs.h" +#include "pvr_debug.h" +#include "mutils.h" + +#if defined(SUPPORT_LINUX_X86_PAT) +#define PAT_LINUX_X86_WC 1 + +#define PAT_X86_ENTRY_BITS 8 + +#define PAT_X86_BIT_PWT 1 +#define PAT_X86_BIT_PCD 2 +#define PAT_X86_BIT_PAT 4 +#define PAT_X86_BIT_MASK (PAT_X86_BIT_PAT | PAT_X86_BIT_PCD | PAT_X86_BIT_PWT) + +static IMG_BOOL g_write_combining_available = IMG_FALSE; + +#define PROT_TO_PAT_INDEX(v, B) ((v & _PAGE_ ## B) ? PAT_X86_BIT_ ## B : 0) + +static inline IMG_UINT +pvr_pat_index(pgprotval_t prot_val) +{ + IMG_UINT ret = 0; + pgprotval_t val = prot_val & _PAGE_CACHE_MASK; + + ret |= PROT_TO_PAT_INDEX(val, PAT); + ret |= PROT_TO_PAT_INDEX(val, PCD); + ret |= PROT_TO_PAT_INDEX(val, PWT); + + return ret; +} + +static inline IMG_UINT +pvr_pat_entry(u64 pat, IMG_UINT index) +{ + return (pat >> (index * PAT_X86_ENTRY_BITS)) & PAT_X86_BIT_MASK; +} + +static IMG_VOID +PVRLinuxX86PATProbe(IMG_VOID) +{ + + if (cpu_has_pat) + { + u64 pat; + IMG_UINT pat_index; + IMG_UINT pat_entry; + + PVR_TRACE(("%s: PAT available", __FUNCTION__)); + + rdmsrl(MSR_IA32_CR_PAT, pat); + PVR_TRACE(("%s: Top 32 bits of PAT: 0x%.8x", __FUNCTION__, (IMG_UINT)(pat >> 32))); + PVR_TRACE(("%s: Bottom 32 bits of PAT: 0x%.8x", __FUNCTION__, (IMG_UINT)(pat))); + + pat_index = pvr_pat_index(_PAGE_CACHE_WC); + PVR_TRACE(("%s: PAT index for write combining: %u", __FUNCTION__, pat_index)); + + pat_entry = pvr_pat_entry(pat, pat_index); + PVR_TRACE(("%s: PAT entry for write combining: 0x%.2x (should be 0x%.2x)", __FUNCTION__, pat_entry, PAT_LINUX_X86_WC)); + +#if defined(SUPPORT_LINUX_X86_WRITECOMBINE) + g_write_combining_available = (IMG_BOOL)(pat_entry == PAT_LINUX_X86_WC); +#endif + } +#if defined(DEBUG) +#if defined(SUPPORT_LINUX_X86_WRITECOMBINE) + if (g_write_combining_available) + { + PVR_TRACE(("%s: Write combining available via PAT", __FUNCTION__)); + } + else + { + PVR_TRACE(("%s: Write combining not available", __FUNCTION__)); + } +#else + PVR_TRACE(("%s: Write combining disabled in driver build", __FUNCTION__)); +#endif +#endif +} + +pgprot_t +pvr_pgprot_writecombine(pgprot_t prot) +{ + + return (g_write_combining_available) ? + __pgprot((pgprot_val(prot) & ~_PAGE_CACHE_MASK) | _PAGE_CACHE_WC) : pgprot_noncached(prot); +} +#endif + +IMG_VOID +PVRLinuxMUtilsInit(IMG_VOID) +{ +#if defined(SUPPORT_LINUX_X86_PAT) + PVRLinuxX86PATProbe(); +#endif +} + diff --git a/services4/srvkm/env/linux/mutils.h b/services4/srvkm/env/linux/mutils.h new file mode 100644 index 0000000..943c2bd --- /dev/null +++ b/services4/srvkm/env/linux/mutils.h @@ -0,0 +1,101 @@ +/********************************************************************** + * + * Copyright(c) 2008 Imagination Technologies Ltd. All rights reserved. + * + * This program is free software; you can redistribute it and/or modify it + * under the terms and conditions of the GNU General Public License, + * version 2, as published by the Free Software Foundation. + * + * This program is distributed in the hope it will be useful but, except + * as otherwise stated in writing, without any warranty; without even the + * implied warranty of merchantability or fitness for a particular purpose. + * See the GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License along with + * this program; if not, write to the Free Software Foundation, Inc., + * 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA. + * + * The full GNU General Public License is included in this distribution in + * the file called "COPYING". + * + * Contact Information: + * Imagination Technologies Ltd. + * Home Park Estate, Kings Langley, Herts, WD4 8LZ, UK + * + ******************************************************************************/ + +#ifndef __IMG_LINUX_MUTILS_H__ +#define __IMG_LINUX_MUTILS_H__ + +#ifndef AUTOCONF_INCLUDED +#include +#endif + +#include + +#if !(defined(__i386__) && (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,26))) +#if defined(SUPPORT_LINUX_X86_PAT) +#undef SUPPORT_LINUX_X86_PAT +#endif +#endif + +#if defined(SUPPORT_LINUX_X86_PAT) + pgprot_t pvr_pgprot_writecombine(pgprot_t prot); + #define PGPROT_WC(pv) pvr_pgprot_writecombine(pv) +#else + #if defined(__arm__) || defined(__sh__) + #define PGPROT_WC(pv) pgprot_writecombine(pv) + #else + #if defined(__i386__) + #define PGPROT_WC(pv) pgprot_noncached(pv) + #else + #define PGPROT_WC(pv) pgprot_noncached(pv) + #error Unsupported architecture! + #endif + #endif +#endif + +#define PGPROT_UC(pv) pgprot_noncached(pv) + +#if defined(__i386__) && (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,26)) + #define IOREMAP(pa, bytes) ioremap_cache(pa, bytes) +#else + #if defined(__arm__) && (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,0)) + #define IOREMAP(pa, bytes) ioremap_cached(pa, bytes) + #else + #define IOREMAP(pa, bytes) ioremap(pa, bytes) + #endif +#endif + +#if defined(SUPPORT_LINUX_X86_PAT) + #if defined(SUPPORT_LINUX_X86_WRITECOMBINE) + #define IOREMAP_WC(pa, bytes) ioremap_wc(pa, bytes) + #else + #define IOREMAP_WC(pa, bytes) ioremap_nocache(pa, bytes) + #endif +#else + #if defined(__arm__) + #if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,27)) + #define IOREMAP_WC(pa, bytes) ioremap_wc(pa, bytes) + #else + #if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,22)) + #define IOREMAP_WC(pa, bytes) ioremap_nocache(pa, bytes) + #else + #if (LINUX_VERSION_CODE < KERNEL_VERSION(2,6,0)) || (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,17)) + #define IOREMAP_WC(pa, bytes) __ioremap(pa, bytes, L_PTE_BUFFERABLE) + #else + #define IOREMAP_WC(pa, bytes) __ioremap(pa, bytes, , L_PTE_BUFFERABLE, 1) + #endif + #endif + #endif + #else + #define IOREMAP_WC(pa, bytes) ioremap_nocache(pa, bytes) + #endif +#endif + +#define IOREMAP_UC(pa, bytes) ioremap_nocache(pa, bytes) + +IMG_VOID PVRLinuxMUtilsInit(IMG_VOID); + +#endif + diff --git a/services4/srvkm/env/linux/osfunc.c b/services4/srvkm/env/linux/osfunc.c new file mode 100644 index 0000000..17e5d97 --- /dev/null +++ b/services4/srvkm/env/linux/osfunc.c @@ -0,0 +1,2227 @@ +/********************************************************************** + * + * Copyright(c) 2008 Imagination Technologies Ltd. All rights reserved. + * + * This program is free software; you can redistribute it and/or modify it + * under the terms and conditions of the GNU General Public License, + * version 2, as published by the Free Software Foundation. + * + * This program is distributed in the hope it will be useful but, except + * as otherwise stated in writing, without any warranty; without even the + * implied warranty of merchantability or fitness for a particular purpose. + * See the GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License along with + * this program; if not, write to the Free Software Foundation, Inc., + * 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA. + * + * The full GNU General Public License is included in this distribution in + * the file called "COPYING". + * + * Contact Information: + * Imagination Technologies Ltd. + * Home Park Estate, Kings Langley, Herts, WD4 8LZ, UK + * + ******************************************************************************/ + +#ifndef AUTOCONF_INCLUDED + #include +#endif + +#include +#include +#include +#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,22)) +#include +#endif +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include +#include +#include +#include +#include +#include + +#include "img_types.h" +#include "services_headers.h" +#include "mm.h" +#include "pvrmmap.h" +#include "mmap.h" +#include "env_data.h" +#include "proc.h" +#include "mutex.h" +#include "event.h" + +#define EVENT_OBJECT_TIMEOUT_MS (100) + +#define HOST_ALLOC_MEM_USING_KMALLOC ((IMG_HANDLE)0) +#define HOST_ALLOC_MEM_USING_VMALLOC ((IMG_HANDLE)1) + +#if !defined(DEBUG_LINUX_MEMORY_ALLOCATIONS) +PVRSRV_ERROR OSAllocMem(IMG_UINT32 ui32Flags, IMG_UINT32 ui32Size, IMG_PVOID *ppvCpuVAddr, IMG_HANDLE *phBlockAlloc) +#else +PVRSRV_ERROR _OSAllocMem(IMG_UINT32 ui32Flags, IMG_UINT32 ui32Size, IMG_PVOID *ppvCpuVAddr, IMG_HANDLE *phBlockAlloc, IMG_CHAR *pszFilename, IMG_UINT32 ui32Line) +#endif +{ + PVR_UNREFERENCED_PARAMETER(ui32Flags); + +#if defined(DEBUG_LINUX_MEMORY_ALLOCATIONS) + *ppvCpuVAddr = _KMallocWrapper(ui32Size, pszFilename, ui32Line); +#else + *ppvCpuVAddr = KMallocWrapper(ui32Size); +#endif + if(*ppvCpuVAddr) + { + if (phBlockAlloc) + { + + *phBlockAlloc = HOST_ALLOC_MEM_USING_KMALLOC; + } + } + else + { + if (!phBlockAlloc) + { + return PVRSRV_ERROR_OUT_OF_MEMORY; + } + + +#if defined(DEBUG_LINUX_MEMORY_ALLOCATIONS) + *ppvCpuVAddr = _VMallocWrapper(ui32Size, PVRSRV_HAP_CACHED, pszFilename, ui32Line); +#else + *ppvCpuVAddr = VMallocWrapper(ui32Size, PVRSRV_HAP_CACHED); +#endif + if (!*ppvCpuVAddr) + { + return PVRSRV_ERROR_OUT_OF_MEMORY; + } + + + *phBlockAlloc = HOST_ALLOC_MEM_USING_VMALLOC; + } + + return PVRSRV_OK; +} + + +#if !defined(DEBUG_LINUX_MEMORY_ALLOCATIONS) +PVRSRV_ERROR OSFreeMem(IMG_UINT32 ui32Flags, IMG_UINT32 ui32Size, IMG_PVOID pvCpuVAddr, IMG_HANDLE hBlockAlloc) +#else +PVRSRV_ERROR _OSFreeMem(IMG_UINT32 ui32Flags, IMG_UINT32 ui32Size, IMG_PVOID pvCpuVAddr, IMG_HANDLE hBlockAlloc, IMG_CHAR *pszFilename, IMG_UINT32 ui32Line) +#endif +{ + PVR_UNREFERENCED_PARAMETER(ui32Flags); + PVR_UNREFERENCED_PARAMETER(ui32Size); + + if (hBlockAlloc == HOST_ALLOC_MEM_USING_VMALLOC) + { +#if defined(DEBUG_LINUX_MEMORY_ALLOCATIONS) + _VFreeWrapper(pvCpuVAddr, pszFilename, ui32Line); +#else + VFreeWrapper(pvCpuVAddr); +#endif + } + else + { +#if defined(DEBUG_LINUX_MEMORY_ALLOCATIONS) + _KFreeWrapper(pvCpuVAddr, pszFilename, ui32Line); +#else + KFreeWrapper(pvCpuVAddr); +#endif + } + + return PVRSRV_OK; +} + + +PVRSRV_ERROR +OSAllocPages(IMG_UINT32 ui32AllocFlags, + IMG_UINT32 ui32Size, + IMG_UINT32 ui32PageSize, + IMG_VOID **ppvCpuVAddr, + IMG_HANDLE *phOSMemHandle) +{ + LinuxMemArea *psLinuxMemArea; + + PVR_UNREFERENCED_PARAMETER(ui32PageSize); + +#if 0 + + if(ui32AllocFlags & PVRSRV_HAP_SINGLE_PROCESS) + { + ui32AllocFlags &= ~PVRSRV_HAP_SINGLE_PROCESS; + ui32AllocFlags |= PVRSRV_HAP_MULTI_PROCESS; + } +#endif + + switch(ui32AllocFlags & PVRSRV_HAP_MAPTYPE_MASK) + { + case PVRSRV_HAP_KERNEL_ONLY: + { + psLinuxMemArea = NewVMallocLinuxMemArea(ui32Size, ui32AllocFlags); + if(!psLinuxMemArea) + { + return PVRSRV_ERROR_OUT_OF_MEMORY; + } + break; + } + case PVRSRV_HAP_SINGLE_PROCESS: + { + + + psLinuxMemArea = NewAllocPagesLinuxMemArea(ui32Size, ui32AllocFlags); + if(!psLinuxMemArea) + { + return PVRSRV_ERROR_OUT_OF_MEMORY; + } + PVRMMapRegisterArea(psLinuxMemArea); + break; + } + + case PVRSRV_HAP_MULTI_PROCESS: + { + +#if defined(VIVT_CACHE) || defined(__sh__) + + ui32AllocFlags &= ~PVRSRV_HAP_CACHED; +#endif + psLinuxMemArea = NewVMallocLinuxMemArea(ui32Size, ui32AllocFlags); + if(!psLinuxMemArea) + { + return PVRSRV_ERROR_OUT_OF_MEMORY; + } + PVRMMapRegisterArea(psLinuxMemArea); + break; + } + default: + PVR_DPF((PVR_DBG_ERROR, "OSAllocPages: invalid flags 0x%x\n", ui32AllocFlags)); + *ppvCpuVAddr = NULL; + *phOSMemHandle = (IMG_HANDLE)0; + return PVRSRV_ERROR_INVALID_PARAMS; + } + + *ppvCpuVAddr = LinuxMemAreaToCpuVAddr(psLinuxMemArea); + *phOSMemHandle = psLinuxMemArea; + + LinuxMemAreaRegister(psLinuxMemArea); + + return PVRSRV_OK; +} + + +PVRSRV_ERROR +OSFreePages(IMG_UINT32 ui32AllocFlags, IMG_UINT32 ui32Bytes, IMG_VOID *pvCpuVAddr, IMG_HANDLE hOSMemHandle) +{ + LinuxMemArea *psLinuxMemArea; + PVR_UNREFERENCED_PARAMETER(ui32Bytes); + PVR_UNREFERENCED_PARAMETER(pvCpuVAddr); + + psLinuxMemArea = (LinuxMemArea *)hOSMemHandle; + + switch(ui32AllocFlags & PVRSRV_HAP_MAPTYPE_MASK) + { + case PVRSRV_HAP_KERNEL_ONLY: + break; + case PVRSRV_HAP_SINGLE_PROCESS: + case PVRSRV_HAP_MULTI_PROCESS: + if(PVRMMapRemoveRegisteredArea(psLinuxMemArea) != PVRSRV_OK) + { + PVR_DPF((PVR_DBG_ERROR, + "OSFreePages(ui32AllocFlags=0x%08X, ui32Bytes=%ld, " + "pvCpuVAddr=%p, hOSMemHandle=%p) FAILED!", + ui32AllocFlags, ui32Bytes, pvCpuVAddr, hOSMemHandle)); + return PVRSRV_ERROR_GENERIC; + } + break; + default: + PVR_DPF((PVR_DBG_ERROR,"%s: invalid flags 0x%x\n", + __FUNCTION__, ui32AllocFlags)); + return PVRSRV_ERROR_INVALID_PARAMS; + } + + LinuxMemAreaDeepFree(psLinuxMemArea); + + return PVRSRV_OK; +} + + +PVRSRV_ERROR +OSGetSubMemHandle(IMG_HANDLE hOSMemHandle, + IMG_UINT32 ui32ByteOffset, + IMG_UINT32 ui32Bytes, + IMG_UINT32 ui32Flags, + IMG_HANDLE *phOSMemHandleRet) +{ + LinuxMemArea *psParentLinuxMemArea, *psLinuxMemArea; + PVRSRV_ERROR eError; + + psParentLinuxMemArea = (LinuxMemArea *)hOSMemHandle; + + psLinuxMemArea = NewSubLinuxMemArea(psParentLinuxMemArea, ui32ByteOffset, ui32Bytes); + if(!psLinuxMemArea) + { + *phOSMemHandleRet = NULL; + return PVRSRV_ERROR_OUT_OF_MEMORY; + } + *phOSMemHandleRet = psLinuxMemArea; + + + if(ui32Flags & PVRSRV_HAP_KERNEL_ONLY) + { + return PVRSRV_OK; + } + + eError = PVRMMapRegisterArea(psLinuxMemArea); + if(eError != PVRSRV_OK) + { + goto failed_register_area; + } + + return PVRSRV_OK; + +failed_register_area: + *phOSMemHandleRet = NULL; + LinuxMemAreaDeepFree(psLinuxMemArea); + return eError; +} + +PVRSRV_ERROR +OSReleaseSubMemHandle(IMG_VOID *hOSMemHandle, IMG_UINT32 ui32Flags) +{ + LinuxMemArea *psLinuxMemArea; + PVRSRV_ERROR eError; + + psLinuxMemArea = (LinuxMemArea *)hOSMemHandle; + PVR_ASSERT(psLinuxMemArea->eAreaType == LINUX_MEM_AREA_SUB_ALLOC); + + if((ui32Flags & PVRSRV_HAP_KERNEL_ONLY) == 0) + { + eError = PVRMMapRemoveRegisteredArea(psLinuxMemArea); + if(eError != PVRSRV_OK) + { + return eError; + } + } + LinuxMemAreaDeepFree(psLinuxMemArea); + + return PVRSRV_OK; +} + + +IMG_CPU_PHYADDR +OSMemHandleToCpuPAddr(IMG_VOID *hOSMemHandle, IMG_UINT32 ui32ByteOffset) +{ + PVR_ASSERT(hOSMemHandle); + + return LinuxMemAreaToCpuPAddr(hOSMemHandle, ui32ByteOffset); +} + + + +IMG_VOID OSMemCopy(IMG_VOID *pvDst, IMG_VOID *pvSrc, IMG_UINT32 ui32Size) +{ +#if defined(USE_UNOPTIMISED_MEMCPY) + IMG_UINT8 *Src,*Dst; + IMG_INT i; + + Src=(IMG_UINT8 *)pvSrc; + Dst=(IMG_UINT8 *)pvDst; + for(i=0;iui32Lock; + + if(*pui32Access) + { + if(psResource->ui32ID == ui32ID) + { + psResource->ui32ID = 0; + *pui32Access = 0; + } + else + { + PVR_DPF((PVR_DBG_MESSAGE,"OSBreakResourceLock: Resource is not locked for this process.")); + } + } + else + { + PVR_DPF((PVR_DBG_MESSAGE,"OSBreakResourceLock: Resource is not locked")); + } +} + + +PVRSRV_ERROR OSCreateResource(PVRSRV_RESOURCE *psResource) +{ + psResource->ui32ID = 0; + psResource->ui32Lock = 0; + + return PVRSRV_OK; +} + + +PVRSRV_ERROR OSDestroyResource (PVRSRV_RESOURCE *psResource) +{ + OSBreakResourceLock (psResource, psResource->ui32ID); + + return PVRSRV_OK; +} + + +PVRSRV_ERROR OSInitEnvData(IMG_PVOID *ppvEnvSpecificData) +{ + ENV_DATA *psEnvData; + + + if(OSAllocMem(PVRSRV_OS_PAGEABLE_HEAP, sizeof(ENV_DATA), (IMG_VOID *)&psEnvData, IMG_NULL) != PVRSRV_OK) + { + return PVRSRV_ERROR_GENERIC; + } + + if(OSAllocMem(PVRSRV_OS_PAGEABLE_HEAP, PVRSRV_MAX_BRIDGE_IN_SIZE + PVRSRV_MAX_BRIDGE_OUT_SIZE, + &psEnvData->pvBridgeData, IMG_NULL) != PVRSRV_OK) + { + OSFreeMem(PVRSRV_OS_PAGEABLE_HEAP, sizeof(ENV_DATA), psEnvData, IMG_NULL); + return PVRSRV_ERROR_GENERIC; + } + + + + psEnvData->bMISRInstalled = IMG_FALSE; + psEnvData->bLISRInstalled = IMG_FALSE; + + + *ppvEnvSpecificData = psEnvData; + + return PVRSRV_OK; +} + + +PVRSRV_ERROR OSDeInitEnvData(IMG_PVOID pvEnvSpecificData) +{ + ENV_DATA *psEnvData = (ENV_DATA*)pvEnvSpecificData; + + PVR_ASSERT(!psEnvData->bMISRInstalled); + PVR_ASSERT(!psEnvData->bLISRInstalled); + + OSFreeMem(PVRSRV_OS_PAGEABLE_HEAP, 0x1000, psEnvData->pvBridgeData, IMG_NULL); + + OSFreeMem(PVRSRV_OS_PAGEABLE_HEAP, sizeof(ENV_DATA), pvEnvSpecificData, IMG_NULL); + + return PVRSRV_OK; +} + + + +IMG_VOID OSReleaseThreadQuanta(IMG_VOID) +{ + schedule(); +} + + + +IMG_UINT32 OSClockus(IMG_VOID) +{ + IMG_UINT32 time, j = jiffies; + + time = j * (1000000 / HZ); + + return time; +} + + + +IMG_VOID OSWaitus(IMG_UINT32 ui32Timeus) +{ + udelay(ui32Timeus); +} + + +IMG_UINT32 OSGetCurrentProcessIDKM(IMG_VOID) +{ + if (in_interrupt()) + { + return KERNEL_ID; + } + +#if (LINUX_VERSION_CODE < KERNEL_VERSION(2,6,0)) + return (IMG_UINT32)current->pgrp; +#else +#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,24)) + return (IMG_UINT32)task_tgid_nr(current); +#else + return (IMG_UINT32)current->tgid; +#endif +#endif +} + + +IMG_UINT32 OSGetPageSize(IMG_VOID) +{ +#if defined(__sh__) + IMG_UINT32 ui32ReturnValue = PAGE_SIZE; + + return (ui32ReturnValue); +#else + return PAGE_SIZE; +#endif +} + +#if (LINUX_VERSION_CODE > KERNEL_VERSION(2,6,0)) +static irqreturn_t DeviceISRWrapper(int irq, void *dev_id +#if (LINUX_VERSION_CODE < KERNEL_VERSION(2,6,19)) + , struct pt_regs *regs +#endif + ) +{ + PVRSRV_DEVICE_NODE *psDeviceNode; + IMG_BOOL bStatus = IMG_FALSE; + + PVR_UNREFERENCED_PARAMETER(irq); + +#if (LINUX_VERSION_CODE < KERNEL_VERSION(2,6,19)) + PVR_UNREFERENCED_PARAMETER(regs); +#endif + psDeviceNode = (PVRSRV_DEVICE_NODE*)dev_id; + if(!psDeviceNode) + { + PVR_DPF((PVR_DBG_ERROR, "DeviceISRWrapper: invalid params\n")); + goto out; + } + + bStatus = PVRSRVDeviceLISR(psDeviceNode); + + if (bStatus) + { + SYS_DATA *psSysData = psDeviceNode->psSysData; + ENV_DATA *psEnvData = (ENV_DATA *)psSysData->pvEnvSpecificData; + + tasklet_schedule(&psEnvData->sMISRTasklet); + } + +out: +#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,0)) + return bStatus ? IRQ_HANDLED : IRQ_NONE; +#endif +} + + + +static irqreturn_t SystemISRWrapper(int irq, void *dev_id +#if (LINUX_VERSION_CODE < KERNEL_VERSION(2,6,19)) + , struct pt_regs *regs +#endif + ) +{ + SYS_DATA *psSysData; + IMG_BOOL bStatus = IMG_FALSE; + + PVR_UNREFERENCED_PARAMETER(irq); + +#if (LINUX_VERSION_CODE < KERNEL_VERSION(2,6,19)) + PVR_UNREFERENCED_PARAMETER(regs); +#endif + psSysData = (SYS_DATA *)dev_id; + if(!psSysData) + { + PVR_DPF((PVR_DBG_ERROR, "SystemISRWrapper: invalid params\n")); + goto out; + } + + bStatus = PVRSRVSystemLISR(psSysData); + + if (bStatus) + { + ENV_DATA *psEnvData = (ENV_DATA *)psSysData->pvEnvSpecificData; + + tasklet_schedule(&psEnvData->sMISRTasklet); + } + +out: +#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,0)) + return bStatus ? IRQ_HANDLED : IRQ_NONE; +#endif +} +PVRSRV_ERROR OSInstallDeviceLISR(IMG_VOID *pvSysData, + IMG_UINT32 ui32Irq, + IMG_CHAR *pszISRName, + IMG_VOID *pvDeviceNode) +{ + SYS_DATA *psSysData = (SYS_DATA*)pvSysData; + ENV_DATA *psEnvData = (ENV_DATA *)psSysData->pvEnvSpecificData; + + if (psEnvData->bLISRInstalled) + { + PVR_DPF((PVR_DBG_ERROR, "OSInstallDeviceLISR: An ISR has already been installed: IRQ %d cookie %x", psEnvData->ui32IRQ, psEnvData->pvISRCookie)); + return PVRSRV_ERROR_GENERIC; + } + + PVR_TRACE(("Installing device LISR %s on IRQ %d with cookie %x", pszISRName, ui32Irq, pvDeviceNode)); + + if(request_irq(ui32Irq, DeviceISRWrapper, +#if (LINUX_VERSION_CODE < KERNEL_VERSION(2,6,22)) + SA_SHIRQ +#else + IRQF_SHARED +#endif + , pszISRName, pvDeviceNode)) + { + PVR_DPF((PVR_DBG_ERROR,"OSInstallDeviceLISR: Couldn't install device LISR on IRQ %d", ui32Irq)); + + return PVRSRV_ERROR_GENERIC; + } + + psEnvData->ui32IRQ = ui32Irq; + psEnvData->pvISRCookie = pvDeviceNode; + psEnvData->bLISRInstalled = IMG_TRUE; + + return PVRSRV_OK; +} + +PVRSRV_ERROR OSUninstallDeviceLISR(IMG_VOID *pvSysData) +{ + SYS_DATA *psSysData = (SYS_DATA*)pvSysData; + ENV_DATA *psEnvData = (ENV_DATA *)psSysData->pvEnvSpecificData; + + if (!psEnvData->bLISRInstalled) + { + PVR_DPF((PVR_DBG_ERROR, "OSUninstallDeviceLISR: No LISR has been installed")); + return PVRSRV_ERROR_GENERIC; + } + + PVR_TRACE(("Uninstalling device LISR on IRQ %d with cookie %x", psEnvData->ui32IRQ, psEnvData->pvISRCookie)); + + free_irq(psEnvData->ui32IRQ, psEnvData->pvISRCookie); + + psEnvData->bLISRInstalled = IMG_FALSE; + + return PVRSRV_OK; +} + + +PVRSRV_ERROR OSInstallSystemLISR(IMG_VOID *pvSysData, IMG_UINT32 ui32Irq) +{ + SYS_DATA *psSysData = (SYS_DATA*)pvSysData; + ENV_DATA *psEnvData = (ENV_DATA *)psSysData->pvEnvSpecificData; + + if (psEnvData->bLISRInstalled) + { + PVR_DPF((PVR_DBG_ERROR, "OSInstallSystemLISR: An LISR has already been installed: IRQ %d cookie %x", psEnvData->ui32IRQ, psEnvData->pvISRCookie)); + return PVRSRV_ERROR_GENERIC; + } + + PVR_TRACE(("Installing system LISR on IRQ %d with cookie %x", ui32Irq, pvSysData)); + + if(request_irq(ui32Irq, SystemISRWrapper, +#if (LINUX_VERSION_CODE < KERNEL_VERSION(2,6,22)) + SA_SHIRQ +#else + IRQF_SHARED +#endif + , "PowerVR", pvSysData)) + { + PVR_DPF((PVR_DBG_ERROR,"OSInstallSystemLISR: Couldn't install system LISR on IRQ %d", ui32Irq)); + + return PVRSRV_ERROR_GENERIC; + } + + psEnvData->ui32IRQ = ui32Irq; + psEnvData->pvISRCookie = pvSysData; + psEnvData->bLISRInstalled = IMG_TRUE; + + return PVRSRV_OK; +} + + +PVRSRV_ERROR OSUninstallSystemLISR(IMG_VOID *pvSysData) +{ + SYS_DATA *psSysData = (SYS_DATA*)pvSysData; + ENV_DATA *psEnvData = (ENV_DATA *)psSysData->pvEnvSpecificData; + + if (!psEnvData->bLISRInstalled) + { + PVR_DPF((PVR_DBG_ERROR, "OSUninstallSystemLISR: No LISR has been installed")); + return PVRSRV_ERROR_GENERIC; + } + + PVR_TRACE(("Uninstalling system LISR on IRQ %d with cookie %x", psEnvData->ui32IRQ, psEnvData->pvISRCookie)); + + free_irq(psEnvData->ui32IRQ, psEnvData->pvISRCookie); + + psEnvData->bLISRInstalled = IMG_FALSE; + + return PVRSRV_OK; +} + + +static void MISRWrapper(unsigned long data) +{ + SYS_DATA *psSysData; + + psSysData = (SYS_DATA *)data; + + PVRSRVMISR(psSysData); +} + + +PVRSRV_ERROR OSInstallMISR(IMG_VOID *pvSysData) +{ + SYS_DATA *psSysData = (SYS_DATA*)pvSysData; + ENV_DATA *psEnvData = (ENV_DATA *)psSysData->pvEnvSpecificData; + + if (psEnvData->bMISRInstalled) + { + PVR_DPF((PVR_DBG_ERROR, "OSInstallMISR: An MISR has already been installed")); + return PVRSRV_ERROR_GENERIC; + } + + PVR_TRACE(("Installing MISR with cookie %x", pvSysData)); + + tasklet_init(&psEnvData->sMISRTasklet, MISRWrapper, (unsigned long)pvSysData); + + psEnvData->bMISRInstalled = IMG_TRUE; + + return PVRSRV_OK; +} + + +PVRSRV_ERROR OSUninstallMISR(IMG_VOID *pvSysData) +{ + SYS_DATA *psSysData = (SYS_DATA*)pvSysData; + ENV_DATA *psEnvData = (ENV_DATA *)psSysData->pvEnvSpecificData; + + if (!psEnvData->bMISRInstalled) + { + PVR_DPF((PVR_DBG_ERROR, "OSUninstallMISR: No MISR has been installed")); + return PVRSRV_ERROR_GENERIC; + } + + PVR_TRACE(("Uninstalling MISR")); + + tasklet_kill(&psEnvData->sMISRTasklet); + + psEnvData->bMISRInstalled = IMG_FALSE; + + return PVRSRV_OK; +} + +PVRSRV_ERROR OSScheduleMISR(IMG_VOID *pvSysData) +{ + SYS_DATA *psSysData = (SYS_DATA*)pvSysData; + ENV_DATA *psEnvData = (ENV_DATA*)psSysData->pvEnvSpecificData; + + if (psEnvData->bMISRInstalled) + { + tasklet_schedule(&psEnvData->sMISRTasklet); + } + + return PVRSRV_OK; +} + + +#endif + +#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,22)) +#define OS_TAS(p) xchg((p), 1) +#else +#define OS_TAS(p) tas(p) +#endif +PVRSRV_ERROR OSLockResource ( PVRSRV_RESOURCE *psResource, + IMG_UINT32 ui32ID) + +{ + PVRSRV_ERROR eError = PVRSRV_OK; + + if(!OS_TAS(&psResource->ui32Lock)) + psResource->ui32ID = ui32ID; + else + eError = PVRSRV_ERROR_GENERIC; + + return eError; +} + + +PVRSRV_ERROR OSUnlockResource (PVRSRV_RESOURCE *psResource, IMG_UINT32 ui32ID) +{ + volatile IMG_UINT32 *pui32Access = (volatile IMG_UINT32 *)&psResource->ui32Lock; + PVRSRV_ERROR eError = PVRSRV_OK; + + if(*pui32Access) + { + if(psResource->ui32ID == ui32ID) + { + psResource->ui32ID = 0; + *pui32Access = 0; + } + else + { + PVR_DPF((PVR_DBG_ERROR,"OSUnlockResource: Resource %p is not locked with expected value.", psResource)); + PVR_DPF((PVR_DBG_MESSAGE,"Should be %x is actually %x", ui32ID, psResource->ui32ID)); + eError = PVRSRV_ERROR_GENERIC; + } + } + else + { + PVR_DPF((PVR_DBG_ERROR,"OSUnlockResource: Resource %p is not locked", psResource)); + eError = PVRSRV_ERROR_GENERIC; + } + + return eError; +} + + +IMG_BOOL OSIsResourceLocked (PVRSRV_RESOURCE *psResource, IMG_UINT32 ui32ID) +{ + volatile IMG_UINT32 *pui32Access = (volatile IMG_UINT32 *)&psResource->ui32Lock; + + return (*(volatile IMG_UINT32 *)pui32Access == 1) && (psResource->ui32ID == ui32ID) + ? IMG_TRUE + : IMG_FALSE; +} + + +IMG_CPU_PHYADDR OSMapLinToCPUPhys(IMG_VOID *pvLinAddr) +{ + IMG_CPU_PHYADDR CpuPAddr; + + CpuPAddr.uiAddr = (IMG_UINTPTR_T)VMallocToPhys(pvLinAddr); + + return CpuPAddr; +} + + +IMG_VOID * +OSMapPhysToLin(IMG_CPU_PHYADDR BasePAddr, + IMG_UINT32 ui32Bytes, + IMG_UINT32 ui32MappingFlags, + IMG_HANDLE *phOSMemHandle) +{ + if(phOSMemHandle) + { + *phOSMemHandle = (IMG_HANDLE)0; + } + + if(ui32MappingFlags & PVRSRV_HAP_KERNEL_ONLY) + { + IMG_VOID *pvIORemapCookie; + pvIORemapCookie = IORemapWrapper(BasePAddr, ui32Bytes, ui32MappingFlags); + if(pvIORemapCookie == IMG_NULL) + { + return NULL; + } + return pvIORemapCookie; + } + else + { + PVR_DPF((PVR_DBG_ERROR, + "OSMapPhysToLin should only be used with PVRSRV_HAP_KERNEL_ONLY " + " (Use OSReservePhys otherwise)")); + return NULL; + } +} + +IMG_BOOL +OSUnMapPhysToLin(IMG_VOID *pvLinAddr, IMG_UINT32 ui32Bytes, IMG_UINT32 ui32MappingFlags, IMG_HANDLE hPageAlloc) +{ + PVR_TRACE(("%s: unmapping %d bytes from 0x%08x", __FUNCTION__, ui32Bytes, pvLinAddr)); + + PVR_UNREFERENCED_PARAMETER(hPageAlloc); + PVR_UNREFERENCED_PARAMETER(ui32Bytes); + + if(ui32MappingFlags & PVRSRV_HAP_KERNEL_ONLY) + { + IOUnmapWrapper(pvLinAddr); + return IMG_TRUE; + } + else + { + PVR_DPF((PVR_DBG_ERROR, + "OSUnMapPhysToLin should only be used with PVRSRV_HAP_KERNEL_ONLY " + " (Use OSUnReservePhys otherwise)")); + return IMG_FALSE; + } +} + +static PVRSRV_ERROR +RegisterExternalMem(IMG_SYS_PHYADDR *pBasePAddr, + IMG_VOID *pvCPUVAddr, + IMG_UINT32 ui32Bytes, + IMG_BOOL bPhysContig, + IMG_UINT32 ui32MappingFlags, + IMG_HANDLE *phOSMemHandle) +{ + LinuxMemArea *psLinuxMemArea; + + switch(ui32MappingFlags & PVRSRV_HAP_MAPTYPE_MASK) + { + case PVRSRV_HAP_KERNEL_ONLY: + { + psLinuxMemArea = NewExternalKVLinuxMemArea(pBasePAddr, pvCPUVAddr, ui32Bytes, bPhysContig, ui32MappingFlags); + + if(!psLinuxMemArea) + { + return PVRSRV_ERROR_GENERIC; + } + break; + } + case PVRSRV_HAP_SINGLE_PROCESS: + { + psLinuxMemArea = NewExternalKVLinuxMemArea(pBasePAddr, pvCPUVAddr, ui32Bytes, bPhysContig, ui32MappingFlags); + + if(!psLinuxMemArea) + { + return PVRSRV_ERROR_GENERIC; + } + PVRMMapRegisterArea(psLinuxMemArea); + break; + } + case PVRSRV_HAP_MULTI_PROCESS: + { + +#if defined(VIVT_CACHE) || defined(__sh__) + + ui32MappingFlags &= ~PVRSRV_HAP_CACHED; +#endif + psLinuxMemArea = NewExternalKVLinuxMemArea(pBasePAddr, pvCPUVAddr, ui32Bytes, bPhysContig, ui32MappingFlags); + + if(!psLinuxMemArea) + { + return PVRSRV_ERROR_GENERIC; + } + PVRMMapRegisterArea(psLinuxMemArea); + break; + } + default: + PVR_DPF((PVR_DBG_ERROR,"OSRegisterMem : invalid flags 0x%x\n", ui32MappingFlags)); + *phOSMemHandle = (IMG_HANDLE)0; + return PVRSRV_ERROR_GENERIC; + } + + *phOSMemHandle = (IMG_HANDLE)psLinuxMemArea; + + LinuxMemAreaRegister(psLinuxMemArea); + + return PVRSRV_OK; +} + + +PVRSRV_ERROR +OSRegisterMem(IMG_CPU_PHYADDR BasePAddr, + IMG_VOID *pvCPUVAddr, + IMG_UINT32 ui32Bytes, + IMG_UINT32 ui32MappingFlags, + IMG_HANDLE *phOSMemHandle) +{ + IMG_SYS_PHYADDR SysPAddr = SysCpuPAddrToSysPAddr(BasePAddr); + + return RegisterExternalMem(&SysPAddr, pvCPUVAddr, ui32Bytes, IMG_TRUE, ui32MappingFlags, phOSMemHandle); +} + + +PVRSRV_ERROR OSRegisterDiscontigMem(IMG_SYS_PHYADDR *pBasePAddr, IMG_VOID *pvCPUVAddr, IMG_UINT32 ui32Bytes, IMG_UINT32 ui32MappingFlags, IMG_HANDLE *phOSMemHandle) +{ + return RegisterExternalMem(pBasePAddr, pvCPUVAddr, ui32Bytes, IMG_FALSE, ui32MappingFlags, phOSMemHandle); +} + + +PVRSRV_ERROR +OSUnRegisterMem (IMG_VOID *pvCpuVAddr, + IMG_UINT32 ui32Bytes, + IMG_UINT32 ui32MappingFlags, + IMG_HANDLE hOSMemHandle) +{ + LinuxMemArea *psLinuxMemArea = (LinuxMemArea *)hOSMemHandle; + + PVR_UNREFERENCED_PARAMETER(pvCpuVAddr); + PVR_UNREFERENCED_PARAMETER(ui32Bytes); + + switch(ui32MappingFlags & PVRSRV_HAP_MAPTYPE_MASK) + { + case PVRSRV_HAP_KERNEL_ONLY: + break; + case PVRSRV_HAP_SINGLE_PROCESS: + case PVRSRV_HAP_MULTI_PROCESS: + { + if(PVRMMapRemoveRegisteredArea(psLinuxMemArea) != PVRSRV_OK) + { + PVR_DPF((PVR_DBG_ERROR, "%s(%p, %d, 0x%08X, %p) FAILED!", + __FUNCTION__, pvCpuVAddr, ui32Bytes, + ui32MappingFlags, hOSMemHandle)); + return PVRSRV_ERROR_GENERIC; + } + break; + } + default: + { + PVR_DPF((PVR_DBG_ERROR, "OSUnRegisterMem : invalid flags 0x%x", ui32MappingFlags)); + return PVRSRV_ERROR_INVALID_PARAMS; + } + } + + LinuxMemAreaDeepFree(psLinuxMemArea); + + return PVRSRV_OK; +} + +PVRSRV_ERROR OSUnRegisterDiscontigMem(IMG_VOID *pvCpuVAddr, IMG_UINT32 ui32Bytes, IMG_UINT32 ui32Flags, IMG_HANDLE hOSMemHandle) +{ + return OSUnRegisterMem(pvCpuVAddr, ui32Bytes, ui32Flags, hOSMemHandle); +} + +PVRSRV_ERROR +OSReservePhys(IMG_CPU_PHYADDR BasePAddr, + IMG_UINT32 ui32Bytes, + IMG_UINT32 ui32MappingFlags, + IMG_VOID **ppvCpuVAddr, + IMG_HANDLE *phOSMemHandle) +{ + LinuxMemArea *psLinuxMemArea; + +#if 0 + + if(ui32MappingFlags & PVRSRV_HAP_SINGLE_PROCESS) + { + ui32MappingFlags &= ~PVRSRV_HAP_SINGLE_PROCESS; + ui32MappingFlags |= PVRSRV_HAP_MULTI_PROCESS; + } +#endif + + switch(ui32MappingFlags & PVRSRV_HAP_MAPTYPE_MASK) + { + case PVRSRV_HAP_KERNEL_ONLY: + { + + psLinuxMemArea = NewIORemapLinuxMemArea(BasePAddr, ui32Bytes, ui32MappingFlags); + if(!psLinuxMemArea) + { + return PVRSRV_ERROR_GENERIC; + } + break; + } + case PVRSRV_HAP_SINGLE_PROCESS: + { + + psLinuxMemArea = NewIOLinuxMemArea(BasePAddr, ui32Bytes, ui32MappingFlags); + if(!psLinuxMemArea) + { + return PVRSRV_ERROR_GENERIC; + } + PVRMMapRegisterArea(psLinuxMemArea); + break; + } + case PVRSRV_HAP_MULTI_PROCESS: + { + +#if defined(VIVT_CACHE) || defined(__sh__) + + ui32MappingFlags &= ~PVRSRV_HAP_CACHED; +#endif + psLinuxMemArea = NewIORemapLinuxMemArea(BasePAddr, ui32Bytes, ui32MappingFlags); + if(!psLinuxMemArea) + { + return PVRSRV_ERROR_GENERIC; + } + PVRMMapRegisterArea(psLinuxMemArea); + break; + } + default: + PVR_DPF((PVR_DBG_ERROR,"OSMapPhysToLin : invalid flags 0x%x\n", ui32MappingFlags)); + *ppvCpuVAddr = NULL; + *phOSMemHandle = (IMG_HANDLE)0; + return PVRSRV_ERROR_GENERIC; + } + + *phOSMemHandle = (IMG_HANDLE)psLinuxMemArea; + *ppvCpuVAddr = LinuxMemAreaToCpuVAddr(psLinuxMemArea); + + LinuxMemAreaRegister(psLinuxMemArea); + + return PVRSRV_OK; +} + +PVRSRV_ERROR +OSUnReservePhys(IMG_VOID *pvCpuVAddr, + IMG_UINT32 ui32Bytes, + IMG_UINT32 ui32MappingFlags, + IMG_HANDLE hOSMemHandle) +{ + LinuxMemArea *psLinuxMemArea; + + PVR_UNREFERENCED_PARAMETER(pvCpuVAddr); + PVR_UNREFERENCED_PARAMETER(ui32Bytes); + + psLinuxMemArea = (LinuxMemArea *)hOSMemHandle; + + switch(ui32MappingFlags & PVRSRV_HAP_MAPTYPE_MASK) + { + case PVRSRV_HAP_KERNEL_ONLY: + break; + case PVRSRV_HAP_SINGLE_PROCESS: + case PVRSRV_HAP_MULTI_PROCESS: + { + if(PVRMMapRemoveRegisteredArea(psLinuxMemArea) != PVRSRV_OK) + { + PVR_DPF((PVR_DBG_ERROR, "%s(%p, %d, 0x%08X, %p) FAILED!", + __FUNCTION__, pvCpuVAddr, ui32Bytes, + ui32MappingFlags, hOSMemHandle)); + return PVRSRV_ERROR_GENERIC; + } + break; + } + default: + { + PVR_DPF((PVR_DBG_ERROR, "OSUnMapPhysToLin : invalid flags 0x%x", ui32MappingFlags)); + return PVRSRV_ERROR_INVALID_PARAMS; + } + } + + LinuxMemAreaDeepFree(psLinuxMemArea); + + return PVRSRV_OK; +} + + +PVRSRV_ERROR OSBaseAllocContigMemory(IMG_UINT32 ui32Size, IMG_CPU_VIRTADDR *pvLinAddr, IMG_CPU_PHYADDR *psPhysAddr) +{ +#if !defined(NO_HARDWARE) + PVR_UNREFERENCED_PARAMETER(ui32Size); + PVR_UNREFERENCED_PARAMETER(pvLinAddr); + PVR_UNREFERENCED_PARAMETER(psPhysAddr); + PVR_DPF((PVR_DBG_ERROR, "%s: Not available", __FUNCTION__)); + + return PVRSRV_ERROR_OUT_OF_MEMORY; +#else + IMG_VOID *pvKernLinAddr; + +#if defined(DEBUG_LINUX_MEMORY_ALLOCATIONS) + pvKernLinAddr = _KMallocWrapper(ui32Size, __FILE__, __LINE__); +#else + pvKernLinAddr = KMallocWrapper(ui32Size); +#endif + if (!pvKernLinAddr) + { + return PVRSRV_ERROR_OUT_OF_MEMORY; + } + + *pvLinAddr = pvKernLinAddr; + + psPhysAddr->uiAddr = virt_to_phys(pvKernLinAddr); + + return PVRSRV_OK; +#endif +} + + +PVRSRV_ERROR OSBaseFreeContigMemory(IMG_UINT32 ui32Size, IMG_CPU_VIRTADDR pvLinAddr, IMG_CPU_PHYADDR psPhysAddr) +{ +#if !defined(NO_HARDWARE) + PVR_UNREFERENCED_PARAMETER(ui32Size); + PVR_UNREFERENCED_PARAMETER(pvLinAddr); + PVR_UNREFERENCED_PARAMETER(psPhysAddr.uiAddr); + + PVR_DPF((PVR_DBG_WARNING, "%s: Not available", __FUNCTION__)); +#else + PVR_UNREFERENCED_PARAMETER(ui32Size); + PVR_UNREFERENCED_PARAMETER(psPhysAddr.uiAddr); + + KFreeWrapper(pvLinAddr); +#endif + return PVRSRV_OK; +} + +IMG_UINT32 OSReadHWReg(IMG_PVOID pvLinRegBaseAddr, IMG_UINT32 ui32Offset) +{ +#if !defined(NO_HARDWARE) + return (IMG_UINT32) readl((IMG_PBYTE)pvLinRegBaseAddr+ui32Offset); +#else + return *(IMG_UINT32 *)((IMG_PBYTE)pvLinRegBaseAddr+ui32Offset); +#endif +} + +IMG_VOID OSWriteHWReg(IMG_PVOID pvLinRegBaseAddr, IMG_UINT32 ui32Offset, IMG_UINT32 ui32Value) +{ +#if !defined(NO_HARDWARE) + writel(ui32Value, (IMG_PBYTE)pvLinRegBaseAddr+ui32Offset); +#else + *(IMG_UINT32 *)((IMG_PBYTE)pvLinRegBaseAddr+ui32Offset) = ui32Value; +#endif +} + +#if defined(CONFIG_PCI) && (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,14)) + +PVRSRV_PCI_DEV_HANDLE OSPCISetDev(IMG_VOID *pvPCICookie, HOST_PCI_INIT_FLAGS eFlags) +{ + int err; + IMG_UINT32 i; + PVR_PCI_DEV *psPVRPCI; + + PVR_TRACE(("OSPCISetDev")); + + if(OSAllocMem(PVRSRV_OS_PAGEABLE_HEAP, sizeof(*psPVRPCI), (IMG_VOID *)&psPVRPCI, IMG_NULL) != PVRSRV_OK) + { + PVR_DPF((PVR_DBG_ERROR, "OSPCISetDev: Couldn't allocate PVR PCI structure")); + return IMG_NULL; + } + + psPVRPCI->psPCIDev = (struct pci_dev *)pvPCICookie; + psPVRPCI->ePCIFlags = eFlags; + + err = pci_enable_device(psPVRPCI->psPCIDev); + if (err != 0) + { + PVR_DPF((PVR_DBG_ERROR, "OSPCISetDev: Couldn't enable device (%d)", err)); + return IMG_NULL; + } + + if (psPVRPCI->ePCIFlags & HOST_PCI_INIT_FLAG_BUS_MASTER) + { + pci_set_master(psPVRPCI->psPCIDev); + } + + if (psPVRPCI->ePCIFlags & HOST_PCI_INIT_FLAG_MSI) + { +#if defined(CONFIG_PCI_MSI) + err = pci_enable_msi(psPVRPCI->psPCIDev); + if (err != 0) + { + PVR_DPF((PVR_DBG_WARNING, "OSPCISetDev: Couldn't enable MSI (%d)", err)); + psPVRPCI->ePCIFlags &= ~HOST_PCI_INIT_FLAG_MSI; + } +#else + PVR_DPF((PVR_DBG_WARNING, "OSPCISetDev: MSI support not enabled in the kernel")); +#endif + } + + + for (i = 0; i < DEVICE_COUNT_RESOURCE; i++) + { + psPVRPCI->abPCIResourceInUse[i] = IMG_FALSE; + } + + return (PVRSRV_PCI_DEV_HANDLE)psPVRPCI; +} + +PVRSRV_PCI_DEV_HANDLE OSPCIAcquireDev(IMG_UINT16 ui16VendorID, IMG_UINT16 ui16DeviceID, HOST_PCI_INIT_FLAGS eFlags) +{ + struct pci_dev *psPCIDev; + + psPCIDev = pci_get_device(ui16VendorID, ui16DeviceID, NULL); + if (psPCIDev == NULL) + { + PVR_DPF((PVR_DBG_ERROR, "OSPCIAcquireDev: Couldn't acquire device")); + return IMG_NULL; + } + + return OSPCISetDev((IMG_VOID *)psPCIDev, eFlags); +} + +PVRSRV_ERROR OSPCIIRQ(PVRSRV_PCI_DEV_HANDLE hPVRPCI, IMG_UINT32 *pui32IRQ) +{ + PVR_PCI_DEV *psPVRPCI = (PVR_PCI_DEV *)hPVRPCI; + + *pui32IRQ = psPVRPCI->psPCIDev->irq; + + return PVRSRV_OK; +} + +enum HOST_PCI_ADDR_RANGE_FUNC +{ + HOST_PCI_ADDR_RANGE_FUNC_LEN, + HOST_PCI_ADDR_RANGE_FUNC_START, + HOST_PCI_ADDR_RANGE_FUNC_END, + HOST_PCI_ADDR_RANGE_FUNC_REQUEST, + HOST_PCI_ADDR_RANGE_FUNC_RELEASE +}; + +static IMG_UINT32 OSPCIAddrRangeFunc(enum HOST_PCI_ADDR_RANGE_FUNC eFunc, + PVRSRV_PCI_DEV_HANDLE hPVRPCI, + IMG_UINT32 ui32Index) +{ + PVR_PCI_DEV *psPVRPCI = (PVR_PCI_DEV *)hPVRPCI; + + if (ui32Index >= DEVICE_COUNT_RESOURCE) + { + PVR_DPF((PVR_DBG_ERROR, "OSPCIAddrRangeFunc: Index out of range")); + return 0; + + } + + switch (eFunc) + { + case HOST_PCI_ADDR_RANGE_FUNC_LEN: + return pci_resource_len(psPVRPCI->psPCIDev, ui32Index); + case HOST_PCI_ADDR_RANGE_FUNC_START: + return pci_resource_start(psPVRPCI->psPCIDev, ui32Index); + case HOST_PCI_ADDR_RANGE_FUNC_END: + return pci_resource_end(psPVRPCI->psPCIDev, ui32Index); + case HOST_PCI_ADDR_RANGE_FUNC_REQUEST: + { + int err; + + err = pci_request_region(psPVRPCI->psPCIDev, (IMG_INT)ui32Index, "PowerVR"); + if (err != 0) + { + PVR_DPF((PVR_DBG_ERROR, "OSPCIAddrRangeFunc: pci_request_region_failed (%d)", err)); + return 0; + } + psPVRPCI->abPCIResourceInUse[ui32Index] = IMG_TRUE; + return 1; + } + case HOST_PCI_ADDR_RANGE_FUNC_RELEASE: + if (psPVRPCI->abPCIResourceInUse[ui32Index]) + { + pci_release_region(psPVRPCI->psPCIDev, (IMG_INT)ui32Index); + psPVRPCI->abPCIResourceInUse[ui32Index] = IMG_FALSE; + } + return 1; + default: + PVR_DPF((PVR_DBG_ERROR, "OSPCIAddrRangeFunc: Unknown function")); + break; + } + + return 0; +} + +IMG_UINT32 OSPCIAddrRangeLen(PVRSRV_PCI_DEV_HANDLE hPVRPCI, IMG_UINT32 ui32Index) +{ + return OSPCIAddrRangeFunc(HOST_PCI_ADDR_RANGE_FUNC_LEN, hPVRPCI, ui32Index); +} + +IMG_UINT32 OSPCIAddrRangeStart(PVRSRV_PCI_DEV_HANDLE hPVRPCI, IMG_UINT32 ui32Index) +{ + return OSPCIAddrRangeFunc(HOST_PCI_ADDR_RANGE_FUNC_START, hPVRPCI, ui32Index); +} + +IMG_UINT32 OSPCIAddrRangeEnd(PVRSRV_PCI_DEV_HANDLE hPVRPCI, IMG_UINT32 ui32Index) +{ + return OSPCIAddrRangeFunc(HOST_PCI_ADDR_RANGE_FUNC_END, hPVRPCI, ui32Index); +} + +PVRSRV_ERROR OSPCIRequestAddrRange(PVRSRV_PCI_DEV_HANDLE hPVRPCI, + IMG_UINT32 ui32Index) +{ + return OSPCIAddrRangeFunc(HOST_PCI_ADDR_RANGE_FUNC_REQUEST, hPVRPCI, ui32Index) == 0 ? PVRSRV_ERROR_GENERIC : PVRSRV_OK; +} + +PVRSRV_ERROR OSPCIReleaseAddrRange(PVRSRV_PCI_DEV_HANDLE hPVRPCI, IMG_UINT32 ui32Index) +{ + return OSPCIAddrRangeFunc(HOST_PCI_ADDR_RANGE_FUNC_RELEASE, hPVRPCI, ui32Index) == 0 ? PVRSRV_ERROR_GENERIC : PVRSRV_OK; +} + +PVRSRV_ERROR OSPCIReleaseDev(PVRSRV_PCI_DEV_HANDLE hPVRPCI) +{ + PVR_PCI_DEV *psPVRPCI = (PVR_PCI_DEV *)hPVRPCI; + int i; + + PVR_TRACE(("OSPCIReleaseDev")); + + + for (i = 0; i < DEVICE_COUNT_RESOURCE; i++) + { + if (psPVRPCI->abPCIResourceInUse[i]) + { + PVR_TRACE(("OSPCIReleaseDev: Releasing Address range %d", i)); + pci_release_region(psPVRPCI->psPCIDev, i); + psPVRPCI->abPCIResourceInUse[i] = IMG_FALSE; + } + } + +#if defined(CONFIG_PCI_MSI) + if (psPVRPCI->ePCIFlags & HOST_PCI_INIT_FLAG_MSI) + { + pci_disable_msi(psPVRPCI->psPCIDev); + } +#endif + +#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,29)) + if (psPVRPCI->ePCIFlags & HOST_PCI_INIT_FLAG_BUS_MASTER) + { + pci_clear_master(psPVRPCI->psPCIDev); + } +#endif + pci_disable_device(psPVRPCI->psPCIDev); + + OSFreeMem(PVRSRV_OS_PAGEABLE_HEAP, sizeof(*psPVRPCI), (IMG_VOID *)psPVRPCI, IMG_NULL); + + return PVRSRV_OK; +} + +PVRSRV_ERROR OSPCISuspendDev(PVRSRV_PCI_DEV_HANDLE hPVRPCI) +{ + PVR_PCI_DEV *psPVRPCI = (PVR_PCI_DEV *)hPVRPCI; + int i; + int err; + + PVR_TRACE(("OSPCISuspendDev")); + + + for (i = 0; i < DEVICE_COUNT_RESOURCE; i++) + { + if (psPVRPCI->abPCIResourceInUse[i]) + { + pci_release_region(psPVRPCI->psPCIDev, i); + } + } + + err = pci_save_state(psPVRPCI->psPCIDev); + if (err != 0) + { + PVR_DPF((PVR_DBG_ERROR, "OSPCISuspendDev: pci_save_state_failed (%d)", err)); + return PVRSRV_ERROR_GENERIC; + } + + pci_disable_device(psPVRPCI->psPCIDev); + + err = pci_set_power_state(psPVRPCI->psPCIDev, pci_choose_state(psPVRPCI->psPCIDev, PMSG_SUSPEND)); + switch(err) + { + case 0: + break; + case -EIO: + PVR_DPF((PVR_DBG_WARNING, "OSPCISuspendDev: device doesn't support PCI PM")); + break; + case -EINVAL: + PVR_DPF((PVR_DBG_ERROR, "OSPCISuspendDev: can't enter requested power state")); + break; + default: + PVR_DPF((PVR_DBG_ERROR, "OSPCISuspendDev: pci_set_power_state failed (%d)", err)); + break; + } + + return PVRSRV_OK; +} + +PVRSRV_ERROR OSPCIResumeDev(PVRSRV_PCI_DEV_HANDLE hPVRPCI) +{ + PVR_PCI_DEV *psPVRPCI = (PVR_PCI_DEV *)hPVRPCI; + int err; + int i; + + PVR_TRACE(("OSPCIResumeDev")); + + err = pci_set_power_state(psPVRPCI->psPCIDev, pci_choose_state(psPVRPCI->psPCIDev, PMSG_ON)); + switch(err) + { + case 0: + break; + case -EIO: + PVR_DPF((PVR_DBG_WARNING, "OSPCIResumeDev: device doesn't support PCI PM")); + break; + case -EINVAL: + PVR_DPF((PVR_DBG_ERROR, "OSPCIResumeDev: can't enter requested power state")); + return PVRSRV_ERROR_GENERIC; + default: + PVR_DPF((PVR_DBG_ERROR, "OSPCIResumeDev: pci_set_power_state failed (%d)", err)); + return PVRSRV_ERROR_GENERIC; + } + + err = pci_restore_state(psPVRPCI->psPCIDev); + if (err != 0) + { + PVR_DPF((PVR_DBG_ERROR, "OSPCIResumeDev: pci_restore_state failed (%d)", err)); + return PVRSRV_ERROR_GENERIC; + } + + err = pci_enable_device(psPVRPCI->psPCIDev); + if (err != 0) + { + PVR_DPF((PVR_DBG_ERROR, "OSPCIResumeDev: Couldn't enable device (%d)", err)); + return PVRSRV_ERROR_GENERIC; + } + + if (psPVRPCI->ePCIFlags & HOST_PCI_INIT_FLAG_BUS_MASTER) + pci_set_master(psPVRPCI->psPCIDev); + + + for (i = 0; i < DEVICE_COUNT_RESOURCE; i++) + { + if (psPVRPCI->abPCIResourceInUse[i]) + { + err = pci_request_region(psPVRPCI->psPCIDev, i, "PowerVR"); + if (err != 0) + { + PVR_DPF((PVR_DBG_ERROR, "OSPCIResumeDev: pci_request_region_failed (region %d, error %d)", i, err)); + } + } + + } + + return PVRSRV_OK; +} + +#endif + +#define OS_MAX_TIMERS 8 + +typedef struct TIMER_CALLBACK_DATA_TAG +{ + IMG_BOOL bInUse; + PFN_TIMER_FUNC pfnTimerFunc; + IMG_VOID *pvData; + struct timer_list sTimer; + IMG_UINT32 ui32Delay; + IMG_BOOL bActive; +}TIMER_CALLBACK_DATA; + +static TIMER_CALLBACK_DATA sTimers[OS_MAX_TIMERS]; + +static spinlock_t sTimerStructLock = SPIN_LOCK_UNLOCKED; + +static IMG_VOID OSTimerCallbackWrapper(IMG_UINT32 ui32Data) +{ + TIMER_CALLBACK_DATA *psTimerCBData = (TIMER_CALLBACK_DATA*)ui32Data; + + if (!psTimerCBData->bActive) + return; + + + psTimerCBData->pfnTimerFunc(psTimerCBData->pvData); + + + mod_timer(&psTimerCBData->sTimer, psTimerCBData->ui32Delay + jiffies); +} + + +IMG_HANDLE OSAddTimer(PFN_TIMER_FUNC pfnTimerFunc, IMG_VOID *pvData, IMG_UINT32 ui32MsTimeout) +{ + TIMER_CALLBACK_DATA *psTimerCBData; + IMG_UINT32 ui32i; + unsigned long ulLockFlags; + + + if(!pfnTimerFunc) + { + PVR_DPF((PVR_DBG_ERROR, "OSAddTimer: passed invalid callback")); + return IMG_NULL; + } + + + spin_lock_irqsave(&sTimerStructLock, ulLockFlags); + for (ui32i = 0; ui32i < OS_MAX_TIMERS; ui32i++) + { + psTimerCBData = &sTimers[ui32i]; + if (!psTimerCBData->bInUse) + { + psTimerCBData->bInUse = IMG_TRUE; + break; + } + } + spin_unlock_irqrestore(&sTimerStructLock, ulLockFlags); + + if (ui32i >= OS_MAX_TIMERS) + { + PVR_DPF((PVR_DBG_ERROR, "OSAddTimer: all timers are in use")); + return IMG_NULL; + } + + psTimerCBData->pfnTimerFunc = pfnTimerFunc; + psTimerCBData->pvData = pvData; + psTimerCBData->bActive = IMG_FALSE; + + + + + psTimerCBData->ui32Delay = ((HZ * ui32MsTimeout) < 1000) + ? 1 + : ((HZ * ui32MsTimeout) / 1000); + + init_timer(&psTimerCBData->sTimer); + + + psTimerCBData->sTimer.function = OSTimerCallbackWrapper; + psTimerCBData->sTimer.data = (IMG_UINT32)psTimerCBData; + psTimerCBData->sTimer.expires = psTimerCBData->ui32Delay + jiffies; + + return (IMG_HANDLE)(ui32i + 1); +} + + +static inline TIMER_CALLBACK_DATA *GetTimerStructure(IMG_HANDLE hTimer) +{ + IMG_UINT32 ui32i = ((IMG_UINT32)hTimer) - 1; + + PVR_ASSERT(ui32i < OS_MAX_TIMERS); + + return &sTimers[ui32i]; +} + +PVRSRV_ERROR OSRemoveTimer (IMG_HANDLE hTimer) +{ + TIMER_CALLBACK_DATA *psTimerCBData = GetTimerStructure(hTimer); + + PVR_ASSERT(psTimerCBData->bInUse); + PVR_ASSERT(!psTimerCBData->bActive); + + + psTimerCBData->bInUse = IMG_FALSE; + + return PVRSRV_OK; +} + + +PVRSRV_ERROR OSEnableTimer (IMG_HANDLE hTimer) +{ + TIMER_CALLBACK_DATA *psTimerCBData = GetTimerStructure(hTimer); + + PVR_ASSERT(psTimerCBData->bInUse); + PVR_ASSERT(!psTimerCBData->bActive); + + + psTimerCBData->bActive = IMG_TRUE; + + + add_timer(&psTimerCBData->sTimer); + + return PVRSRV_OK; +} + + +PVRSRV_ERROR OSDisableTimer (IMG_HANDLE hTimer) +{ + TIMER_CALLBACK_DATA *psTimerCBData = GetTimerStructure(hTimer); + + PVR_ASSERT(psTimerCBData->bInUse); + PVR_ASSERT(psTimerCBData->bActive); + + + psTimerCBData->bActive = IMG_FALSE; + + + del_timer_sync(&psTimerCBData->sTimer); + + return PVRSRV_OK; +} + + +PVRSRV_ERROR OSEventObjectCreate(const IMG_CHAR *pszName, PVRSRV_EVENTOBJECT *psEventObject) +{ + + PVRSRV_ERROR eError = PVRSRV_OK; + + if(psEventObject) + { + if(pszName) + { + + strncpy(psEventObject->szName, pszName, EVENTOBJNAME_MAXLENGTH); + } + else + { + + static IMG_UINT16 ui16NameIndex = 0; + snprintf(psEventObject->szName, EVENTOBJNAME_MAXLENGTH, "PVRSRV_EVENTOBJECT_%d", ui16NameIndex++); + } + + if(LinuxEventObjectListCreate(&psEventObject->hOSEventKM) != PVRSRV_OK) + { + eError = PVRSRV_ERROR_OUT_OF_MEMORY; + } + + } + else + { + PVR_DPF((PVR_DBG_ERROR, "OSEventObjectCreate: psEventObject is not a valid pointer")); + eError = PVRSRV_ERROR_GENERIC; + } + + return eError; + +} + + +PVRSRV_ERROR OSEventObjectDestroy(PVRSRV_EVENTOBJECT *psEventObject) +{ + PVRSRV_ERROR eError = PVRSRV_OK; + + if(psEventObject) + { + if(psEventObject->hOSEventKM) + { + LinuxEventObjectListDestroy(psEventObject->hOSEventKM); + } + else + { + PVR_DPF((PVR_DBG_ERROR, "OSEventObjectDestroy: hOSEventKM is not a valid pointer")); + eError = PVRSRV_ERROR_INVALID_PARAMS; + } + } + else + { + PVR_DPF((PVR_DBG_ERROR, "OSEventObjectDestroy: psEventObject is not a valid pointer")); + eError = PVRSRV_ERROR_INVALID_PARAMS; + } + + return eError; +} + +PVRSRV_ERROR OSEventObjectWait(IMG_HANDLE hOSEventKM) +{ + PVRSRV_ERROR eError; + + if(hOSEventKM) + { + eError = LinuxEventObjectWait(hOSEventKM, EVENT_OBJECT_TIMEOUT_MS); + } + else + { + PVR_DPF((PVR_DBG_ERROR, "OSEventObjectWait: hOSEventKM is not a valid handle")); + eError = PVRSRV_ERROR_INVALID_PARAMS; + } + + return eError; +} + +PVRSRV_ERROR OSEventObjectOpen(PVRSRV_EVENTOBJECT *psEventObject, + IMG_HANDLE *phOSEvent) +{ + PVRSRV_ERROR eError = PVRSRV_OK; + + if(psEventObject) + { + if(LinuxEventObjectAdd(psEventObject->hOSEventKM, phOSEvent) != PVRSRV_OK) + { + PVR_DPF((PVR_DBG_ERROR, "LinuxEventObjectAdd: failed")); + eError = PVRSRV_ERROR_INVALID_PARAMS; + } + + } + else + { + PVR_DPF((PVR_DBG_ERROR, "OSEventObjectCreate: psEventObject is not a valid pointer")); + eError = PVRSRV_ERROR_INVALID_PARAMS; + } + + return eError; +} + +PVRSRV_ERROR OSEventObjectClose(PVRSRV_EVENTOBJECT *psEventObject, + IMG_HANDLE hOSEventKM) +{ + PVRSRV_ERROR eError = PVRSRV_OK; + + if(psEventObject) + { + if(LinuxEventObjectDelete(psEventObject->hOSEventKM, hOSEventKM) != PVRSRV_OK) + { + PVR_DPF((PVR_DBG_ERROR, "LinuxEventObjectDelete: failed")); + eError = PVRSRV_ERROR_INVALID_PARAMS; + } + + } + else + { + PVR_DPF((PVR_DBG_ERROR, "OSEventObjectDestroy: psEventObject is not a valid pointer")); + eError = PVRSRV_ERROR_INVALID_PARAMS; + } + + return eError; + +} + +PVRSRV_ERROR OSEventObjectSignal(IMG_HANDLE hOSEventKM) +{ + PVRSRV_ERROR eError; + + if(hOSEventKM) + { + eError = LinuxEventObjectSignal(hOSEventKM); + } + else + { + PVR_DPF((PVR_DBG_ERROR, "OSEventObjectSignal: hOSEventKM is not a valid handle")); + eError = PVRSRV_ERROR_INVALID_PARAMS; + } + + return eError; +} + +IMG_BOOL OSProcHasPrivSrvInit(IMG_VOID) +{ + return (capable(CAP_SYS_MODULE) != 0) ? IMG_TRUE : IMG_FALSE; +} + +PVRSRV_ERROR OSCopyToUser(IMG_PVOID pvProcess, + IMG_VOID *pvDest, + IMG_VOID *pvSrc, + IMG_UINT32 ui32Bytes) +{ + PVR_UNREFERENCED_PARAMETER(pvProcess); + + if(copy_to_user(pvDest, pvSrc, ui32Bytes)==0) + return PVRSRV_OK; + else + return PVRSRV_ERROR_GENERIC; +} + +PVRSRV_ERROR OSCopyFromUser( IMG_PVOID pvProcess, + IMG_VOID *pvDest, + IMG_VOID *pvSrc, + IMG_UINT32 ui32Bytes) +{ + PVR_UNREFERENCED_PARAMETER(pvProcess); + + if(copy_from_user(pvDest, pvSrc, ui32Bytes)==0) + return PVRSRV_OK; + else + return PVRSRV_ERROR_GENERIC; +} + +IMG_BOOL OSAccessOK(IMG_VERIFY_TEST eVerification, IMG_VOID *pvUserPtr, IMG_UINT32 ui32Bytes) +{ + IMG_INT linuxType; + + if (eVerification == PVR_VERIFY_READ) + { + linuxType = VERIFY_READ; + } + else + { + PVR_ASSERT(eVerification == PVR_VERIFY_WRITE); + linuxType = VERIFY_WRITE; + } + + return access_ok(linuxType, pvUserPtr, ui32Bytes); +} + +typedef enum _eWrapMemType_ +{ + WRAP_TYPE_CLEANUP, + WRAP_TYPE_GET_USER_PAGES, + WRAP_TYPE_FIND_VMA_PAGES, + WRAP_TYPE_FIND_VMA_PFN +} eWrapMemType; + +typedef struct _sWrapMemInfo_ +{ + eWrapMemType eType; + IMG_INT iNumPages; + struct page **ppsPages; + IMG_SYS_PHYADDR *psPhysAddr; + IMG_INT iPageOffset; + IMG_INT iContiguous; +#if defined(DEBUG) + IMG_UINT32 ulStartAddr; + IMG_UINT32 ulBeyondEndAddr; + struct vm_area_struct *psVMArea; +#endif +} sWrapMemInfo; + +static IMG_VOID CheckPagesContiguous(sWrapMemInfo *psInfo) +{ + IMG_INT i; + IMG_UINT32 ui32AddrChk; + + BUG_ON(psInfo == IMG_NULL); + + psInfo->iContiguous = 1; + + for (i = 0, ui32AddrChk = psInfo->psPhysAddr[0].uiAddr; + i < psInfo->iNumPages; + i++, ui32AddrChk += PAGE_SIZE) + { + if (psInfo->psPhysAddr[i].uiAddr != ui32AddrChk) + { + psInfo->iContiguous = 0; + break; + } + } +} + +static struct page *CPUVAddrToPage(struct vm_area_struct *psVMArea, IMG_UINT32 ulCPUVAddr) +{ +#if (LINUX_VERSION_CODE > KERNEL_VERSION(2,6,10)) + pgd_t *psPGD; + pud_t *psPUD; + pmd_t *psPMD; + pte_t *psPTE; + struct mm_struct *psMM = psVMArea->vm_mm; + IMG_UINT32 ulPFN; + spinlock_t *psPTLock; + struct page *psPage; + + psPGD = pgd_offset(psMM, ulCPUVAddr); + if (pgd_none(*psPGD) || pgd_bad(*psPGD)) + return NULL; + + psPUD = pud_offset(psPGD, ulCPUVAddr); + if (pud_none(*psPUD) || pud_bad(*psPUD)) + return NULL; + + psPMD = pmd_offset(psPUD, ulCPUVAddr); + if (pmd_none(*psPMD) || pmd_bad(*psPMD)) + return NULL; + + psPage = NULL; + + psPTE = (pte_t *)pte_offset_map_lock(psMM, psPMD, ulCPUVAddr, &psPTLock); + if ((pte_none(*psPTE) != 0) || (pte_present(*psPTE) == 0) || (pte_write(*psPTE) == 0)) + goto exit_unlock; + + ulPFN = pte_pfn(*psPTE); + if (!pfn_valid(ulPFN)) + goto exit_unlock; + + psPage = pfn_to_page(ulPFN); + + get_page(psPage); + +exit_unlock: + pte_unmap_unlock(psPTE, psPTLock); + + return psPage; +#else + return NULL; +#endif +} +PVRSRV_ERROR OSReleasePhysPageAddr(IMG_HANDLE hOSWrapMem) +{ + sWrapMemInfo *psInfo = (sWrapMemInfo *)hOSWrapMem; + IMG_INT i; + + BUG_ON(psInfo == IMG_NULL); + + switch (psInfo->eType) + { + case WRAP_TYPE_CLEANUP: + break; + case WRAP_TYPE_FIND_VMA_PFN: + break; + case WRAP_TYPE_GET_USER_PAGES: + { + for (i = 0; i < psInfo->iNumPages; i++) + { + struct page *psPage = psInfo->ppsPages[i]; + + + if (!PageReserved(psPage)); + { + SetPageDirty(psPage); + } + page_cache_release(psPage); + } + break; + } + case WRAP_TYPE_FIND_VMA_PAGES: + { + for (i = 0; i < psInfo->iNumPages; i++) + { + put_page_testzero(psInfo->ppsPages[i]); + } + break; + } + default: + { + PVR_DPF((PVR_DBG_ERROR, + "OSReleasePhysPageAddr: Unknown wrap type (%d)", psInfo->eType)); + return PVRSRV_ERROR_GENERIC; + } + } + + if (psInfo->ppsPages != IMG_NULL) + { + kfree(psInfo->ppsPages); + } + + if (psInfo->psPhysAddr != IMG_NULL) + { + kfree(psInfo->psPhysAddr); + } + + kfree(psInfo); + + return PVRSRV_OK; +} + +PVRSRV_ERROR OSAcquirePhysPageAddr(IMG_VOID* pvCPUVAddr, + IMG_UINT32 ui32Bytes, + IMG_SYS_PHYADDR *psSysPAddr, + IMG_HANDLE *phOSWrapMem) +{ + IMG_UINT32 ulStartAddrOrig = (IMG_UINT32) pvCPUVAddr; + IMG_UINT32 ulAddrRangeOrig = (IMG_UINT32) ui32Bytes; + IMG_UINT32 ulBeyondEndAddrOrig = ulStartAddrOrig + ulAddrRangeOrig; + IMG_UINT32 ulStartAddr; + IMG_UINT32 ulAddrRange; + IMG_UINT32 ulBeyondEndAddr; + IMG_UINT32 ulAddr; + IMG_INT iNumPagesMapped; + IMG_INT i; + struct vm_area_struct *psVMArea; + sWrapMemInfo *psInfo; + + + ulStartAddr = ulStartAddrOrig & PAGE_MASK; + ulBeyondEndAddr = PAGE_ALIGN(ulBeyondEndAddrOrig); + ulAddrRange = ulBeyondEndAddr - ulStartAddr; + + + psInfo = kmalloc(sizeof(*psInfo), GFP_KERNEL); + if (psInfo == NULL) + { + PVR_DPF((PVR_DBG_ERROR, + "OSAcquirePhysPageAddr: Couldn't allocate information structure")); + return PVRSRV_ERROR_OUT_OF_MEMORY; + } + memset(psInfo, 0, sizeof(*psInfo)); + +#if defined(DEBUG) + psInfo->ulStartAddr = ulStartAddrOrig; + psInfo->ulBeyondEndAddr = ulBeyondEndAddrOrig; +#endif + + psInfo->iNumPages = (IMG_INT)(ulAddrRange >> PAGE_SHIFT); + psInfo->iPageOffset = (IMG_INT)(ulStartAddrOrig & ~PAGE_MASK); + + + psInfo->psPhysAddr = kmalloc((size_t)psInfo->iNumPages * sizeof(*psInfo->psPhysAddr), GFP_KERNEL); + if (psInfo->psPhysAddr == NULL) + { + PVR_DPF((PVR_DBG_ERROR, + "OSAcquirePhysPageAddr: Couldn't allocate page array")); + goto error_free; + } + + + psInfo->ppsPages = kmalloc((size_t)psInfo->iNumPages * sizeof(*psInfo->ppsPages), GFP_KERNEL); + if (psInfo->ppsPages == NULL) + { + PVR_DPF((PVR_DBG_ERROR, + "OSAcquirePhysPageAddr: Couldn't allocate page array")); + goto error_free; + } + + + down_read(¤t->mm->mmap_sem); + iNumPagesMapped = get_user_pages(current, current->mm, ulStartAddr, psInfo->iNumPages, 1, 0, psInfo->ppsPages, NULL); + up_read(¤t->mm->mmap_sem); + + if (iNumPagesMapped >= 0) + { + + if (iNumPagesMapped != psInfo->iNumPages) + { + PVR_TRACE(("OSAcquirePhysPageAddr: Couldn't map all the pages needed (wanted: %d, got %d)", psInfo->iNumPages, iNumPagesMapped)); + + + for (i = 0; i < iNumPagesMapped; i++) + { + page_cache_release(psInfo->ppsPages[i]); + + } + goto error_free; + } + + + for (i = 0; i < psInfo->iNumPages; i++) + { + IMG_CPU_PHYADDR CPUPhysAddr; + + CPUPhysAddr.uiAddr = page_to_pfn(psInfo->ppsPages[i]) << PAGE_SHIFT; + psInfo->psPhysAddr[i] = SysCpuPAddrToSysPAddr(CPUPhysAddr); + psSysPAddr[i] = psInfo->psPhysAddr[i]; + + } + + psInfo->eType = WRAP_TYPE_GET_USER_PAGES; + + goto exit_check; + } + + PVR_TRACE(("OSAcquirePhysPageAddr: get_user_pages failed (%d), trying something else", iNumPagesMapped)); + + + down_read(¤t->mm->mmap_sem); + + psVMArea = find_vma(current->mm, ulStartAddrOrig); + if (psVMArea == NULL) + { + PVR_DPF((PVR_DBG_ERROR, + "OSAcquirePhysPageAddr: Couldn't find memory region containing start address %lx", ulStartAddrOrig)); + + goto error_release_mmap_sem; + } +#if defined(DEBUG) + psInfo->psVMArea = psVMArea; +#endif + + + if (ulStartAddrOrig < psVMArea->vm_start) + { + PVR_DPF((PVR_DBG_ERROR, + "OSAcquirePhysPageAddr: Start address %lx is outside of the region returned by find_vma", ulStartAddrOrig)); + goto error_release_mmap_sem; + } + + + if (ulBeyondEndAddrOrig > psVMArea->vm_end) + { + PVR_DPF((PVR_DBG_ERROR, + "OSAcquirePhysPageAddr: End address %lx is outside of the region returned by find_vma", ulBeyondEndAddrOrig)); + goto error_release_mmap_sem; + } + + + if ((psVMArea->vm_flags & (VM_IO | VM_RESERVED)) != (VM_IO | VM_RESERVED)) + { + PVR_DPF((PVR_DBG_ERROR, + "OSAcquirePhysPageAddr: Memory region does not represent memory mapped I/O (VMA flags: 0x%lx)", psVMArea->vm_flags)); + goto error_release_mmap_sem; + } + + + if ((psVMArea->vm_flags & (VM_READ | VM_WRITE)) != (VM_READ | VM_WRITE)) + { + PVR_DPF((PVR_DBG_ERROR, + "OSAcquirePhysPageAddr: No read/write access to memory region (VMA flags: 0x%lx)", psVMArea->vm_flags)); + goto error_release_mmap_sem; + } + + + for (ulAddr = ulStartAddrOrig, i = 0; ulAddr < ulBeyondEndAddrOrig; ulAddr += PAGE_SIZE, i++) + { + struct page *psPage; + + BUG_ON(i >= psInfo->iNumPages); + + psPage = CPUVAddrToPage(psVMArea, ulAddr); + if (psPage == NULL) + { + IMG_INT j; + + PVR_TRACE(("OSAcquirePhysPageAddr: Couldn't lookup page structure for address 0x%lx, trying something else", ulAddr)); + + + for (j = 0; j < i; j++) + { + put_page_testzero(psInfo->ppsPages[j]); + } + break; + } + + psInfo->ppsPages[i] = psPage; + } + + BUG_ON(i > psInfo->iNumPages); + if (i == psInfo->iNumPages) + { + + for (i = 0; i < psInfo->iNumPages; i++) + { + struct page *psPage = psInfo->ppsPages[i]; + IMG_CPU_PHYADDR CPUPhysAddr; + + + CPUPhysAddr.uiAddr = page_to_pfn(psPage) << PAGE_SHIFT; + + psInfo->psPhysAddr[i] = SysCpuPAddrToSysPAddr(CPUPhysAddr); + psSysPAddr[i] = psInfo->psPhysAddr[i]; + } + + psInfo->eType = WRAP_TYPE_FIND_VMA_PAGES; + } + else + { +#if (LINUX_VERSION_CODE > KERNEL_VERSION(2,6,10)) && defined(PVR_SECURE_HANDLES) + + + + if ((psVMArea->vm_flags & VM_PFNMAP) == 0) + { + PVR_DPF((PVR_DBG_WARNING, + "OSAcquirePhysPageAddr: Region isn't a raw PFN mapping. Giving up.")); + goto error_release_mmap_sem; + } + + for (ulAddr = ulStartAddrOrig, i = 0; ulAddr < ulBeyondEndAddrOrig; ulAddr += PAGE_SIZE, i++) + { + IMG_CPU_PHYADDR CPUPhysAddr; + + CPUPhysAddr.uiAddr = ((ulAddr - psVMArea->vm_start) + (psVMArea->vm_pgoff << PAGE_SHIFT)) & PAGE_MASK; + + psInfo->psPhysAddr[i] = SysCpuPAddrToSysPAddr(CPUPhysAddr); + psSysPAddr[i] = psInfo->psPhysAddr[i]; + } + BUG_ON(i != psInfo->iNumPages); + + psInfo->eType = WRAP_TYPE_FIND_VMA_PFN; + + + PVR_DPF((PVR_DBG_WARNING, + "OSAcquirePhysPageAddr: Region can't be locked down")); +#else + PVR_DPF((PVR_DBG_WARNING, + "OSAcquirePhysPageAddr: Raw PFN mappings not supported. Giving up.")); + goto error_release_mmap_sem; +#endif + } + + up_read(¤t->mm->mmap_sem); + +exit_check: + CheckPagesContiguous(psInfo); + + + + *phOSWrapMem = (IMG_HANDLE)psInfo; + + return PVRSRV_OK; + +error_release_mmap_sem: + up_read(¤t->mm->mmap_sem); +error_free: + psInfo->eType = WRAP_TYPE_CLEANUP; + OSReleasePhysPageAddr((IMG_HANDLE)psInfo); + return PVRSRV_ERROR_GENERIC; +} + diff --git a/services4/srvkm/env/linux/osperproc.c b/services4/srvkm/env/linux/osperproc.c new file mode 100644 index 0000000..0793875 --- /dev/null +++ b/services4/srvkm/env/linux/osperproc.c @@ -0,0 +1,97 @@ +/********************************************************************** + * + * Copyright(c) 2008 Imagination Technologies Ltd. All rights reserved. + * + * This program is free software; you can redistribute it and/or modify it + * under the terms and conditions of the GNU General Public License, + * version 2, as published by the Free Software Foundation. + * + * This program is distributed in the hope it will be useful but, except + * as otherwise stated in writing, without any warranty; without even the + * implied warranty of merchantability or fitness for a particular purpose. + * See the GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License along with + * this program; if not, write to the Free Software Foundation, Inc., + * 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA. + * + * The full GNU General Public License is included in this distribution in + * the file called "COPYING". + * + * Contact Information: + * Imagination Technologies Ltd. + * Home Park Estate, Kings Langley, Herts, WD4 8LZ, UK + * + ******************************************************************************/ + +#include "services_headers.h" +#include "osperproc.h" + +#include "env_perproc.h" +#include "proc.h" + +PVRSRV_ERROR OSPerProcessPrivateDataInit(IMG_HANDLE *phOsPrivateData) +{ + PVRSRV_ERROR eError; + IMG_HANDLE hBlockAlloc; + PVRSRV_ENV_PER_PROCESS_DATA *psEnvPerProc; + + eError = OSAllocMem(PVRSRV_OS_NON_PAGEABLE_HEAP, + sizeof(PVRSRV_ENV_PER_PROCESS_DATA), + phOsPrivateData, + &hBlockAlloc); + + if (eError != PVRSRV_OK) + { + *phOsPrivateData = IMG_NULL; + + PVR_DPF((PVR_DBG_ERROR, "%s: OSAllocMem failed (%d)", __FUNCTION__, eError)); + return eError; + } + + psEnvPerProc = (PVRSRV_ENV_PER_PROCESS_DATA *)*phOsPrivateData; + OSMemSet(psEnvPerProc, 0, sizeof(*psEnvPerProc)); + + psEnvPerProc->hBlockAlloc = hBlockAlloc; + + + LinuxMMapPerProcessConnect(psEnvPerProc); + + return PVRSRV_OK; +} + +PVRSRV_ERROR OSPerProcessPrivateDataDeInit(IMG_HANDLE hOsPrivateData) +{ + PVRSRV_ERROR eError; + PVRSRV_ENV_PER_PROCESS_DATA *psEnvPerProc; + + if (hOsPrivateData == IMG_NULL) + { + return PVRSRV_OK; + } + + psEnvPerProc = (PVRSRV_ENV_PER_PROCESS_DATA *)hOsPrivateData; + + + LinuxMMapPerProcessDisconnect(psEnvPerProc); + + + RemovePerProcessProcDir(psEnvPerProc); + + eError = OSFreeMem(PVRSRV_OS_NON_PAGEABLE_HEAP, + sizeof(PVRSRV_ENV_PER_PROCESS_DATA), + hOsPrivateData, + psEnvPerProc->hBlockAlloc); + if (eError != PVRSRV_OK) + { + PVR_DPF((PVR_DBG_ERROR, "%s: OSFreeMem failed (%d)", __FUNCTION__, eError)); + } + + return PVRSRV_OK; +} + +PVRSRV_ERROR OSPerProcessSetHandleOptions(PVRSRV_HANDLE_BASE *psHandleBase) +{ + return LinuxMMapPerProcessHandleOptions(psHandleBase); +} + diff --git a/services4/srvkm/env/linux/pdump.c b/services4/srvkm/env/linux/pdump.c new file mode 100644 index 0000000..b7f948a --- /dev/null +++ b/services4/srvkm/env/linux/pdump.c @@ -0,0 +1,1509 @@ +/********************************************************************** + * + * Copyright(c) 2008 Imagination Technologies Ltd. All rights reserved. + * + * This program is free software; you can redistribute it and/or modify it + * under the terms and conditions of the GNU General Public License, + * version 2, as published by the Free Software Foundation. + * + * This program is distributed in the hope it will be useful but, except + * as otherwise stated in writing, without any warranty; without even the + * implied warranty of merchantability or fitness for a particular purpose. + * See the GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License along with + * this program; if not, write to the Free Software Foundation, Inc., + * 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA. + * + * The full GNU General Public License is included in this distribution in + * the file called "COPYING". + * + * Contact Information: + * Imagination Technologies Ltd. + * Home Park Estate, Kings Langley, Herts, WD4 8LZ, UK + * + ******************************************************************************/ + +#if defined (SUPPORT_SGX) +#if defined (PDUMP) +#include +#include +#include "sgxdefs.h" +#include "services_headers.h" + +#include "pvrversion.h" +#include "pvr_debug.h" + +#include "dbgdrvif.h" +#include "sgxmmu.h" +#include "mm.h" +#include "pdump_km.h" + +#include + +static IMG_BOOL PDumpWriteString2 (IMG_CHAR * pszString, IMG_UINT32 ui32Flags); +static IMG_BOOL PDumpWriteILock (PDBG_STREAM psStream, IMG_UINT8 *pui8Data, IMG_UINT32 ui32Count, IMG_UINT32 ui32Flags); +static IMG_VOID DbgSetFrame (PDBG_STREAM psStream, IMG_UINT32 ui32Frame); +static IMG_UINT32 DbgGetFrame (PDBG_STREAM psStream); +static IMG_VOID DbgSetMarker (PDBG_STREAM psStream, IMG_UINT32 ui32Marker); +static IMG_UINT32 DbgWrite (PDBG_STREAM psStream, IMG_UINT8 *pui8Data, IMG_UINT32 ui32BCount, IMG_UINT32 ui32Flags); + +#define PDUMP_DATAMASTER_PIXEL (1) + +#define MIN(a,b) (a > b ? b : a) + +#define MAX_FILE_SIZE 0x40000000 + +static atomic_t gsPDumpSuspended = ATOMIC_INIT(0); + +static PDBGKM_SERVICE_TABLE gpfnDbgDrv = IMG_NULL; + +#define PDUMP_STREAM_PARAM2 0 +#define PDUMP_STREAM_SCRIPT2 1 +#define PDUMP_STREAM_DRIVERINFO 2 +#define PDUMP_NUM_STREAMS 3 + + + +IMG_CHAR *pszStreamName[PDUMP_NUM_STREAMS] = { "ParamStream2", + "ScriptStream2", + "DriverInfoStream"}; + +#define __PDBG_PDUMP_STATE_GET_MSG_STRING(ERROR) \ + IMG_CHAR *pszMsg = gsDBGPdumpState.pszMsg; \ + if ((!pszMsg) || PDumpSuspended()) return ERROR + +#define __PDBG_PDUMP_STATE_GET_SCRIPT_STRING(ERROR) \ + IMG_CHAR *pszScript = gsDBGPdumpState.pszScript; \ + if ((!pszScript) || PDumpSuspended()) return ERROR + +#define __PDBG_PDUMP_STATE_GET_SCRIPT_AND_FILE_STRING(ERROR) \ + IMG_CHAR *pszScript = gsDBGPdumpState.pszScript; \ + IMG_CHAR *pszFile = gsDBGPdumpState.pszFile; \ + if ((!pszScript) || (!pszFile) || PDumpSuspended()) return ERROR + +typedef struct PDBG_PDUMP_STATE_TAG +{ + PDBG_STREAM psStream[PDUMP_NUM_STREAMS]; + IMG_UINT32 ui32ParamFileNum; + + IMG_CHAR *pszMsg; + IMG_CHAR *pszScript; + IMG_CHAR *pszFile; + +} PDBG_PDUMP_STATE; + +static PDBG_PDUMP_STATE gsDBGPdumpState = {{IMG_NULL}, 0, IMG_NULL, IMG_NULL, IMG_NULL}; + +#define SZ_MSG_SIZE_MAX PVRSRV_PDUMP_MAX_COMMENT_SIZE-1 +#define SZ_SCRIPT_SIZE_MAX PVRSRV_PDUMP_MAX_COMMENT_SIZE-1 +#define SZ_FILENAME_SIZE_MAX PVRSRV_PDUMP_MAX_COMMENT_SIZE-1 + + + + +IMG_VOID DBGDrvGetServiceTable(IMG_VOID **fn_table); + +static inline IMG_BOOL PDumpSuspended(IMG_VOID) +{ + return atomic_read(&gsPDumpSuspended) != 0; +} + +IMG_VOID PDumpInit(IMG_VOID) +{ + IMG_UINT32 i=0; + + + if (!gpfnDbgDrv) + { + DBGDrvGetServiceTable((IMG_VOID **)&gpfnDbgDrv); + + + + + if (gpfnDbgDrv == IMG_NULL) + { + return; + } + + if(!gsDBGPdumpState.pszFile) + { + if(OSAllocMem(PVRSRV_OS_PAGEABLE_HEAP, SZ_FILENAME_SIZE_MAX, (IMG_PVOID *)&gsDBGPdumpState.pszFile, 0) != PVRSRV_OK) + { + goto init_failed; + } + } + + if(!gsDBGPdumpState.pszMsg) + { + if(OSAllocMem(PVRSRV_OS_PAGEABLE_HEAP, SZ_MSG_SIZE_MAX, (IMG_PVOID *)&gsDBGPdumpState.pszMsg, 0) != PVRSRV_OK) + { + goto init_failed; + } + } + + if(!gsDBGPdumpState.pszScript) + { + if(OSAllocMem(PVRSRV_OS_PAGEABLE_HEAP, SZ_SCRIPT_SIZE_MAX, (IMG_PVOID *)&gsDBGPdumpState.pszScript, 0) != PVRSRV_OK) + { + goto init_failed; + } + } + + for(i=0; i < PDUMP_NUM_STREAMS; i++) + { + gsDBGPdumpState.psStream[i] = gpfnDbgDrv->pfnCreateStream(pszStreamName[i], + DEBUG_CAPMODE_FRAMED, + DEBUG_OUTMODE_STREAMENABLE, + 0, + 10); + + gpfnDbgDrv->pfnSetCaptureMode(gsDBGPdumpState.psStream[i],DEBUG_CAPMODE_FRAMED,0xFFFFFFFF, 0xFFFFFFFF, 1); + gpfnDbgDrv->pfnSetFrame(gsDBGPdumpState.psStream[i],0); + } + + PDUMPCOMMENT("Driver Product Name: %s", VS_PRODUCT_NAME); + PDUMPCOMMENT("Driver Product Version: %s (%s)", PVRVERSION_STRING, PVRVERSION_FILE); + PDUMPCOMMENT("Start of Init Phase"); + } + + return; + +init_failed: + + if(gsDBGPdumpState.pszFile) + { + OSFreeMem(PVRSRV_OS_PAGEABLE_HEAP, SZ_FILENAME_SIZE_MAX, (IMG_PVOID) gsDBGPdumpState.pszFile, 0); + gsDBGPdumpState.pszFile = IMG_NULL; + } + + if(gsDBGPdumpState.pszScript) + { + OSFreeMem(PVRSRV_OS_PAGEABLE_HEAP, SZ_SCRIPT_SIZE_MAX, (IMG_PVOID) gsDBGPdumpState.pszScript, 0); + gsDBGPdumpState.pszScript = IMG_NULL; + } + + if(gsDBGPdumpState.pszMsg) + { + OSFreeMem(PVRSRV_OS_PAGEABLE_HEAP, SZ_MSG_SIZE_MAX, (IMG_PVOID) gsDBGPdumpState.pszMsg, 0); + gsDBGPdumpState.pszMsg = IMG_NULL; + } + + gpfnDbgDrv = IMG_NULL; +} + + +IMG_VOID PDumpDeInit(IMG_VOID) +{ + IMG_UINT32 i=0; + + for(i=0; i < PDUMP_NUM_STREAMS; i++) + { + gpfnDbgDrv->pfnDestroyStream(gsDBGPdumpState.psStream[i]); + } + + if(gsDBGPdumpState.pszFile) + { + OSFreeMem(PVRSRV_OS_PAGEABLE_HEAP, SZ_FILENAME_SIZE_MAX, (IMG_PVOID) gsDBGPdumpState.pszFile, 0); + gsDBGPdumpState.pszFile = IMG_NULL; + } + + if(gsDBGPdumpState.pszScript) + { + OSFreeMem(PVRSRV_OS_PAGEABLE_HEAP, SZ_SCRIPT_SIZE_MAX, (IMG_PVOID) gsDBGPdumpState.pszScript, 0); + gsDBGPdumpState.pszScript = IMG_NULL; + } + + if(gsDBGPdumpState.pszMsg) + { + OSFreeMem(PVRSRV_OS_PAGEABLE_HEAP, SZ_MSG_SIZE_MAX, (IMG_PVOID) gsDBGPdumpState.pszMsg, 0); + gsDBGPdumpState.pszMsg = IMG_NULL; + } + + gpfnDbgDrv = IMG_NULL; +} + +PVRSRV_ERROR PDumpStartInitPhaseKM(IMG_VOID) +{ + IMG_UINT32 i; + + if (gpfnDbgDrv) + { + PDUMPCOMMENT("Start Init Phase"); + for(i=0; i < PDUMP_NUM_STREAMS; i++) + { + gpfnDbgDrv->pfnStartInitPhase(gsDBGPdumpState.psStream[i]); + } + } + return PVRSRV_OK; +} + +PVRSRV_ERROR PDumpStopInitPhaseKM(IMG_VOID) +{ + IMG_UINT32 i; + + if (gpfnDbgDrv) + { + PDUMPCOMMENT("Stop Init Phase"); + + for(i=0; i < PDUMP_NUM_STREAMS; i++) + { + gpfnDbgDrv->pfnStopInitPhase(gsDBGPdumpState.psStream[i]); + } + } + return PVRSRV_OK; +} + +IMG_VOID PDumpComment(IMG_CHAR *pszFormat, ...) +{ + va_list ap; + + __PDBG_PDUMP_STATE_GET_MSG_STRING(); + + + va_start(ap, pszFormat); + vsnprintf(pszMsg, SZ_MSG_SIZE_MAX, pszFormat, ap); + va_end(ap); + + PDumpCommentKM(pszMsg, PDUMP_FLAGS_CONTINUOUS); +} + +IMG_VOID PDumpCommentWithFlags(IMG_UINT32 ui32Flags, IMG_CHAR * pszFormat, ...) +{ + va_list ap; + + __PDBG_PDUMP_STATE_GET_MSG_STRING(); + + + va_start(ap, pszFormat); + vsnprintf(pszMsg, SZ_MSG_SIZE_MAX, pszFormat, ap); + va_end(ap); + + PDumpCommentKM(pszMsg, ui32Flags); +} + +IMG_BOOL PDumpIsLastCaptureFrameKM(IMG_VOID) +{ + return gpfnDbgDrv->pfnIsLastCaptureFrame(gsDBGPdumpState.psStream[PDUMP_STREAM_SCRIPT2]); +} + + +IMG_BOOL PDumpIsCaptureFrameKM(IMG_VOID) +{ + if (PDumpSuspended()) + { + return IMG_FALSE; + } + return gpfnDbgDrv->pfnIsCaptureFrame(gsDBGPdumpState.psStream[PDUMP_STREAM_SCRIPT2], IMG_FALSE); +} + +PVRSRV_ERROR PDumpRegWithFlagsKM(IMG_UINT32 ui32Reg, IMG_UINT32 ui32Data, IMG_UINT32 ui32Flags) +{ + __PDBG_PDUMP_STATE_GET_SCRIPT_STRING(PVRSRV_ERROR_GENERIC); + + snprintf(pszScript, SZ_SCRIPT_SIZE_MAX, "WRW :SGXREG:0x%8.8lX 0x%8.8lX\r\n", ui32Reg, ui32Data); + PDumpWriteString2(pszScript, ui32Flags); + + return PVRSRV_OK; +} + +IMG_VOID PDumpReg(IMG_UINT32 ui32Reg,IMG_UINT32 ui32Data) +{ + __PDBG_PDUMP_STATE_GET_SCRIPT_STRING(); + + snprintf(pszScript, SZ_SCRIPT_SIZE_MAX, "WRW :SGXREG:0x%8.8lX 0x%8.8lX\r\n", ui32Reg, ui32Data); + PDumpWriteString2(pszScript, PDUMP_FLAGS_CONTINUOUS); +} + +PVRSRV_ERROR PDumpRegPolWithFlagsKM(IMG_UINT32 ui32RegAddr, IMG_UINT32 ui32RegValue, IMG_UINT32 ui32Mask, IMG_UINT32 ui32Flags) +{ + #define POLL_DELAY 1000 + #define POLL_COUNT_LONG (2000000000 / POLL_DELAY) + #define POLL_COUNT_SHORT (1000000 / POLL_DELAY) + + IMG_UINT32 ui32PollCount; + __PDBG_PDUMP_STATE_GET_SCRIPT_STRING(PVRSRV_ERROR_GENERIC); + + if (((ui32RegAddr == EUR_CR_EVENT_STATUS) && + (ui32RegValue & ui32Mask & EUR_CR_EVENT_STATUS_TA_FINISHED_MASK)) || + ((ui32RegAddr == EUR_CR_EVENT_STATUS) && + (ui32RegValue & ui32Mask & EUR_CR_EVENT_STATUS_PIXELBE_END_RENDER_MASK)) || + ((ui32RegAddr == EUR_CR_EVENT_STATUS) && + (ui32RegValue & ui32Mask & EUR_CR_EVENT_STATUS_DPM_3D_MEM_FREE_MASK))) + { + ui32PollCount = POLL_COUNT_LONG; + } + else + { + ui32PollCount = POLL_COUNT_SHORT; + } + + snprintf(pszScript, SZ_SCRIPT_SIZE_MAX, "POL :SGXREG:0x%8.8lX 0x%8.8lX 0x%8.8lX %d %lu %d\r\n", ui32RegAddr, ui32RegValue, ui32Mask, 0, ui32PollCount, POLL_DELAY); + PDumpWriteString2(pszScript, ui32Flags); + + return PVRSRV_OK; +} + + +PVRSRV_ERROR PDumpRegPolKM(IMG_UINT32 ui32RegAddr, IMG_UINT32 ui32RegValue, IMG_UINT32 ui32Mask) +{ + return PDumpRegPolWithFlagsKM(ui32RegAddr, ui32RegValue, ui32Mask, PDUMP_FLAGS_CONTINUOUS); +} + +IMG_VOID PDumpMallocPages (PVRSRV_DEVICE_TYPE eDeviceType, + IMG_UINT32 ui32DevVAddr, + IMG_CPU_VIRTADDR pvLinAddr, + IMG_HANDLE hOSMemHandle, + IMG_UINT32 ui32NumBytes, + IMG_UINT32 ui32PageSize, + IMG_HANDLE hUniqueTag) +{ + IMG_UINT32 ui32Offset; + IMG_UINT32 ui32NumPages; + IMG_CPU_PHYADDR sCpuPAddr; + IMG_DEV_PHYADDR sDevPAddr; + IMG_UINT32 ui32Page; + __PDBG_PDUMP_STATE_GET_SCRIPT_STRING(); + PVR_UNREFERENCED_PARAMETER(pvLinAddr); + + + PVR_ASSERT(((IMG_UINT32) ui32DevVAddr & (ui32PageSize - 1)) == 0); + PVR_ASSERT(hOSMemHandle); + PVR_ASSERT(((IMG_UINT32) ui32NumBytes & (ui32PageSize - 1)) == 0); + + + + snprintf(pszScript, SZ_SCRIPT_SIZE_MAX, "-- MALLOC :SGXMEM:VA_%8.8lX 0x%8.8lX %lu\r\n", ui32DevVAddr, ui32NumBytes, ui32PageSize); + PDumpWriteString2(pszScript, PDUMP_FLAGS_CONTINUOUS); + + + + ui32Offset = 0; + ui32NumPages = ui32NumBytes / ui32PageSize; + while (ui32NumPages--) + { + sCpuPAddr = OSMemHandleToCpuPAddr(hOSMemHandle, ui32Offset); + PVR_ASSERT((sCpuPAddr.uiAddr & (ui32PageSize - 1)) == 0); + ui32Offset += ui32PageSize; + sDevPAddr = SysCpuPAddrToDevPAddr(eDeviceType, sCpuPAddr); + ui32Page = sDevPAddr.uiAddr / ui32PageSize; + + snprintf(pszScript, SZ_SCRIPT_SIZE_MAX, "MALLOC :SGXMEM:PA_%8.8lX%8.8lX %lu %lu 0x%8.8lX\r\n", + (IMG_UINT32) hUniqueTag, + ui32Page * ui32PageSize, + ui32PageSize, + ui32PageSize, + ui32Page * ui32PageSize); + PDumpWriteString2(pszScript, PDUMP_FLAGS_CONTINUOUS); + } +} + +IMG_VOID PDumpMallocPageTable (PVRSRV_DEVICE_TYPE eDeviceType, + IMG_CPU_VIRTADDR pvLinAddr, + IMG_UINT32 ui32PTSize, + IMG_HANDLE hUniqueTag) +{ + IMG_PUINT8 pui8LinAddr; + IMG_UINT32 ui32NumPages; + IMG_CPU_PHYADDR sCpuPAddr; + IMG_DEV_PHYADDR sDevPAddr; + IMG_UINT32 ui32Page; + __PDBG_PDUMP_STATE_GET_SCRIPT_STRING(); + + PVR_ASSERT(((IMG_UINT32) pvLinAddr & (ui32PTSize - 1)) == 0); + + + + snprintf(pszScript, SZ_SCRIPT_SIZE_MAX, "-- MALLOC :SGXMEM:PAGE_TABLE 0x%8.8lX %lu\r\n", ui32PTSize, SGX_MMU_PAGE_SIZE); + PDumpWriteString2(pszScript, PDUMP_FLAGS_CONTINUOUS); + + + + pui8LinAddr = (IMG_PUINT8) pvLinAddr; + + + + + + + + ui32NumPages = 1; + + while (ui32NumPages--) + { + sCpuPAddr = OSMapLinToCPUPhys(pui8LinAddr); + sDevPAddr = SysCpuPAddrToDevPAddr(eDeviceType, sCpuPAddr); + ui32Page = sDevPAddr.uiAddr >> SGX_MMU_PAGE_SHIFT; + + snprintf(pszScript, SZ_SCRIPT_SIZE_MAX, "MALLOC :SGXMEM:PA_%8.8lX%8.8lX 0x%lX %lu 0x%8.8lX\r\n", + (IMG_UINT32) hUniqueTag, + ui32Page * SGX_MMU_PAGE_SIZE, + SGX_MMU_PAGE_SIZE, + SGX_MMU_PAGE_SIZE, + ui32Page * SGX_MMU_PAGE_SIZE); + PDumpWriteString2(pszScript, PDUMP_FLAGS_CONTINUOUS); + pui8LinAddr += SGX_MMU_PAGE_SIZE; + } +} + +IMG_VOID PDumpFreePages (BM_HEAP *psBMHeap, + IMG_DEV_VIRTADDR sDevVAddr, + IMG_UINT32 ui32NumBytes, + IMG_UINT32 ui32PageSize, + IMG_HANDLE hUniqueTag, + IMG_BOOL bInterleaved) +{ + IMG_UINT32 ui32NumPages, ui32PageCounter; + IMG_DEV_PHYADDR sDevPAddr; + PVRSRV_DEVICE_NODE *psDeviceNode; + __PDBG_PDUMP_STATE_GET_SCRIPT_STRING(); + + PVR_ASSERT(((IMG_UINT32) sDevVAddr.uiAddr & (ui32PageSize - 1)) == 0); + PVR_ASSERT(((IMG_UINT32) ui32NumBytes & (ui32PageSize - 1)) == 0); + + + + snprintf(pszScript, SZ_SCRIPT_SIZE_MAX, "-- FREE :SGXMEM:VA_%8.8lX\r\n", sDevVAddr.uiAddr); + PDumpWriteString2(pszScript, PDUMP_FLAGS_CONTINUOUS); + + + + ui32NumPages = ui32NumBytes / ui32PageSize; + psDeviceNode = psBMHeap->pBMContext->psDeviceNode; + for (ui32PageCounter = 0; ui32PageCounter < ui32NumPages; ui32PageCounter++) + { + if (!bInterleaved || (ui32PageCounter % 2) == 0) + { + sDevPAddr = psDeviceNode->pfnMMUGetPhysPageAddr(psBMHeap->pMMUHeap, sDevVAddr); + + snprintf(pszScript, SZ_SCRIPT_SIZE_MAX, "FREE :SGXMEM:PA_%8.8lX%8.8lX\r\n", (IMG_UINT32) hUniqueTag, sDevPAddr.uiAddr); + PDumpWriteString2(pszScript, PDUMP_FLAGS_CONTINUOUS); + } + else + { + + } + + sDevVAddr.uiAddr += ui32PageSize; + } +} + +IMG_VOID PDumpFreePageTable (PVRSRV_DEVICE_TYPE eDeviceType, + IMG_CPU_VIRTADDR pvLinAddr, + IMG_UINT32 ui32PTSize, + IMG_HANDLE hUniqueTag) +{ + IMG_PUINT8 pui8LinAddr; + IMG_UINT32 ui32NumPages; + IMG_CPU_PHYADDR sCpuPAddr; + IMG_DEV_PHYADDR sDevPAddr; + IMG_UINT32 ui32Page; + __PDBG_PDUMP_STATE_GET_SCRIPT_STRING(); + + PVR_ASSERT(((IMG_UINT32) pvLinAddr & (ui32PTSize - 1)) == 0); + + + + snprintf(pszScript, SZ_SCRIPT_SIZE_MAX, "-- FREE :SGXMEM:PAGE_TABLE\r\n"); + PDumpWriteString2(pszScript, PDUMP_FLAGS_CONTINUOUS); + + + + pui8LinAddr = (IMG_PUINT8) pvLinAddr; + + + + + + + + ui32NumPages = 1; + + while (ui32NumPages--) + { + sCpuPAddr = OSMapLinToCPUPhys(pui8LinAddr); + sDevPAddr = SysCpuPAddrToDevPAddr(eDeviceType, sCpuPAddr); + ui32Page = sDevPAddr.uiAddr >> SGX_MMU_PAGE_SHIFT; + pui8LinAddr += SGX_MMU_PAGE_SIZE; + + snprintf(pszScript, SZ_SCRIPT_SIZE_MAX, "FREE :SGXMEM:PA_%8.8lX%8.8lX\r\n", (IMG_UINT32) hUniqueTag, ui32Page * SGX_MMU_PAGE_SIZE); + PDumpWriteString2(pszScript, PDUMP_FLAGS_CONTINUOUS); + } +} + +IMG_VOID PDumpPDReg (IMG_UINT32 ui32Reg, + IMG_UINT32 ui32Data, + IMG_HANDLE hUniqueTag) +{ + __PDBG_PDUMP_STATE_GET_SCRIPT_STRING(); + + + + snprintf (pszScript, + SZ_SCRIPT_SIZE_MAX, + "WRW :SGXREG:0x%8.8lX :SGXMEM:PA_%8.8lX%8.8lX:0x%8.8lX\r\n", + ui32Reg, + (IMG_UINT32) hUniqueTag, + ui32Data & ~(SGX_MMU_PAGE_SIZE - 1), + ui32Data & (SGX_MMU_PAGE_SIZE - 1)); + PDumpWriteString2(pszScript, PDUMP_FLAGS_CONTINUOUS); +} + +IMG_VOID PDumpPDRegWithFlags(IMG_UINT32 ui32Reg, + IMG_UINT32 ui32Data, + IMG_UINT32 ui32Flags, + IMG_HANDLE hUniqueTag) +{ + __PDBG_PDUMP_STATE_GET_SCRIPT_STRING(); + + + + snprintf (pszScript, + SZ_SCRIPT_SIZE_MAX, + "WRW :SGXREG:0x%8.8lX :SGXMEM:PA_%8.8lX%8.8lX:0x%8.8lX\r\n", + ui32Reg, + (IMG_UINT32) hUniqueTag, + ui32Data & ~(SGX_MMU_PAGE_SIZE - 1), + ui32Data & (SGX_MMU_PAGE_SIZE - 1)); + PDumpWriteString2(pszScript, ui32Flags); +} + +PVRSRV_ERROR PDumpMemPolKM(PVRSRV_KERNEL_MEM_INFO *psMemInfo, + IMG_UINT32 ui32Offset, + IMG_UINT32 ui32Value, + IMG_UINT32 ui32Mask, + PDUMP_POLL_OPERATOR eOperator, + IMG_BOOL bLastFrame, + IMG_BOOL bOverwrite, + IMG_HANDLE hUniqueTag) +{ + #define MEMPOLL_DELAY (1000) + #define MEMPOLL_COUNT (2000000000 / MEMPOLL_DELAY) + + IMG_UINT32 ui32PageOffset; + IMG_DEV_PHYADDR sDevPAddr; + IMG_DEV_VIRTADDR sDevVPageAddr; + IMG_CPU_PHYADDR CpuPAddr; + IMG_UINT32 ui32Flags; + __PDBG_PDUMP_STATE_GET_SCRIPT_AND_FILE_STRING(PVRSRV_ERROR_GENERIC); + + + PVR_ASSERT((ui32Offset + sizeof(IMG_UINT32)) <= psMemInfo->ui32AllocSize); + + if (gsDBGPdumpState.ui32ParamFileNum == 0) + { + snprintf(pszFile, SZ_FILENAME_SIZE_MAX, "%%0%%.prm"); + } + else + { + snprintf(pszFile, SZ_FILENAME_SIZE_MAX, "%%0%%%lu.prm", gsDBGPdumpState.ui32ParamFileNum); + } + + + ui32Flags = 0; + + if (bLastFrame) + { + ui32Flags |= PDUMP_FLAGS_LASTFRAME; + } + + if (bOverwrite) + { + ui32Flags |= PDUMP_FLAGS_RESETLFBUFFER; + } + + + + + CpuPAddr = OSMemHandleToCpuPAddr(psMemInfo->sMemBlk.hOSMemHandle, ui32Offset); + ui32PageOffset = CpuPAddr.uiAddr & (PAGE_SIZE -1); + + + sDevVPageAddr.uiAddr = psMemInfo->sDevVAddr.uiAddr + ui32Offset - ui32PageOffset; + + + BM_GetPhysPageAddr(psMemInfo, sDevVPageAddr, &sDevPAddr); + + + sDevPAddr.uiAddr += ui32PageOffset; + + snprintf(pszScript, + SZ_SCRIPT_SIZE_MAX, + "POL :SGXMEM:PA_%8.8lX%8.8lX:0x%8.8lX 0x%8.8lX 0x%8.8lX %d %d %d\r\n", + (IMG_UINT32) hUniqueTag, + sDevPAddr.uiAddr & ~(SGX_MMU_PAGE_SIZE - 1), + sDevPAddr.uiAddr & (SGX_MMU_PAGE_SIZE - 1), + ui32Value, + ui32Mask, + eOperator, + MEMPOLL_COUNT, + MEMPOLL_DELAY); + PDumpWriteString2(pszScript, ui32Flags); + + return PVRSRV_OK; +} + +PVRSRV_ERROR PDumpMemKM(IMG_PVOID pvAltLinAddr, + PVRSRV_KERNEL_MEM_INFO *psMemInfo, + IMG_UINT32 ui32Offset, + IMG_UINT32 ui32Bytes, + IMG_UINT32 ui32Flags, + IMG_HANDLE hUniqueTag) +{ + IMG_UINT32 ui32PageByteOffset; + IMG_UINT8* pui8DataLinAddr = IMG_NULL; + IMG_DEV_VIRTADDR sDevVPageAddr; + IMG_DEV_VIRTADDR sDevVAddr; + IMG_DEV_PHYADDR sDevPAddr; + IMG_CPU_PHYADDR CpuPAddr; + IMG_UINT32 ui32ParamOutPos; + IMG_UINT32 ui32CurrentOffset; + IMG_UINT32 ui32BytesRemaining; + + __PDBG_PDUMP_STATE_GET_SCRIPT_AND_FILE_STRING(PVRSRV_ERROR_GENERIC); + + + PVR_ASSERT((ui32Offset + ui32Bytes) <= psMemInfo->ui32AllocSize); + + if (ui32Bytes == 0) + { + return PVRSRV_OK; + } + + if(pvAltLinAddr) + { + pui8DataLinAddr = pvAltLinAddr; + } + else if(psMemInfo->pvLinAddrKM) + { + pui8DataLinAddr = (IMG_UINT8 *)psMemInfo->pvLinAddrKM + ui32Offset; + } + + PVR_ASSERT(pui8DataLinAddr); + + ui32ParamOutPos = gpfnDbgDrv->pfnGetStreamOffset(gsDBGPdumpState.psStream[PDUMP_STREAM_PARAM2]); + + + + if(!PDumpWriteILock(gsDBGPdumpState.psStream[PDUMP_STREAM_PARAM2], + pui8DataLinAddr, + ui32Bytes, + ui32Flags)) + { + return PVRSRV_ERROR_GENERIC; + } + + if (gsDBGPdumpState.ui32ParamFileNum == 0) + { + snprintf(pszFile, SZ_FILENAME_SIZE_MAX, "%%0%%.prm"); + } + else + { + snprintf(pszFile, SZ_FILENAME_SIZE_MAX, "%%0%%%lu.prm", gsDBGPdumpState.ui32ParamFileNum); + } + + + + snprintf(pszScript, + SZ_SCRIPT_SIZE_MAX, + "-- LDB :SGXMEM:VA_%8.8lX:0x%8.8lX 0x%8.8lX 0x%8.8lX %s\r\n", + psMemInfo->sDevVAddr.uiAddr, + ui32Offset, + ui32Bytes, + ui32ParamOutPos, + pszFile); + PDumpWriteString2(pszScript, ui32Flags); + + + + + CpuPAddr = OSMemHandleToCpuPAddr(psMemInfo->sMemBlk.hOSMemHandle, ui32Offset); + ui32PageByteOffset = CpuPAddr.uiAddr & (PAGE_SIZE -1); + + + sDevVAddr = psMemInfo->sDevVAddr; + sDevVAddr.uiAddr += ui32Offset; + + ui32BytesRemaining = ui32Bytes; + ui32CurrentOffset = ui32Offset; + + while(ui32BytesRemaining > 0) + { + IMG_UINT32 ui32BlockBytes = MIN(ui32BytesRemaining, PAGE_SIZE); + CpuPAddr = OSMemHandleToCpuPAddr(psMemInfo->sMemBlk.hOSMemHandle, + ui32CurrentOffset); + + sDevVPageAddr.uiAddr = psMemInfo->sDevVAddr.uiAddr + ui32CurrentOffset - ui32PageByteOffset; + + BM_GetPhysPageAddr(psMemInfo, sDevVPageAddr, &sDevPAddr); + + + sDevPAddr.uiAddr += ui32PageByteOffset; + + if(ui32PageByteOffset) + { + ui32BlockBytes = + MIN(ui32BytesRemaining, PAGE_ALIGN(CpuPAddr.uiAddr) - CpuPAddr.uiAddr); + + ui32PageByteOffset = 0; + } + + snprintf(pszScript, + SZ_SCRIPT_SIZE_MAX, + "LDB :SGXMEM:PA_%8.8lX%8.8lX:0x%8.8lX 0x%8.8lX 0x%8.8lX %s\r\n", + (IMG_UINT32) hUniqueTag, + sDevPAddr.uiAddr & ~(SGX_MMU_PAGE_SIZE - 1), + sDevPAddr.uiAddr & (SGX_MMU_PAGE_SIZE - 1), + ui32BlockBytes, + ui32ParamOutPos, + pszFile); + PDumpWriteString2(pszScript, ui32Flags); + + ui32BytesRemaining -= ui32BlockBytes; + ui32CurrentOffset += ui32BlockBytes; + ui32ParamOutPos += ui32BlockBytes; + } + + PVR_ASSERT(ui32BytesRemaining == 0); + + return PVRSRV_OK; +} + +PVRSRV_ERROR PDumpMem2KM(PVRSRV_DEVICE_TYPE eDeviceType, + IMG_CPU_VIRTADDR pvLinAddr, + IMG_UINT32 ui32Bytes, + IMG_UINT32 ui32Flags, + IMG_BOOL bInitialisePages, + IMG_HANDLE hUniqueTag1, + IMG_HANDLE hUniqueTag2) +{ + IMG_UINT32 ui32NumPages; + IMG_UINT32 ui32PageOffset; + IMG_UINT32 ui32BlockBytes; + IMG_UINT8* pui8LinAddr; + IMG_DEV_PHYADDR sDevPAddr; + IMG_CPU_PHYADDR sCpuPAddr; + IMG_UINT32 ui32Offset; + IMG_UINT32 ui32ParamOutPos; + + __PDBG_PDUMP_STATE_GET_SCRIPT_AND_FILE_STRING(PVRSRV_ERROR_GENERIC); + + if (ui32Flags); + + if (!pvLinAddr) + { + return PVRSRV_ERROR_GENERIC; + } + + ui32ParamOutPos = gpfnDbgDrv->pfnGetStreamOffset(gsDBGPdumpState.psStream[PDUMP_STREAM_PARAM2]); + + if (bInitialisePages) + { + + + + if (!PDumpWriteILock(gsDBGPdumpState.psStream[PDUMP_STREAM_PARAM2], + pvLinAddr, + ui32Bytes, + PDUMP_FLAGS_CONTINUOUS)) + { + return PVRSRV_ERROR_GENERIC; + } + + if (gsDBGPdumpState.ui32ParamFileNum == 0) + { + snprintf(pszFile, SZ_FILENAME_SIZE_MAX, "%%0%%.prm"); + } + else + { + snprintf(pszFile, SZ_FILENAME_SIZE_MAX, "%%0%%%lu.prm", gsDBGPdumpState.ui32ParamFileNum); + } + } + + + + + ui32PageOffset = (IMG_UINT32) pvLinAddr & (HOST_PAGESIZE() - 1); + ui32NumPages = (ui32PageOffset + ui32Bytes + HOST_PAGESIZE() - 1) / HOST_PAGESIZE(); + pui8LinAddr = (IMG_UINT8*) pvLinAddr; + + while (ui32NumPages--) + { + sCpuPAddr = OSMapLinToCPUPhys(pui8LinAddr); + sDevPAddr = SysCpuPAddrToDevPAddr(eDeviceType, sCpuPAddr); + + + if (ui32PageOffset + ui32Bytes > HOST_PAGESIZE()) + { + + ui32BlockBytes = HOST_PAGESIZE() - ui32PageOffset; + } + else + { + + ui32BlockBytes = ui32Bytes; + } + + + + if (bInitialisePages) + { + snprintf(pszScript, + SZ_SCRIPT_SIZE_MAX, + "LDB :SGXMEM:PA_%8.8lX%8.8lX:0x%8.8lX 0x%8.8lX 0x%8.8lX %s\r\n", + (IMG_UINT32) hUniqueTag1, + sDevPAddr.uiAddr & ~(SGX_MMU_PAGE_SIZE - 1), + sDevPAddr.uiAddr & (SGX_MMU_PAGE_SIZE - 1), + ui32BlockBytes, + ui32ParamOutPos, + pszFile); + PDumpWriteString2(pszScript, PDUMP_FLAGS_CONTINUOUS); + } + else + { + for (ui32Offset = 0; ui32Offset < ui32BlockBytes; ui32Offset += sizeof(IMG_UINT32)) + { + IMG_UINT32 ui32PTE = *((IMG_UINT32 *) (pui8LinAddr + ui32Offset)); + + if ((ui32PTE & SGX_MMU_PDE_ADDR_MASK) != 0) + { + snprintf(pszScript, + SZ_SCRIPT_SIZE_MAX, + "WRW :SGXMEM:PA_%8.8lX%8.8lX:0x%8.8lX :SGXMEM:PA_%8.8lX%8.8lX:0x%8.8lX\r\n", + (IMG_UINT32) hUniqueTag1, + (sDevPAddr.uiAddr + ui32Offset) & ~(SGX_MMU_PAGE_SIZE - 1), + (sDevPAddr.uiAddr + ui32Offset) & (SGX_MMU_PAGE_SIZE - 1), + (IMG_UINT32) hUniqueTag2, + ui32PTE & SGX_MMU_PDE_ADDR_MASK, + ui32PTE & ~SGX_MMU_PDE_ADDR_MASK); + } + else + { + PVR_ASSERT(!(ui32PTE & SGX_MMU_PTE_VALID)); + snprintf(pszScript, + SZ_SCRIPT_SIZE_MAX, + "WRW :SGXMEM:PA_%8.8lX%8.8lX:0x%8.8lX 0x%8.8lX%8.8lX\r\n", + (IMG_UINT32) hUniqueTag1, + (sDevPAddr.uiAddr + ui32Offset) & ~(SGX_MMU_PAGE_SIZE - 1), + (sDevPAddr.uiAddr + ui32Offset) & (SGX_MMU_PAGE_SIZE - 1), + ui32PTE, + (IMG_UINT32) hUniqueTag2); + } + PDumpWriteString2(pszScript, PDUMP_FLAGS_CONTINUOUS); + } + } + + + + + ui32PageOffset = 0; + + ui32Bytes -= ui32BlockBytes; + + pui8LinAddr += ui32BlockBytes; + + ui32ParamOutPos += ui32BlockBytes; + } + + return PVRSRV_OK; +} + +PVRSRV_ERROR PDumpPDDevPAddrKM(PVRSRV_KERNEL_MEM_INFO *psMemInfo, + IMG_UINT32 ui32Offset, + IMG_DEV_PHYADDR sPDDevPAddr, + IMG_HANDLE hUniqueTag1, + IMG_HANDLE hUniqueTag2) +{ + IMG_UINT32 ui32ParamOutPos; + IMG_CPU_PHYADDR CpuPAddr; + IMG_UINT32 ui32PageByteOffset; + IMG_DEV_VIRTADDR sDevVAddr; + IMG_DEV_VIRTADDR sDevVPageAddr; + IMG_DEV_PHYADDR sDevPAddr; + + __PDBG_PDUMP_STATE_GET_SCRIPT_AND_FILE_STRING(PVRSRV_ERROR_GENERIC); + + ui32ParamOutPos = gpfnDbgDrv->pfnGetStreamOffset(gsDBGPdumpState.psStream[PDUMP_STREAM_PARAM2]); + + if(!PDumpWriteILock(gsDBGPdumpState.psStream[PDUMP_STREAM_PARAM2], + (IMG_UINT8 *)&sPDDevPAddr, + sizeof(IMG_DEV_PHYADDR), + PDUMP_FLAGS_CONTINUOUS)) + { + return PVRSRV_ERROR_GENERIC; + } + + if (gsDBGPdumpState.ui32ParamFileNum == 0) + { + snprintf(pszFile, SZ_FILENAME_SIZE_MAX, "%%0%%.prm"); + } + else + { + snprintf(pszFile, SZ_FILENAME_SIZE_MAX, "%%0%%%lu.prm", gsDBGPdumpState.ui32ParamFileNum); + } + + CpuPAddr = OSMemHandleToCpuPAddr(psMemInfo->sMemBlk.hOSMemHandle, ui32Offset); + ui32PageByteOffset = CpuPAddr.uiAddr & (PAGE_SIZE -1); + + sDevVAddr = psMemInfo->sDevVAddr; + sDevVAddr.uiAddr += ui32Offset; + + sDevVPageAddr.uiAddr = sDevVAddr.uiAddr - ui32PageByteOffset; + BM_GetPhysPageAddr(psMemInfo, sDevVPageAddr, &sDevPAddr); + sDevPAddr.uiAddr += ui32PageByteOffset; + + if ((sPDDevPAddr.uiAddr & SGX_MMU_PDE_ADDR_MASK) != 0) + { + snprintf(pszScript, + SZ_SCRIPT_SIZE_MAX, + "WRW :SGXMEM:PA_%8.8lX%8.8lX:0x%8.8lX :SGXMEM:PA_%8.8lX%8.8lX:0x%8.8lX\r\n", + (IMG_UINT32) hUniqueTag1, + sDevPAddr.uiAddr & ~(SGX_MMU_PAGE_SIZE - 1), + sDevPAddr.uiAddr & (SGX_MMU_PAGE_SIZE - 1), + (IMG_UINT32) hUniqueTag2, + sPDDevPAddr.uiAddr & SGX_MMU_PDE_ADDR_MASK, + sPDDevPAddr.uiAddr & ~SGX_MMU_PDE_ADDR_MASK); + } + else + { + PVR_ASSERT(!(sDevPAddr.uiAddr & SGX_MMU_PTE_VALID)); + snprintf(pszScript, + SZ_SCRIPT_SIZE_MAX, + "WRW :SGXMEM:PA_%8.8lX%8.8lX:0x%8.8lX 0x%8.8lX\r\n", + (IMG_UINT32) hUniqueTag1, + sDevPAddr.uiAddr & ~(SGX_MMU_PAGE_SIZE - 1), + sDevPAddr.uiAddr & (SGX_MMU_PAGE_SIZE - 1), + sPDDevPAddr.uiAddr); + } + PDumpWriteString2(pszScript, PDUMP_FLAGS_CONTINUOUS); + + return PVRSRV_OK; +} + +PVRSRV_ERROR PDumpSetFrameKM(IMG_UINT32 ui32Frame) +{ + IMG_UINT32 ui32Stream; + + for (ui32Stream = 0; ui32Stream < PDUMP_NUM_STREAMS; ui32Stream++) + { + if (gsDBGPdumpState.psStream[ui32Stream]) + { + DbgSetFrame(gsDBGPdumpState.psStream[ui32Stream], ui32Frame); + } + } + + return PVRSRV_OK; +} + +PVRSRV_ERROR PDumpGetFrameKM(IMG_PUINT32 pui32Frame) +{ + *pui32Frame = DbgGetFrame(gsDBGPdumpState.psStream[PDUMP_STREAM_SCRIPT2]); + + return PVRSRV_OK; +} + +PVRSRV_ERROR PDumpCommentKM(IMG_CHAR *pszComment, IMG_UINT32 ui32Flags) +{ + IMG_UINT32 ui32Count = 0; + PVRSRV_ERROR eError; + __PDBG_PDUMP_STATE_GET_MSG_STRING(PVRSRV_ERROR_GENERIC); + + if(ui32Flags & PDUMP_FLAGS_CONTINUOUS) + { + eError = PVRSRV_ERROR_GENERIC; + } + else + { + eError = PVRSRV_ERROR_CMD_NOT_PROCESSED; + } + + if (!PDumpWriteString2("-- ", ui32Flags)) + { + return eError; + } + + + snprintf(pszMsg, SZ_MSG_SIZE_MAX, "%s",pszComment); + + + while ((pszMsg[ui32Count]!=0) && (ui32CountpfnGetStreamOffset(gsDBGPdumpState.psStream[PDUMP_STREAM_PARAM2]); + + if (ui32ParamOutPos + ui32Count > MAX_FILE_SIZE) + { + if ((gsDBGPdumpState.psStream[PDUMP_STREAM_SCRIPT2] && PDumpWriteString2("\r\n-- Splitting pdump output file\r\n\r\n", ui32Flags))) + { + DbgSetMarker(gsDBGPdumpState.psStream[PDUMP_STREAM_PARAM2], ui32ParamOutPos); + gsDBGPdumpState.ui32ParamFileNum++; + } + } + } + + + while (((IMG_UINT32) ui32Count > 0) && (ui32Written != 0xFFFFFFFF)) + { + ui32Written = DbgWrite(psStream, &pui8Data[ui32Off], ui32Count, ui32Flags); + + + + + if (ui32Written == 0) + { + OSReleaseThreadQuanta(); + } + + if (ui32Written != 0xFFFFFFFF) + { + ui32Off += ui32Written; + ui32Count -= ui32Written; + } + } + + if (ui32Written == 0xFFFFFFFF) + { + return IMG_FALSE; + } + + return IMG_TRUE; +} + +static IMG_VOID DbgSetFrame(PDBG_STREAM psStream, IMG_UINT32 ui32Frame) +{ + gpfnDbgDrv->pfnSetFrame(psStream, ui32Frame); +} + + +static IMG_UINT32 DbgGetFrame(PDBG_STREAM psStream) +{ + return gpfnDbgDrv->pfnGetFrame(psStream); +} + +static IMG_VOID DbgSetMarker(PDBG_STREAM psStream, IMG_UINT32 ui32Marker) +{ + gpfnDbgDrv->pfnSetMarker(psStream, ui32Marker); +} + +static IMG_UINT32 DbgWrite(PDBG_STREAM psStream, IMG_UINT8 *pui8Data, IMG_UINT32 ui32BCount, IMG_UINT32 ui32Flags) +{ + IMG_UINT32 ui32BytesWritten; + + if (ui32Flags & PDUMP_FLAGS_CONTINUOUS) + { + + + if ((psStream->ui32CapMode & DEBUG_CAPMODE_FRAMED) && + (psStream->ui32Start == 0xFFFFFFFF) && + (psStream->ui32End == 0xFFFFFFFF) && + psStream->bInitPhaseComplete) + { + ui32BytesWritten = ui32BCount; + } + else + { + ui32BytesWritten = gpfnDbgDrv->pfnDBGDrivWrite2(psStream, pui8Data, ui32BCount, 1); + } + } + else + { + if (ui32Flags & PDUMP_FLAGS_LASTFRAME) + { + IMG_UINT32 ui32DbgFlags; + + ui32DbgFlags = 0; + if (ui32Flags & PDUMP_FLAGS_RESETLFBUFFER) + { + ui32DbgFlags |= WRITELF_FLAGS_RESETBUF; + } + + ui32BytesWritten = gpfnDbgDrv->pfnWriteLF(psStream, pui8Data, ui32BCount, 1, ui32DbgFlags); + } + else + { + ui32BytesWritten = gpfnDbgDrv->pfnWriteBINCM(psStream, pui8Data, ui32BCount, 1); + } + } + + return ui32BytesWritten; +} + +IMG_BOOL PDumpTestNextFrame(IMG_UINT32 ui32CurrentFrame) +{ + IMG_BOOL bFrameDumped; + + + + bFrameDumped = IMG_FALSE; + PDumpSetFrameKM(ui32CurrentFrame + 1); + bFrameDumped = PDumpIsCaptureFrameKM(); + PDumpSetFrameKM(ui32CurrentFrame); + + return bFrameDumped; +} + +IMG_VOID PDump3DSignatureRegisters(IMG_UINT32 ui32DumpFrameNum, + IMG_BOOL bLastFrame, + IMG_UINT32 *pui32Registers, + IMG_UINT32 ui32NumRegisters) +{ + IMG_UINT32 ui32FileOffset, ui32Flags; + IMG_UINT32 i; + + __PDBG_PDUMP_STATE_GET_SCRIPT_AND_FILE_STRING(); + + ui32Flags = bLastFrame ? PDUMP_FLAGS_LASTFRAME : 0; + ui32FileOffset = 0; + + PDUMPCOMMENTWITHFLAGS(ui32Flags, "\r\n-- Dump 3D signature registers\r\n"); + snprintf(pszFile, SZ_FILENAME_SIZE_MAX, "out%lu_3d.sig", ui32DumpFrameNum); + + for (i = 0; i < ui32NumRegisters; i++) + { + PDumpReadRegKM(pszFile, ui32FileOffset, pui32Registers[i], sizeof(IMG_UINT32), ui32Flags); + ui32FileOffset += sizeof(IMG_UINT32); + } +} + +static IMG_VOID PDumpCountRead(IMG_CHAR *pszFileName, + IMG_UINT32 ui32Address, + IMG_UINT32 ui32Size, + IMG_UINT32 *pui32FileOffset, + IMG_BOOL bLastFrame) +{ + __PDBG_PDUMP_STATE_GET_SCRIPT_STRING(); + + snprintf(pszScript, SZ_SCRIPT_SIZE_MAX, "SAB :SGXREG:0x%08lX 0x%08lX %s\r\n", ui32Address, *pui32FileOffset, pszFileName); + PDumpWriteString2(pszScript, bLastFrame ? PDUMP_FLAGS_LASTFRAME : 0); + + *pui32FileOffset += ui32Size; +} + +IMG_VOID PDumpCounterRegisters (IMG_UINT32 ui32DumpFrameNum, + IMG_BOOL bLastFrame, + IMG_UINT32 *pui32Registers, + IMG_UINT32 ui32NumRegisters) +{ + IMG_UINT32 ui32FileOffset; + IMG_UINT32 i; + + __PDBG_PDUMP_STATE_GET_SCRIPT_AND_FILE_STRING(); + + PDUMPCOMMENTWITHFLAGS(bLastFrame ? PDUMP_FLAGS_LASTFRAME : 0, "\r\n-- Dump counter registers\r\n"); + snprintf(pszFile, SZ_FILENAME_SIZE_MAX, "out%lu.perf", ui32DumpFrameNum); + ui32FileOffset = 0; + + for (i = 0; i < ui32NumRegisters; i++) + { + PDumpCountRead(pszFile, pui32Registers[i], sizeof(IMG_UINT32), &ui32FileOffset, bLastFrame); + } +} + +IMG_VOID PDumpTASignatureRegisters (IMG_UINT32 ui32DumpFrameNum, + IMG_UINT32 ui32TAKickCount, + IMG_BOOL bLastFrame, + IMG_UINT32 *pui32Registers, + IMG_UINT32 ui32NumRegisters) +{ + IMG_UINT32 ui32FileOffset, ui32Flags; + IMG_UINT32 i; + + __PDBG_PDUMP_STATE_GET_SCRIPT_AND_FILE_STRING(); + + ui32Flags = bLastFrame ? PDUMP_FLAGS_LASTFRAME : 0; + PDUMPCOMMENTWITHFLAGS(ui32Flags, "\r\n-- Dump TA signature registers\r\n"); + snprintf(pszFile, SZ_FILENAME_SIZE_MAX, "out%lu_ta.sig", ui32DumpFrameNum); + + ui32FileOffset = ui32TAKickCount * ui32NumRegisters * sizeof(IMG_UINT32); + + for (i = 0; i < ui32NumRegisters; i++) + { + PDumpReadRegKM(pszFile, ui32FileOffset, pui32Registers[i], sizeof(IMG_UINT32), ui32Flags); + ui32FileOffset += sizeof(IMG_UINT32); + } +} + +IMG_VOID PDumpRegRead(const IMG_UINT32 ui32RegOffset, IMG_UINT32 ui32Flags) +{ + __PDBG_PDUMP_STATE_GET_SCRIPT_STRING(); + + snprintf(pszScript, SZ_SCRIPT_SIZE_MAX, "RDW :SGXREG:0x%lX\r\n", ui32RegOffset); + PDumpWriteString2(pszScript, ui32Flags); +} + +IMG_VOID PDumpCycleCountRegRead(const IMG_UINT32 ui32RegOffset, IMG_BOOL bLastFrame) +{ + __PDBG_PDUMP_STATE_GET_SCRIPT_STRING(); + + snprintf(pszScript, SZ_SCRIPT_SIZE_MAX, "RDW :SGXREG:0x%lX\r\n", ui32RegOffset); + PDumpWriteString2(pszScript, bLastFrame ? PDUMP_FLAGS_LASTFRAME : 0); +} + + +IMG_VOID PDumpHWPerfCBKM (IMG_CHAR *pszFileName, + IMG_UINT32 ui32FileOffset, + IMG_DEV_VIRTADDR sDevBaseAddr, + IMG_UINT32 ui32Size, + IMG_UINT32 ui32PDumpFlags) +{ + __PDBG_PDUMP_STATE_GET_SCRIPT_STRING(); + PDUMPCOMMENTWITHFLAGS(ui32PDumpFlags, "\r\n-- Dump Hardware Performance Circular Buffer\r\n"); + + snprintf(pszScript, + SZ_SCRIPT_SIZE_MAX, +#if defined(SGX_FEATURE_MULTIPLE_MEM_CONTEXTS) + "SAB :SGXMEM:v%x:0x%08lX 0x%08lX 0x%08lX %s.bin\r\n", + PDUMP_DATAMASTER_PIXEL, +#else + "SAB :SGXMEM:v:0x%08lX 0x%08lX 0x%08lX %s.bin\r\n", +#endif + sDevBaseAddr.uiAddr, + ui32Size, + ui32FileOffset, + pszFileName); + + PDumpWriteString2( pszScript, ui32PDumpFlags); +} + + +IMG_VOID PDumpCBP(PPVRSRV_KERNEL_MEM_INFO psROffMemInfo, + IMG_UINT32 ui32ROffOffset, + IMG_UINT32 ui32WPosVal, + IMG_UINT32 ui32PacketSize, + IMG_UINT32 ui32BufferSize, + IMG_UINT32 ui32Flags, + IMG_HANDLE hUniqueTag) +{ + IMG_UINT32 ui32PageOffset; + IMG_DEV_VIRTADDR sDevVAddr; + IMG_DEV_PHYADDR sDevPAddr; + IMG_DEV_VIRTADDR sDevVPageAddr; + IMG_CPU_PHYADDR CpuPAddr; + + __PDBG_PDUMP_STATE_GET_SCRIPT_STRING(); + + + PVR_ASSERT((ui32ROffOffset + sizeof(IMG_UINT32)) <= psROffMemInfo->ui32AllocSize); + + sDevVAddr = psROffMemInfo->sDevVAddr; + + + sDevVAddr.uiAddr += ui32ROffOffset; + + + + + CpuPAddr = OSMemHandleToCpuPAddr(psROffMemInfo->sMemBlk.hOSMemHandle, ui32ROffOffset); + ui32PageOffset = CpuPAddr.uiAddr & (PAGE_SIZE -1); + + + sDevVPageAddr.uiAddr = sDevVAddr.uiAddr - ui32PageOffset; + + + BM_GetPhysPageAddr(psROffMemInfo, sDevVPageAddr, &sDevPAddr); + + + sDevPAddr.uiAddr += ui32PageOffset; + + snprintf(pszScript, + SZ_SCRIPT_SIZE_MAX, + "CBP :SGXMEM:PA_%8.8lX%8.8lX:0x%8.8lX 0x%8.8lX 0x%8.8lX 0x%8.8lX\r\n", + (IMG_UINT32) hUniqueTag, + sDevPAddr.uiAddr & ~(SGX_MMU_PAGE_SIZE - 1), + sDevPAddr.uiAddr & (SGX_MMU_PAGE_SIZE - 1), + ui32WPosVal, + ui32PacketSize, + ui32BufferSize); + PDumpWriteString2(pszScript, ui32Flags); +} + + +IMG_VOID PDumpIDLWithFlags(IMG_UINT32 ui32Clocks, IMG_UINT32 ui32Flags) +{ + __PDBG_PDUMP_STATE_GET_SCRIPT_STRING(); + + sprintf(pszScript, "IDL %lu\r\n", ui32Clocks); + PDumpWriteString2(pszScript, ui32Flags); +} + + +IMG_VOID PDumpIDL(IMG_UINT32 ui32Clocks) +{ + PDumpIDLWithFlags(ui32Clocks, PDUMP_FLAGS_CONTINUOUS); +} + + +IMG_VOID PDumpSuspendKM(IMG_VOID) +{ + atomic_inc(&gsPDumpSuspended); +} + +IMG_VOID PDumpResumeKM(IMG_VOID) +{ + atomic_dec(&gsPDumpSuspended); +} + +#endif +#endif diff --git a/services4/srvkm/env/linux/private_data.h b/services4/srvkm/env/linux/private_data.h new file mode 100644 index 0000000..9629a63 --- /dev/null +++ b/services4/srvkm/env/linux/private_data.h @@ -0,0 +1,47 @@ +/********************************************************************** + * + * Copyright(c) 2008 Imagination Technologies Ltd. All rights reserved. + * + * This program is free software; you can redistribute it and/or modify it + * under the terms and conditions of the GNU General Public License, + * version 2, as published by the Free Software Foundation. + * + * This program is distributed in the hope it will be useful but, except + * as otherwise stated in writing, without any warranty; without even the + * implied warranty of merchantability or fitness for a particular purpose. + * See the GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License along with + * this program; if not, write to the Free Software Foundation, Inc., + * 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA. + * + * The full GNU General Public License is included in this distribution in + * the file called "COPYING". + * + * Contact Information: + * Imagination Technologies Ltd. + * Home Park Estate, Kings Langley, Herts, WD4 8LZ, UK + * + ******************************************************************************/ + +#ifndef __INCLUDED_PRIVATE_DATA_H_ +#define __INCLUDED_PRIVATE_DATA_H_ + +typedef struct +{ + + IMG_UINT32 ui32OpenPID; + +#if defined(PVR_SECURE_FD_EXPORT) + + IMG_HANDLE hKernelMemInfo; +#endif + + + + IMG_HANDLE hBlockAlloc; +} +PVRSRV_FILE_PRIVATE_DATA; + +#endif + diff --git a/services4/srvkm/env/linux/proc.c b/services4/srvkm/env/linux/proc.c new file mode 100644 index 0000000..bc8fd00 --- /dev/null +++ b/services4/srvkm/env/linux/proc.c @@ -0,0 +1,477 @@ +/********************************************************************** + * + * Copyright(c) 2008 Imagination Technologies Ltd. All rights reserved. + * + * This program is free software; you can redistribute it and/or modify it + * under the terms and conditions of the GNU General Public License, + * version 2, as published by the Free Software Foundation. + * + * This program is distributed in the hope it will be useful but, except + * as otherwise stated in writing, without any warranty; without even the + * implied warranty of merchantability or fitness for a particular purpose. + * See the GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License along with + * this program; if not, write to the Free Software Foundation, Inc., + * 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA. + * + * The full GNU General Public License is included in this distribution in + * the file called "COPYING". + * + * Contact Information: + * Imagination Technologies Ltd. + * Home Park Estate, Kings Langley, Herts, WD4 8LZ, UK + * + ******************************************************************************/ + +#ifndef AUTOCONF_INCLUDED + #include +#endif + +#include +#include +#include +#include +#include + +#include "services_headers.h" + +#include "queue.h" +#include "resman.h" +#include "pvrmmap.h" +#include "pvr_debug.h" +#include "pvrversion.h" +#include "proc.h" +#include "perproc.h" +#include "env_perproc.h" +#include "linkage.h" + +static struct proc_dir_entry * dir; + +static off_t procDumpSysNodes(IMG_CHAR *buf, size_t size, off_t off); +static off_t procDumpVersion(IMG_CHAR *buf, size_t size, off_t off); + +static const IMG_CHAR PVRProcDirRoot[] = "pvr"; + +off_t printAppend(IMG_CHAR * buffer, size_t size, off_t off, const IMG_CHAR * format, ...) +{ + IMG_INT n; + IMG_INT space = size - off; + va_list ap; + + PVR_ASSERT(space >= 0); + + va_start (ap, format); + + n = vsnprintf (buffer+off, space, format, ap); + + va_end (ap); + + if (n >= space || n < 0) + { + + buffer[size - 1] = 0; + return size - 1; + } + else + { + return off + n; + } +} + + +static IMG_INT pvr_read_proc(IMG_CHAR *page, IMG_CHAR **start, off_t off, + IMG_INT count, IMG_INT *eof, IMG_VOID *data) +{ + pvr_read_proc_t *pprn = data; + + off_t len = pprn (page, count, off); + + if (len == END_OF_FILE) + { + len = 0; + *eof = 1; + } + else if (!len) + { + *start = (IMG_CHAR *) 0; + } + else + { + *start = (IMG_CHAR *) 1; + } + + return len; +} + + +static IMG_INT CreateProcEntryInDir(struct proc_dir_entry *pdir, const IMG_CHAR * name, read_proc_t rhandler, write_proc_t whandler, IMG_VOID *data) +{ + struct proc_dir_entry * file; + mode_t mode; + + if (!pdir) + { + PVR_DPF((PVR_DBG_ERROR, "CreateProcEntryInDir: parent directory doesn't exist")); + + return -ENOMEM; + } + + mode = S_IFREG; + + if (rhandler) + { + mode |= S_IRUGO; + } + + if (whandler) + { + mode |= S_IWUSR; + } + + file = create_proc_entry(name, mode, pdir); + + if (file) + { +#if (LINUX_VERSION_CODE < KERNEL_VERSION(2,6,30)) + file->owner = THIS_MODULE; +#endif + file->read_proc = rhandler; + file->write_proc = whandler; + file->data = data; + + PVR_DPF((PVR_DBG_MESSAGE, "Created proc entry %s in %s", name, pdir->name)); + + return 0; + } + + PVR_DPF((PVR_DBG_ERROR, "CreateProcEntry: cannot create proc entry %s in %s", name, pdir->name)); + + return -ENOMEM; +} + + +IMG_INT CreateProcEntry(const IMG_CHAR * name, read_proc_t rhandler, write_proc_t whandler, IMG_VOID *data) +{ + return CreateProcEntryInDir(dir, name, rhandler, whandler, data); +} + + +IMG_INT CreatePerProcessProcEntry(const IMG_CHAR * name, read_proc_t rhandler, write_proc_t whandler, IMG_VOID *data) +{ + PVRSRV_ENV_PER_PROCESS_DATA *psPerProc; + IMG_UINT32 ui32PID; + + if (!dir) + { + PVR_DPF((PVR_DBG_ERROR, "CreatePerProcessProcEntries: /proc/%s doesn't exist", PVRProcDirRoot)); + + return -ENOMEM; + } + + ui32PID = OSGetCurrentProcessIDKM(); + + psPerProc = PVRSRVPerProcessPrivateData(ui32PID); + if (!psPerProc) + { + PVR_DPF((PVR_DBG_ERROR, "CreatePerProcessProcEntries: no per process data")); + + return -ENOMEM; + } + + if (!psPerProc->psProcDir) + { + IMG_CHAR dirname[16]; + IMG_INT ret; + + ret = snprintf(dirname, sizeof(dirname), "%lu", ui32PID); + + if (ret <=0 || ret >= sizeof(dirname)) + { + PVR_DPF((PVR_DBG_ERROR, "CreatePerProcessProcEntries: couldn't generate per process proc directory name \"%u\"", ui32PID)); + + return -ENOMEM; + } + else + { + psPerProc->psProcDir = proc_mkdir(dirname, dir); + if (!psPerProc->psProcDir) + { + PVR_DPF((PVR_DBG_ERROR, "CreatePerProcessProcEntries: couldn't create per process proc directory /proc/%s/%u", PVRProcDirRoot, ui32PID)); + + return -ENOMEM; + } + } + } + + return CreateProcEntryInDir(psPerProc->psProcDir, name, rhandler, whandler, data); +} + + +IMG_INT CreateProcReadEntry(const IMG_CHAR * name, pvr_read_proc_t handler) +{ + struct proc_dir_entry * file; + + if (!dir) + { + PVR_DPF((PVR_DBG_ERROR, "CreateProcReadEntry: cannot make proc entry /proc/%s/%s: no parent", PVRProcDirRoot, name)); + + return -ENOMEM; + } + + file = create_proc_read_entry (name, S_IFREG | S_IRUGO, dir, pvr_read_proc, (IMG_VOID *)handler); + + if (file) + { +#if (LINUX_VERSION_CODE < KERNEL_VERSION(2,6,30)) + file->owner = THIS_MODULE; +#endif + return 0; + } + + PVR_DPF((PVR_DBG_ERROR, "CreateProcReadEntry: cannot make proc entry /proc/%s/%s: no memory", PVRProcDirRoot, name)); + + return -ENOMEM; +} + + +IMG_INT CreateProcEntries(IMG_VOID) +{ + dir = proc_mkdir (PVRProcDirRoot, NULL); + + if (!dir) + { + PVR_DPF((PVR_DBG_ERROR, "CreateProcEntries: cannot make /proc/%s directory", PVRProcDirRoot)); + + return -ENOMEM; + } + + if (CreateProcReadEntry("queue", QueuePrintQueues) || + CreateProcReadEntry("version", procDumpVersion) || + CreateProcReadEntry("nodes", procDumpSysNodes)) + { + PVR_DPF((PVR_DBG_ERROR, "CreateProcEntries: couldn't make /proc/%s files", PVRProcDirRoot)); + + return -ENOMEM; + } + +#ifdef DEBUG + if (CreateProcEntry ("debug_level", PVRDebugProcGetLevel, PVRDebugProcSetLevel, 0)) + { + PVR_DPF((PVR_DBG_ERROR, "CreateProcEntries: couldn't make /proc/%s/debug_level", PVRProcDirRoot)); + + return -ENOMEM; + } + +#ifdef PVR_MANUAL_POWER_CONTROL + if (CreateProcEntry("power_control", PVRProcGetPowerLevel, PVRProcSetPowerLevel, 0)) + { + PVR_DPF((PVR_DBG_ERROR, "CreateProcEntries: couldn't make /proc/%s/power_control", PVRProcDirRoot)); + + return -ENOMEM; + } +#endif +#endif + + return 0; +} + + +IMG_VOID RemoveProcEntry(const IMG_CHAR *name) +{ + if (dir) + { + remove_proc_entry(name, dir); + PVR_DPF((PVR_DBG_MESSAGE, "Removing /proc/%s/%s", PVRProcDirRoot, name)); + } +} + + +IMG_VOID RemovePerProcessProcEntry(const IMG_CHAR *name) +{ + PVRSRV_ENV_PER_PROCESS_DATA *psPerProc = PVRSRVFindPerProcessPrivateData(); + + if (!psPerProc) + { + PVR_DPF((PVR_DBG_ERROR, "CreatePerProcessProcEntries: can't remove %s, no per process data", name)); + return; + } + + if (psPerProc->psProcDir) + { + remove_proc_entry(name, psPerProc->psProcDir); + + PVR_DPF((PVR_DBG_MESSAGE, "Removing proc entry %s from %s", name, psPerProc->psProcDir->name)); + } +} + + +IMG_VOID RemovePerProcessProcDir(PVRSRV_ENV_PER_PROCESS_DATA *psPerProc) +{ + if (psPerProc->psProcDir) + { + while (psPerProc->psProcDir->subdir) + { + PVR_DPF((PVR_DBG_WARNING, "Belatedly removing /proc/%s/%s/%s", PVRProcDirRoot, psPerProc->psProcDir->name, psPerProc->psProcDir->subdir->name)); + + RemoveProcEntry(psPerProc->psProcDir->subdir->name); + } + RemoveProcEntry(psPerProc->psProcDir->name); + } +} + +IMG_VOID RemoveProcEntries(IMG_VOID) +{ +#ifdef DEBUG + RemoveProcEntry("debug_level"); +#ifdef PVR_MANUAL_POWER_CONTROL + RemoveProcEntry("power_control"); +#endif +#endif + RemoveProcEntry("queue"); + RemoveProcEntry("nodes"); + RemoveProcEntry("version"); + + while (dir->subdir) + { + PVR_DPF((PVR_DBG_WARNING, "Belatedly removing /proc/%s/%s", PVRProcDirRoot, dir->subdir->name)); + + RemoveProcEntry(dir->subdir->name); + } + + remove_proc_entry(PVRProcDirRoot, NULL); +} + + +static off_t procDumpVersion(IMG_CHAR *buf, size_t size, off_t off) +{ + SYS_DATA *psSysData; + + if (off == 0) + { + return printAppend(buf, size, 0, + "Version %s (%s) %s\n", + PVRVERSION_STRING, + PVR_BUILD_TYPE, PVR_BUILD_DIR); + } + + if (SysAcquireData(&psSysData) != PVRSRV_OK) + { + return PVRSRV_ERROR_GENERIC; + } + + if (off == 1) + { + IMG_CHAR *pszSystemVersionString = "None"; + + if(psSysData->pszVersionString) + { + pszSystemVersionString = psSysData->pszVersionString; + } + + if(strlen(pszSystemVersionString) + + strlen("System Version String: \n") + + 1 > size) + { + return 0; + } + return printAppend(buf, size, 0, + "System Version String: %s\n", + pszSystemVersionString); + } + + return END_OF_FILE; +} + + +static const IMG_CHAR *deviceTypeToString(PVRSRV_DEVICE_TYPE deviceType) +{ + switch (deviceType) + { + default: + { + static IMG_CHAR text[10]; + + sprintf(text, "?%x", deviceType); + + return text; + } + } +} + + +static const IMG_CHAR *deviceClassToString(PVRSRV_DEVICE_CLASS deviceClass) +{ + switch (deviceClass) + { + case PVRSRV_DEVICE_CLASS_3D: + { + return "3D"; + } + case PVRSRV_DEVICE_CLASS_DISPLAY: + { + return "display"; + } + case PVRSRV_DEVICE_CLASS_BUFFER: + { + return "buffer"; + } + default: + { + static IMG_CHAR text[10]; + + sprintf(text, "?%x", deviceClass); + return text; + } + } +} + +static +off_t procDumpSysNodes(IMG_CHAR *buf, size_t size, off_t off) +{ + SYS_DATA *psSysData; + PVRSRV_DEVICE_NODE *psDevNode; + off_t len; + + + if (size < 80) + { + return 0; + } + + if (off == 0) + { + return printAppend(buf, size, 0, + "Registered nodes\n" + "Addr Type Class Index Ref pvDev Size Res\n"); + } + + if (SysAcquireData(&psSysData) != PVRSRV_OK) + { + return PVRSRV_ERROR_GENERIC; + } + + + for(psDevNode = psSysData->psDeviceNodeList; + --off && psDevNode; + psDevNode = psDevNode->psNext) + ; + + if (!psDevNode) + { + return END_OF_FILE; + } + + len = printAppend(buf, size, 0, + "%p %-8s %-8s %4d %2lu %p %3lu %p\n", + psDevNode, + deviceTypeToString(psDevNode->sDevId.eDeviceType), + deviceClassToString(psDevNode->sDevId.eDeviceClass), + psDevNode->sDevId.eDeviceClass, + psDevNode->ui32RefCount, + psDevNode->pvDevice, + psDevNode->ui32pvDeviceSize, + psDevNode->hResManContext); + return (len); +} + diff --git a/services4/srvkm/env/linux/proc.h b/services4/srvkm/env/linux/proc.h new file mode 100644 index 0000000..dbb5a7a --- /dev/null +++ b/services4/srvkm/env/linux/proc.h @@ -0,0 +1,54 @@ +/********************************************************************** + * + * Copyright(c) 2008 Imagination Technologies Ltd. All rights reserved. + * + * This program is free software; you can redistribute it and/or modify it + * under the terms and conditions of the GNU General Public License, + * version 2, as published by the Free Software Foundation. + * + * This program is distributed in the hope it will be useful but, except + * as otherwise stated in writing, without any warranty; without even the + * implied warranty of merchantability or fitness for a particular purpose. + * See the GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License along with + * this program; if not, write to the Free Software Foundation, Inc., + * 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA. + * + * The full GNU General Public License is included in this distribution in + * the file called "COPYING". + * + * Contact Information: + * Imagination Technologies Ltd. + * Home Park Estate, Kings Langley, Herts, WD4 8LZ, UK + * + ******************************************************************************/ + +#ifndef __SERVICES_PROC_H__ +#define __SERVICES_PROC_H__ + +#include +#include + +#define END_OF_FILE (off_t) -1 + +typedef off_t (pvr_read_proc_t)(IMG_CHAR *, size_t, off_t); + +off_t printAppend(IMG_CHAR * buffer, size_t size, off_t off, const IMG_CHAR * format, ...) + __attribute__((format(printf, 4, 5))); + +IMG_INT CreateProcEntries(IMG_VOID); + +IMG_INT CreateProcReadEntry (const IMG_CHAR * name, pvr_read_proc_t handler); + +IMG_INT CreateProcEntry(const IMG_CHAR * name, read_proc_t rhandler, write_proc_t whandler, IMG_VOID *data); + +IMG_INT CreatePerProcessProcEntry(const IMG_CHAR * name, read_proc_t rhandler, write_proc_t whandler, IMG_VOID *data); + +IMG_VOID RemoveProcEntry(const IMG_CHAR * name); + +IMG_VOID RemovePerProcessProcEntry(const IMG_CHAR * name); + +IMG_VOID RemoveProcEntries(IMG_VOID); + +#endif diff --git a/services4/srvkm/env/linux/pvr_bridge_k.c b/services4/srvkm/env/linux/pvr_bridge_k.c new file mode 100644 index 0000000..c211023 --- /dev/null +++ b/services4/srvkm/env/linux/pvr_bridge_k.c @@ -0,0 +1,440 @@ +/********************************************************************** + * + * Copyright(c) 2008 Imagination Technologies Ltd. All rights reserved. + * + * This program is free software; you can redistribute it and/or modify it + * under the terms and conditions of the GNU General Public License, + * version 2, as published by the Free Software Foundation. + * + * This program is distributed in the hope it will be useful but, except + * as otherwise stated in writing, without any warranty; without even the + * implied warranty of merchantability or fitness for a particular purpose. + * See the GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License along with + * this program; if not, write to the Free Software Foundation, Inc., + * 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA. + * + * The full GNU General Public License is included in this distribution in + * the file called "COPYING". + * + * Contact Information: + * Imagination Technologies Ltd. + * Home Park Estate, Kings Langley, Herts, WD4 8LZ, UK + * + ******************************************************************************/ + +#include "img_defs.h" +#include "services.h" +#include "pvr_bridge.h" +#include "perproc.h" +#include "mutex.h" +#include "syscommon.h" +#include "pvr_debug.h" +#include "proc.h" +#include "private_data.h" +#include "linkage.h" + +#if defined(SUPPORT_VGX) +#include "vgx_bridge.h" +#endif + +#if defined(SUPPORT_SGX) +#include "sgx_bridge.h" +#endif + +#include "bridged_pvr_bridge.h" + +#ifdef MODULE_TEST +#include "pvr_test_bridge.h" +#include "kern_test.h" +#endif + + +#if defined(DEBUG_BRIDGE_KM) +static off_t printLinuxBridgeStats(IMG_CHAR * buffer, size_t size, off_t off); +#endif + +extern PVRSRV_LINUX_MUTEX gPVRSRVLock; + + +PVRSRV_ERROR +LinuxBridgeInit(IMG_VOID) +{ +#if defined(DEBUG_BRIDGE_KM) + { + IMG_INT iStatus; + iStatus = CreateProcReadEntry("bridge_stats", printLinuxBridgeStats); + if(iStatus!=0) + { + return PVRSRV_ERROR_OUT_OF_MEMORY; + } + } +#endif + return CommonBridgeInit(); +} + +IMG_VOID +LinuxBridgeDeInit(IMG_VOID) +{ +#if defined(DEBUG_BRIDGE_KM) + RemoveProcEntry("bridge_stats"); +#endif +} + +#if defined(DEBUG_BRIDGE_KM) +static off_t +printLinuxBridgeStats(IMG_CHAR * buffer, size_t count, off_t off) +{ + PVRSRV_BRIDGE_DISPATCH_TABLE_ENTRY *psEntry; + off_t Ret; + + LinuxLockMutex(&gPVRSRVLock); + + if(!off) + { + if(count < 500) + { + Ret = 0; + goto unlock_and_return; + } + Ret = printAppend(buffer, count, 0, + "Total ioctl call count = %lu\n" + "Total number of bytes copied via copy_from_user = %lu\n" + "Total number of bytes copied via copy_to_user = %lu\n" + "Total number of bytes copied via copy_*_user = %lu\n\n" + "%-45s | %-40s | %10s | %20s | %10s\n", + g_BridgeGlobalStats.ui32IOCTLCount, + g_BridgeGlobalStats.ui32TotalCopyFromUserBytes, + g_BridgeGlobalStats.ui32TotalCopyToUserBytes, + g_BridgeGlobalStats.ui32TotalCopyFromUserBytes+g_BridgeGlobalStats.ui32TotalCopyToUserBytes, + "Bridge Name", + "Wrapper Function", + "Call Count", + "copy_from_user Bytes", + "copy_to_user Bytes" + ); + goto unlock_and_return; + } + + if(off > BRIDGE_DISPATCH_TABLE_ENTRY_COUNT) + { + Ret = END_OF_FILE; + goto unlock_and_return; + } + + if(count < 300) + { + Ret = 0; + goto unlock_and_return; + } + + psEntry = &g_BridgeDispatchTable[off-1]; + Ret = printAppend(buffer, count, 0, + "%-45s %-40s %-10lu %-20lu %-10lu\n", + psEntry->pszIOCName, + psEntry->pszFunctionName, + psEntry->ui32CallCount, + psEntry->ui32CopyFromUserTotalBytes, + psEntry->ui32CopyToUserTotalBytes); + +unlock_and_return: + LinuxUnLockMutex(&gPVRSRVLock); + return Ret; +} +#endif + + + +IMG_INT32 +PVRSRV_BridgeDispatchKM(struct file *pFile, IMG_UINT cmd, IMG_UINT32 arg) +{ + IMG_UINT32 ui32BridgeID = PVRSRV_GET_BRIDGE_ID(cmd); + PVRSRV_BRIDGE_PACKAGE *psBridgePackageUM = (PVRSRV_BRIDGE_PACKAGE *)arg; + PVRSRV_BRIDGE_PACKAGE sBridgePackageKM; + IMG_UINT32 ui32PID = OSGetCurrentProcessIDKM(); + PVRSRV_PER_PROCESS_DATA *psPerProc; + IMG_INT err = -EFAULT; + + LinuxLockMutex(&gPVRSRVLock); + + + if(!OSAccessOK(PVR_VERIFY_WRITE, + psBridgePackageUM, + sizeof(PVRSRV_BRIDGE_PACKAGE))) + { + PVR_DPF((PVR_DBG_ERROR, "%s: Received invalid pointer to function arguments", + __FUNCTION__)); + + goto unlock_and_return; + } + + + if(OSCopyFromUser(IMG_NULL, + &sBridgePackageKM, + psBridgePackageUM, + sizeof(PVRSRV_BRIDGE_PACKAGE)) + != PVRSRV_OK) + { + goto unlock_and_return; + } + +#ifdef MODULE_TEST + switch (cmd) + { + case PVRSRV_BRIDGE_SERVICES_TEST_MEM1: + { + PVRSRV_ERROR eError = MemTest1(); + if (sBridgePackageKM.ui32OutBufferSize == sizeof(PVRSRV_BRIDGE_RETURN)) + { + PVRSRV_BRIDGE_RETURN* pReturn = (PVRSRV_BRIDGE_RETURN*)sBridgePackageKM.pvParamOut ; + pReturn->eError = eError; + } + } + err = 0; + goto unlock_and_return; + case PVRSRV_BRIDGE_SERVICES_TEST_MEM2: + { + PVRSRV_ERROR eError = MemTest2(); + if (sBridgePackageKM.ui32OutBufferSize == sizeof(PVRSRV_BRIDGE_RETURN)) + { + PVRSRV_BRIDGE_RETURN* pReturn = (PVRSRV_BRIDGE_RETURN*)sBridgePackageKM.pvParamOut ; + pReturn->eError = eError; + } + } + err = 0; + goto unlock_and_return; + + case PVRSRV_BRIDGE_SERVICES_TEST_RESOURCE: + { + PVRSRV_ERROR eError = ResourceTest(); + if (sBridgePackageKM.ui32OutBufferSize == sizeof(PVRSRV_BRIDGE_RETURN)) + { + PVRSRV_BRIDGE_RETURN* pReturn = (PVRSRV_BRIDGE_RETURN*)sBridgePackageKM.pvParamOut ; + pReturn->eError = eError; + } + } + err = 0; + goto unlock_and_return; + + case PVRSRV_BRIDGE_SERVICES_TEST_EVENTOBJECT: + { + PVRSRV_ERROR eError = EventObjectTest(); + if (sBridgePackageKM.ui32OutBufferSize == sizeof(PVRSRV_BRIDGE_RETURN)) + { + PVRSRV_BRIDGE_RETURN* pReturn = (PVRSRV_BRIDGE_RETURN*)sBridgePackageKM.pvParamOut ; + pReturn->eError = eError; + } + } + err = 0; + goto unlock_and_return; + + case PVRSRV_BRIDGE_SERVICES_TEST_MEMMAPPING: + { + PVRSRV_ERROR eError = MemMappingTest(); + if (sBridgePackageKM.ui32OutBufferSize == sizeof(PVRSRV_BRIDGE_RETURN)) + { + PVRSRV_BRIDGE_RETURN* pReturn = (PVRSRV_BRIDGE_RETURN*)sBridgePackageKM.pvParamOut ; + pReturn->eError = eError; + } + } + err = 0; + goto unlock_and_return; + + case PVRSRV_BRIDGE_SERVICES_TEST_PROCESSID: + { + PVRSRV_ERROR eError = ProcessIDTest(); + if (sBridgePackageKM.ui32OutBufferSize == sizeof(PVRSRV_BRIDGE_RETURN)) + { + PVRSRV_BRIDGE_RETURN* pReturn = (PVRSRV_BRIDGE_RETURN*)sBridgePackageKM.pvParamOut ; + pReturn->eError = eError; + } + } + err = 0; + goto unlock_and_return; + + case PVRSRV_BRIDGE_SERVICES_TEST_CLOCKUSWAITUS: + { + PVRSRV_ERROR eError = ClockusWaitusTest(); + if (sBridgePackageKM.ui32OutBufferSize == sizeof(PVRSRV_BRIDGE_RETURN)) + { + PVRSRV_BRIDGE_RETURN* pReturn = (PVRSRV_BRIDGE_RETURN*)sBridgePackageKM.pvParamOut ; + pReturn->eError = eError; + } + } + err = 0; + goto unlock_and_return; + + case PVRSRV_BRIDGE_SERVICES_TEST_TIMER: + { + PVRSRV_ERROR eError = TimerTest(); + if (sBridgePackageKM.ui32OutBufferSize == sizeof(PVRSRV_BRIDGE_RETURN)) + { + PVRSRV_BRIDGE_RETURN* pReturn = (PVRSRV_BRIDGE_RETURN*)sBridgePackageKM.pvParamOut ; + pReturn->eError = eError; + } + } + err = 0; + goto unlock_and_return; + + case PVRSRV_BRIDGE_SERVICES_TEST_PRIVSRV: + { + PVRSRV_ERROR eError = PrivSrvTest(); + if (sBridgePackageKM.ui32OutBufferSize == sizeof(PVRSRV_BRIDGE_RETURN)) + { + PVRSRV_BRIDGE_RETURN* pReturn = (PVRSRV_BRIDGE_RETURN*)sBridgePackageKM.pvParamOut ; + pReturn->eError = eError; + } + } + err = 0; + goto unlock_and_return; + case PVRSRV_BRIDGE_SERVICES_TEST_COPYDATA: + { + IMG_UINT32 ui32PID; + PVRSRV_PER_PROCESS_DATA *psPerProc; + PVRSRV_ERROR eError; + + ui32PID = OSGetCurrentProcessIDKM(); + + PVRSRVTrace("PVRSRV_BRIDGE_SERVICES_TEST_COPYDATA %d", ui32PID); + + psPerProc = PVRSRVPerProcessData(ui32PID); + + eError = CopyDataTest(sBridgePackageKM.pvParamIn, sBridgePackageKM.pvParamOut, psPerProc); + + *(PVRSRV_ERROR*)sBridgePackageKM.pvParamOut = eError; + err = 0; + goto unlock_and_return; + } + + + case PVRSRV_BRIDGE_SERVICES_TEST_POWERMGMT: + { + PVRSRV_ERROR eError = PowerMgmtTest(); + if (sBridgePackageKM.ui32OutBufferSize == sizeof(PVRSRV_BRIDGE_RETURN)) + { + PVRSRV_BRIDGE_RETURN* pReturn = (PVRSRV_BRIDGE_RETURN*)sBridgePackageKM.pvParamOut ; + pReturn->eError = eError; + } + } + err = 0; + goto unlock_and_return; + + } +#endif + + if(ui32BridgeID != PVRSRV_GET_BRIDGE_ID(PVRSRV_BRIDGE_CONNECT_SERVICES)) + { + PVRSRV_ERROR eError; + + eError = PVRSRVLookupHandle(KERNEL_HANDLE_BASE, + (IMG_PVOID *)&psPerProc, + sBridgePackageKM.hKernelServices, + PVRSRV_HANDLE_TYPE_PERPROC_DATA); + if(eError != PVRSRV_OK) + { + PVR_DPF((PVR_DBG_ERROR, "%s: Invalid kernel services handle (%d)", + __FUNCTION__, eError)); + goto unlock_and_return; + } + + if(psPerProc->ui32PID != ui32PID) + { + PVR_DPF((PVR_DBG_ERROR, "%s: Process %d tried to access data " + "belonging to process %d", __FUNCTION__, ui32PID, + psPerProc->ui32PID)); + goto unlock_and_return; + } + } + else + { + + psPerProc = PVRSRVPerProcessData(ui32PID); + if(psPerProc == IMG_NULL) + { + PVR_DPF((PVR_DBG_ERROR, "PVRSRV_BridgeDispatchKM: " + "Couldn't create per-process data area")); + goto unlock_and_return; + } + } + + sBridgePackageKM.ui32BridgeID = PVRSRV_GET_BRIDGE_ID(sBridgePackageKM.ui32BridgeID); + +#if defined(PVR_SECURE_FD_EXPORT) + switch(cmd) + { + case PVRSRV_BRIDGE_EXPORT_DEVICEMEM: + { + PVRSRV_FILE_PRIVATE_DATA *psPrivateData = pFile->private_data; + + if(psPrivateData->hKernelMemInfo) + { + PVR_DPF((PVR_DBG_ERROR, "%s: Can only export one MemInfo " + "per file descriptor", __FUNCTION__)); + err = -EINVAL; + goto unlock_and_return; + } + break; + } + + case PVRSRV_BRIDGE_MAP_DEV_MEMORY: + { + PVRSRV_BRIDGE_IN_MAP_DEV_MEMORY *psMapDevMemIN = + (PVRSRV_BRIDGE_IN_MAP_DEV_MEMORY *)sBridgePackageKM.pvParamIn; + PVRSRV_FILE_PRIVATE_DATA *psPrivateData = pFile->private_data; + + if(!psPrivateData->hKernelMemInfo) + { + PVR_DPF((PVR_DBG_ERROR, "%s: File descriptor has no " + "associated MemInfo handle", __FUNCTION__)); + err = -EINVAL; + goto unlock_and_return; + } + + psMapDevMemIN->hKernelMemInfo = psPrivateData->hKernelMemInfo; + break; + } + + default: + { + PVRSRV_FILE_PRIVATE_DATA *psPrivateData = pFile->private_data; + + if(psPrivateData->hKernelMemInfo) + { + PVR_DPF((PVR_DBG_ERROR, "%s: Import/Export handle tried " + "to use privileged service", __FUNCTION__)); + goto unlock_and_return; + } + break; + } + } +#endif + + err = BridgedDispatchKM(psPerProc, &sBridgePackageKM); + if(err != PVRSRV_OK) + goto unlock_and_return; + + switch(cmd) + { +#if defined(PVR_SECURE_FD_EXPORT) + case PVRSRV_BRIDGE_EXPORT_DEVICEMEM: + { + PVRSRV_BRIDGE_OUT_EXPORTDEVICEMEM *psExportDeviceMemOUT = + (PVRSRV_BRIDGE_OUT_EXPORTDEVICEMEM *)sBridgePackageKM.pvParamOut; + PVRSRV_FILE_PRIVATE_DATA *psPrivateData = pFile->private_data; + + psPrivateData->hKernelMemInfo = psExportDeviceMemOUT->hMemInfo; + break; + } +#endif + + + default: + break; + } + +unlock_and_return: + LinuxUnLockMutex(&gPVRSRVLock); + return err; +} + diff --git a/services4/srvkm/env/linux/pvr_debug.c b/services4/srvkm/env/linux/pvr_debug.c new file mode 100644 index 0000000..bdee215 --- /dev/null +++ b/services4/srvkm/env/linux/pvr_debug.c @@ -0,0 +1,317 @@ +/********************************************************************** + * + * Copyright(c) 2008 Imagination Technologies Ltd. All rights reserved. + * + * This program is free software; you can redistribute it and/or modify it + * under the terms and conditions of the GNU General Public License, + * version 2, as published by the Free Software Foundation. + * + * This program is distributed in the hope it will be useful but, except + * as otherwise stated in writing, without any warranty; without even the + * implied warranty of merchantability or fitness for a particular purpose. + * See the GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License along with + * this program; if not, write to the Free Software Foundation, Inc., + * 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA. + * + * The full GNU General Public License is included in this distribution in + * the file called "COPYING". + * + * Contact Information: + * Imagination Technologies Ltd. + * Home Park Estate, Kings Langley, Herts, WD4 8LZ, UK + * + ******************************************************************************/ + + +#ifndef AUTOCONF_INCLUDED + #include +#endif + +#include +#include +#include +#include +#include +#include +#include +#include +#include "img_types.h" +#include "servicesext.h" +#include "pvr_debug.h" +#include "proc.h" +#include "mutex.h" +#include "linkage.h" + +#if defined(DEBUG) || defined(TIMING) + +IMG_UINT32 gPVRDebugLevel = DBGPRIV_WARNING; + +#define PVR_MAX_MSG_LEN PVR_MAX_DEBUG_MESSAGE_LEN + +static IMG_CHAR gszBufferNonIRQ[PVR_MAX_MSG_LEN + 1]; + +static IMG_CHAR gszBufferIRQ[PVR_MAX_MSG_LEN + 1]; + +static PVRSRV_LINUX_MUTEX gsDebugMutexNonIRQ; + +static spinlock_t gsDebugLockIRQ = SPIN_LOCK_UNLOCKED; + +#define USE_SPIN_LOCK (in_interrupt() || !preemptible()) + +static inline void GetBufferLock(unsigned long *pulLockFlags) +{ + if (USE_SPIN_LOCK) + { + spin_lock_irqsave(&gsDebugLockIRQ, *pulLockFlags); + } + else + { + LinuxLockMutex(&gsDebugMutexNonIRQ); + } +} + +static inline void ReleaseBufferLock(unsigned long ulLockFlags) +{ + if (USE_SPIN_LOCK) + { + spin_unlock_irqrestore(&gsDebugLockIRQ, ulLockFlags); + } + else + { + LinuxUnLockMutex(&gsDebugMutexNonIRQ); + } +} + +static inline void SelectBuffer(IMG_CHAR **ppszBuf, IMG_UINT32 *pui32BufSiz) +{ + if (USE_SPIN_LOCK) + { + *ppszBuf = gszBufferIRQ; + *pui32BufSiz = sizeof(gszBufferIRQ); + } + else + { + *ppszBuf = gszBufferNonIRQ; + *pui32BufSiz = sizeof(gszBufferNonIRQ); + } +} + +static IMG_BOOL VBAppend(IMG_CHAR *pszBuf, IMG_UINT32 ui32BufSiz, const IMG_CHAR* pszFormat, va_list VArgs) +{ + IMG_UINT32 ui32Used; + IMG_UINT32 ui32Space; + IMG_INT32 i32Len; + + ui32Used = strlen(pszBuf); + BUG_ON(ui32Used >= ui32BufSiz); + ui32Space = ui32BufSiz - ui32Used; + + i32Len = vsnprintf(&pszBuf[ui32Used], ui32Space, pszFormat, VArgs); + pszBuf[ui32BufSiz - 1] = 0; + + + return (i32Len < 0 || i32Len >= ui32Space); +} + +static IMG_BOOL BAppend(IMG_CHAR *pszBuf, IMG_UINT32 ui32BufSiz, const IMG_CHAR *pszFormat, ...) +{ + va_list VArgs; + IMG_BOOL bTrunc; + + va_start (VArgs, pszFormat); + + bTrunc = VBAppend(pszBuf, ui32BufSiz, pszFormat, VArgs); + + va_end (VArgs); + + return bTrunc; +} + +IMG_VOID PVRSRVDebugPrintf ( + IMG_UINT32 ui32DebugLevel, + const IMG_CHAR* pszFileName, + IMG_UINT32 ui32Line, + const IMG_CHAR* pszFormat, + ... + ) +{ + IMG_BOOL bTrace, bDebug; +#if !defined(__sh__) + IMG_CHAR *pszLeafName; + + pszLeafName = (IMG_CHAR *)strrchr (pszFileName, '\\'); + + if (pszLeafName) + { + pszFileName = pszLeafName; + } +#endif + + bTrace = gPVRDebugLevel & ui32DebugLevel & DBGPRIV_CALLTRACE; + bDebug = ((gPVRDebugLevel & DBGPRIV_ALLLEVELS) >= ui32DebugLevel); + + if (bTrace || bDebug) + { + va_list vaArgs; + unsigned long ulLockFlags = 0; + IMG_CHAR *pszBuf; + IMG_UINT32 ui32BufSiz; + + SelectBuffer(&pszBuf, &ui32BufSiz); + + va_start(vaArgs, pszFormat); + + GetBufferLock(&ulLockFlags); + + + if (bDebug) + { + switch(ui32DebugLevel) + { + case DBGPRIV_FATAL: + { + strncpy (pszBuf, "PVR_K:(Fatal): ", (ui32BufSiz -1)); + break; + } + case DBGPRIV_ERROR: + { + strncpy (pszBuf, "PVR_K:(Error): ", (ui32BufSiz -1)); + break; + } + case DBGPRIV_WARNING: + { + strncpy (pszBuf, "PVR_K:(Warning): ", (ui32BufSiz -1)); + break; + } + case DBGPRIV_MESSAGE: + { + strncpy (pszBuf, "PVR_K:(Message): ", (ui32BufSiz -1)); + break; + } + case DBGPRIV_VERBOSE: + { + strncpy (pszBuf, "PVR_K:(Verbose): ", (ui32BufSiz -1)); + break; + } + default: + { + strncpy (pszBuf, "PVR_K:(Unknown message level)", (ui32BufSiz -1)); + break; + } + } + } + else + { + strncpy (pszBuf, "PVR_K: ", (ui32BufSiz -1)); + } + + if (VBAppend(pszBuf, ui32BufSiz, pszFormat, vaArgs)) + { + printk(KERN_INFO "PVR_K:(Message Truncated): %s\n", pszBuf); + } + else + { + + if (!bTrace) + { + if (BAppend(pszBuf, ui32BufSiz, " [%lu, %s]", ui32Line, pszFileName)) + { + printk(KERN_INFO "PVR_K:(Message Truncated): %s\n", pszBuf); + } + else + { + printk(KERN_INFO "%s\n", pszBuf); + } + } + } + + ReleaseBufferLock(ulLockFlags); + + va_end (vaArgs); + } +} + +IMG_VOID PVRSRVDebugAssertFail(const IMG_CHAR* pszFile, IMG_UINT32 uLine) +{ + PVRSRVDebugPrintf(DBGPRIV_FATAL, pszFile, uLine, "Debug assertion failed!"); + BUG(); +} + +IMG_VOID PVRSRVTrace(const IMG_CHAR* pszFormat, ...) +{ + va_list VArgs; + unsigned long ulLockFlags = 0; + IMG_CHAR *pszBuf; + IMG_UINT32 ui32BufSiz; + + SelectBuffer(&pszBuf, &ui32BufSiz); + + va_start(VArgs, pszFormat); + + GetBufferLock(&ulLockFlags); + + strncpy(pszBuf, "PVR: ", (ui32BufSiz -1)); + + if (VBAppend(pszBuf, ui32BufSiz, pszFormat, VArgs)) + { + printk(KERN_INFO "PVR_K:(Message Truncated): %s\n", pszBuf); + } + else + { + printk(KERN_INFO "%s\n", pszBuf); + } + + ReleaseBufferLock(ulLockFlags); + + va_end(VArgs); +} + + +IMG_VOID PVRDebugSetLevel(IMG_UINT32 uDebugLevel) +{ + printk(KERN_INFO "PVR: Setting Debug Level = 0x%x\n",(IMG_UINT)uDebugLevel); + + gPVRDebugLevel = uDebugLevel; +} + +IMG_INT PVRDebugProcSetLevel(struct file *file, const IMG_CHAR *buffer, IMG_UINT32 count, IMG_VOID *data) +{ +#define _PROC_SET_BUFFER_SZ 2 + IMG_CHAR data_buffer[_PROC_SET_BUFFER_SZ]; + + if (count != _PROC_SET_BUFFER_SZ) + { + return -EINVAL; + } + else + { + if (copy_from_user(data_buffer, buffer, count)) + return -EINVAL; + if (data_buffer[count - 1] != '\n') + return -EINVAL; + PVRDebugSetLevel(data_buffer[0] - '0'); + } + return (count); +} + +IMG_INT PVRDebugProcGetLevel(IMG_CHAR *page, IMG_CHAR **start, off_t off, IMG_INT count, IMG_INT *eof, IMG_VOID *data) +{ + if (off == 0) { + *start = (IMG_CHAR *)1; + return printAppend(page, count, 0, "%lu\n", gPVRDebugLevel); + } + *eof = 1; + return 0; +} +#endif + +IMG_VOID +PVRDPFInit(IMG_VOID) +{ +#if defined(DEBUG) || defined(TIMING) + LinuxInitMutex(&gsDebugMutexNonIRQ); +#endif +} + diff --git a/services4/srvkm/hwdefs/sgx530defs.h b/services4/srvkm/hwdefs/sgx530defs.h new file mode 100644 index 0000000..830600d --- /dev/null +++ b/services4/srvkm/hwdefs/sgx530defs.h @@ -0,0 +1,428 @@ +/********************************************************************** + * + * Copyright(c) 2008 Imagination Technologies Ltd. All rights reserved. + * + * This program is free software; you can redistribute it and/or modify it + * under the terms and conditions of the GNU General Public License, + * version 2, as published by the Free Software Foundation. + * + * This program is distributed in the hope it will be useful but, except + * as otherwise stated in writing, without any warranty; without even the + * implied warranty of merchantability or fitness for a particular purpose. + * See the GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License along with + * this program; if not, write to the Free Software Foundation, Inc., + * 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA. + * + * The full GNU General Public License is included in this distribution in + * the file called "COPYING". + * + * Contact Information: + * Imagination Technologies Ltd. + * Home Park Estate, Kings Langley, Herts, WD4 8LZ, UK + * + ******************************************************************************/ + +#ifndef _SGX530DEFS_KM_H_ +#define _SGX530DEFS_KM_H_ + +#define EUR_CR_CLKGATECTL 0x0000 +#define EUR_CR_CLKGATECTL_2D_CLKG_MASK 0x00000003 +#define EUR_CR_CLKGATECTL_2D_CLKG_SHIFT 0 +#define EUR_CR_CLKGATECTL_ISP_CLKG_MASK 0x00000030 +#define EUR_CR_CLKGATECTL_ISP_CLKG_SHIFT 4 +#define EUR_CR_CLKGATECTL_TSP_CLKG_MASK 0x00000300 +#define EUR_CR_CLKGATECTL_TSP_CLKG_SHIFT 8 +#define EUR_CR_CLKGATECTL_TA_CLKG_MASK 0x00003000 +#define EUR_CR_CLKGATECTL_TA_CLKG_SHIFT 12 +#define EUR_CR_CLKGATECTL_DPM_CLKG_MASK 0x00030000 +#define EUR_CR_CLKGATECTL_DPM_CLKG_SHIFT 16 +#define EUR_CR_CLKGATECTL_USE_CLKG_MASK 0x00300000 +#define EUR_CR_CLKGATECTL_USE_CLKG_SHIFT 20 +#define EUR_CR_CLKGATECTL_AUTO_MAN_REG_MASK 0x01000000 +#define EUR_CR_CLKGATECTL_AUTO_MAN_REG_SHIFT 24 +#define EUR_CR_CLKGATESTATUS 0x0004 +#define EUR_CR_CLKGATESTATUS_2D_CLKS_MASK 0x00000001 +#define EUR_CR_CLKGATESTATUS_2D_CLKS_SHIFT 0 +#define EUR_CR_CLKGATESTATUS_ISP_CLKS_MASK 0x00000010 +#define EUR_CR_CLKGATESTATUS_ISP_CLKS_SHIFT 4 +#define EUR_CR_CLKGATESTATUS_TSP_CLKS_MASK 0x00000100 +#define EUR_CR_CLKGATESTATUS_TSP_CLKS_SHIFT 8 +#define EUR_CR_CLKGATESTATUS_TA_CLKS_MASK 0x00001000 +#define EUR_CR_CLKGATESTATUS_TA_CLKS_SHIFT 12 +#define EUR_CR_CLKGATESTATUS_DPM_CLKS_MASK 0x00010000 +#define EUR_CR_CLKGATESTATUS_DPM_CLKS_SHIFT 16 +#define EUR_CR_CLKGATESTATUS_USE_CLKS_MASK 0x00100000 +#define EUR_CR_CLKGATESTATUS_USE_CLKS_SHIFT 20 +#define EUR_CR_CLKGATECTLOVR 0x0008 +#define EUR_CR_CLKGATECTLOVR_2D_CLKO_MASK 0x00000003 +#define EUR_CR_CLKGATECTLOVR_2D_CLKO_SHIFT 0 +#define EUR_CR_CLKGATECTLOVR_ISP_CLKO_MASK 0x00000030 +#define EUR_CR_CLKGATECTLOVR_ISP_CLKO_SHIFT 4 +#define EUR_CR_CLKGATECTLOVR_TSP_CLKO_MASK 0x00000300 +#define EUR_CR_CLKGATECTLOVR_TSP_CLKO_SHIFT 8 +#define EUR_CR_CLKGATECTLOVR_TA_CLKO_MASK 0x00003000 +#define EUR_CR_CLKGATECTLOVR_TA_CLKO_SHIFT 12 +#define EUR_CR_CLKGATECTLOVR_DPM_CLKO_MASK 0x00030000 +#define EUR_CR_CLKGATECTLOVR_DPM_CLKO_SHIFT 16 +#define EUR_CR_CLKGATECTLOVR_USE_CLKO_MASK 0x00300000 +#define EUR_CR_CLKGATECTLOVR_USE_CLKO_SHIFT 20 +#define EUR_CR_CORE_ID 0x0010 +#define EUR_CR_CORE_ID_CONFIG_MASK 0x0000FFFF +#define EUR_CR_CORE_ID_CONFIG_SHIFT 0 +#define EUR_CR_CORE_ID_ID_MASK 0xFFFF0000 +#define EUR_CR_CORE_ID_ID_SHIFT 16 +#define EUR_CR_CORE_REVISION 0x0014 +#define EUR_CR_CORE_REVISION_MAINTENANCE_MASK 0x000000FF +#define EUR_CR_CORE_REVISION_MAINTENANCE_SHIFT 0 +#define EUR_CR_CORE_REVISION_MINOR_MASK 0x0000FF00 +#define EUR_CR_CORE_REVISION_MINOR_SHIFT 8 +#define EUR_CR_CORE_REVISION_MAJOR_MASK 0x00FF0000 +#define EUR_CR_CORE_REVISION_MAJOR_SHIFT 16 +#define EUR_CR_CORE_REVISION_DESIGNER_MASK 0xFF000000 +#define EUR_CR_CORE_REVISION_DESIGNER_SHIFT 24 +#define EUR_CR_DESIGNER_REV_FIELD1 0x0018 +#define EUR_CR_DESIGNER_REV_FIELD1_DESIGNER_REV_FIELD1_MASK 0xFFFFFFFF +#define EUR_CR_DESIGNER_REV_FIELD1_DESIGNER_REV_FIELD1_SHIFT 0 +#define EUR_CR_DESIGNER_REV_FIELD2 0x001C +#define EUR_CR_DESIGNER_REV_FIELD2_DESIGNER_REV_FIELD2_MASK 0xFFFFFFFF +#define EUR_CR_DESIGNER_REV_FIELD2_DESIGNER_REV_FIELD2_SHIFT 0 +#define EUR_CR_SOFT_RESET 0x0080 +#define EUR_CR_SOFT_RESET_BIF_RESET_MASK 0x00000001 +#define EUR_CR_SOFT_RESET_BIF_RESET_SHIFT 0 +#define EUR_CR_SOFT_RESET_TWOD_RESET_MASK 0x00000002 +#define EUR_CR_SOFT_RESET_TWOD_RESET_SHIFT 1 +#define EUR_CR_SOFT_RESET_DPM_RESET_MASK 0x00000004 +#define EUR_CR_SOFT_RESET_DPM_RESET_SHIFT 2 +#define EUR_CR_SOFT_RESET_TA_RESET_MASK 0x00000008 +#define EUR_CR_SOFT_RESET_TA_RESET_SHIFT 3 +#define EUR_CR_SOFT_RESET_USE_RESET_MASK 0x00000010 +#define EUR_CR_SOFT_RESET_USE_RESET_SHIFT 4 +#define EUR_CR_SOFT_RESET_ISP_RESET_MASK 0x00000020 +#define EUR_CR_SOFT_RESET_ISP_RESET_SHIFT 5 +#define EUR_CR_SOFT_RESET_TSP_RESET_MASK 0x00000040 +#define EUR_CR_SOFT_RESET_TSP_RESET_SHIFT 6 +#define EUR_CR_EVENT_HOST_ENABLE2 0x0110 +#define EUR_CR_EVENT_HOST_ENABLE2_DPM_3D_FREE_LOAD_MASK 0x00000002 +#define EUR_CR_EVENT_HOST_ENABLE2_DPM_3D_FREE_LOAD_SHIFT 1 +#define EUR_CR_EVENT_HOST_ENABLE2_DPM_TA_FREE_LOAD_MASK 0x00000001 +#define EUR_CR_EVENT_HOST_ENABLE2_DPM_TA_FREE_LOAD_SHIFT 0 +#define EUR_CR_EVENT_HOST_CLEAR2 0x0114 +#define EUR_CR_EVENT_HOST_CLEAR2_DPM_3D_FREE_LOAD_MASK 0x00000002 +#define EUR_CR_EVENT_HOST_CLEAR2_DPM_3D_FREE_LOAD_SHIFT 1 +#define EUR_CR_EVENT_HOST_CLEAR2_DPM_TA_FREE_LOAD_MASK 0x00000001 +#define EUR_CR_EVENT_HOST_CLEAR2_DPM_TA_FREE_LOAD_SHIFT 0 +#define EUR_CR_EVENT_STATUS2 0x0118 +#define EUR_CR_EVENT_STATUS2_DPM_3D_FREE_LOAD_MASK 0x00000002 +#define EUR_CR_EVENT_STATUS2_DPM_3D_FREE_LOAD_SHIFT 1 +#define EUR_CR_EVENT_STATUS2_DPM_TA_FREE_LOAD_MASK 0x00000001 +#define EUR_CR_EVENT_STATUS2_DPM_TA_FREE_LOAD_SHIFT 0 +#define EUR_CR_EVENT_STATUS 0x012C +#define EUR_CR_EVENT_STATUS_MASTER_INTERRUPT_MASK 0x80000000 +#define EUR_CR_EVENT_STATUS_MASTER_INTERRUPT_SHIFT 31 +#define EUR_CR_EVENT_STATUS_TIMER_MASK 0x20000000 +#define EUR_CR_EVENT_STATUS_TIMER_SHIFT 29 +#define EUR_CR_EVENT_STATUS_TA_DPM_FAULT_MASK 0x10000000 +#define EUR_CR_EVENT_STATUS_TA_DPM_FAULT_SHIFT 28 +#define EUR_CR_EVENT_STATUS_TWOD_COMPLETE_MASK 0x08000000 +#define EUR_CR_EVENT_STATUS_TWOD_COMPLETE_SHIFT 27 +#define EUR_CR_EVENT_STATUS_MADD_CACHE_INVALCOMPLETE_MASK 0x04000000 +#define EUR_CR_EVENT_STATUS_MADD_CACHE_INVALCOMPLETE_SHIFT 26 +#define EUR_CR_EVENT_STATUS_DPM_OUT_OF_MEMORY_ZLS_MASK 0x02000000 +#define EUR_CR_EVENT_STATUS_DPM_OUT_OF_MEMORY_ZLS_SHIFT 25 +#define EUR_CR_EVENT_STATUS_DPM_TA_MEM_FREE_MASK 0x01000000 +#define EUR_CR_EVENT_STATUS_DPM_TA_MEM_FREE_SHIFT 24 +#define EUR_CR_EVENT_STATUS_ISP_END_TILE_MASK 0x00800000 +#define EUR_CR_EVENT_STATUS_ISP_END_TILE_SHIFT 23 +#define EUR_CR_EVENT_STATUS_DPM_INITEND_MASK 0x00400000 +#define EUR_CR_EVENT_STATUS_DPM_INITEND_SHIFT 22 +#define EUR_CR_EVENT_STATUS_OTPM_LOADED_MASK 0x00200000 +#define EUR_CR_EVENT_STATUS_OTPM_LOADED_SHIFT 21 +#define EUR_CR_EVENT_STATUS_OTPM_INV_MASK 0x00100000 +#define EUR_CR_EVENT_STATUS_OTPM_INV_SHIFT 20 +#define EUR_CR_EVENT_STATUS_OTPM_FLUSHED_MASK 0x00080000 +#define EUR_CR_EVENT_STATUS_OTPM_FLUSHED_SHIFT 19 +#define EUR_CR_EVENT_STATUS_PIXELBE_END_RENDER_MASK 0x00040000 +#define EUR_CR_EVENT_STATUS_PIXELBE_END_RENDER_SHIFT 18 +#define EUR_CR_EVENT_STATUS_ISP_HALT_MASK 0x00020000 +#define EUR_CR_EVENT_STATUS_ISP_HALT_SHIFT 17 +#define EUR_CR_EVENT_STATUS_ISP_VISIBILITY_FAIL_MASK 0x00010000 +#define EUR_CR_EVENT_STATUS_ISP_VISIBILITY_FAIL_SHIFT 16 +#define EUR_CR_EVENT_STATUS_BREAKPOINT_MASK 0x00008000 +#define EUR_CR_EVENT_STATUS_BREAKPOINT_SHIFT 15 +#define EUR_CR_EVENT_STATUS_SW_EVENT_MASK 0x00004000 +#define EUR_CR_EVENT_STATUS_SW_EVENT_SHIFT 14 +#define EUR_CR_EVENT_STATUS_TA_FINISHED_MASK 0x00002000 +#define EUR_CR_EVENT_STATUS_TA_FINISHED_SHIFT 13 +#define EUR_CR_EVENT_STATUS_TA_TERMINATE_MASK 0x00001000 +#define EUR_CR_EVENT_STATUS_TA_TERMINATE_SHIFT 12 +#define EUR_CR_EVENT_STATUS_TPC_CLEAR_MASK 0x00000800 +#define EUR_CR_EVENT_STATUS_TPC_CLEAR_SHIFT 11 +#define EUR_CR_EVENT_STATUS_TPC_FLUSH_MASK 0x00000400 +#define EUR_CR_EVENT_STATUS_TPC_FLUSH_SHIFT 10 +#define EUR_CR_EVENT_STATUS_DPM_CONTROL_CLEAR_MASK 0x00000200 +#define EUR_CR_EVENT_STATUS_DPM_CONTROL_CLEAR_SHIFT 9 +#define EUR_CR_EVENT_STATUS_DPM_CONTROL_LOAD_MASK 0x00000100 +#define EUR_CR_EVENT_STATUS_DPM_CONTROL_LOAD_SHIFT 8 +#define EUR_CR_EVENT_STATUS_DPM_CONTROL_STORE_MASK 0x00000080 +#define EUR_CR_EVENT_STATUS_DPM_CONTROL_STORE_SHIFT 7 +#define EUR_CR_EVENT_STATUS_DPM_STATE_CLEAR_MASK 0x00000040 +#define EUR_CR_EVENT_STATUS_DPM_STATE_CLEAR_SHIFT 6 +#define EUR_CR_EVENT_STATUS_DPM_STATE_LOAD_MASK 0x00000020 +#define EUR_CR_EVENT_STATUS_DPM_STATE_LOAD_SHIFT 5 +#define EUR_CR_EVENT_STATUS_DPM_STATE_STORE_MASK 0x00000010 +#define EUR_CR_EVENT_STATUS_DPM_STATE_STORE_SHIFT 4 +#define EUR_CR_EVENT_STATUS_DPM_REACHED_MEM_THRESH_MASK 0x00000008 +#define EUR_CR_EVENT_STATUS_DPM_REACHED_MEM_THRESH_SHIFT 3 +#define EUR_CR_EVENT_STATUS_DPM_OUT_OF_MEMORY_GBL_MASK 0x00000004 +#define EUR_CR_EVENT_STATUS_DPM_OUT_OF_MEMORY_GBL_SHIFT 2 +#define EUR_CR_EVENT_STATUS_DPM_OUT_OF_MEMORY_MT_MASK 0x00000002 +#define EUR_CR_EVENT_STATUS_DPM_OUT_OF_MEMORY_MT_SHIFT 1 +#define EUR_CR_EVENT_STATUS_DPM_3D_MEM_FREE_MASK 0x00000001 +#define EUR_CR_EVENT_STATUS_DPM_3D_MEM_FREE_SHIFT 0 +#define EUR_CR_EVENT_HOST_ENABLE 0x0130 +#define EUR_CR_EVENT_HOST_ENABLE_MASTER_INTERRUPT_MASK 0x80000000 +#define EUR_CR_EVENT_HOST_ENABLE_MASTER_INTERRUPT_SHIFT 31 +#define EUR_CR_EVENT_HOST_ENABLE_TIMER_MASK 0x20000000 +#define EUR_CR_EVENT_HOST_ENABLE_TIMER_SHIFT 29 +#define EUR_CR_EVENT_HOST_ENABLE_TA_DPM_FAULT_MASK 0x10000000 +#define EUR_CR_EVENT_HOST_ENABLE_TA_DPM_FAULT_SHIFT 28 +#define EUR_CR_EVENT_HOST_ENABLE_TWOD_COMPLETE_MASK 0x08000000 +#define EUR_CR_EVENT_HOST_ENABLE_TWOD_COMPLETE_SHIFT 27 +#define EUR_CR_EVENT_HOST_ENABLE_MADD_CACHE_INVALCOMPLETE_MASK 0x04000000 +#define EUR_CR_EVENT_HOST_ENABLE_MADD_CACHE_INVALCOMPLETE_SHIFT 26 +#define EUR_CR_EVENT_HOST_ENABLE_DPM_OUT_OF_MEMORY_ZLS_MASK 0x02000000 +#define EUR_CR_EVENT_HOST_ENABLE_DPM_OUT_OF_MEMORY_ZLS_SHIFT 25 +#define EUR_CR_EVENT_HOST_ENABLE_DPM_TA_MEM_FREE_MASK 0x01000000 +#define EUR_CR_EVENT_HOST_ENABLE_DPM_TA_MEM_FREE_SHIFT 24 +#define EUR_CR_EVENT_HOST_ENABLE_ISP_END_TILE_MASK 0x00800000 +#define EUR_CR_EVENT_HOST_ENABLE_ISP_END_TILE_SHIFT 23 +#define EUR_CR_EVENT_HOST_ENABLE_DPM_INITEND_MASK 0x00400000 +#define EUR_CR_EVENT_HOST_ENABLE_DPM_INITEND_SHIFT 22 +#define EUR_CR_EVENT_HOST_ENABLE_OTPM_LOADED_MASK 0x00200000 +#define EUR_CR_EVENT_HOST_ENABLE_OTPM_LOADED_SHIFT 21 +#define EUR_CR_EVENT_HOST_ENABLE_OTPM_INV_MASK 0x00100000 +#define EUR_CR_EVENT_HOST_ENABLE_OTPM_INV_SHIFT 20 +#define EUR_CR_EVENT_HOST_ENABLE_OTPM_FLUSHED_MASK 0x00080000 +#define EUR_CR_EVENT_HOST_ENABLE_OTPM_FLUSHED_SHIFT 19 +#define EUR_CR_EVENT_HOST_ENABLE_PIXELBE_END_RENDER_MASK 0x00040000 +#define EUR_CR_EVENT_HOST_ENABLE_PIXELBE_END_RENDER_SHIFT 18 +#define EUR_CR_EVENT_HOST_ENABLE_ISP_HALT_MASK 0x00020000 +#define EUR_CR_EVENT_HOST_ENABLE_ISP_HALT_SHIFT 17 +#define EUR_CR_EVENT_HOST_ENABLE_ISP_VISIBILITY_FAIL_MASK 0x00010000 +#define EUR_CR_EVENT_HOST_ENABLE_ISP_VISIBILITY_FAIL_SHIFT 16 +#define EUR_CR_EVENT_HOST_ENABLE_BREAKPOINT_MASK 0x00008000 +#define EUR_CR_EVENT_HOST_ENABLE_BREAKPOINT_SHIFT 15 +#define EUR_CR_EVENT_HOST_ENABLE_SW_EVENT_MASK 0x00004000 +#define EUR_CR_EVENT_HOST_ENABLE_SW_EVENT_SHIFT 14 +#define EUR_CR_EVENT_HOST_ENABLE_TA_FINISHED_MASK 0x00002000 +#define EUR_CR_EVENT_HOST_ENABLE_TA_FINISHED_SHIFT 13 +#define EUR_CR_EVENT_HOST_ENABLE_TA_TERMINATE_MASK 0x00001000 +#define EUR_CR_EVENT_HOST_ENABLE_TA_TERMINATE_SHIFT 12 +#define EUR_CR_EVENT_HOST_ENABLE_TPC_CLEAR_MASK 0x00000800 +#define EUR_CR_EVENT_HOST_ENABLE_TPC_CLEAR_SHIFT 11 +#define EUR_CR_EVENT_HOST_ENABLE_TPC_FLUSH_MASK 0x00000400 +#define EUR_CR_EVENT_HOST_ENABLE_TPC_FLUSH_SHIFT 10 +#define EUR_CR_EVENT_HOST_ENABLE_DPM_CONTROL_CLEAR_MASK 0x00000200 +#define EUR_CR_EVENT_HOST_ENABLE_DPM_CONTROL_CLEAR_SHIFT 9 +#define EUR_CR_EVENT_HOST_ENABLE_DPM_CONTROL_LOAD_MASK 0x00000100 +#define EUR_CR_EVENT_HOST_ENABLE_DPM_CONTROL_LOAD_SHIFT 8 +#define EUR_CR_EVENT_HOST_ENABLE_DPM_CONTROL_STORE_MASK 0x00000080 +#define EUR_CR_EVENT_HOST_ENABLE_DPM_CONTROL_STORE_SHIFT 7 +#define EUR_CR_EVENT_HOST_ENABLE_DPM_STATE_CLEAR_MASK 0x00000040 +#define EUR_CR_EVENT_HOST_ENABLE_DPM_STATE_CLEAR_SHIFT 6 +#define EUR_CR_EVENT_HOST_ENABLE_DPM_STATE_LOAD_MASK 0x00000020 +#define EUR_CR_EVENT_HOST_ENABLE_DPM_STATE_LOAD_SHIFT 5 +#define EUR_CR_EVENT_HOST_ENABLE_DPM_STATE_STORE_MASK 0x00000010 +#define EUR_CR_EVENT_HOST_ENABLE_DPM_STATE_STORE_SHIFT 4 +#define EUR_CR_EVENT_HOST_ENABLE_DPM_REACHED_MEM_THRESH_MASK 0x00000008 +#define EUR_CR_EVENT_HOST_ENABLE_DPM_REACHED_MEM_THRESH_SHIFT 3 +#define EUR_CR_EVENT_HOST_ENABLE_DPM_OUT_OF_MEMORY_GBL_MASK 0x00000004 +#define EUR_CR_EVENT_HOST_ENABLE_DPM_OUT_OF_MEMORY_GBL_SHIFT 2 +#define EUR_CR_EVENT_HOST_ENABLE_DPM_OUT_OF_MEMORY_MT_MASK 0x00000002 +#define EUR_CR_EVENT_HOST_ENABLE_DPM_OUT_OF_MEMORY_MT_SHIFT 1 +#define EUR_CR_EVENT_HOST_ENABLE_DPM_3D_MEM_FREE_MASK 0x00000001 +#define EUR_CR_EVENT_HOST_ENABLE_DPM_3D_MEM_FREE_SHIFT 0 +#define EUR_CR_EVENT_HOST_CLEAR 0x0134 +#define EUR_CR_EVENT_HOST_CLEAR_MASTER_INTERRUPT_MASK 0x80000000 +#define EUR_CR_EVENT_HOST_CLEAR_MASTER_INTERRUPT_SHIFT 31 +#define EUR_CR_EVENT_HOST_CLEAR_TIMER_MASK 0x20000000 +#define EUR_CR_EVENT_HOST_CLEAR_TIMER_SHIFT 29 +#define EUR_CR_EVENT_HOST_CLEAR_TA_DPM_FAULT_MASK 0x10000000 +#define EUR_CR_EVENT_HOST_CLEAR_TA_DPM_FAULT_SHIFT 28 +#define EUR_CR_EVENT_HOST_CLEAR_TWOD_COMPLETE_MASK 0x08000000 +#define EUR_CR_EVENT_HOST_CLEAR_TWOD_COMPLETE_SHIFT 27 +#define EUR_CR_EVENT_HOST_CLEAR_MADD_CACHE_INVALCOMPLETE_MASK 0x04000000 +#define EUR_CR_EVENT_HOST_CLEAR_MADD_CACHE_INVALCOMPLETE_SHIFT 26 +#define EUR_CR_EVENT_HOST_CLEAR_DPM_OUT_OF_MEMORY_ZLS_MASK 0x02000000 +#define EUR_CR_EVENT_HOST_CLEAR_DPM_OUT_OF_MEMORY_ZLS_SHIFT 25 +#define EUR_CR_EVENT_HOST_CLEAR_DPM_TA_MEM_FREE_MASK 0x01000000 +#define EUR_CR_EVENT_HOST_CLEAR_DPM_TA_MEM_FREE_SHIFT 24 +#define EUR_CR_EVENT_HOST_CLEAR_ISP_END_TILE_MASK 0x00800000 +#define EUR_CR_EVENT_HOST_CLEAR_ISP_END_TILE_SHIFT 23 +#define EUR_CR_EVENT_HOST_CLEAR_DPM_INITEND_MASK 0x00400000 +#define EUR_CR_EVENT_HOST_CLEAR_DPM_INITEND_SHIFT 22 +#define EUR_CR_EVENT_HOST_CLEAR_OTPM_LOADED_MASK 0x00200000 +#define EUR_CR_EVENT_HOST_CLEAR_OTPM_LOADED_SHIFT 21 +#define EUR_CR_EVENT_HOST_CLEAR_OTPM_INV_MASK 0x00100000 +#define EUR_CR_EVENT_HOST_CLEAR_OTPM_INV_SHIFT 20 +#define EUR_CR_EVENT_HOST_CLEAR_OTPM_FLUSHED_MASK 0x00080000 +#define EUR_CR_EVENT_HOST_CLEAR_OTPM_FLUSHED_SHIFT 19 +#define EUR_CR_EVENT_HOST_CLEAR_PIXELBE_END_RENDER_MASK 0x00040000 +#define EUR_CR_EVENT_HOST_CLEAR_PIXELBE_END_RENDER_SHIFT 18 +#define EUR_CR_EVENT_HOST_CLEAR_ISP_HALT_MASK 0x00020000 +#define EUR_CR_EVENT_HOST_CLEAR_ISP_HALT_SHIFT 17 +#define EUR_CR_EVENT_HOST_CLEAR_ISP_VISIBILITY_FAIL_MASK 0x00010000 +#define EUR_CR_EVENT_HOST_CLEAR_ISP_VISIBILITY_FAIL_SHIFT 16 +#define EUR_CR_EVENT_HOST_CLEAR_BREAKPOINT_MASK 0x00008000 +#define EUR_CR_EVENT_HOST_CLEAR_BREAKPOINT_SHIFT 15 +#define EUR_CR_EVENT_HOST_CLEAR_SW_EVENT_MASK 0x00004000 +#define EUR_CR_EVENT_HOST_CLEAR_SW_EVENT_SHIFT 14 +#define EUR_CR_EVENT_HOST_CLEAR_TA_FINISHED_MASK 0x00002000 +#define EUR_CR_EVENT_HOST_CLEAR_TA_FINISHED_SHIFT 13 +#define EUR_CR_EVENT_HOST_CLEAR_TA_TERMINATE_MASK 0x00001000 +#define EUR_CR_EVENT_HOST_CLEAR_TA_TERMINATE_SHIFT 12 +#define EUR_CR_EVENT_HOST_CLEAR_TPC_CLEAR_MASK 0x00000800 +#define EUR_CR_EVENT_HOST_CLEAR_TPC_CLEAR_SHIFT 11 +#define EUR_CR_EVENT_HOST_CLEAR_TPC_FLUSH_MASK 0x00000400 +#define EUR_CR_EVENT_HOST_CLEAR_TPC_FLUSH_SHIFT 10 +#define EUR_CR_EVENT_HOST_CLEAR_DPM_CONTROL_CLEAR_MASK 0x00000200 +#define EUR_CR_EVENT_HOST_CLEAR_DPM_CONTROL_CLEAR_SHIFT 9 +#define EUR_CR_EVENT_HOST_CLEAR_DPM_CONTROL_LOAD_MASK 0x00000100 +#define EUR_CR_EVENT_HOST_CLEAR_DPM_CONTROL_LOAD_SHIFT 8 +#define EUR_CR_EVENT_HOST_CLEAR_DPM_CONTROL_STORE_MASK 0x00000080 +#define EUR_CR_EVENT_HOST_CLEAR_DPM_CONTROL_STORE_SHIFT 7 +#define EUR_CR_EVENT_HOST_CLEAR_DPM_STATE_CLEAR_MASK 0x00000040 +#define EUR_CR_EVENT_HOST_CLEAR_DPM_STATE_CLEAR_SHIFT 6 +#define EUR_CR_EVENT_HOST_CLEAR_DPM_STATE_LOAD_MASK 0x00000020 +#define EUR_CR_EVENT_HOST_CLEAR_DPM_STATE_LOAD_SHIFT 5 +#define EUR_CR_EVENT_HOST_CLEAR_DPM_STATE_STORE_MASK 0x00000010 +#define EUR_CR_EVENT_HOST_CLEAR_DPM_STATE_STORE_SHIFT 4 +#define EUR_CR_EVENT_HOST_CLEAR_DPM_REACHED_MEM_THRESH_MASK 0x00000008 +#define EUR_CR_EVENT_HOST_CLEAR_DPM_REACHED_MEM_THRESH_SHIFT 3 +#define EUR_CR_EVENT_HOST_CLEAR_DPM_OUT_OF_MEMORY_GBL_MASK 0x00000004 +#define EUR_CR_EVENT_HOST_CLEAR_DPM_OUT_OF_MEMORY_GBL_SHIFT 2 +#define EUR_CR_EVENT_HOST_CLEAR_DPM_OUT_OF_MEMORY_MT_MASK 0x00000002 +#define EUR_CR_EVENT_HOST_CLEAR_DPM_OUT_OF_MEMORY_MT_SHIFT 1 +#define EUR_CR_EVENT_HOST_CLEAR_DPM_3D_MEM_FREE_MASK 0x00000001 +#define EUR_CR_EVENT_HOST_CLEAR_DPM_3D_MEM_FREE_SHIFT 0 +#define EUR_CR_PDS 0x0ABC +#define EUR_CR_PDS_DOUT_TIMEOUT_DISABLE_MASK 0x00000040 +#define EUR_CR_PDS_DOUT_TIMEOUT_DISABLE_SHIFT 6 +#define EUR_CR_PDS_EXEC_BASE 0x0AB8 +#define EUR_CR_PDS_EXEC_BASE_ADDR_MASK 0x0FF00000 +#define EUR_CR_PDS_EXEC_BASE_ADDR_SHIFT 20 +#define EUR_CR_EVENT_KICKER 0x0AC4 +#define EUR_CR_EVENT_KICKER_ADDRESS_MASK 0x0FFFFFF0 +#define EUR_CR_EVENT_KICKER_ADDRESS_SHIFT 4 +#define EUR_CR_EVENT_KICK 0x0AC8 +#define EUR_CR_EVENT_KICK_NOW_MASK 0x00000001 +#define EUR_CR_EVENT_KICK_NOW_SHIFT 0 +#define EUR_CR_EVENT_TIMER 0x0ACC +#define EUR_CR_EVENT_TIMER_ENABLE_MASK 0x01000000 +#define EUR_CR_EVENT_TIMER_ENABLE_SHIFT 24 +#define EUR_CR_EVENT_TIMER_VALUE_MASK 0x00FFFFFF +#define EUR_CR_EVENT_TIMER_VALUE_SHIFT 0 +#define EUR_CR_PDS_INV0 0x0AD0 +#define EUR_CR_PDS_INV0_DSC_MASK 0x00000001 +#define EUR_CR_PDS_INV0_DSC_SHIFT 0 +#define EUR_CR_PDS_INV1 0x0AD4 +#define EUR_CR_PDS_INV1_DSC_MASK 0x00000001 +#define EUR_CR_PDS_INV1_DSC_SHIFT 0 +#define EUR_CR_PDS_INV2 0x0AD8 +#define EUR_CR_PDS_INV2_DSC_MASK 0x00000001 +#define EUR_CR_PDS_INV2_DSC_SHIFT 0 +#define EUR_CR_PDS_INV3 0x0ADC +#define EUR_CR_PDS_INV3_DSC_MASK 0x00000001 +#define EUR_CR_PDS_INV3_DSC_SHIFT 0 +#define EUR_CR_PDS_INV_CSC 0x0AE0 +#define EUR_CR_PDS_INV_CSC_KICK_MASK 0x00000001 +#define EUR_CR_PDS_INV_CSC_KICK_SHIFT 0 +#define EUR_CR_PDS_PC_BASE 0x0B2C +#define EUR_CR_PDS_PC_BASE_ADDRESS_MASK 0x3FFFFFFF +#define EUR_CR_PDS_PC_BASE_ADDRESS_SHIFT 0 +#define EUR_CR_BIF_CTRL 0x0C00 +#define EUR_CR_BIF_CTRL_NOREORDER_MASK 0x00000001 +#define EUR_CR_BIF_CTRL_NOREORDER_SHIFT 0 +#define EUR_CR_BIF_CTRL_PAUSE_MASK 0x00000002 +#define EUR_CR_BIF_CTRL_PAUSE_SHIFT 1 +#define EUR_CR_BIF_CTRL_FLUSH_MASK 0x00000004 +#define EUR_CR_BIF_CTRL_FLUSH_SHIFT 2 +#define EUR_CR_BIF_CTRL_INVALDC_MASK 0x00000008 +#define EUR_CR_BIF_CTRL_INVALDC_SHIFT 3 +#define EUR_CR_BIF_CTRL_CLEAR_FAULT_MASK 0x00000010 +#define EUR_CR_BIF_CTRL_CLEAR_FAULT_SHIFT 4 +#define EUR_CR_BIF_CTRL_MMU_BYPASS_CACHE_MASK 0x00000100 +#define EUR_CR_BIF_CTRL_MMU_BYPASS_CACHE_SHIFT 8 +#define EUR_CR_BIF_CTRL_MMU_BYPASS_VDM_MASK 0x00000200 +#define EUR_CR_BIF_CTRL_MMU_BYPASS_VDM_SHIFT 9 +#define EUR_CR_BIF_CTRL_MMU_BYPASS_TE_MASK 0x00000400 +#define EUR_CR_BIF_CTRL_MMU_BYPASS_TE_SHIFT 10 +#define EUR_CR_BIF_CTRL_MMU_BYPASS_TWOD_MASK 0x00000800 +#define EUR_CR_BIF_CTRL_MMU_BYPASS_TWOD_SHIFT 11 +#define EUR_CR_BIF_CTRL_MMU_BYPASS_PBE_MASK 0x00001000 +#define EUR_CR_BIF_CTRL_MMU_BYPASS_PBE_SHIFT 12 +#define EUR_CR_BIF_CTRL_MMU_BYPASS_TSPP_MASK 0x00002000 +#define EUR_CR_BIF_CTRL_MMU_BYPASS_TSPP_SHIFT 13 +#define EUR_CR_BIF_CTRL_MMU_BYPASS_ISP_MASK 0x00004000 +#define EUR_CR_BIF_CTRL_MMU_BYPASS_ISP_SHIFT 14 +#define EUR_CR_BIF_CTRL_MMU_BYPASS_USE_MASK 0x00008000 +#define EUR_CR_BIF_CTRL_MMU_BYPASS_USE_SHIFT 15 +#define EUR_CR_BIF_INT_STAT 0x0C04 +#define EUR_CR_BIF_INT_STAT_FAULT_MASK 0x00003FFF +#define EUR_CR_BIF_INT_STAT_FAULT_SHIFT 0 +#define EUR_CR_BIF_INT_STAT_PF_N_RW_MASK 0x00004000 +#define EUR_CR_BIF_INT_STAT_PF_N_RW_SHIFT 14 +#define EUR_CR_BIF_FAULT 0x0C08 +#define EUR_CR_BIF_FAULT_ADDR_MASK 0x0FFFF000 +#define EUR_CR_BIF_FAULT_ADDR_SHIFT 12 +#define EUR_CR_BIF_DIR_LIST_BASE0 0x0C84 +#define EUR_CR_BIF_DIR_LIST_BASE0_ADDR_MASK 0xFFFFF000 +#define EUR_CR_BIF_DIR_LIST_BASE0_ADDR_SHIFT 12 +#define EUR_CR_BIF_TWOD_REQ_BASE 0x0C88 +#define EUR_CR_BIF_TWOD_REQ_BASE_ADDR_MASK 0x0FF00000 +#define EUR_CR_BIF_TWOD_REQ_BASE_ADDR_SHIFT 20 +#define EUR_CR_BIF_TA_REQ_BASE 0x0C90 +#define EUR_CR_BIF_TA_REQ_BASE_ADDR_MASK 0x0FF00000 +#define EUR_CR_BIF_TA_REQ_BASE_ADDR_SHIFT 20 +#define EUR_CR_BIF_MEM_REQ_STAT 0x0CA8 +#define EUR_CR_BIF_MEM_REQ_STAT_READS_MASK 0x000000FF +#define EUR_CR_BIF_MEM_REQ_STAT_READS_SHIFT 0 +#define EUR_CR_BIF_3D_REQ_BASE 0x0CAC +#define EUR_CR_BIF_3D_REQ_BASE_ADDR_MASK 0x0FF00000 +#define EUR_CR_BIF_3D_REQ_BASE_ADDR_SHIFT 20 +#define EUR_CR_BIF_ZLS_REQ_BASE 0x0CB0 +#define EUR_CR_BIF_ZLS_REQ_BASE_ADDR_MASK 0x0FF00000 +#define EUR_CR_BIF_ZLS_REQ_BASE_ADDR_SHIFT 20 +#define EUR_CR_2D_BLIT_STATUS 0x0E04 +#define EUR_CR_2D_BLIT_STATUS_COMPLETE_MASK 0x00FFFFFF +#define EUR_CR_2D_BLIT_STATUS_COMPLETE_SHIFT 0 +#define EUR_CR_2D_BLIT_STATUS_BUSY_MASK 0x01000000 +#define EUR_CR_2D_BLIT_STATUS_BUSY_SHIFT 24 +#define EUR_CR_2D_VIRTUAL_FIFO_0 0x0E10 +#define EUR_CR_2D_VIRTUAL_FIFO_0_ENABLE_MASK 0x00000001 +#define EUR_CR_2D_VIRTUAL_FIFO_0_ENABLE_SHIFT 0 +#define EUR_CR_2D_VIRTUAL_FIFO_0_FLOWRATE_MASK 0x0000000E +#define EUR_CR_2D_VIRTUAL_FIFO_0_FLOWRATE_SHIFT 1 +#define EUR_CR_2D_VIRTUAL_FIFO_0_FLOWRATE_DIV_MASK 0x00000FF0 +#define EUR_CR_2D_VIRTUAL_FIFO_0_FLOWRATE_DIV_SHIFT 4 +#define EUR_CR_2D_VIRTUAL_FIFO_0_FLOWRATE_MUL_MASK 0x0000F000 +#define EUR_CR_2D_VIRTUAL_FIFO_0_FLOWRATE_MUL_SHIFT 12 +#define EUR_CR_2D_VIRTUAL_FIFO_1 0x0E14 +#define EUR_CR_2D_VIRTUAL_FIFO_1_MIN_ACC_MASK 0x00000FFF +#define EUR_CR_2D_VIRTUAL_FIFO_1_MIN_ACC_SHIFT 0 +#define EUR_CR_2D_VIRTUAL_FIFO_1_MAX_ACC_MASK 0x00FFF000 +#define EUR_CR_2D_VIRTUAL_FIFO_1_MAX_ACC_SHIFT 12 +#define EUR_CR_2D_VIRTUAL_FIFO_1_MIN_METRIC_MASK 0xFF000000 +#define EUR_CR_2D_VIRTUAL_FIFO_1_MIN_METRIC_SHIFT 24 +#define EUR_CR_USE_CODE_BASE(X) (0x0A0C + (4 * (X))) +#define EUR_CR_USE_CODE_BASE_ADDR_MASK 0x00FFFFFF +#define EUR_CR_USE_CODE_BASE_ADDR_SHIFT 0 +#define EUR_CR_USE_CODE_BASE_DM_MASK 0x03000000 +#define EUR_CR_USE_CODE_BASE_DM_SHIFT 24 +#define EUR_CR_USE_CODE_BASE_SIZE_UINT32 16 +#define EUR_CR_USE_CODE_BASE_NUM_ENTRIES 16 + +#endif + diff --git a/services4/srvkm/hwdefs/sgx540defs.h b/services4/srvkm/hwdefs/sgx540defs.h new file mode 100644 index 0000000..b755374 --- /dev/null +++ b/services4/srvkm/hwdefs/sgx540defs.h @@ -0,0 +1,586 @@ +/********************************************************************** + * + * Copyright(c) 2008 Imagination Technologies Ltd. All rights reserved. + * + * This program is free software; you can redistribute it and/or modify it + * under the terms and conditions of the GNU General Public License, + * version 2, as published by the Free Software Foundation. + * + * This program is distributed in the hope it will be useful but, except + * as otherwise stated in writing, without any warranty; without even the + * implied warranty of merchantability or fitness for a particular purpose. + * See the GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License along with + * this program; if not, write to the Free Software Foundation, Inc., + * 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA. + * + * The full GNU General Public License is included in this distribution in + * the file called "COPYING". + * + * Contact Information: + * Imagination Technologies Ltd. + * Home Park Estate, Kings Langley, Herts, WD4 8LZ, UK + * + ******************************************************************************/ + +#ifndef _SGX540DEFS_KM_H_ +#define _SGX540DEFS_KM_H_ + +#define EUR_CR_CLKGATECTL 0x0000 +#define EUR_CR_CLKGATECTL_ISP_CLKG_MASK 0x00000003 +#define EUR_CR_CLKGATECTL_ISP_CLKG_SHIFT 0 +#define EUR_CR_CLKGATECTL_ISP2_CLKG_MASK 0x0000000C +#define EUR_CR_CLKGATECTL_ISP2_CLKG_SHIFT 2 +#define EUR_CR_CLKGATECTL_TSP_CLKG_MASK 0x00000030 +#define EUR_CR_CLKGATECTL_TSP_CLKG_SHIFT 4 +#define EUR_CR_CLKGATECTL_TE_CLKG_MASK 0x000000C0 +#define EUR_CR_CLKGATECTL_TE_CLKG_SHIFT 6 +#define EUR_CR_CLKGATECTL_MTE_CLKG_MASK 0x00000300 +#define EUR_CR_CLKGATECTL_MTE_CLKG_SHIFT 8 +#define EUR_CR_CLKGATECTL_DPM_CLKG_MASK 0x00000C00 +#define EUR_CR_CLKGATECTL_DPM_CLKG_SHIFT 10 +#define EUR_CR_CLKGATECTL_VDM_CLKG_MASK 0x00003000 +#define EUR_CR_CLKGATECTL_VDM_CLKG_SHIFT 12 +#define EUR_CR_CLKGATECTL_PDS_CLKG_MASK 0x0000C000 +#define EUR_CR_CLKGATECTL_PDS_CLKG_SHIFT 14 +#define EUR_CR_CLKGATECTL_IDXFIFO_CLKG_MASK 0x00030000 +#define EUR_CR_CLKGATECTL_IDXFIFO_CLKG_SHIFT 16 +#define EUR_CR_CLKGATECTL_TA_CLKG_MASK 0x000C0000 +#define EUR_CR_CLKGATECTL_TA_CLKG_SHIFT 18 +#define EUR_CR_CLKGATECTL_AUTO_MAN_REG_MASK 0x01000000 +#define EUR_CR_CLKGATECTL_AUTO_MAN_REG_SHIFT 24 +#define EUR_CR_CLKGATECTL_SYSTEM_CLKG_MASK 0x10000000 +#define EUR_CR_CLKGATECTL_SYSTEM_CLKG_SHIFT 28 +#define EUR_CR_CLKGATECTL2 0x0004 +#define EUR_CR_CLKGATECTL2_PBE_CLKG_MASK 0x00000003 +#define EUR_CR_CLKGATECTL2_PBE_CLKG_SHIFT 0 +#define EUR_CR_CLKGATECTL2_CACHEL2_CLKG_MASK 0x0000000C +#define EUR_CR_CLKGATECTL2_CACHEL2_CLKG_SHIFT 2 +#define EUR_CR_CLKGATECTL2_UCACHEL2_CLKG_MASK 0x00000030 +#define EUR_CR_CLKGATECTL2_UCACHEL2_CLKG_SHIFT 4 +#define EUR_CR_CLKGATECTL2_USE0_CLKG_MASK 0x000000C0 +#define EUR_CR_CLKGATECTL2_USE0_CLKG_SHIFT 6 +#define EUR_CR_CLKGATECTL2_ITR0_CLKG_MASK 0x00000300 +#define EUR_CR_CLKGATECTL2_ITR0_CLKG_SHIFT 8 +#define EUR_CR_CLKGATECTL2_TEX0_CLKG_MASK 0x00000C00 +#define EUR_CR_CLKGATECTL2_TEX0_CLKG_SHIFT 10 +#define EUR_CR_CLKGATECTL2_MADD0_CLKG_MASK 0x00003000 +#define EUR_CR_CLKGATECTL2_MADD0_CLKG_SHIFT 12 +#define EUR_CR_CLKGATECTL2_USE1_CLKG_MASK 0x0000C000 +#define EUR_CR_CLKGATECTL2_USE1_CLKG_SHIFT 14 +#define EUR_CR_CLKGATECTL2_ITR1_CLKG_MASK 0x00030000 +#define EUR_CR_CLKGATECTL2_ITR1_CLKG_SHIFT 16 +#define EUR_CR_CLKGATECTL2_TEX1_CLKG_MASK 0x000C0000 +#define EUR_CR_CLKGATECTL2_TEX1_CLKG_SHIFT 18 +#define EUR_CR_CLKGATECTL2_MADD1_CLKG_MASK 0x00300000 +#define EUR_CR_CLKGATECTL2_MADD1_CLKG_SHIFT 20 +#define EUR_CR_CLKGATESTATUS 0x0008 +#define EUR_CR_CLKGATESTATUS_ISP_CLKS_MASK 0x00000001 +#define EUR_CR_CLKGATESTATUS_ISP_CLKS_SHIFT 0 +#define EUR_CR_CLKGATESTATUS_ISP2_CLKS_MASK 0x00000002 +#define EUR_CR_CLKGATESTATUS_ISP2_CLKS_SHIFT 1 +#define EUR_CR_CLKGATESTATUS_TSP_CLKS_MASK 0x00000004 +#define EUR_CR_CLKGATESTATUS_TSP_CLKS_SHIFT 2 +#define EUR_CR_CLKGATESTATUS_TE_CLKS_MASK 0x00000008 +#define EUR_CR_CLKGATESTATUS_TE_CLKS_SHIFT 3 +#define EUR_CR_CLKGATESTATUS_MTE_CLKS_MASK 0x00000010 +#define EUR_CR_CLKGATESTATUS_MTE_CLKS_SHIFT 4 +#define EUR_CR_CLKGATESTATUS_DPM_CLKS_MASK 0x00000020 +#define EUR_CR_CLKGATESTATUS_DPM_CLKS_SHIFT 5 +#define EUR_CR_CLKGATESTATUS_VDM_CLKS_MASK 0x00000040 +#define EUR_CR_CLKGATESTATUS_VDM_CLKS_SHIFT 6 +#define EUR_CR_CLKGATESTATUS_PDS_CLKS_MASK 0x00000080 +#define EUR_CR_CLKGATESTATUS_PDS_CLKS_SHIFT 7 +#define EUR_CR_CLKGATESTATUS_PBE_CLKS_MASK 0x00000100 +#define EUR_CR_CLKGATESTATUS_PBE_CLKS_SHIFT 8 +#define EUR_CR_CLKGATESTATUS_CACHEL2_CLKS_MASK 0x00000200 +#define EUR_CR_CLKGATESTATUS_CACHEL2_CLKS_SHIFT 9 +#define EUR_CR_CLKGATESTATUS_UCACHEL2_CLKS_MASK 0x00000400 +#define EUR_CR_CLKGATESTATUS_UCACHEL2_CLKS_SHIFT 10 +#define EUR_CR_CLKGATESTATUS_USE0_CLKS_MASK 0x00000800 +#define EUR_CR_CLKGATESTATUS_USE0_CLKS_SHIFT 11 +#define EUR_CR_CLKGATESTATUS_ITR0_CLKS_MASK 0x00001000 +#define EUR_CR_CLKGATESTATUS_ITR0_CLKS_SHIFT 12 +#define EUR_CR_CLKGATESTATUS_TEX0_CLKS_MASK 0x00002000 +#define EUR_CR_CLKGATESTATUS_TEX0_CLKS_SHIFT 13 +#define EUR_CR_CLKGATESTATUS_MADD0_CLKS_MASK 0x00004000 +#define EUR_CR_CLKGATESTATUS_MADD0_CLKS_SHIFT 14 +#define EUR_CR_CLKGATESTATUS_USE1_CLKS_MASK 0x00008000 +#define EUR_CR_CLKGATESTATUS_USE1_CLKS_SHIFT 15 +#define EUR_CR_CLKGATESTATUS_ITR1_CLKS_MASK 0x00010000 +#define EUR_CR_CLKGATESTATUS_ITR1_CLKS_SHIFT 16 +#define EUR_CR_CLKGATESTATUS_TEX1_CLKS_MASK 0x00020000 +#define EUR_CR_CLKGATESTATUS_TEX1_CLKS_SHIFT 17 +#define EUR_CR_CLKGATESTATUS_MADD1_CLKS_MASK 0x00040000 +#define EUR_CR_CLKGATESTATUS_MADD1_CLKS_SHIFT 18 +#define EUR_CR_CLKGATESTATUS_IDXFIFO_CLKS_MASK 0x00080000 +#define EUR_CR_CLKGATESTATUS_IDXFIFO_CLKS_SHIFT 19 +#define EUR_CR_CLKGATESTATUS_TA_CLKS_MASK 0x00100000 +#define EUR_CR_CLKGATESTATUS_TA_CLKS_SHIFT 20 +#define EUR_CR_CLKGATECTLOVR 0x000C +#define EUR_CR_CLKGATECTLOVR_ISP_CLKO_MASK 0x00000003 +#define EUR_CR_CLKGATECTLOVR_ISP_CLKO_SHIFT 0 +#define EUR_CR_CLKGATECTLOVR_ISP2_CLKO_MASK 0x0000000C +#define EUR_CR_CLKGATECTLOVR_ISP2_CLKO_SHIFT 2 +#define EUR_CR_CLKGATECTLOVR_TSP_CLKO_MASK 0x00000030 +#define EUR_CR_CLKGATECTLOVR_TSP_CLKO_SHIFT 4 +#define EUR_CR_CLKGATECTLOVR_TE_CLKO_MASK 0x000000C0 +#define EUR_CR_CLKGATECTLOVR_TE_CLKO_SHIFT 6 +#define EUR_CR_CLKGATECTLOVR_MTE_CLKO_MASK 0x00000300 +#define EUR_CR_CLKGATECTLOVR_MTE_CLKO_SHIFT 8 +#define EUR_CR_CLKGATECTLOVR_DPM_CLKO_MASK 0x00000C00 +#define EUR_CR_CLKGATECTLOVR_DPM_CLKO_SHIFT 10 +#define EUR_CR_CLKGATECTLOVR_VDM_CLKO_MASK 0x00003000 +#define EUR_CR_CLKGATECTLOVR_VDM_CLKO_SHIFT 12 +#define EUR_CR_CLKGATECTLOVR_PDS_CLKO_MASK 0x0000C000 +#define EUR_CR_CLKGATECTLOVR_PDS_CLKO_SHIFT 14 +#define EUR_CR_CLKGATECTLOVR_IDXFIFO_CLKO_MASK 0x00030000 +#define EUR_CR_CLKGATECTLOVR_IDXFIFO_CLKO_SHIFT 16 +#define EUR_CR_CLKGATECTLOVR_TA_CLKO_MASK 0x000C0000 +#define EUR_CR_CLKGATECTLOVR_TA_CLKO_SHIFT 18 +#define EUR_CR_POWER 0x001C +#define EUR_CR_POWER_PIPE_DISABLE_MASK 0x00000001 +#define EUR_CR_POWER_PIPE_DISABLE_SHIFT 0 +#define EUR_CR_CORE_ID 0x0020 +#define EUR_CR_CORE_ID_CONFIG_MASK 0x0000FFFF +#define EUR_CR_CORE_ID_CONFIG_SHIFT 0 +#define EUR_CR_CORE_ID_ID_MASK 0xFFFF0000 +#define EUR_CR_CORE_ID_ID_SHIFT 16 +#define EUR_CR_CORE_REVISION 0x0024 +#define EUR_CR_CORE_REVISION_MAINTENANCE_MASK 0x000000FF +#define EUR_CR_CORE_REVISION_MAINTENANCE_SHIFT 0 +#define EUR_CR_CORE_REVISION_MINOR_MASK 0x0000FF00 +#define EUR_CR_CORE_REVISION_MINOR_SHIFT 8 +#define EUR_CR_CORE_REVISION_MAJOR_MASK 0x00FF0000 +#define EUR_CR_CORE_REVISION_MAJOR_SHIFT 16 +#define EUR_CR_CORE_REVISION_DESIGNER_MASK 0xFF000000 +#define EUR_CR_CORE_REVISION_DESIGNER_SHIFT 24 +#define EUR_CR_DESIGNER_REV_FIELD1 0x0028 +#define EUR_CR_DESIGNER_REV_FIELD1_DESIGNER_REV_FIELD1_MASK 0xFFFFFFFF +#define EUR_CR_DESIGNER_REV_FIELD1_DESIGNER_REV_FIELD1_SHIFT 0 +#define EUR_CR_DESIGNER_REV_FIELD2 0x002C +#define EUR_CR_DESIGNER_REV_FIELD2_DESIGNER_REV_FIELD2_MASK 0xFFFFFFFF +#define EUR_CR_DESIGNER_REV_FIELD2_DESIGNER_REV_FIELD2_SHIFT 0 +#define EUR_CR_SOFT_RESET 0x0080 +#define EUR_CR_SOFT_RESET_BIF_RESET_MASK 0x00000001 +#define EUR_CR_SOFT_RESET_BIF_RESET_SHIFT 0 +#define EUR_CR_SOFT_RESET_VDM_RESET_MASK 0x00000002 +#define EUR_CR_SOFT_RESET_VDM_RESET_SHIFT 1 +#define EUR_CR_SOFT_RESET_DPM_RESET_MASK 0x00000004 +#define EUR_CR_SOFT_RESET_DPM_RESET_SHIFT 2 +#define EUR_CR_SOFT_RESET_TE_RESET_MASK 0x00000008 +#define EUR_CR_SOFT_RESET_TE_RESET_SHIFT 3 +#define EUR_CR_SOFT_RESET_MTE_RESET_MASK 0x00000010 +#define EUR_CR_SOFT_RESET_MTE_RESET_SHIFT 4 +#define EUR_CR_SOFT_RESET_ISP_RESET_MASK 0x00000020 +#define EUR_CR_SOFT_RESET_ISP_RESET_SHIFT 5 +#define EUR_CR_SOFT_RESET_ISP2_RESET_MASK 0x00000040 +#define EUR_CR_SOFT_RESET_ISP2_RESET_SHIFT 6 +#define EUR_CR_SOFT_RESET_TSP_RESET_MASK 0x00000080 +#define EUR_CR_SOFT_RESET_TSP_RESET_SHIFT 7 +#define EUR_CR_SOFT_RESET_PDS_RESET_MASK 0x00000100 +#define EUR_CR_SOFT_RESET_PDS_RESET_SHIFT 8 +#define EUR_CR_SOFT_RESET_PBE_RESET_MASK 0x00000200 +#define EUR_CR_SOFT_RESET_PBE_RESET_SHIFT 9 +#define EUR_CR_SOFT_RESET_CACHEL2_RESET_MASK 0x00000400 +#define EUR_CR_SOFT_RESET_CACHEL2_RESET_SHIFT 10 +#define EUR_CR_SOFT_RESET_UCACHEL2_RESET_MASK 0x00000800 +#define EUR_CR_SOFT_RESET_UCACHEL2_RESET_SHIFT 11 +#define EUR_CR_SOFT_RESET_MADD_RESET_MASK 0x00001000 +#define EUR_CR_SOFT_RESET_MADD_RESET_SHIFT 12 +#define EUR_CR_SOFT_RESET_ITR_RESET_MASK 0x00002000 +#define EUR_CR_SOFT_RESET_ITR_RESET_SHIFT 13 +#define EUR_CR_SOFT_RESET_TEX_RESET_MASK 0x00004000 +#define EUR_CR_SOFT_RESET_TEX_RESET_SHIFT 14 +#define EUR_CR_SOFT_RESET_USE_RESET_MASK 0x00008000 +#define EUR_CR_SOFT_RESET_USE_RESET_SHIFT 15 +#define EUR_CR_SOFT_RESET_IDXFIFO_RESET_MASK 0x00010000 +#define EUR_CR_SOFT_RESET_IDXFIFO_RESET_SHIFT 16 +#define EUR_CR_SOFT_RESET_TA_RESET_MASK 0x00020000 +#define EUR_CR_SOFT_RESET_TA_RESET_SHIFT 17 +#define EUR_CR_EVENT_HOST_ENABLE2 0x0110 +#define EUR_CR_EVENT_HOST_ENABLE2_TRIG_TA_MASK 0x00000010 +#define EUR_CR_EVENT_HOST_ENABLE2_TRIG_TA_SHIFT 4 +#define EUR_CR_EVENT_HOST_ENABLE2_TRIG_3D_MASK 0x00000008 +#define EUR_CR_EVENT_HOST_ENABLE2_TRIG_3D_SHIFT 3 +#define EUR_CR_EVENT_HOST_ENABLE2_TRIG_DL_MASK 0x00000004 +#define EUR_CR_EVENT_HOST_ENABLE2_TRIG_DL_SHIFT 2 +#define EUR_CR_EVENT_HOST_ENABLE2_DPM_3D_FREE_LOAD_MASK 0x00000002 +#define EUR_CR_EVENT_HOST_ENABLE2_DPM_3D_FREE_LOAD_SHIFT 1 +#define EUR_CR_EVENT_HOST_ENABLE2_DPM_TA_FREE_LOAD_MASK 0x00000001 +#define EUR_CR_EVENT_HOST_ENABLE2_DPM_TA_FREE_LOAD_SHIFT 0 +#define EUR_CR_EVENT_HOST_CLEAR2 0x0114 +#define EUR_CR_EVENT_HOST_CLEAR2_TRIG_TA_MASK 0x00000010 +#define EUR_CR_EVENT_HOST_CLEAR2_TRIG_TA_SHIFT 4 +#define EUR_CR_EVENT_HOST_CLEAR2_TRIG_3D_MASK 0x00000008 +#define EUR_CR_EVENT_HOST_CLEAR2_TRIG_3D_SHIFT 3 +#define EUR_CR_EVENT_HOST_CLEAR2_TRIG_DL_MASK 0x00000004 +#define EUR_CR_EVENT_HOST_CLEAR2_TRIG_DL_SHIFT 2 +#define EUR_CR_EVENT_HOST_CLEAR2_DPM_3D_FREE_LOAD_MASK 0x00000002 +#define EUR_CR_EVENT_HOST_CLEAR2_DPM_3D_FREE_LOAD_SHIFT 1 +#define EUR_CR_EVENT_HOST_CLEAR2_DPM_TA_FREE_LOAD_MASK 0x00000001 +#define EUR_CR_EVENT_HOST_CLEAR2_DPM_TA_FREE_LOAD_SHIFT 0 +#define EUR_CR_EVENT_STATUS2 0x0118 +#define EUR_CR_EVENT_STATUS2_TRIG_TA_MASK 0x00000010 +#define EUR_CR_EVENT_STATUS2_TRIG_TA_SHIFT 4 +#define EUR_CR_EVENT_STATUS2_TRIG_3D_MASK 0x00000008 +#define EUR_CR_EVENT_STATUS2_TRIG_3D_SHIFT 3 +#define EUR_CR_EVENT_STATUS2_TRIG_DL_MASK 0x00000004 +#define EUR_CR_EVENT_STATUS2_TRIG_DL_SHIFT 2 +#define EUR_CR_EVENT_STATUS2_DPM_3D_FREE_LOAD_MASK 0x00000002 +#define EUR_CR_EVENT_STATUS2_DPM_3D_FREE_LOAD_SHIFT 1 +#define EUR_CR_EVENT_STATUS2_DPM_TA_FREE_LOAD_MASK 0x00000001 +#define EUR_CR_EVENT_STATUS2_DPM_TA_FREE_LOAD_SHIFT 0 +#define EUR_CR_EVENT_STATUS 0x012C +#define EUR_CR_EVENT_STATUS_MASTER_INTERRUPT_MASK 0x80000000 +#define EUR_CR_EVENT_STATUS_MASTER_INTERRUPT_SHIFT 31 +#define EUR_CR_EVENT_STATUS_TIMER_MASK 0x20000000 +#define EUR_CR_EVENT_STATUS_TIMER_SHIFT 29 +#define EUR_CR_EVENT_STATUS_TA_DPM_FAULT_MASK 0x10000000 +#define EUR_CR_EVENT_STATUS_TA_DPM_FAULT_SHIFT 28 +#define EUR_CR_EVENT_STATUS_TWOD_COMPLETE_MASK 0x08000000 +#define EUR_CR_EVENT_STATUS_TWOD_COMPLETE_SHIFT 27 +#define EUR_CR_EVENT_STATUS_MADD_CACHE_INVALCOMPLETE_MASK 0x04000000 +#define EUR_CR_EVENT_STATUS_MADD_CACHE_INVALCOMPLETE_SHIFT 26 +#define EUR_CR_EVENT_STATUS_DPM_OUT_OF_MEMORY_ZLS_MASK 0x02000000 +#define EUR_CR_EVENT_STATUS_DPM_OUT_OF_MEMORY_ZLS_SHIFT 25 +#define EUR_CR_EVENT_STATUS_DPM_TA_MEM_FREE_MASK 0x01000000 +#define EUR_CR_EVENT_STATUS_DPM_TA_MEM_FREE_SHIFT 24 +#define EUR_CR_EVENT_STATUS_ISP_END_TILE_MASK 0x00800000 +#define EUR_CR_EVENT_STATUS_ISP_END_TILE_SHIFT 23 +#define EUR_CR_EVENT_STATUS_DPM_INITEND_MASK 0x00400000 +#define EUR_CR_EVENT_STATUS_DPM_INITEND_SHIFT 22 +#define EUR_CR_EVENT_STATUS_OTPM_LOADED_MASK 0x00200000 +#define EUR_CR_EVENT_STATUS_OTPM_LOADED_SHIFT 21 +#define EUR_CR_EVENT_STATUS_OTPM_INV_MASK 0x00100000 +#define EUR_CR_EVENT_STATUS_OTPM_INV_SHIFT 20 +#define EUR_CR_EVENT_STATUS_OTPM_FLUSHED_MASK 0x00080000 +#define EUR_CR_EVENT_STATUS_OTPM_FLUSHED_SHIFT 19 +#define EUR_CR_EVENT_STATUS_PIXELBE_END_RENDER_MASK 0x00040000 +#define EUR_CR_EVENT_STATUS_PIXELBE_END_RENDER_SHIFT 18 +#define EUR_CR_EVENT_STATUS_ISP_HALT_MASK 0x00020000 +#define EUR_CR_EVENT_STATUS_ISP_HALT_SHIFT 17 +#define EUR_CR_EVENT_STATUS_ISP_VISIBILITY_FAIL_MASK 0x00010000 +#define EUR_CR_EVENT_STATUS_ISP_VISIBILITY_FAIL_SHIFT 16 +#define EUR_CR_EVENT_STATUS_BREAKPOINT_MASK 0x00008000 +#define EUR_CR_EVENT_STATUS_BREAKPOINT_SHIFT 15 +#define EUR_CR_EVENT_STATUS_SW_EVENT_MASK 0x00004000 +#define EUR_CR_EVENT_STATUS_SW_EVENT_SHIFT 14 +#define EUR_CR_EVENT_STATUS_TA_FINISHED_MASK 0x00002000 +#define EUR_CR_EVENT_STATUS_TA_FINISHED_SHIFT 13 +#define EUR_CR_EVENT_STATUS_TA_TERMINATE_MASK 0x00001000 +#define EUR_CR_EVENT_STATUS_TA_TERMINATE_SHIFT 12 +#define EUR_CR_EVENT_STATUS_TPC_CLEAR_MASK 0x00000800 +#define EUR_CR_EVENT_STATUS_TPC_CLEAR_SHIFT 11 +#define EUR_CR_EVENT_STATUS_TPC_FLUSH_MASK 0x00000400 +#define EUR_CR_EVENT_STATUS_TPC_FLUSH_SHIFT 10 +#define EUR_CR_EVENT_STATUS_DPM_CONTROL_CLEAR_MASK 0x00000200 +#define EUR_CR_EVENT_STATUS_DPM_CONTROL_CLEAR_SHIFT 9 +#define EUR_CR_EVENT_STATUS_DPM_CONTROL_LOAD_MASK 0x00000100 +#define EUR_CR_EVENT_STATUS_DPM_CONTROL_LOAD_SHIFT 8 +#define EUR_CR_EVENT_STATUS_DPM_CONTROL_STORE_MASK 0x00000080 +#define EUR_CR_EVENT_STATUS_DPM_CONTROL_STORE_SHIFT 7 +#define EUR_CR_EVENT_STATUS_DPM_STATE_CLEAR_MASK 0x00000040 +#define EUR_CR_EVENT_STATUS_DPM_STATE_CLEAR_SHIFT 6 +#define EUR_CR_EVENT_STATUS_DPM_STATE_LOAD_MASK 0x00000020 +#define EUR_CR_EVENT_STATUS_DPM_STATE_LOAD_SHIFT 5 +#define EUR_CR_EVENT_STATUS_DPM_STATE_STORE_MASK 0x00000010 +#define EUR_CR_EVENT_STATUS_DPM_STATE_STORE_SHIFT 4 +#define EUR_CR_EVENT_STATUS_DPM_REACHED_MEM_THRESH_MASK 0x00000008 +#define EUR_CR_EVENT_STATUS_DPM_REACHED_MEM_THRESH_SHIFT 3 +#define EUR_CR_EVENT_STATUS_DPM_OUT_OF_MEMORY_GBL_MASK 0x00000004 +#define EUR_CR_EVENT_STATUS_DPM_OUT_OF_MEMORY_GBL_SHIFT 2 +#define EUR_CR_EVENT_STATUS_DPM_OUT_OF_MEMORY_MT_MASK 0x00000002 +#define EUR_CR_EVENT_STATUS_DPM_OUT_OF_MEMORY_MT_SHIFT 1 +#define EUR_CR_EVENT_STATUS_DPM_3D_MEM_FREE_MASK 0x00000001 +#define EUR_CR_EVENT_STATUS_DPM_3D_MEM_FREE_SHIFT 0 +#define EUR_CR_EVENT_HOST_ENABLE 0x0130 +#define EUR_CR_EVENT_HOST_ENABLE_MASTER_INTERRUPT_MASK 0x80000000 +#define EUR_CR_EVENT_HOST_ENABLE_MASTER_INTERRUPT_SHIFT 31 +#define EUR_CR_EVENT_HOST_ENABLE_TIMER_MASK 0x20000000 +#define EUR_CR_EVENT_HOST_ENABLE_TIMER_SHIFT 29 +#define EUR_CR_EVENT_HOST_ENABLE_TA_DPM_FAULT_MASK 0x10000000 +#define EUR_CR_EVENT_HOST_ENABLE_TA_DPM_FAULT_SHIFT 28 +#define EUR_CR_EVENT_HOST_ENABLE_TWOD_COMPLETE_MASK 0x08000000 +#define EUR_CR_EVENT_HOST_ENABLE_TWOD_COMPLETE_SHIFT 27 +#define EUR_CR_EVENT_HOST_ENABLE_MADD_CACHE_INVALCOMPLETE_MASK 0x04000000 +#define EUR_CR_EVENT_HOST_ENABLE_MADD_CACHE_INVALCOMPLETE_SHIFT 26 +#define EUR_CR_EVENT_HOST_ENABLE_DPM_OUT_OF_MEMORY_ZLS_MASK 0x02000000 +#define EUR_CR_EVENT_HOST_ENABLE_DPM_OUT_OF_MEMORY_ZLS_SHIFT 25 +#define EUR_CR_EVENT_HOST_ENABLE_DPM_TA_MEM_FREE_MASK 0x01000000 +#define EUR_CR_EVENT_HOST_ENABLE_DPM_TA_MEM_FREE_SHIFT 24 +#define EUR_CR_EVENT_HOST_ENABLE_ISP_END_TILE_MASK 0x00800000 +#define EUR_CR_EVENT_HOST_ENABLE_ISP_END_TILE_SHIFT 23 +#define EUR_CR_EVENT_HOST_ENABLE_DPM_INITEND_MASK 0x00400000 +#define EUR_CR_EVENT_HOST_ENABLE_DPM_INITEND_SHIFT 22 +#define EUR_CR_EVENT_HOST_ENABLE_OTPM_LOADED_MASK 0x00200000 +#define EUR_CR_EVENT_HOST_ENABLE_OTPM_LOADED_SHIFT 21 +#define EUR_CR_EVENT_HOST_ENABLE_OTPM_INV_MASK 0x00100000 +#define EUR_CR_EVENT_HOST_ENABLE_OTPM_INV_SHIFT 20 +#define EUR_CR_EVENT_HOST_ENABLE_OTPM_FLUSHED_MASK 0x00080000 +#define EUR_CR_EVENT_HOST_ENABLE_OTPM_FLUSHED_SHIFT 19 +#define EUR_CR_EVENT_HOST_ENABLE_PIXELBE_END_RENDER_MASK 0x00040000 +#define EUR_CR_EVENT_HOST_ENABLE_PIXELBE_END_RENDER_SHIFT 18 +#define EUR_CR_EVENT_HOST_ENABLE_ISP_HALT_MASK 0x00020000 +#define EUR_CR_EVENT_HOST_ENABLE_ISP_HALT_SHIFT 17 +#define EUR_CR_EVENT_HOST_ENABLE_ISP_VISIBILITY_FAIL_MASK 0x00010000 +#define EUR_CR_EVENT_HOST_ENABLE_ISP_VISIBILITY_FAIL_SHIFT 16 +#define EUR_CR_EVENT_HOST_ENABLE_BREAKPOINT_MASK 0x00008000 +#define EUR_CR_EVENT_HOST_ENABLE_BREAKPOINT_SHIFT 15 +#define EUR_CR_EVENT_HOST_ENABLE_SW_EVENT_MASK 0x00004000 +#define EUR_CR_EVENT_HOST_ENABLE_SW_EVENT_SHIFT 14 +#define EUR_CR_EVENT_HOST_ENABLE_TA_FINISHED_MASK 0x00002000 +#define EUR_CR_EVENT_HOST_ENABLE_TA_FINISHED_SHIFT 13 +#define EUR_CR_EVENT_HOST_ENABLE_TA_TERMINATE_MASK 0x00001000 +#define EUR_CR_EVENT_HOST_ENABLE_TA_TERMINATE_SHIFT 12 +#define EUR_CR_EVENT_HOST_ENABLE_TPC_CLEAR_MASK 0x00000800 +#define EUR_CR_EVENT_HOST_ENABLE_TPC_CLEAR_SHIFT 11 +#define EUR_CR_EVENT_HOST_ENABLE_TPC_FLUSH_MASK 0x00000400 +#define EUR_CR_EVENT_HOST_ENABLE_TPC_FLUSH_SHIFT 10 +#define EUR_CR_EVENT_HOST_ENABLE_DPM_CONTROL_CLEAR_MASK 0x00000200 +#define EUR_CR_EVENT_HOST_ENABLE_DPM_CONTROL_CLEAR_SHIFT 9 +#define EUR_CR_EVENT_HOST_ENABLE_DPM_CONTROL_LOAD_MASK 0x00000100 +#define EUR_CR_EVENT_HOST_ENABLE_DPM_CONTROL_LOAD_SHIFT 8 +#define EUR_CR_EVENT_HOST_ENABLE_DPM_CONTROL_STORE_MASK 0x00000080 +#define EUR_CR_EVENT_HOST_ENABLE_DPM_CONTROL_STORE_SHIFT 7 +#define EUR_CR_EVENT_HOST_ENABLE_DPM_STATE_CLEAR_MASK 0x00000040 +#define EUR_CR_EVENT_HOST_ENABLE_DPM_STATE_CLEAR_SHIFT 6 +#define EUR_CR_EVENT_HOST_ENABLE_DPM_STATE_LOAD_MASK 0x00000020 +#define EUR_CR_EVENT_HOST_ENABLE_DPM_STATE_LOAD_SHIFT 5 +#define EUR_CR_EVENT_HOST_ENABLE_DPM_STATE_STORE_MASK 0x00000010 +#define EUR_CR_EVENT_HOST_ENABLE_DPM_STATE_STORE_SHIFT 4 +#define EUR_CR_EVENT_HOST_ENABLE_DPM_REACHED_MEM_THRESH_MASK 0x00000008 +#define EUR_CR_EVENT_HOST_ENABLE_DPM_REACHED_MEM_THRESH_SHIFT 3 +#define EUR_CR_EVENT_HOST_ENABLE_DPM_OUT_OF_MEMORY_GBL_MASK 0x00000004 +#define EUR_CR_EVENT_HOST_ENABLE_DPM_OUT_OF_MEMORY_GBL_SHIFT 2 +#define EUR_CR_EVENT_HOST_ENABLE_DPM_OUT_OF_MEMORY_MT_MASK 0x00000002 +#define EUR_CR_EVENT_HOST_ENABLE_DPM_OUT_OF_MEMORY_MT_SHIFT 1 +#define EUR_CR_EVENT_HOST_ENABLE_DPM_3D_MEM_FREE_MASK 0x00000001 +#define EUR_CR_EVENT_HOST_ENABLE_DPM_3D_MEM_FREE_SHIFT 0 +#define EUR_CR_EVENT_HOST_CLEAR 0x0134 +#define EUR_CR_EVENT_HOST_CLEAR_MASTER_INTERRUPT_MASK 0x80000000 +#define EUR_CR_EVENT_HOST_CLEAR_MASTER_INTERRUPT_SHIFT 31 +#define EUR_CR_EVENT_HOST_CLEAR_TIMER_MASK 0x20000000 +#define EUR_CR_EVENT_HOST_CLEAR_TIMER_SHIFT 29 +#define EUR_CR_EVENT_HOST_CLEAR_TA_DPM_FAULT_MASK 0x10000000 +#define EUR_CR_EVENT_HOST_CLEAR_TA_DPM_FAULT_SHIFT 28 +#define EUR_CR_EVENT_HOST_CLEAR_TWOD_COMPLETE_MASK 0x08000000 +#define EUR_CR_EVENT_HOST_CLEAR_TWOD_COMPLETE_SHIFT 27 +#define EUR_CR_EVENT_HOST_CLEAR_MADD_CACHE_INVALCOMPLETE_MASK 0x04000000 +#define EUR_CR_EVENT_HOST_CLEAR_MADD_CACHE_INVALCOMPLETE_SHIFT 26 +#define EUR_CR_EVENT_HOST_CLEAR_DPM_OUT_OF_MEMORY_ZLS_MASK 0x02000000 +#define EUR_CR_EVENT_HOST_CLEAR_DPM_OUT_OF_MEMORY_ZLS_SHIFT 25 +#define EUR_CR_EVENT_HOST_CLEAR_DPM_TA_MEM_FREE_MASK 0x01000000 +#define EUR_CR_EVENT_HOST_CLEAR_DPM_TA_MEM_FREE_SHIFT 24 +#define EUR_CR_EVENT_HOST_CLEAR_ISP_END_TILE_MASK 0x00800000 +#define EUR_CR_EVENT_HOST_CLEAR_ISP_END_TILE_SHIFT 23 +#define EUR_CR_EVENT_HOST_CLEAR_DPM_INITEND_MASK 0x00400000 +#define EUR_CR_EVENT_HOST_CLEAR_DPM_INITEND_SHIFT 22 +#define EUR_CR_EVENT_HOST_CLEAR_OTPM_LOADED_MASK 0x00200000 +#define EUR_CR_EVENT_HOST_CLEAR_OTPM_LOADED_SHIFT 21 +#define EUR_CR_EVENT_HOST_CLEAR_OTPM_INV_MASK 0x00100000 +#define EUR_CR_EVENT_HOST_CLEAR_OTPM_INV_SHIFT 20 +#define EUR_CR_EVENT_HOST_CLEAR_OTPM_FLUSHED_MASK 0x00080000 +#define EUR_CR_EVENT_HOST_CLEAR_OTPM_FLUSHED_SHIFT 19 +#define EUR_CR_EVENT_HOST_CLEAR_PIXELBE_END_RENDER_MASK 0x00040000 +#define EUR_CR_EVENT_HOST_CLEAR_PIXELBE_END_RENDER_SHIFT 18 +#define EUR_CR_EVENT_HOST_CLEAR_ISP_HALT_MASK 0x00020000 +#define EUR_CR_EVENT_HOST_CLEAR_ISP_HALT_SHIFT 17 +#define EUR_CR_EVENT_HOST_CLEAR_ISP_VISIBILITY_FAIL_MASK 0x00010000 +#define EUR_CR_EVENT_HOST_CLEAR_ISP_VISIBILITY_FAIL_SHIFT 16 +#define EUR_CR_EVENT_HOST_CLEAR_BREAKPOINT_MASK 0x00008000 +#define EUR_CR_EVENT_HOST_CLEAR_BREAKPOINT_SHIFT 15 +#define EUR_CR_EVENT_HOST_CLEAR_SW_EVENT_MASK 0x00004000 +#define EUR_CR_EVENT_HOST_CLEAR_SW_EVENT_SHIFT 14 +#define EUR_CR_EVENT_HOST_CLEAR_TA_FINISHED_MASK 0x00002000 +#define EUR_CR_EVENT_HOST_CLEAR_TA_FINISHED_SHIFT 13 +#define EUR_CR_EVENT_HOST_CLEAR_TA_TERMINATE_MASK 0x00001000 +#define EUR_CR_EVENT_HOST_CLEAR_TA_TERMINATE_SHIFT 12 +#define EUR_CR_EVENT_HOST_CLEAR_TPC_CLEAR_MASK 0x00000800 +#define EUR_CR_EVENT_HOST_CLEAR_TPC_CLEAR_SHIFT 11 +#define EUR_CR_EVENT_HOST_CLEAR_TPC_FLUSH_MASK 0x00000400 +#define EUR_CR_EVENT_HOST_CLEAR_TPC_FLUSH_SHIFT 10 +#define EUR_CR_EVENT_HOST_CLEAR_DPM_CONTROL_CLEAR_MASK 0x00000200 +#define EUR_CR_EVENT_HOST_CLEAR_DPM_CONTROL_CLEAR_SHIFT 9 +#define EUR_CR_EVENT_HOST_CLEAR_DPM_CONTROL_LOAD_MASK 0x00000100 +#define EUR_CR_EVENT_HOST_CLEAR_DPM_CONTROL_LOAD_SHIFT 8 +#define EUR_CR_EVENT_HOST_CLEAR_DPM_CONTROL_STORE_MASK 0x00000080 +#define EUR_CR_EVENT_HOST_CLEAR_DPM_CONTROL_STORE_SHIFT 7 +#define EUR_CR_EVENT_HOST_CLEAR_DPM_STATE_CLEAR_MASK 0x00000040 +#define EUR_CR_EVENT_HOST_CLEAR_DPM_STATE_CLEAR_SHIFT 6 +#define EUR_CR_EVENT_HOST_CLEAR_DPM_STATE_LOAD_MASK 0x00000020 +#define EUR_CR_EVENT_HOST_CLEAR_DPM_STATE_LOAD_SHIFT 5 +#define EUR_CR_EVENT_HOST_CLEAR_DPM_STATE_STORE_MASK 0x00000010 +#define EUR_CR_EVENT_HOST_CLEAR_DPM_STATE_STORE_SHIFT 4 +#define EUR_CR_EVENT_HOST_CLEAR_DPM_REACHED_MEM_THRESH_MASK 0x00000008 +#define EUR_CR_EVENT_HOST_CLEAR_DPM_REACHED_MEM_THRESH_SHIFT 3 +#define EUR_CR_EVENT_HOST_CLEAR_DPM_OUT_OF_MEMORY_GBL_MASK 0x00000004 +#define EUR_CR_EVENT_HOST_CLEAR_DPM_OUT_OF_MEMORY_GBL_SHIFT 2 +#define EUR_CR_EVENT_HOST_CLEAR_DPM_OUT_OF_MEMORY_MT_MASK 0x00000002 +#define EUR_CR_EVENT_HOST_CLEAR_DPM_OUT_OF_MEMORY_MT_SHIFT 1 +#define EUR_CR_EVENT_HOST_CLEAR_DPM_3D_MEM_FREE_MASK 0x00000001 +#define EUR_CR_EVENT_HOST_CLEAR_DPM_3D_MEM_FREE_SHIFT 0 +#define EUR_CR_EVENT_KICK1 0x0AB0 +#define EUR_CR_EVENT_KICK1_NOW_MASK 0x000000FF +#define EUR_CR_EVENT_KICK1_NOW_SHIFT 0 +#define EUR_CR_PDS_EXEC_BASE 0x0AB8 +#define EUR_CR_PDS_EXEC_BASE_ADDR_MASK 0x0FF00000 +#define EUR_CR_PDS_EXEC_BASE_ADDR_SHIFT 20 +#define EUR_CR_EVENT_KICK2 0x0AC0 +#define EUR_CR_EVENT_KICK2_NOW_MASK 0x00000001 +#define EUR_CR_EVENT_KICK2_NOW_SHIFT 0 +#define EUR_CR_EVENT_KICKER 0x0AC4 +#define EUR_CR_EVENT_KICKER_ADDRESS_MASK 0x0FFFFFF0 +#define EUR_CR_EVENT_KICKER_ADDRESS_SHIFT 4 +#define EUR_CR_EVENT_KICK 0x0AC8 +#define EUR_CR_EVENT_KICK_NOW_MASK 0x00000001 +#define EUR_CR_EVENT_KICK_NOW_SHIFT 0 +#define EUR_CR_EVENT_TIMER 0x0ACC +#define EUR_CR_EVENT_TIMER_ENABLE_MASK 0x01000000 +#define EUR_CR_EVENT_TIMER_ENABLE_SHIFT 24 +#define EUR_CR_EVENT_TIMER_VALUE_MASK 0x00FFFFFF +#define EUR_CR_EVENT_TIMER_VALUE_SHIFT 0 +#define EUR_CR_PDS_INV0 0x0AD0 +#define EUR_CR_PDS_INV0_DSC_MASK 0x00000001 +#define EUR_CR_PDS_INV0_DSC_SHIFT 0 +#define EUR_CR_PDS_INV1 0x0AD4 +#define EUR_CR_PDS_INV1_DSC_MASK 0x00000001 +#define EUR_CR_PDS_INV1_DSC_SHIFT 0 +#define EUR_CR_EVENT_KICK3 0x0AD8 +#define EUR_CR_EVENT_KICK3_NOW_MASK 0x00000001 +#define EUR_CR_EVENT_KICK3_NOW_SHIFT 0 +#define EUR_CR_PDS_INV3 0x0ADC +#define EUR_CR_PDS_INV3_DSC_MASK 0x00000001 +#define EUR_CR_PDS_INV3_DSC_SHIFT 0 +#define EUR_CR_PDS_INV_CSC 0x0AE0 +#define EUR_CR_PDS_INV_CSC_KICK_MASK 0x00000001 +#define EUR_CR_PDS_INV_CSC_KICK_SHIFT 0 +#define EUR_CR_PDS_PC_BASE 0x0B2C +#define EUR_CR_PDS_PC_BASE_ADDRESS_MASK 0x00FFFFFF +#define EUR_CR_PDS_PC_BASE_ADDRESS_SHIFT 0 +#define EUR_CR_BIF_CTRL 0x0C00 +#define EUR_CR_BIF_CTRL_NOREORDER_MASK 0x00000001 +#define EUR_CR_BIF_CTRL_NOREORDER_SHIFT 0 +#define EUR_CR_BIF_CTRL_PAUSE_MASK 0x00000002 +#define EUR_CR_BIF_CTRL_PAUSE_SHIFT 1 +#define EUR_CR_BIF_CTRL_FLUSH_MASK 0x00000004 +#define EUR_CR_BIF_CTRL_FLUSH_SHIFT 2 +#define EUR_CR_BIF_CTRL_INVALDC_MASK 0x00000008 +#define EUR_CR_BIF_CTRL_INVALDC_SHIFT 3 +#define EUR_CR_BIF_CTRL_CLEAR_FAULT_MASK 0x00000010 +#define EUR_CR_BIF_CTRL_CLEAR_FAULT_SHIFT 4 +#define EUR_CR_BIF_CTRL_MMU_BYPASS_CACHE_MASK 0x00000100 +#define EUR_CR_BIF_CTRL_MMU_BYPASS_CACHE_SHIFT 8 +#define EUR_CR_BIF_CTRL_MMU_BYPASS_VDM_MASK 0x00000200 +#define EUR_CR_BIF_CTRL_MMU_BYPASS_VDM_SHIFT 9 +#define EUR_CR_BIF_CTRL_MMU_BYPASS_TE_MASK 0x00000400 +#define EUR_CR_BIF_CTRL_MMU_BYPASS_TE_SHIFT 10 +#define EUR_CR_BIF_CTRL_MMU_BYPASS_PBE_MASK 0x00001000 +#define EUR_CR_BIF_CTRL_MMU_BYPASS_PBE_SHIFT 12 +#define EUR_CR_BIF_CTRL_MMU_BYPASS_TSPP_MASK 0x00002000 +#define EUR_CR_BIF_CTRL_MMU_BYPASS_TSPP_SHIFT 13 +#define EUR_CR_BIF_CTRL_MMU_BYPASS_ISP_MASK 0x00004000 +#define EUR_CR_BIF_CTRL_MMU_BYPASS_ISP_SHIFT 14 +#define EUR_CR_BIF_CTRL_MMU_BYPASS_USE_MASK 0x00008000 +#define EUR_CR_BIF_CTRL_MMU_BYPASS_USE_SHIFT 15 +#define EUR_CR_BIF_INT_STAT 0x0C04 +#define EUR_CR_BIF_INT_STAT_FAULT_MASK 0x00003FFF +#define EUR_CR_BIF_INT_STAT_FAULT_SHIFT 0 +#define EUR_CR_BIF_INT_STAT_PF_N_RW_MASK 0x00004000 +#define EUR_CR_BIF_INT_STAT_PF_N_RW_SHIFT 14 +#define EUR_CR_BIF_INT_STAT_FLUSH_COMPLETE_MASK 0x00008000 +#define EUR_CR_BIF_INT_STAT_FLUSH_COMPLETE_SHIFT 15 +#define EUR_CR_BIF_FAULT 0x0C08 +#define EUR_CR_BIF_FAULT_SB_MASK 0x000001F0 +#define EUR_CR_BIF_FAULT_SB_SHIFT 4 +#define EUR_CR_BIF_FAULT_ADDR_MASK 0x0FFFF000 +#define EUR_CR_BIF_FAULT_ADDR_SHIFT 12 +#define EUR_CR_BIF_DIR_LIST_BASE0 0x0C84 +#define EUR_CR_BIF_DIR_LIST_BASE0_ADDR_MASK 0xFFFFF000 +#define EUR_CR_BIF_DIR_LIST_BASE0_ADDR_SHIFT 12 +#define EUR_CR_BIF_TA_REQ_BASE 0x0C90 +#define EUR_CR_BIF_TA_REQ_BASE_ADDR_MASK 0x0FF00000 +#define EUR_CR_BIF_TA_REQ_BASE_ADDR_SHIFT 20 +#define EUR_CR_BIF_MEM_REQ_STAT 0x0CA8 +#define EUR_CR_BIF_MEM_REQ_STAT_READS_MASK 0x000000FF +#define EUR_CR_BIF_MEM_REQ_STAT_READS_SHIFT 0 +#define EUR_CR_BIF_3D_REQ_BASE 0x0CAC +#define EUR_CR_BIF_3D_REQ_BASE_ADDR_MASK 0x0FF00000 +#define EUR_CR_BIF_3D_REQ_BASE_ADDR_SHIFT 20 +#define EUR_CR_BIF_ZLS_REQ_BASE 0x0CB0 +#define EUR_CR_BIF_ZLS_REQ_BASE_ADDR_MASK 0x0FF00000 +#define EUR_CR_BIF_ZLS_REQ_BASE_ADDR_SHIFT 20 +#define EUR_CR_2D_BLIT_STATUS 0x0E04 +#define EUR_CR_2D_BLIT_STATUS_COMPLETE_MASK 0x00FFFFFF +#define EUR_CR_2D_BLIT_STATUS_COMPLETE_SHIFT 0 +#define EUR_CR_2D_BLIT_STATUS_BUSY_MASK 0x01000000 +#define EUR_CR_2D_BLIT_STATUS_BUSY_SHIFT 24 +#define EUR_CR_2D_VIRTUAL_FIFO_0 0x0E10 +#define EUR_CR_2D_VIRTUAL_FIFO_0_ENABLE_MASK 0x00000001 +#define EUR_CR_2D_VIRTUAL_FIFO_0_ENABLE_SHIFT 0 +#define EUR_CR_2D_VIRTUAL_FIFO_0_FLOWRATE_MASK 0x0000000E +#define EUR_CR_2D_VIRTUAL_FIFO_0_FLOWRATE_SHIFT 1 +#define EUR_CR_2D_VIRTUAL_FIFO_0_FLOWRATE_DIV_MASK 0x00000FF0 +#define EUR_CR_2D_VIRTUAL_FIFO_0_FLOWRATE_DIV_SHIFT 4 +#define EUR_CR_2D_VIRTUAL_FIFO_0_FLOWRATE_MUL_MASK 0x0000F000 +#define EUR_CR_2D_VIRTUAL_FIFO_0_FLOWRATE_MUL_SHIFT 12 +#define EUR_CR_2D_VIRTUAL_FIFO_1 0x0E14 +#define EUR_CR_2D_VIRTUAL_FIFO_1_MIN_ACC_MASK 0x00000FFF +#define EUR_CR_2D_VIRTUAL_FIFO_1_MIN_ACC_SHIFT 0 +#define EUR_CR_2D_VIRTUAL_FIFO_1_MAX_ACC_MASK 0x00FFF000 +#define EUR_CR_2D_VIRTUAL_FIFO_1_MAX_ACC_SHIFT 12 +#define EUR_CR_2D_VIRTUAL_FIFO_1_MIN_METRIC_MASK 0xFF000000 +#define EUR_CR_2D_VIRTUAL_FIFO_1_MIN_METRIC_SHIFT 24 +#define EUR_CR_USE_CODE_BASE(X) (0x0A0C + (4 * (X))) +#define EUR_CR_USE_CODE_BASE_ADDR_MASK 0x00FFFFFF +#define EUR_CR_USE_CODE_BASE_ADDR_SHIFT 0 +#define EUR_CR_USE_CODE_BASE_DM_MASK 0x03000000 +#define EUR_CR_USE_CODE_BASE_DM_SHIFT 24 +#define EUR_CR_USE_CODE_BASE_SIZE_UINT32 16 +#define EUR_CR_USE_CODE_BASE_NUM_ENTRIES 16 +#define EUR_CR_MNE_CR_CTRL 0x0D00 +#define EUR_CR_MNE_CR_CTRL_BYP_CC_N_MASK 0x00010000 +#define EUR_CR_MNE_CR_CTRL_BYP_CC_N_SHIFT 16 +#define EUR_CR_MNE_CR_CTRL_BYP_CC_MASK 0x00008000 +#define EUR_CR_MNE_CR_CTRL_BYP_CC_SHIFT 15 +#define EUR_CR_MNE_CR_CTRL_USE_INVAL_ADDR_MASK 0x00007800 +#define EUR_CR_MNE_CR_CTRL_USE_INVAL_ADDR_SHIFT 11 +#define EUR_CR_MNE_CR_CTRL_BYPASS_ALL_MASK 0x00000400 +#define EUR_CR_MNE_CR_CTRL_BYPASS_ALL_SHIFT 10 +#define EUR_CR_MNE_CR_CTRL_BYPASS_MASK 0x000003E0 +#define EUR_CR_MNE_CR_CTRL_BYPASS_SHIFT 5 +#define EUR_CR_MNE_CR_CTRL_PAUSE_MASK 0x00000010 +#define EUR_CR_MNE_CR_CTRL_PAUSE_SHIFT 4 +#define EUR_CR_MNE_CR_CTRL_INVAL_PREQ_MASK 0x0000000E +#define EUR_CR_MNE_CR_CTRL_INVAL_PREQ_SHIFT 1 +#define EUR_CR_MNE_CR_CTRL_INVAL_PREQ_PDS_MASK (1< + * Home Park Estate, Kings Langley, Herts, WD4 8LZ, UK + * + ******************************************************************************/ + +#ifndef _SGXCORETYPES_KM_H_ +#define _SGXCORETYPES_KM_H_ + +typedef enum +{ + SGX_CORE_ID_INVALID = 0, + SGX_CORE_ID_530 = 2, + SGX_CORE_ID_535 = 3, +} SGX_CORE_ID_TYPE; + +typedef struct _SGX_CORE_INFO +{ + SGX_CORE_ID_TYPE eID; + IMG_UINT32 uiRev; +} SGX_CORE_INFO, *PSGX_CORE_INFO; + +#endif + diff --git a/services4/srvkm/hwdefs/sgxdefs.h b/services4/srvkm/hwdefs/sgxdefs.h new file mode 100644 index 0000000..0f92a31 --- /dev/null +++ b/services4/srvkm/hwdefs/sgxdefs.h @@ -0,0 +1,74 @@ +/********************************************************************** + * + * Copyright(c) 2008 Imagination Technologies Ltd. All rights reserved. + * + * This program is free software; you can redistribute it and/or modify it + * under the terms and conditions of the GNU General Public License, + * version 2, as published by the Free Software Foundation. + * + * This program is distributed in the hope it will be useful but, except + * as otherwise stated in writing, without any warranty; without even the + * implied warranty of merchantability or fitness for a particular purpose. + * See the GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License along with + * this program; if not, write to the Free Software Foundation, Inc., + * 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA. + * + * The full GNU General Public License is included in this distribution in + * the file called "COPYING". + * + * Contact Information: + * Imagination Technologies Ltd. + * Home Park Estate, Kings Langley, Herts, WD4 8LZ, UK + * + ******************************************************************************/ + +#ifndef _SGXDEFS_H_ +#define _SGXDEFS_H_ + +#if defined(SGX520) +#include "sgx520defs.h" +#else +#if defined(SGX530) +#include "sgx530defs.h" +#else +#if defined(SGX535) +#include "sgx535defs.h" +#else +#if defined(SGX535_V1_1) +#include "sgx535defs.h" +#else +#if defined(SGX540) +#include "sgx540defs.h" +#else +#if defined(SGX541) +#include "sgx541defs.h" +#else +#if defined(SGX543) +#include "sgx543defs.h" +#else +#if defined(SGX545) +#include "sgx545defs.h" +#else +#if defined(SGX531) +#include "sgx531defs.h" +#endif +#endif +#endif +#endif +#endif +#endif +#endif +#endif +#endif + +#if defined(SGX_FEATURE_MP) +#include "sgxmpdefs.h" +#endif + +#include "sgxerrata.h" +#include "sgxfeaturedefs.h" + +#endif + diff --git a/services4/srvkm/hwdefs/sgxerrata.h b/services4/srvkm/hwdefs/sgxerrata.h new file mode 100644 index 0000000..ba4b9c3 --- /dev/null +++ b/services4/srvkm/hwdefs/sgxerrata.h @@ -0,0 +1,274 @@ +/********************************************************************** + * + * Copyright(c) 2008 Imagination Technologies Ltd. All rights reserved. + * + * This program is free software; you can redistribute it and/or modify it + * under the terms and conditions of the GNU General Public License, + * version 2, as published by the Free Software Foundation. + * + * This program is distributed in the hope it will be useful but, except + * as otherwise stated in writing, without any warranty; without even the + * implied warranty of merchantability or fitness for a particular purpose. + * See the GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License along with + * this program; if not, write to the Free Software Foundation, Inc., + * 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA. + * + * The full GNU General Public License is included in this distribution in + * the file called "COPYING". + * + * Contact Information: + * Imagination Technologies Ltd. + * Home Park Estate, Kings Langley, Herts, WD4 8LZ, UK + * + ******************************************************************************/ + +#ifndef _SGXERRATA_KM_H_ +#define _SGXERRATA_KM_H_ + + +#if defined(SGX520) && !defined(SGX_CORE_DEFINED) + + #define SGX_CORE_REV_HEAD 0 + #if defined(USE_SGX_CORE_REV_HEAD) + + #define SGX_CORE_REV SGX_CORE_REV_HEAD + #endif + + #if SGX_CORE_REV == 100 + #else + #if SGX_CORE_REV == SGX_CORE_REV_HEAD + + #else + #error "sgxerrata.h: SGX520 Core Revision unspecified" + #endif + #endif + + #define SGX_CORE_DEFINED +#endif + +#if defined(SGX530) && !defined(SGX_CORE_DEFINED) + + #define SGX_CORE_REV_HEAD 0 + #if defined(USE_SGX_CORE_REV_HEAD) + + #define SGX_CORE_REV SGX_CORE_REV_HEAD + #endif + + #if SGX_CORE_REV == 103 + #define FIX_HW_BRN_22934 + #else + #if SGX_CORE_REV == 110 + #define FIX_HW_BRN_22934 + #else + #if SGX_CORE_REV == 111 + #define FIX_HW_BRN_22934 + #else + #if SGX_CORE_REV == 120 + #define FIX_HW_BRN_22934 + #else + #if SGX_CORE_REV == 121 + #define FIX_HW_BRN_22934 + #else + #if SGX_CORE_REV == 125 + #else + #if SGX_CORE_REV == SGX_CORE_REV_HEAD + + #else + #error "sgxerrata.h: SGX530 Core Revision unspecified" + #endif + #endif + #endif + #endif + #endif +#endif + #endif + + #define SGX_CORE_DEFINED +#endif + +#if defined(SGX531) && !defined(SGX_CORE_DEFINED) + + #define SGX_CORE_REV_HEAD 0 + #if defined(USE_SGX_CORE_REV_HEAD) + + #define SGX_CORE_REV SGX_CORE_REV_HEAD + #endif + + #if SGX_CORE_REV == 101 + #define FIX_HW_BRN_26620 + #else + #if SGX_CORE_REV == SGX_CORE_REV_HEAD + + #else + #error "sgxerrata.h: SGX531 Core Revision unspecified" + #endif + #endif + + #define SGX_CORE_DEFINED +#endif + +#if (defined(SGX535) || defined(SGX535_V1_1)) && !defined(SGX_CORE_DEFINED) + + #define SGX_CORE_REV_HEAD 0 + #if defined(USE_SGX_CORE_REV_HEAD) + + #define SGX_CORE_REV SGX_CORE_REV_HEAD + #endif + + #if SGX_CORE_REV == 111 + #define FIX_HW_BRN_23281 + #define FIX_HW_BRN_23410 + #define FIX_HW_BRN_22693 + #define FIX_HW_BRN_22934 + #define FIX_HW_BRN_22997 + #define FIX_HW_BRN_23030 + #else + #if SGX_CORE_REV == 1111 + #define FIX_HW_BRN_23281 + #define FIX_HW_BRN_23410 + #define FIX_HW_BRN_22693 + #define FIX_HW_BRN_22934 + #define FIX_HW_BRN_22997 + #define FIX_HW_BRN_23030 + #else + #if SGX_CORE_REV == 112 + #define FIX_HW_BRN_23281 + #define FIX_HW_BRN_23410 + #define FIX_HW_BRN_22693 + #define FIX_HW_BRN_22934 + #define FIX_HW_BRN_22997 + #define FIX_HW_BRN_23030 + #else + #if SGX_CORE_REV == 113 + #define FIX_HW_BRN_22934 + #define FIX_HW_BRN_23281 + #define FIX_HW_BRN_23944 + #define FIX_HW_BRN_23410 + #else + #if SGX_CORE_REV == 121 + #define FIX_HW_BRN_22934 + #define FIX_HW_BRN_23944 + #define FIX_HW_BRN_23410 + #else + #if SGX_CORE_REV == SGX_CORE_REV_HEAD + + #else + #error "sgxerrata.h: SGX535 Core Revision unspecified" + + #endif + #endif + #endif + #endif + #endif + #endif + + #define SGX_CORE_DEFINED +#endif + +#if defined(SGX540) && !defined(SGX_CORE_DEFINED) + + #define SGX_CORE_REV_HEAD 0 + #if defined(USE_SGX_CORE_REV_HEAD) + + #define SGX_CORE_REV SGX_CORE_REV_HEAD + #endif + + #if SGX_CORE_REV == 101 + #define FIX_HW_BRN_25499 + #define FIX_HW_BRN_25503 + #define FIX_HW_BRN_26620 + #else + #if SGX_CORE_REV == 110 + #define FIX_HW_BRN_25503 + #define FIX_HW_BRN_26620 + #else + #if SGX_CORE_REV == 120 + #else + #if SGX_CORE_REV == SGX_CORE_REV_HEAD + + #else + #error "sgxerrata.h: SGX540 Core Revision unspecified" + #endif + #endif + #endif + #endif + + #define SGX_CORE_DEFINED +#endif + +#if defined(SGX541) && !defined(SGX_CORE_DEFINED) + + #define SGX_CORE_REV_HEAD 0 + #if defined(USE_SGX_CORE_REV_HEAD) + + #define SGX_CORE_REV SGX_CORE_REV_HEAD + #endif + + #if SGX_CORE_REV == 100 + + #else + #if SGX_CORE_REV == SGX_CORE_REV_HEAD + + #else + #error "sgxerrata.h: SGX541 Core Revision unspecified" + #endif + #endif + + #define SGX_CORE_DEFINED +#endif + +#if defined(SGX543) && !defined(SGX_CORE_DEFINED) + + #define SGX_CORE_REV_HEAD 0 + #if defined(USE_SGX_CORE_REV_HEAD) + + #define SGX_CORE_REV SGX_CORE_REV_HEAD + #endif + + #if SGX_CORE_REV == 100 + + #else + #if SGX_CORE_REV == SGX_CORE_REV_HEAD + + #else + #error "sgxerrata.h: SGX543 Core Revision unspecified" + #endif + #endif + + #define SGX_CORE_DEFINED +#endif + +#if defined(SGX545) && !defined(SGX_CORE_DEFINED) + + #define SGX_CORE_REV_HEAD 0 + #if defined(USE_SGX_CORE_REV_HEAD) + + #define SGX_CORE_REV SGX_CORE_REV_HEAD + #endif + + #if SGX_CORE_REV == 100 + #define FIX_HW_BRN_26620 + #else + #if SGX_CORE_REV == SGX_CORE_REV_HEAD + + #else + #error "sgxerrata.h: SGX545 Core Revision unspecified" + #endif + #endif + + #define SGX_CORE_DEFINED +#endif + +#if !defined(SGX_CORE_DEFINED) +#if defined (__GNUC__) + #warning "sgxerrata.h: SGX Core Version unspecified" +#else + #pragma message("sgxerrata.h: SGX Core Version unspecified") +#endif +#endif + + +#endif + diff --git a/services4/srvkm/hwdefs/sgxfeaturedefs.h b/services4/srvkm/hwdefs/sgxfeaturedefs.h new file mode 100644 index 0000000..a161658 --- /dev/null +++ b/services4/srvkm/hwdefs/sgxfeaturedefs.h @@ -0,0 +1,161 @@ +/********************************************************************** + * + * Copyright(c) 2008 Imagination Technologies Ltd. All rights reserved. + * + * This program is free software; you can redistribute it and/or modify it + * under the terms and conditions of the GNU General Public License, + * version 2, as published by the Free Software Foundation. + * + * This program is distributed in the hope it will be useful but, except + * as otherwise stated in writing, without any warranty; without even the + * implied warranty of merchantability or fitness for a particular purpose. + * See the GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License along with + * this program; if not, write to the Free Software Foundation, Inc., + * 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA. + * + * The full GNU General Public License is included in this distribution in + * the file called "COPYING". + * + * Contact Information: + * Imagination Technologies Ltd. + * Home Park Estate, Kings Langley, Herts, WD4 8LZ, UK + * + ******************************************************************************/ + +#if defined(SGX520) + #define SGX_CORE_FRIENDLY_NAME "SGX520" + #define SGX_CORE_ID SGX_CORE_ID_520 + #define SGX_FEATURE_ADDRESS_SPACE_SIZE (28) + #define SGX_FEATURE_AUTOCLOCKGATING +#else +#if defined(SGX530) + #define SGX_CORE_FRIENDLY_NAME "SGX530" + #define SGX_CORE_ID SGX_CORE_ID_530 + #define SGX_FEATURE_ADDRESS_SPACE_SIZE (28) + #define SGX_FEATURE_AUTOCLOCKGATING +#else +#if defined(SGX535) + #define SGX_CORE_FRIENDLY_NAME "SGX535" + #define SGX_CORE_ID SGX_CORE_ID_535 + #define SGX_FEATURE_ADDRESS_SPACE_SIZE (32) + #define SGX_FEATURE_MULTIPLE_MEM_CONTEXTS + #define SGX_FEATURE_BIF_NUM_DIRLISTS (16) + #define SGX_FEATURE_2D_HARDWARE + #define SGX_FEATURE_AUTOCLOCKGATING + #define SUPPORT_SGX_GENERAL_MAPPING_HEAP +#else +#if defined(SGX540) + #define SGX_CORE_FRIENDLY_NAME "SGX540" + #define SGX_CORE_ID SGX_CORE_ID_540 + #define SGX_FEATURE_ADDRESS_SPACE_SIZE (28) + #define SGX_FEATURE_AUTOCLOCKGATING + #define SGX_FEATURE_MULTI_EVENT_KICK +#else +#if defined(SGX541) + #define SGX_CORE_FRIENDLY_NAME "SGX541" + #define SGX_CORE_ID SGX_CORE_ID_541 + #define SGX_FEATURE_ADDRESS_SPACE_SIZE (32) + #define SGX_FEATURE_MULTIPLE_MEM_CONTEXTS + #define SGX_FEATURE_BIF_NUM_DIRLISTS (8) + #define SGX_FEATURE_AUTOCLOCKGATING + #define SGX_FEATURE_SPM_MODE_0 + #define SGX_FEATURE_MULTI_EVENT_KICK +#else +#if defined(SGX543) + #define SGX_CORE_FRIENDLY_NAME "SGX543" + #define SGX_CORE_ID SGX_CORE_ID_543 + #define SGX_FEATURE_USE_NO_INSTRUCTION_PAIRING + #define SGX_FEATURE_USE_UNLIMITED_PHASES + #define SGX_FEATURE_ADDRESS_SPACE_SIZE (32) + #define SGX_FEATURE_MULTIPLE_MEM_CONTEXTS + #define SGX_FEATURE_BIF_NUM_DIRLISTS (8) + #define SGX_FEATURE_AUTOCLOCKGATING + #define SGX_FEATURE_MONOLITHIC_UKERNEL + #define SGX_FEATURE_SPM_MODE_0 + #define SGX_FEATURE_MULTI_EVENT_KICK +#else +#if defined(SGX531) + #define SGX_CORE_FRIENDLY_NAME "SGX531" + #define SGX_CORE_ID SGX_CORE_ID_531 + #define SGX_FEATURE_ADDRESS_SPACE_SIZE (28) + #define SGX_FEATURE_AUTOCLOCKGATING + #define SGX_FEATURE_MULTI_EVENT_KICK +#else +#if defined(SGX545) + #define SGX_CORE_FRIENDLY_NAME "SGX545" + #define SGX_CORE_ID SGX_CORE_ID_545 + #define SGX_FEATURE_ADDRESS_SPACE_SIZE (32) + #define SGX_FEATURE_AUTOCLOCKGATING + #define SGX_FEATURE_USE_NO_INSTRUCTION_PAIRING + #define SGX_FEATURE_USE_UNLIMITED_PHASES + #define SGX_FEATURE_DXT_TEXTURES + #define SGX_FEATURE_VOLUME_TEXTURES + #define SGX_FEATURE_EDM_VERTEX_PDSADDR_FULL_RANGE + #define SGX_FEATURE_HOST_ALLOC_FROM_DPM + #define SGX_FEATURE_MULTIPLE_MEM_CONTEXTS + #define SGX_FEATURE_MULTIPLE_MEM_CONTEXTS + #define SGX_FEATURE_BIF_NUM_DIRLISTS (16) + #define SGX_FEATURE_NUM_USE_PIPES (4) + #define SGX_FEATURE_TEXTURESTRIDE_EXTENSION + #define SGX_FEATURE_PDS_DATA_INTERLEAVE_2DWORDS + #define SGX_FEATURE_MONOLITHIC_UKERNEL + #define SGX_FEATURE_ZLS_EXTERNALZ + #define SGX_FEATURE_VDM_CONTEXT_SWITCH_REV_2 + #define SGX_FEATURE_ISP_CONTEXT_SWITCH_REV_2 + #define SGX_FEATURE_NUM_PDS_PIPES (2) + #define SGX_FEATURE_NATIVE_BACKWARD_BLIT + + #define SGX_FEATURE_MAX_TA_RENDER_TARGETS (512) + #define SGX_FEATURE_SPM_MODE_0 + + + + + #define SGX_FEATURE_SECONDARY_REQUIRES_USE_KICK + #define SGX_FEATURE_DCU + #define SGX_FEATURE_MULTI_EVENT_KICK +#endif +#endif +#endif +#endif +#endif +#endif +#endif +#endif + +#if defined(SGX_FEATURE_MP) +#if !defined(SGX_FEATURE_MP_CORE_COUNT) +#error SGX_FEATURE_MP_CORE_COUNT must be defined when SGX_FEATURE_MP is defined +#endif +#else +#define SGX_FEATURE_MP_CORE_COUNT (1) +#endif + + +#if defined(SUPPORT_SGX_LOW_LATENCY_SCHEDULING) && !defined(SUPPORT_SGX_PRIORITY_SCHEDULING) + #define SUPPORT_SGX_PRIORITY_SCHEDULING +#endif + +#if !defined(SGX_DONT_SWITCH_OFF_FEATURES) + +#if defined(FIX_HW_BRN_22934) \ + || defined(FIX_HW_BRN_25499) +#undef SGX_FEATURE_MULTI_EVENT_KICK +#endif + +#if defined(FIX_HW_BRN_22693) +#undef SGX_FEATURE_AUTOCLOCKGATING +#endif + +#endif + +#if defined(FIX_HW_BRN_26620) && defined(SGX_FEATURE_SYSTEM_CACHE) && !defined(SGX_FEATURE_MULTI_EVENT_KICK) + #define SGX_BYPASS_SYSTEM_CACHE +#endif + +#include "img_types.h" + +#include "sgxcoretypes.h" + diff --git a/services4/srvkm/hwdefs/sgxmmu.h b/services4/srvkm/hwdefs/sgxmmu.h new file mode 100644 index 0000000..2100788 --- /dev/null +++ b/services4/srvkm/hwdefs/sgxmmu.h @@ -0,0 +1,66 @@ +/********************************************************************** + * + * Copyright(c) 2008 Imagination Technologies Ltd. All rights reserved. + * + * This program is free software; you can redistribute it and/or modify it + * under the terms and conditions of the GNU General Public License, + * version 2, as published by the Free Software Foundation. + * + * This program is distributed in the hope it will be useful but, except + * as otherwise stated in writing, without any warranty; without even the + * implied warranty of merchantability or fitness for a particular purpose. + * See the GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License along with + * this program; if not, write to the Free Software Foundation, Inc., + * 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA. + * + * The full GNU General Public License is included in this distribution in + * the file called "COPYING". + * + * Contact Information: + * Imagination Technologies Ltd. + * Home Park Estate, Kings Langley, Herts, WD4 8LZ, UK + * + ******************************************************************************/ + +#if !defined(__SGXMMU_KM_H__) +#define __SGXMMU_KM_H__ + +#define SGX_MMU_PAGE_SHIFT (12) +#define SGX_MMU_PAGE_SIZE (1UL< + * Home Park Estate, Kings Langley, Herts, WD4 8LZ, UK + * + ******************************************************************************/ + +#ifndef _BUFFER_MANAGER_H_ +#define _BUFFER_MANAGER_H_ + +#include "img_types.h" +#include "ra.h" +#include "perproc.h" + +#if defined(__cplusplus) +extern "C"{ +#endif + +typedef struct _BM_HEAP_ BM_HEAP; + +struct _BM_MAPPING_ +{ + enum + { + hm_wrapped = 1, + hm_wrapped_scatter, + hm_wrapped_virtaddr, + hm_wrapped_scatter_virtaddr, + hm_env, + hm_contiguous + } eCpuMemoryOrigin; + + BM_HEAP *pBMHeap; + RA_ARENA *pArena; + + IMG_CPU_VIRTADDR CpuVAddr; + IMG_CPU_PHYADDR CpuPAddr; + IMG_DEV_VIRTADDR DevVAddr; + IMG_SYS_PHYADDR *psSysAddr; + IMG_SIZE_T uSize; + IMG_HANDLE hOSMemHandle; + IMG_UINT32 ui32Flags; +}; + +typedef struct _BM_BUF_ +{ + IMG_CPU_VIRTADDR *CpuVAddr; + IMG_VOID *hOSMemHandle; + IMG_CPU_PHYADDR CpuPAddr; + IMG_DEV_VIRTADDR DevVAddr; + + BM_MAPPING *pMapping; + IMG_UINT32 ui32RefCount; +} BM_BUF; + +struct _BM_HEAP_ +{ + IMG_UINT32 ui32Attribs; + BM_CONTEXT *pBMContext; + RA_ARENA *pImportArena; + RA_ARENA *pLocalDevMemArena; + RA_ARENA *pVMArena; + DEV_ARENA_DESCRIPTOR sDevArena; + MMU_HEAP *pMMUHeap; + + struct _BM_HEAP_ *psNext; +}; + +struct _BM_CONTEXT_ +{ + MMU_CONTEXT *psMMUContext; + + + BM_HEAP *psBMHeap; + + + BM_HEAP *psBMSharedHeap; + + PVRSRV_DEVICE_NODE *psDeviceNode; + + + HASH_TABLE *pBufferHash; + + + IMG_HANDLE hResItem; + + IMG_UINT32 ui32RefCount; + + + + struct _BM_CONTEXT_ *psNext; +}; + + + +typedef IMG_VOID *BM_HANDLE; + +#define BP_POOL_MASK 0x7 + +#define BP_CONTIGUOUS (1 << 3) +#define BP_PARAMBUFFER (1 << 4) + +#define BM_MAX_DEVMEM_ARENAS 2 + +IMG_HANDLE +BM_CreateContext(PVRSRV_DEVICE_NODE *psDeviceNode, + IMG_DEV_PHYADDR *psPDDevPAddr, + PVRSRV_PER_PROCESS_DATA *psPerProc, + IMG_BOOL *pbCreated); + + +PVRSRV_ERROR +BM_DestroyContext (IMG_HANDLE hBMContext, + IMG_BOOL *pbCreated); + + +IMG_HANDLE +BM_CreateHeap (IMG_HANDLE hBMContext, + DEVICE_MEMORY_HEAP_INFO *psDevMemHeapInfo); + +IMG_VOID +BM_DestroyHeap (IMG_HANDLE hDevMemHeap); + + +IMG_BOOL +BM_Reinitialise (PVRSRV_DEVICE_NODE *psDeviceNode); + +IMG_BOOL +BM_Alloc (IMG_HANDLE hDevMemHeap, + IMG_DEV_VIRTADDR *psDevVAddr, + IMG_SIZE_T uSize, + IMG_UINT32 *pui32Flags, + IMG_UINT32 uDevVAddrAlignment, + BM_HANDLE *phBuf); + +IMG_BOOL +BM_Wrap ( IMG_HANDLE hDevMemHeap, + IMG_UINT32 ui32Size, + IMG_UINT32 ui32Offset, + IMG_BOOL bPhysContig, + IMG_SYS_PHYADDR *psSysAddr, + IMG_VOID *pvCPUVAddr, + IMG_UINT32 *pui32Flags, + BM_HANDLE *phBuf); + +IMG_VOID +BM_Free (BM_HANDLE hBuf, + IMG_UINT32 ui32Flags); + + +IMG_CPU_VIRTADDR +BM_HandleToCpuVaddr (BM_HANDLE hBuf); + +IMG_DEV_VIRTADDR +BM_HandleToDevVaddr (BM_HANDLE hBuf); + +IMG_SYS_PHYADDR +BM_HandleToSysPaddr (BM_HANDLE hBuf); + +IMG_HANDLE +BM_HandleToOSMemHandle (BM_HANDLE hBuf); + +IMG_BOOL +BM_ContiguousStatistics (IMG_UINT32 uFlags, + IMG_UINT32 *pTotalBytes, + IMG_UINT32 *pAvailableBytes); + + +PVRSRV_ERROR BM_GetPhysPageAddr(PVRSRV_KERNEL_MEM_INFO *psMemInfo, + IMG_DEV_VIRTADDR sDevVPageAddr, + IMG_DEV_PHYADDR *psDevPAddr); + +PVRSRV_ERROR BM_GetHeapInfo(IMG_HANDLE hDevMemHeap, + PVRSRV_HEAP_INFO *psHeapInfo); + +MMU_CONTEXT* BM_GetMMUContext(IMG_HANDLE hDevMemHeap); + +MMU_CONTEXT* BM_GetMMUContextFromMemContext(IMG_HANDLE hDevMemContext); + +IMG_HANDLE BM_GetMMUHeap(IMG_HANDLE hDevMemHeap); + +PVRSRV_DEVICE_NODE* BM_GetDeviceNode(IMG_HANDLE hDevMemContext); + + +IMG_HANDLE BM_GetMappingHandle(PVRSRV_KERNEL_MEM_INFO *psMemInfo); + +#if defined(__cplusplus) +} +#endif + +#endif + diff --git a/services4/srvkm/include/device.h b/services4/srvkm/include/device.h new file mode 100644 index 0000000..31ee11e --- /dev/null +++ b/services4/srvkm/include/device.h @@ -0,0 +1,277 @@ +/********************************************************************** + * + * Copyright(c) 2008 Imagination Technologies Ltd. All rights reserved. + * + * This program is free software; you can redistribute it and/or modify it + * under the terms and conditions of the GNU General Public License, + * version 2, as published by the Free Software Foundation. + * + * This program is distributed in the hope it will be useful but, except + * as otherwise stated in writing, without any warranty; without even the + * implied warranty of merchantability or fitness for a particular purpose. + * See the GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License along with + * this program; if not, write to the Free Software Foundation, Inc., + * 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA. + * + * The full GNU General Public License is included in this distribution in + * the file called "COPYING". + * + * Contact Information: + * Imagination Technologies Ltd. + * Home Park Estate, Kings Langley, Herts, WD4 8LZ, UK + * + ******************************************************************************/ + +#ifndef __DEVICE_H__ +#define __DEVICE_H__ + +#if defined(__cplusplus) +extern "C" { +#endif + +#include "ra.h" +#include "resman.h" + +typedef struct _BM_CONTEXT_ BM_CONTEXT; + +typedef struct _MMU_HEAP_ MMU_HEAP; +typedef struct _MMU_CONTEXT_ MMU_CONTEXT; + +#define PVRSRV_BACKINGSTORE_SYSMEM_CONTIG (1<<(PVRSRV_MEM_BACKINGSTORE_FIELD_SHIFT+0)) +#define PVRSRV_BACKINGSTORE_SYSMEM_NONCONTIG (1<<(PVRSRV_MEM_BACKINGSTORE_FIELD_SHIFT+1)) +#define PVRSRV_BACKINGSTORE_LOCALMEM_CONTIG (1<<(PVRSRV_MEM_BACKINGSTORE_FIELD_SHIFT+2)) +#define PVRSRV_BACKINGSTORE_LOCALMEM_NONCONTIG (1<<(PVRSRV_MEM_BACKINGSTORE_FIELD_SHIFT+3)) + +typedef IMG_UINT32 DEVICE_MEMORY_HEAP_TYPE; +#define DEVICE_MEMORY_HEAP_PERCONTEXT 0 +#define DEVICE_MEMORY_HEAP_KERNEL 1 +#define DEVICE_MEMORY_HEAP_SHARED 2 +#define DEVICE_MEMORY_HEAP_SHARED_EXPORTED 3 + +#define PVRSRV_DEVICE_NODE_FLAGS_PORT80DISPLAY 1 +#define PVRSRV_DEVICE_NODE_FLAGS_MMU_OPT_INV 2 + +typedef struct _DEVICE_MEMORY_HEAP_INFO_ +{ + + IMG_UINT32 ui32HeapID; + + + IMG_CHAR *pszName; + + + IMG_CHAR *pszBSName; + + + IMG_DEV_VIRTADDR sDevVAddrBase; + + + IMG_UINT32 ui32HeapSize; + + + IMG_UINT32 ui32Attribs; + + + DEVICE_MEMORY_HEAP_TYPE DevMemHeapType; + + + IMG_HANDLE hDevMemHeap; + + + RA_ARENA *psLocalDevMemArena; + + + IMG_UINT32 ui32DataPageSize; + +} DEVICE_MEMORY_HEAP_INFO; + +typedef struct _DEVICE_MEMORY_INFO_ +{ + + IMG_UINT32 ui32AddressSpaceSizeLog2; + + + + + IMG_UINT32 ui32Flags; + + + IMG_UINT32 ui32HeapCount; + + + IMG_UINT32 ui32SyncHeapID; + + + IMG_UINT32 ui32MappingHeapID; + + + DEVICE_MEMORY_HEAP_INFO *psDeviceMemoryHeap; + + + BM_CONTEXT *pBMKernelContext; + + + BM_CONTEXT *pBMContext; + +} DEVICE_MEMORY_INFO; + + +typedef struct DEV_ARENA_DESCRIPTOR_TAG +{ + IMG_UINT32 ui32HeapID; + + IMG_CHAR *pszName; + + IMG_DEV_VIRTADDR BaseDevVAddr; + + IMG_UINT32 ui32Size; + + DEVICE_MEMORY_HEAP_TYPE DevMemHeapType; + + + IMG_UINT32 ui32DataPageSize; + + DEVICE_MEMORY_HEAP_INFO *psDeviceMemoryHeapInfo; + +} DEV_ARENA_DESCRIPTOR; + +typedef struct _SYS_DATA_TAG_ *PSYS_DATA; + +typedef struct _PVRSRV_DEVICE_NODE_ +{ + PVRSRV_DEVICE_IDENTIFIER sDevId; + IMG_UINT32 ui32RefCount; + + + + + PVRSRV_ERROR (*pfnInitDevice) (IMG_VOID*); + + PVRSRV_ERROR (*pfnDeInitDevice) (IMG_VOID*); + + + PVRSRV_ERROR (*pfnInitDeviceCompatCheck) (struct _PVRSRV_DEVICE_NODE_*); + + + PVRSRV_ERROR (*pfnMMUInitialise)(struct _PVRSRV_DEVICE_NODE_*, MMU_CONTEXT**, IMG_DEV_PHYADDR*); + IMG_VOID (*pfnMMUFinalise)(MMU_CONTEXT*); + IMG_VOID (*pfnMMUInsertHeap)(MMU_CONTEXT*, MMU_HEAP*); + MMU_HEAP* (*pfnMMUCreate)(MMU_CONTEXT*,DEV_ARENA_DESCRIPTOR*,RA_ARENA**); + IMG_VOID (*pfnMMUDelete)(MMU_HEAP*); + IMG_BOOL (*pfnMMUAlloc)(MMU_HEAP*pMMU, + IMG_SIZE_T uSize, + IMG_SIZE_T *pActualSize, + IMG_UINT32 uFlags, + IMG_UINT32 uDevVAddrAlignment, + IMG_DEV_VIRTADDR *pDevVAddr); + IMG_VOID (*pfnMMUFree)(MMU_HEAP*,IMG_DEV_VIRTADDR,IMG_UINT32); + IMG_VOID (*pfnMMUEnable)(MMU_HEAP*); + IMG_VOID (*pfnMMUDisable)(MMU_HEAP*); + IMG_VOID (*pfnMMUMapPages)(MMU_HEAP *pMMU, + IMG_DEV_VIRTADDR devVAddr, + IMG_SYS_PHYADDR SysPAddr, + IMG_SIZE_T uSize, + IMG_UINT32 ui32MemFlags, + IMG_HANDLE hUniqueTag); + IMG_VOID (*pfnMMUMapShadow)(MMU_HEAP *pMMU, + IMG_DEV_VIRTADDR MapBaseDevVAddr, + IMG_SIZE_T uSize, + IMG_CPU_VIRTADDR CpuVAddr, + IMG_HANDLE hOSMemHandle, + IMG_DEV_VIRTADDR *pDevVAddr, + IMG_UINT32 ui32MemFlags, + IMG_HANDLE hUniqueTag); + IMG_VOID (*pfnMMUUnmapPages)(MMU_HEAP *pMMU, + IMG_DEV_VIRTADDR dev_vaddr, + IMG_UINT32 ui32PageCount, + IMG_HANDLE hUniqueTag); + + IMG_VOID (*pfnMMUMapScatter)(MMU_HEAP *pMMU, + IMG_DEV_VIRTADDR DevVAddr, + IMG_SYS_PHYADDR *psSysAddr, + IMG_SIZE_T uSize, + IMG_UINT32 ui32MemFlags, + IMG_HANDLE hUniqueTag); + + IMG_DEV_PHYADDR (*pfnMMUGetPhysPageAddr)(MMU_HEAP *pMMUHeap, IMG_DEV_VIRTADDR sDevVPageAddr); + IMG_DEV_PHYADDR (*pfnMMUGetPDDevPAddr)(MMU_CONTEXT *pMMUContext); + + + IMG_BOOL (*pfnDeviceISR)(IMG_VOID*); + + IMG_VOID *pvISRData; + + IMG_UINT32 ui32SOCInterruptBit; + + IMG_VOID (*pfnDeviceMISR)(IMG_VOID*); + + + IMG_VOID (*pfnDeviceCommandComplete)(struct _PVRSRV_DEVICE_NODE_ *psDeviceNode); + + IMG_BOOL bReProcessDeviceCommandComplete; + + + DEVICE_MEMORY_INFO sDevMemoryInfo; + + + IMG_VOID *pvDevice; + IMG_UINT32 ui32pvDeviceSize; + + + PRESMAN_CONTEXT hResManContext; + + + PSYS_DATA psSysData; + + + RA_ARENA *psLocalDevMemArena; + + IMG_UINT32 ui32Flags; + + struct _PVRSRV_DEVICE_NODE_ *psNext; +} PVRSRV_DEVICE_NODE; + +PVRSRV_ERROR IMG_CALLCONV PVRSRVRegisterDevice(PSYS_DATA psSysData, + PVRSRV_ERROR (*pfnRegisterDevice)(PVRSRV_DEVICE_NODE*), + IMG_UINT32 ui32SOCInterruptBit, + IMG_UINT32 *pui32DeviceIndex ); + +PVRSRV_ERROR IMG_CALLCONV PVRSRVInitialiseDevice(IMG_UINT32 ui32DevIndex); +PVRSRV_ERROR IMG_CALLCONV PVRSRVFinaliseSystem(IMG_BOOL bInitSuccesful); + +PVRSRV_ERROR IMG_CALLCONV PVRSRVDevInitCompatCheck(PVRSRV_DEVICE_NODE *psDeviceNode); + +PVRSRV_ERROR IMG_CALLCONV PVRSRVDeinitialiseDevice(IMG_UINT32 ui32DevIndex); + +#if !defined(USE_CODE) + +IMG_IMPORT PVRSRV_ERROR IMG_CALLCONV PollForValueKM(volatile IMG_UINT32* pui32LinMemAddr, + IMG_UINT32 ui32Value, + IMG_UINT32 ui32Mask, + IMG_UINT32 ui32Waitus, + IMG_UINT32 ui32Tries); + +#endif + + +#if defined (USING_ISR_INTERRUPTS) +PVRSRV_ERROR IMG_CALLCONV PollForInterruptKM(IMG_UINT32 ui32Value, + IMG_UINT32 ui32Mask, + IMG_UINT32 ui32Waitus, + IMG_UINT32 ui32Tries); +#endif + +PVRSRV_ERROR IMG_CALLCONV PVRSRVInit(PSYS_DATA psSysData); +IMG_VOID IMG_CALLCONV PVRSRVDeInit(PSYS_DATA psSysData); +IMG_BOOL IMG_CALLCONV PVRSRVDeviceLISR(PVRSRV_DEVICE_NODE *psDeviceNode); +IMG_BOOL IMG_CALLCONV PVRSRVSystemLISR(IMG_VOID *pvSysData); +IMG_VOID IMG_CALLCONV PVRSRVMISR(IMG_VOID *pvSysData); + +#if defined(__cplusplus) +} +#endif + +#endif + diff --git a/services4/srvkm/include/handle.h b/services4/srvkm/include/handle.h new file mode 100644 index 0000000..fda74f1 --- /dev/null +++ b/services4/srvkm/include/handle.h @@ -0,0 +1,382 @@ +/********************************************************************** + * + * Copyright(c) 2008 Imagination Technologies Ltd. All rights reserved. + * + * This program is free software; you can redistribute it and/or modify it + * under the terms and conditions of the GNU General Public License, + * version 2, as published by the Free Software Foundation. + * + * This program is distributed in the hope it will be useful but, except + * as otherwise stated in writing, without any warranty; without even the + * implied warranty of merchantability or fitness for a particular purpose. + * See the GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License along with + * this program; if not, write to the Free Software Foundation, Inc., + * 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA. + * + * The full GNU General Public License is included in this distribution in + * the file called "COPYING". + * + * Contact Information: + * Imagination Technologies Ltd. + * Home Park Estate, Kings Langley, Herts, WD4 8LZ, UK + * + ******************************************************************************/ + +#ifndef __HANDLE_H__ +#define __HANDLE_H__ + +#if defined (__cplusplus) +extern "C" { +#endif + +#include "img_types.h" +#include "hash.h" +#include "resman.h" + +typedef enum +{ + PVRSRV_HANDLE_TYPE_NONE = 0, + PVRSRV_HANDLE_TYPE_PERPROC_DATA, + PVRSRV_HANDLE_TYPE_DEV_NODE, + PVRSRV_HANDLE_TYPE_DEV_MEM_CONTEXT, + PVRSRV_HANDLE_TYPE_DEV_MEM_HEAP, + PVRSRV_HANDLE_TYPE_MEM_INFO, + PVRSRV_HANDLE_TYPE_SYNC_INFO, + PVRSRV_HANDLE_TYPE_DISP_INFO, + PVRSRV_HANDLE_TYPE_DISP_SWAP_CHAIN, + PVRSRV_HANDLE_TYPE_BUF_INFO, + PVRSRV_HANDLE_TYPE_DISP_BUFFER, + PVRSRV_HANDLE_TYPE_BUF_BUFFER, + PVRSRV_HANDLE_TYPE_SGX_HW_RENDER_CONTEXT, + PVRSRV_HANDLE_TYPE_SGX_HW_TRANSFER_CONTEXT, + PVRSRV_HANDLE_TYPE_SGX_HW_2D_CONTEXT, + PVRSRV_HANDLE_TYPE_SHARED_PB_DESC, + PVRSRV_HANDLE_TYPE_MEM_INFO_REF, + PVRSRV_HANDLE_TYPE_SHARED_SYS_MEM_INFO, + PVRSRV_HANDLE_TYPE_SHARED_EVENT_OBJECT, + PVRSRV_HANDLE_TYPE_EVENT_OBJECT_CONNECT, + PVRSRV_HANDLE_TYPE_MMAP_INFO, + PVRSRV_HANDLE_TYPE_SOC_TIMER +} PVRSRV_HANDLE_TYPE; + +typedef enum +{ + + PVRSRV_HANDLE_ALLOC_FLAG_NONE = 0, + + PVRSRV_HANDLE_ALLOC_FLAG_SHARED = 0x01, + + PVRSRV_HANDLE_ALLOC_FLAG_MULTI = 0x02, + + PVRSRV_HANDLE_ALLOC_FLAG_PRIVATE = 0x04 +} PVRSRV_HANDLE_ALLOC_FLAG; + +struct _PVRSRV_HANDLE_BASE_; +typedef struct _PVRSRV_HANDLE_BASE_ PVRSRV_HANDLE_BASE; + +#ifdef PVR_SECURE_HANDLES +extern PVRSRV_HANDLE_BASE *gpsKernelHandleBase; + +#define KERNEL_HANDLE_BASE (gpsKernelHandleBase) + +PVRSRV_ERROR PVRSRVAllocHandle(PVRSRV_HANDLE_BASE *psBase, IMG_HANDLE *phHandle, IMG_VOID *pvData, PVRSRV_HANDLE_TYPE eType, PVRSRV_HANDLE_ALLOC_FLAG eFlag); + +PVRSRV_ERROR PVRSRVAllocSubHandle(PVRSRV_HANDLE_BASE *psBase, IMG_HANDLE *phHandle, IMG_VOID *pvData, PVRSRV_HANDLE_TYPE eType, PVRSRV_HANDLE_ALLOC_FLAG eFlag, IMG_HANDLE hParent); + +PVRSRV_ERROR PVRSRVFindHandle(PVRSRV_HANDLE_BASE *psBase, IMG_HANDLE *phHandle, IMG_VOID *pvData, PVRSRV_HANDLE_TYPE eType); + +PVRSRV_ERROR PVRSRVLookupHandleAnyType(PVRSRV_HANDLE_BASE *psBase, IMG_PVOID *ppvData, PVRSRV_HANDLE_TYPE *peType, IMG_HANDLE hHandle); + +PVRSRV_ERROR PVRSRVLookupHandle(PVRSRV_HANDLE_BASE *psBase, IMG_PVOID *ppvData, IMG_HANDLE hHandle, PVRSRV_HANDLE_TYPE eType); + +PVRSRV_ERROR PVRSRVLookupSubHandle(PVRSRV_HANDLE_BASE *psBase, IMG_PVOID *ppvData, IMG_HANDLE hHandle, PVRSRV_HANDLE_TYPE eType, IMG_HANDLE hAncestor); + +PVRSRV_ERROR PVRSRVGetParentHandle(PVRSRV_HANDLE_BASE *psBase, IMG_PVOID *phParent, IMG_HANDLE hHandle, PVRSRV_HANDLE_TYPE eType); + +PVRSRV_ERROR PVRSRVLookupAndReleaseHandle(PVRSRV_HANDLE_BASE *psBase, IMG_PVOID *ppvData, IMG_HANDLE hHandle, PVRSRV_HANDLE_TYPE eType); + +PVRSRV_ERROR PVRSRVReleaseHandle(PVRSRV_HANDLE_BASE *psBase, IMG_HANDLE hHandle, PVRSRV_HANDLE_TYPE eType); + +PVRSRV_ERROR PVRSRVNewHandleBatch(PVRSRV_HANDLE_BASE *psBase, IMG_UINT32 ui32BatchSize); + +PVRSRV_ERROR PVRSRVCommitHandleBatch(PVRSRV_HANDLE_BASE *psBase); + +IMG_VOID PVRSRVReleaseHandleBatch(PVRSRV_HANDLE_BASE *psBase); + +PVRSRV_ERROR PVRSRVSetMaxHandle(PVRSRV_HANDLE_BASE *psBase, IMG_UINT32 ui32MaxHandle); + +IMG_UINT32 PVRSRVGetMaxHandle(PVRSRV_HANDLE_BASE *psBase); + +PVRSRV_ERROR PVRSRVEnableHandlePurging(PVRSRV_HANDLE_BASE *psBase); + +PVRSRV_ERROR PVRSRVPurgeHandles(PVRSRV_HANDLE_BASE *psBase); + +PVRSRV_ERROR PVRSRVAllocHandleBase(PVRSRV_HANDLE_BASE **ppsBase); + +PVRSRV_ERROR PVRSRVFreeHandleBase(PVRSRV_HANDLE_BASE *psBase); + +PVRSRV_ERROR PVRSRVHandleInit(IMG_VOID); + +PVRSRV_ERROR PVRSRVHandleDeInit(IMG_VOID); + +#else + +#define KERNEL_HANDLE_BASE IMG_NULL + +#ifdef INLINE_IS_PRAGMA +#pragma inline(PVRSRVAllocHandle) +#endif +static INLINE +PVRSRV_ERROR PVRSRVAllocHandle(PVRSRV_HANDLE_BASE *psBase, IMG_HANDLE *phHandle, IMG_VOID *pvData, PVRSRV_HANDLE_TYPE eType, PVRSRV_HANDLE_ALLOC_FLAG eFlag) +{ + PVR_UNREFERENCED_PARAMETER(eType); + PVR_UNREFERENCED_PARAMETER(eFlag); + PVR_UNREFERENCED_PARAMETER(psBase); + + *phHandle = pvData; + return PVRSRV_OK; +} + +#ifdef INLINE_IS_PRAGMA +#pragma inline(PVRSRVAllocSubHandle) +#endif +static INLINE +PVRSRV_ERROR PVRSRVAllocSubHandle(PVRSRV_HANDLE_BASE *psBase, IMG_HANDLE *phHandle, IMG_VOID *pvData, PVRSRV_HANDLE_TYPE eType, PVRSRV_HANDLE_ALLOC_FLAG eFlag, IMG_HANDLE hParent) +{ + PVR_UNREFERENCED_PARAMETER(eType); + PVR_UNREFERENCED_PARAMETER(eFlag); + PVR_UNREFERENCED_PARAMETER(hParent); + PVR_UNREFERENCED_PARAMETER(psBase); + + *phHandle = pvData; + return PVRSRV_OK; +} + +#ifdef INLINE_IS_PRAGMA +#pragma inline(PVRSRVFindHandle) +#endif +static INLINE +PVRSRV_ERROR PVRSRVFindHandle(PVRSRV_HANDLE_BASE *psBase, IMG_HANDLE *phHandle, IMG_VOID *pvData, PVRSRV_HANDLE_TYPE eType) +{ + PVR_UNREFERENCED_PARAMETER(eType); + PVR_UNREFERENCED_PARAMETER(psBase); + + *phHandle = pvData; + return PVRSRV_OK; +} + +#ifdef INLINE_IS_PRAGMA +#pragma inline(PVRSRVLookupHandleAnyType) +#endif +static INLINE +PVRSRV_ERROR PVRSRVLookupHandleAnyType(PVRSRV_HANDLE_BASE *psBase, IMG_PVOID *ppvData, PVRSRV_HANDLE_TYPE *peType, IMG_HANDLE hHandle) +{ + PVR_UNREFERENCED_PARAMETER(psBase); + + *peType = PVRSRV_HANDLE_TYPE_NONE; + + *ppvData = hHandle; + return PVRSRV_OK; +} + +#ifdef INLINE_IS_PRAGMA +#pragma inline(PVRSRVLookupHandle) +#endif +static INLINE +PVRSRV_ERROR PVRSRVLookupHandle(PVRSRV_HANDLE_BASE *psBase, IMG_PVOID *ppvData, IMG_HANDLE hHandle, PVRSRV_HANDLE_TYPE eType) +{ + PVR_UNREFERENCED_PARAMETER(psBase); + PVR_UNREFERENCED_PARAMETER(eType); + + *ppvData = hHandle; + return PVRSRV_OK; +} + +#ifdef INLINE_IS_PRAGMA +#pragma inline(PVRSRVLookupSubHandle) +#endif +static INLINE +PVRSRV_ERROR PVRSRVLookupSubHandle(PVRSRV_HANDLE_BASE *psBase, IMG_PVOID *ppvData, IMG_HANDLE hHandle, PVRSRV_HANDLE_TYPE eType, IMG_HANDLE hAncestor) +{ + PVR_UNREFERENCED_PARAMETER(psBase); + PVR_UNREFERENCED_PARAMETER(eType); + PVR_UNREFERENCED_PARAMETER(hAncestor); + + *ppvData = hHandle; + return PVRSRV_OK; +} + +#ifdef INLINE_IS_PRAGMA +#pragma inline(PVRSRVGetParentHandle) +#endif +static INLINE +PVRSRV_ERROR PVRSRVGetParentHandle(PVRSRV_HANDLE_BASE *psBase, IMG_PVOID *phParent, IMG_HANDLE hHandle, PVRSRV_HANDLE_TYPE eType) +{ + PVR_UNREFERENCED_PARAMETER(psBase); + PVR_UNREFERENCED_PARAMETER(eType); + PVR_UNREFERENCED_PARAMETER(hHandle); + + *phParent = IMG_NULL; + + return PVRSRV_OK; +} + +#ifdef INLINE_IS_PRAGMA +#pragma inline(PVRSRVLookupAndReleaseHandle) +#endif +static INLINE +PVRSRV_ERROR PVRSRVLookupAndReleaseHandle(PVRSRV_HANDLE_BASE *psBase, IMG_PVOID *ppvData, IMG_HANDLE hHandle, PVRSRV_HANDLE_TYPE eType) +{ + PVR_UNREFERENCED_PARAMETER(eType); + PVR_UNREFERENCED_PARAMETER(psBase); + + *ppvData = hHandle; + return PVRSRV_OK; +} + +#ifdef INLINE_IS_PRAGMA +#pragma inline(PVRSRVReleaseHandle) +#endif +static INLINE +PVRSRV_ERROR PVRSRVReleaseHandle(PVRSRV_HANDLE_BASE *psBase, IMG_HANDLE hHandle, PVRSRV_HANDLE_TYPE eType) +{ + PVR_UNREFERENCED_PARAMETER(hHandle); + PVR_UNREFERENCED_PARAMETER(eType); + PVR_UNREFERENCED_PARAMETER(psBase); + + return PVRSRV_OK; +} + +#ifdef INLINE_IS_PRAGMA +#pragma inline(PVRSRVNewHandleBatch) +#endif +static INLINE +PVRSRV_ERROR PVRSRVNewHandleBatch(PVRSRV_HANDLE_BASE *psBase, IMG_UINT32 ui32BatchSize) +{ + PVR_UNREFERENCED_PARAMETER(psBase); + PVR_UNREFERENCED_PARAMETER(ui32BatchSize); + + return PVRSRV_OK; +} + +#ifdef INLINE_IS_PRAGMA +#pragma inline(PVRSRVCommitHandleBatch) +#endif +static INLINE +PVRSRV_ERROR PVRSRVCommitHandleBatch(PVRSRV_HANDLE_BASE *psBase) +{ + PVR_UNREFERENCED_PARAMETER(psBase); + + return PVRSRV_OK; +} + +#ifdef INLINE_IS_PRAGMA +#pragma inline(PVRSRVReleaseHandleBatch) +#endif +static INLINE +IMG_VOID PVRSRVReleaseHandleBatch(PVRSRV_HANDLE_BASE *psBase) +{ + PVR_UNREFERENCED_PARAMETER(psBase); +} + +#ifdef INLINE_IS_PRAGMA +#pragma inline(PVRSRVSetMaxHandle) +#endif +static INLINE +PVRSRV_ERROR PVRSRVSetMaxHandle(PVRSRV_HANDLE_BASE *psBase, IMG_UINT32 ui32MaxHandle) +{ + PVR_UNREFERENCED_PARAMETER(psBase); + PVR_UNREFERENCED_PARAMETER(ui32MaxHandle); + + return PVRSRV_ERROR_NOT_SUPPORTED; +} + +#ifdef INLINE_IS_PRAGMA +#pragma inline(PVRSRVGetMaxHandle) +#endif +static INLINE +IMG_UINT32 PVRSRVGetMaxHandle(PVRSRV_HANDLE_BASE *psBase) +{ + PVR_UNREFERENCED_PARAMETER(psBase); + + return 0; +} + +#ifdef INLINE_IS_PRAGMA +#pragma inline(PVRSRVEnableHandlePurging) +#endif +static INLINE +PVRSRV_ERROR PVRSRVEnableHandlePurging(PVRSRV_HANDLE_BASE *psBase) +{ + PVR_UNREFERENCED_PARAMETER(psBase); + + return PVRSRV_OK; +} + +#ifdef INLINE_IS_PRAGMA +#pragma inline(PVRSRVPurgeHandles) +#endif +static INLINE +PVRSRV_ERROR PVRSRVPurgeHandles(PVRSRV_HANDLE_BASE *psBase) +{ + PVR_UNREFERENCED_PARAMETER(psBase); + + return PVRSRV_OK; +} + +#ifdef INLINE_IS_PRAGMA +#pragma inline(PVRSRVAllocHandleBase) +#endif +static INLINE +PVRSRV_ERROR PVRSRVAllocHandleBase(PVRSRV_HANDLE_BASE **ppsBase) +{ + *ppsBase = IMG_NULL; + + return PVRSRV_OK; +} + +#ifdef INLINE_IS_PRAGMA +#pragma inline(PVRSRVFreeHandleBase) +#endif +static INLINE +PVRSRV_ERROR PVRSRVFreeHandleBase(PVRSRV_HANDLE_BASE *psBase) +{ + PVR_UNREFERENCED_PARAMETER(psBase); + + return PVRSRV_OK; +} + +#ifdef INLINE_IS_PRAGMA +#pragma inline(PVRSRVHandleInit) +#endif +static INLINE +PVRSRV_ERROR PVRSRVHandleInit(IMG_VOID) +{ + return PVRSRV_OK; +} + +#ifdef INLINE_IS_PRAGMA +#pragma inline(PVRSRVHandleDeInit) +#endif +static INLINE +PVRSRV_ERROR PVRSRVHandleDeInit(IMG_VOID) +{ + return PVRSRV_OK; +} + +#endif + +#define PVRSRVAllocHandleNR(psBase, phHandle, pvData, eType, eFlag) \ + (IMG_VOID)PVRSRVAllocHandle(psBase, phHandle, pvData, eType, eFlag) + +#define PVRSRVAllocSubHandleNR(psBase, phHandle, pvData, eType, eFlag, hParent) \ + (IMG_VOID)PVRSRVAllocSubHandle(psBase, phHandle, pvData, eType, eFlag, hParent) + +#if defined (__cplusplus) +} +#endif + +#endif + diff --git a/services4/srvkm/include/hash.h b/services4/srvkm/include/hash.h new file mode 100644 index 0000000..d45f4a9 --- /dev/null +++ b/services4/srvkm/include/hash.h @@ -0,0 +1,73 @@ +/********************************************************************** + * + * Copyright(c) 2008 Imagination Technologies Ltd. All rights reserved. + * + * This program is free software; you can redistribute it and/or modify it + * under the terms and conditions of the GNU General Public License, + * version 2, as published by the Free Software Foundation. + * + * This program is distributed in the hope it will be useful but, except + * as otherwise stated in writing, without any warranty; without even the + * implied warranty of merchantability or fitness for a particular purpose. + * See the GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License along with + * this program; if not, write to the Free Software Foundation, Inc., + * 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA. + * + * The full GNU General Public License is included in this distribution in + * the file called "COPYING". + * + * Contact Information: + * Imagination Technologies Ltd. + * Home Park Estate, Kings Langley, Herts, WD4 8LZ, UK + * + ******************************************************************************/ + +#ifndef _HASH_H_ +#define _HASH_H_ + +#include "img_types.h" +#include "osfunc.h" + +#if defined (__cplusplus) +extern "C" { +#endif + +typedef IMG_UINT32 HASH_FUNC(IMG_SIZE_T uKeySize, IMG_VOID *pKey, IMG_UINT32 uHashTabLen); +typedef IMG_BOOL HASH_KEY_COMP(IMG_SIZE_T uKeySize, IMG_VOID *pKey1, IMG_VOID *pKey2); + +typedef struct _HASH_TABLE_ HASH_TABLE; + +IMG_UINT32 HASH_Func_Default (IMG_SIZE_T uKeySize, IMG_VOID *pKey, IMG_UINT32 uHashTabLen); + +IMG_BOOL HASH_Key_Comp_Default (IMG_SIZE_T uKeySize, IMG_VOID *pKey1, IMG_VOID *pKey2); + +HASH_TABLE * HASH_Create_Extended (IMG_UINT32 uInitialLen, IMG_SIZE_T uKeySize, HASH_FUNC *pfnHashFunc, HASH_KEY_COMP *pfnKeyComp); + +HASH_TABLE * HASH_Create (IMG_UINT32 uInitialLen); + +IMG_VOID HASH_Delete (HASH_TABLE *pHash); + +IMG_BOOL HASH_Insert_Extended (HASH_TABLE *pHash, IMG_VOID *pKey, IMG_UINTPTR_T v); + +IMG_BOOL HASH_Insert (HASH_TABLE *pHash, IMG_UINTPTR_T k, IMG_UINTPTR_T v); + +IMG_UINTPTR_T HASH_Remove_Extended(HASH_TABLE *pHash, IMG_VOID *pKey); + +IMG_UINTPTR_T HASH_Remove (HASH_TABLE *pHash, IMG_UINTPTR_T k); + +IMG_UINTPTR_T HASH_Retrieve_Extended (HASH_TABLE *pHash, IMG_VOID *pKey); + +IMG_UINTPTR_T HASH_Retrieve (HASH_TABLE *pHash, IMG_UINTPTR_T k); + +#ifdef HASH_TRACE +IMG_VOID HASH_Dump (HASH_TABLE *pHash); +#endif + +#if defined (__cplusplus) +} +#endif + +#endif + diff --git a/services4/srvkm/include/metrics.h b/services4/srvkm/include/metrics.h new file mode 100644 index 0000000..2632f8d --- /dev/null +++ b/services4/srvkm/include/metrics.h @@ -0,0 +1,130 @@ +/********************************************************************** + * + * Copyright(c) 2008 Imagination Technologies Ltd. All rights reserved. + * + * This program is free software; you can redistribute it and/or modify it + * under the terms and conditions of the GNU General Public License, + * version 2, as published by the Free Software Foundation. + * + * This program is distributed in the hope it will be useful but, except + * as otherwise stated in writing, without any warranty; without even the + * implied warranty of merchantability or fitness for a particular purpose. + * See the GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License along with + * this program; if not, write to the Free Software Foundation, Inc., + * 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA. + * + * The full GNU General Public License is included in this distribution in + * the file called "COPYING". + * + * Contact Information: + * Imagination Technologies Ltd. + * Home Park Estate, Kings Langley, Herts, WD4 8LZ, UK + * + ******************************************************************************/ + +#ifndef _METRICS_ +#define _METRICS_ + + +#if defined (__cplusplus) +extern "C" { +#endif + + +#if defined(DEBUG) || defined(TIMING) + + +typedef struct +{ + IMG_UINT32 ui32Start; + IMG_UINT32 ui32Stop; + IMG_UINT32 ui32Total; + IMG_UINT32 ui32Count; +} Temporal_Data; + +extern Temporal_Data asTimers[]; + +extern IMG_UINT32 PVRSRVTimeNow(IMG_VOID); +extern IMG_VOID PVRSRVSetupMetricTimers(IMG_VOID *pvDevInfo); +extern IMG_VOID PVRSRVOutputMetricTotals(IMG_VOID); + + +#define PVRSRV_TIMER_DUMMY 0 + +#define PVRSRV_TIMER_EXAMPLE_1 1 +#define PVRSRV_TIMER_EXAMPLE_2 2 + + +#define PVRSRV_NUM_TIMERS (PVRSRV_TIMER_EXAMPLE_2 + 1) + +#define PVRSRV_TIME_START(X) { \ + asTimers[X].ui32Count += 1; \ + asTimers[X].ui32Count |= 0x80000000L; \ + asTimers[X].ui32Start = PVRSRVTimeNow(); \ + asTimers[X].ui32Stop = 0; \ + } + +#define PVRSRV_TIME_SUSPEND(X) { \ + asTimers[X].ui32Stop += PVRSRVTimeNow() - asTimers[X].ui32Start; \ + } + +#define PVRSRV_TIME_RESUME(X) { \ + asTimers[X].ui32Start = PVRSRVTimeNow(); \ + } + +#define PVRSRV_TIME_STOP(X) { \ + asTimers[X].ui32Stop += PVRSRVTimeNow() - asTimers[X].ui32Start; \ + asTimers[X].ui32Total += asTimers[X].ui32Stop; \ + asTimers[X].ui32Count &= 0x7FFFFFFFL; \ + } + +#define PVRSRV_TIME_RESET(X) { \ + asTimers[X].ui32Start = 0; \ + asTimers[X].ui32Stop = 0; \ + asTimers[X].ui32Total = 0; \ + asTimers[X].ui32Count = 0; \ + } + + +#if defined(__sh__) + +#define TST_REG ((volatile IMG_UINT8 *) (psDevInfo->pvSOCRegsBaseKM)) + +#define TCOR_2 ((volatile IMG_UINT *) (psDevInfo->pvSOCRegsBaseKM+28)) +#define TCNT_2 ((volatile IMG_UINT *) (psDevInfo->pvSOCRegsBaseKM+32)) +#define TCR_2 ((volatile IMG_UINT16 *)(psDevInfo->pvSOCRegsBaseKM+36)) + +#define TIMER_DIVISOR 4 + +#endif + + + + + +#else + + + +#define PVRSRV_TIME_START(X) +#define PVRSRV_TIME_SUSPEND(X) +#define PVRSRV_TIME_RESUME(X) +#define PVRSRV_TIME_STOP(X) +#define PVRSRV_TIME_RESET(X) + +#define PVRSRVSetupMetricTimers(X) +#define PVRSRVOutputMetricTotals() + + + +#endif + +#if defined(__cplusplus) +} +#endif + + +#endif + diff --git a/services4/srvkm/include/osfunc.h b/services4/srvkm/include/osfunc.h new file mode 100644 index 0000000..da48598 --- /dev/null +++ b/services4/srvkm/include/osfunc.h @@ -0,0 +1,384 @@ +/********************************************************************** + * + * Copyright(c) 2008 Imagination Technologies Ltd. All rights reserved. + * + * This program is free software; you can redistribute it and/or modify it + * under the terms and conditions of the GNU General Public License, + * version 2, as published by the Free Software Foundation. + * + * This program is distributed in the hope it will be useful but, except + * as otherwise stated in writing, without any warranty; without even the + * implied warranty of merchantability or fitness for a particular purpose. + * See the GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License along with + * this program; if not, write to the Free Software Foundation, Inc., + * 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA. + * + * The full GNU General Public License is included in this distribution in + * the file called "COPYING". + * + * Contact Information: + * Imagination Technologies Ltd. + * Home Park Estate, Kings Langley, Herts, WD4 8LZ, UK + * + ******************************************************************************/ + +#ifdef DEBUG_RELEASE_BUILD +#pragma optimize( "", off ) +#define DEBUG 1 +#endif + +#ifndef __OSFUNC_H__ +#define __OSFUNC_H__ + +#if defined (__cplusplus) +extern "C" { +#endif + +#if defined(__linux__) && defined(__KERNEL__) +#include +#include +#endif + + + + #define PVRSRV_PAGEABLE_SELECT PVRSRV_OS_PAGEABLE_HEAP + +#define KERNEL_ID 0xffffffffL +#define POWER_MANAGER_ID 0xfffffffeL +#define ISR_ID 0xfffffffdL +#define TIMER_ID 0xfffffffcL + + +#define HOST_PAGESIZE OSGetPageSize +#define HOST_PAGEMASK (~(HOST_PAGESIZE()-1)) +#define HOST_PAGEALIGN(addr) (((addr)+HOST_PAGESIZE()-1)&HOST_PAGEMASK) + +#define PVRSRV_OS_HEAP_MASK 0xf +#define PVRSRV_OS_PAGEABLE_HEAP 0x1 +#define PVRSRV_OS_NON_PAGEABLE_HEAP 0x2 + + +IMG_UINT32 OSClockus(IMG_VOID); +IMG_UINT32 OSGetPageSize(IMG_VOID); +PVRSRV_ERROR OSInstallDeviceLISR(IMG_VOID *pvSysData, + IMG_UINT32 ui32Irq, + IMG_CHAR *pszISRName, + IMG_VOID *pvDeviceNode); +PVRSRV_ERROR OSUninstallDeviceLISR(IMG_VOID *pvSysData); +PVRSRV_ERROR OSInstallSystemLISR(IMG_VOID *pvSysData, IMG_UINT32 ui32Irq); +PVRSRV_ERROR OSUninstallSystemLISR(IMG_VOID *pvSysData); +PVRSRV_ERROR OSInstallMISR(IMG_VOID *pvSysData); +PVRSRV_ERROR OSUninstallMISR(IMG_VOID *pvSysData); +IMG_CPU_PHYADDR OSMapLinToCPUPhys(IMG_VOID* pvLinAddr); +IMG_VOID OSMemCopy(IMG_VOID *pvDst, IMG_VOID *pvSrc, IMG_UINT32 ui32Size); +IMG_VOID *OSMapPhysToLin(IMG_CPU_PHYADDR BasePAddr, IMG_UINT32 ui32Bytes, IMG_UINT32 ui32Flags, IMG_HANDLE *phOSMemHandle); +IMG_BOOL OSUnMapPhysToLin(IMG_VOID *pvLinAddr, IMG_UINT32 ui32Bytes, IMG_UINT32 ui32Flags, IMG_HANDLE hOSMemHandle); + +PVRSRV_ERROR OSReservePhys(IMG_CPU_PHYADDR BasePAddr, IMG_UINT32 ui32Bytes, IMG_UINT32 ui32Flags, IMG_VOID **ppvCpuVAddr, IMG_HANDLE *phOSMemHandle); +PVRSRV_ERROR OSUnReservePhys(IMG_VOID *pvCpuVAddr, IMG_UINT32 ui32Bytes, IMG_UINT32 ui32Flags, IMG_HANDLE hOSMemHandle); + +#if defined(__linux__) +PVRSRV_ERROR OSRegisterDiscontigMem(IMG_SYS_PHYADDR *pBasePAddr, IMG_VOID *pvCpuVAddr, IMG_UINT32 ui32Bytes, IMG_UINT32 ui32Flags, IMG_HANDLE *phOSMemHandle); +PVRSRV_ERROR OSUnRegisterDiscontigMem(IMG_VOID *pvCpuVAddr, IMG_UINT32 ui32Bytes, IMG_UINT32 ui32Flags, IMG_HANDLE hOSMemHandle); +#else +#ifdef INLINE_IS_PRAGMA +#pragma inline(OSRegisterDiscontigMem) +#endif +static INLINE PVRSRV_ERROR OSRegisterDiscontigMem(IMG_SYS_PHYADDR *pBasePAddr, IMG_VOID *pvCpuVAddr, IMG_UINT32 ui32Bytes, IMG_UINT32 ui32Flags, IMG_HANDLE *phOSMemHandle) +{ + PVR_UNREFERENCED_PARAMETER(pBasePAddr); + PVR_UNREFERENCED_PARAMETER(pvCpuVAddr); + PVR_UNREFERENCED_PARAMETER(ui32Bytes); + PVR_UNREFERENCED_PARAMETER(ui32Flags); + PVR_UNREFERENCED_PARAMETER(phOSMemHandle); + + return PVRSRV_ERROR_NOT_SUPPORTED; +} + +#ifdef INLINE_IS_PRAGMA +#pragma inline(OSUnRegisterDiscontigMem) +#endif +static INLINE PVRSRV_ERROR OSUnRegisterDiscontigMem(IMG_VOID *pvCpuVAddr, IMG_UINT32 ui32Bytes, IMG_UINT32 ui32Flags, IMG_HANDLE hOSMemHandle) +{ + PVR_UNREFERENCED_PARAMETER(pvCpuVAddr); + PVR_UNREFERENCED_PARAMETER(ui32Bytes); + PVR_UNREFERENCED_PARAMETER(ui32Flags); + PVR_UNREFERENCED_PARAMETER(hOSMemHandle); + + return PVRSRV_ERROR_NOT_SUPPORTED; +} +#endif + + +#if defined(__linux__) +#ifdef INLINE_IS_PRAGMA +#pragma inline(OSReserveDiscontigPhys) +#endif +static INLINE PVRSRV_ERROR OSReserveDiscontigPhys(IMG_SYS_PHYADDR *pBasePAddr, IMG_UINT32 ui32Bytes, IMG_UINT32 ui32Flags, IMG_VOID **ppvCpuVAddr, IMG_HANDLE *phOSMemHandle) +{ +#if defined(__linux__) + *ppvCpuVAddr = IMG_NULL; + return OSRegisterDiscontigMem(pBasePAddr, *ppvCpuVAddr, ui32Bytes, ui32Flags, phOSMemHandle); +#else + extern IMG_CPU_PHYADDR SysSysPAddrToCpuPAddr(IMG_SYS_PHYADDR SysPAddr); + + + return OSReservePhys(SysSysPAddrToCpuPAddr(pBasePAddr[0]), ui32Bytes, ui32Flags, ppvCpuVAddr, phOSMemHandle); +#endif +} + +static INLINE PVRSRV_ERROR OSUnReserveDiscontigPhys(IMG_VOID *pvCpuVAddr, IMG_UINT32 ui32Bytes, IMG_UINT32 ui32Flags, IMG_HANDLE hOSMemHandle) +{ +#if defined(__linux__) + OSUnRegisterDiscontigMem(pvCpuVAddr, ui32Bytes, ui32Flags, hOSMemHandle); +#endif + + return PVRSRV_OK; +} +#else + + +#ifdef INLINE_IS_PRAGMA +#pragma inline(OSReserveDiscontigPhys) +#endif +static INLINE PVRSRV_ERROR OSReserveDiscontigPhys(IMG_SYS_PHYADDR *pBasePAddr, IMG_UINT32 ui32Bytes, IMG_UINT32 ui32Flags, IMG_VOID **ppvCpuVAddr, IMG_HANDLE *phOSMemHandle) +{ + PVR_UNREFERENCED_PARAMETER(pBasePAddr); + PVR_UNREFERENCED_PARAMETER(ui32Bytes); + PVR_UNREFERENCED_PARAMETER(ui32Flags); + PVR_UNREFERENCED_PARAMETER(ppvCpuVAddr); + PVR_UNREFERENCED_PARAMETER(phOSMemHandle); + + return PVRSRV_ERROR_NOT_SUPPORTED; +} + +#ifdef INLINE_IS_PRAGMA +#pragma inline(OSUnReserveDiscontigPhys) +#endif +static INLINE PVRSRV_ERROR OSUnReserveDiscontigPhys(IMG_VOID *pvCpuVAddr, IMG_UINT32 ui32Bytes, IMG_UINT32 ui32Flags, IMG_HANDLE hOSMemHandle) +{ + PVR_UNREFERENCED_PARAMETER(pvCpuVAddr); + PVR_UNREFERENCED_PARAMETER(ui32Bytes); + PVR_UNREFERENCED_PARAMETER(ui32Flags); + PVR_UNREFERENCED_PARAMETER(hOSMemHandle); + + return PVRSRV_ERROR_NOT_SUPPORTED; +} +#endif + +PVRSRV_ERROR OSRegisterMem(IMG_CPU_PHYADDR BasePAddr, IMG_VOID *pvCpuVAddr, IMG_UINT32 ui32Bytes, IMG_UINT32 ui32Flags, IMG_HANDLE *phOSMemHandle); +PVRSRV_ERROR OSUnRegisterMem(IMG_VOID *pvCpuVAddr, IMG_UINT32 ui32Bytes, IMG_UINT32 ui32Flags, IMG_HANDLE hOSMemHandle); + + + +#if defined(__linux__) +PVRSRV_ERROR OSGetSubMemHandle(IMG_HANDLE hOSMemHandle, + IMG_UINT32 ui32ByteOffset, + IMG_UINT32 ui32Bytes, + IMG_UINT32 ui32Flags, + IMG_HANDLE *phOSMemHandleRet); +PVRSRV_ERROR OSReleaseSubMemHandle(IMG_HANDLE hOSMemHandle, IMG_UINT32 ui32Flags); +#else +#ifdef INLINE_IS_PRAGMA +#pragma inline(OSGetSubMemHandle) +#endif +static INLINE PVRSRV_ERROR OSGetSubMemHandle(IMG_HANDLE hOSMemHandle, + IMG_UINT32 ui32ByteOffset, + IMG_UINT32 ui32Bytes, + IMG_UINT32 ui32Flags, + IMG_HANDLE *phOSMemHandleRet) +{ + PVR_UNREFERENCED_PARAMETER(ui32ByteOffset); + PVR_UNREFERENCED_PARAMETER(ui32Bytes); + PVR_UNREFERENCED_PARAMETER(ui32Flags); + + *phOSMemHandleRet = hOSMemHandle; + return PVRSRV_OK; +} + +static INLINE PVRSRV_ERROR OSReleaseSubMemHandle(IMG_HANDLE hOSMemHandle, IMG_UINT32 ui32Flags) +{ + PVR_UNREFERENCED_PARAMETER(hOSMemHandle); + PVR_UNREFERENCED_PARAMETER(ui32Flags); + return PVRSRV_OK; +} +#endif + +IMG_UINT32 OSGetCurrentProcessIDKM(IMG_VOID); +IMG_UINT32 OSGetCurrentThreadID( IMG_VOID ); +IMG_VOID OSMemSet(IMG_VOID *pvDest, IMG_UINT8 ui8Value, IMG_UINT32 ui32Size); + +#if defined(__linux__) && defined(DEBUG_LINUX_MEMORY_ALLOCATIONS) +PVRSRV_ERROR _OSAllocMem(IMG_UINT32 ui32Flags, IMG_UINT32 ui32Size, IMG_PVOID *ppvLinAddr, IMG_HANDLE *phBlockAlloc, IMG_CHAR *pszFilename, IMG_UINT32 ui32Line); +#define OSAllocMem(ui32Flags, ui32Size, ppvLinAddr, phBlockAlloc) _OSAllocMem(ui32Flags, ui32Size, ppvLinAddr, phBlockAlloc, __FILE__, __LINE__) +PVRSRV_ERROR _OSFreeMem(IMG_UINT32 ui32Flags, IMG_UINT32 ui32Size, IMG_PVOID pvLinAddr, IMG_HANDLE hBlockAlloc, IMG_CHAR *pszFilename, IMG_UINT32 ui32Line); +#define OSFreeMem(ui32Flags, ui32Size, pvLinAddr, phBlockAlloc) _OSFreeMem(ui32Flags, ui32Size, pvLinAddr, phBlockAlloc, __FILE__, __LINE__) +#else +PVRSRV_ERROR OSAllocMem(IMG_UINT32 ui32Flags, IMG_UINT32 ui32Size, IMG_PVOID *ppvLinAddr, IMG_HANDLE *phBlockAlloc); +PVRSRV_ERROR OSFreeMem(IMG_UINT32 ui32Flags, IMG_UINT32 ui32Size, IMG_PVOID pvLinAddr, IMG_HANDLE hBlockAlloc); +#endif +PVRSRV_ERROR OSAllocPages(IMG_UINT32 ui32Flags, IMG_UINT32 ui32Size, IMG_UINT32 ui32PageSize, IMG_PVOID *ppvLinAddr, IMG_HANDLE *phPageAlloc); +PVRSRV_ERROR OSFreePages(IMG_UINT32 ui32Flags, IMG_UINT32 ui32Size, IMG_PVOID pvLinAddr, IMG_HANDLE hPageAlloc); +#if defined(__linux__) +IMG_CPU_PHYADDR OSMemHandleToCpuPAddr(IMG_VOID *hOSMemHandle, IMG_UINT32 ui32ByteOffset); +#else +#ifdef INLINE_IS_PRAGMA +#pragma inline(OSMemHandleToCpuPAddr) +#endif +static INLINE IMG_CPU_PHYADDR OSMemHandleToCpuPAddr(IMG_HANDLE hOSMemHandle, IMG_UINT32 ui32ByteOffset) +{ + IMG_CPU_PHYADDR sCpuPAddr; + PVR_UNREFERENCED_PARAMETER(hOSMemHandle); + PVR_UNREFERENCED_PARAMETER(ui32ByteOffset); + sCpuPAddr.uiAddr = 0; + return sCpuPAddr; +} +#endif +PVRSRV_ERROR OSInitEnvData(IMG_PVOID *ppvEnvSpecificData); +PVRSRV_ERROR OSDeInitEnvData(IMG_PVOID pvEnvSpecificData); +IMG_CHAR* OSStringCopy(IMG_CHAR *pszDest, const IMG_CHAR *pszSrc); +IMG_INT32 OSSNPrintf(IMG_CHAR *pStr, IMG_UINT32 ui32Size, const IMG_CHAR *pszFormat, ...); +#define OSStringLength(pszString) strlen(pszString) + +PVRSRV_ERROR OSEventObjectCreate(const IMG_CHAR *pszName, + PVRSRV_EVENTOBJECT *psEventObject); +PVRSRV_ERROR OSEventObjectDestroy(PVRSRV_EVENTOBJECT *psEventObject); +PVRSRV_ERROR OSEventObjectSignal(IMG_HANDLE hOSEventKM); +PVRSRV_ERROR OSEventObjectWait(IMG_HANDLE hOSEventKM); +PVRSRV_ERROR OSEventObjectOpen(PVRSRV_EVENTOBJECT *psEventObject, + IMG_HANDLE *phOSEvent); +PVRSRV_ERROR OSEventObjectClose(PVRSRV_EVENTOBJECT *psEventObject, + IMG_HANDLE hOSEventKM); + + +PVRSRV_ERROR OSBaseAllocContigMemory(IMG_UINT32 ui32Size, IMG_CPU_VIRTADDR *pLinAddr, IMG_CPU_PHYADDR *pPhysAddr); +PVRSRV_ERROR OSBaseFreeContigMemory(IMG_UINT32 ui32Size, IMG_CPU_VIRTADDR LinAddr, IMG_CPU_PHYADDR PhysAddr); + +IMG_PVOID MapUserFromKernel(IMG_PVOID pvLinAddrKM,IMG_UINT32 ui32Size,IMG_HANDLE *phMemBlock); +IMG_PVOID OSMapHWRegsIntoUserSpace(IMG_HANDLE hDevCookie, IMG_SYS_PHYADDR sRegAddr, IMG_UINT32 ulSize, IMG_PVOID *ppvProcess); +IMG_VOID OSUnmapHWRegsFromUserSpace(IMG_HANDLE hDevCookie, IMG_PVOID pvUserAddr, IMG_PVOID pvProcess); + +IMG_VOID UnmapUserFromKernel(IMG_PVOID pvLinAddrUM, IMG_UINT32 ui32Size, IMG_HANDLE hMemBlock); + +PVRSRV_ERROR OSMapPhysToUserSpace(IMG_HANDLE hDevCookie, + IMG_SYS_PHYADDR sCPUPhysAddr, + IMG_UINT32 uiSizeInBytes, + IMG_UINT32 ui32CacheFlags, + IMG_PVOID *ppvUserAddr, + IMG_UINT32 *puiActualSize, + IMG_HANDLE hMappingHandle); + +PVRSRV_ERROR OSUnmapPhysToUserSpace(IMG_HANDLE hDevCookie, + IMG_PVOID pvUserAddr, + IMG_PVOID pvProcess); + +PVRSRV_ERROR OSLockResource(PVRSRV_RESOURCE *psResource, IMG_UINT32 ui32ID); +PVRSRV_ERROR OSUnlockResource(PVRSRV_RESOURCE *psResource, IMG_UINT32 ui32ID); +IMG_BOOL OSIsResourceLocked(PVRSRV_RESOURCE *psResource, IMG_UINT32 ui32ID); +PVRSRV_ERROR OSCreateResource(PVRSRV_RESOURCE *psResource); +PVRSRV_ERROR OSDestroyResource(PVRSRV_RESOURCE *psResource); +IMG_VOID OSBreakResourceLock(PVRSRV_RESOURCE *psResource, IMG_UINT32 ui32ID); +IMG_VOID OSWaitus(IMG_UINT32 ui32Timeus); +IMG_VOID OSReleaseThreadQuanta(IMG_VOID); +IMG_UINT32 OSPCIReadDword(IMG_UINT32 ui32Bus, IMG_UINT32 ui32Dev, IMG_UINT32 ui32Func, IMG_UINT32 ui32Reg); +IMG_VOID OSPCIWriteDword(IMG_UINT32 ui32Bus, IMG_UINT32 ui32Dev, IMG_UINT32 ui32Func, IMG_UINT32 ui32Reg, IMG_UINT32 ui32Value); + +#ifndef OSReadHWReg +IMG_UINT32 OSReadHWReg(IMG_PVOID pvLinRegBaseAddr, IMG_UINT32 ui32Offset); +#endif +#ifndef OSWriteHWReg +IMG_VOID OSWriteHWReg(IMG_PVOID pvLinRegBaseAddr, IMG_UINT32 ui32Offset, IMG_UINT32 ui32Value); +#endif + +typedef IMG_VOID (*PFN_TIMER_FUNC)(IMG_VOID*); +IMG_HANDLE OSAddTimer(PFN_TIMER_FUNC pfnTimerFunc, IMG_VOID *pvData, IMG_UINT32 ui32MsTimeout); +PVRSRV_ERROR OSRemoveTimer (IMG_HANDLE hTimer); +PVRSRV_ERROR OSEnableTimer (IMG_HANDLE hTimer); +PVRSRV_ERROR OSDisableTimer (IMG_HANDLE hTimer); + +PVRSRV_ERROR OSGetSysMemSize(IMG_UINT32 *pui32Bytes); + +typedef enum _HOST_PCI_INIT_FLAGS_ +{ + HOST_PCI_INIT_FLAG_BUS_MASTER = 0x00000001, + HOST_PCI_INIT_FLAG_MSI = 0x00000002, + HOST_PCI_INIT_FLAG_FORCE_I32 = 0x7fffffff +} HOST_PCI_INIT_FLAGS; + +struct _PVRSRV_PCI_DEV_OPAQUE_STRUCT_; +typedef struct _PVRSRV_PCI_DEV_OPAQUE_STRUCT_ *PVRSRV_PCI_DEV_HANDLE; + +PVRSRV_PCI_DEV_HANDLE OSPCIAcquireDev(IMG_UINT16 ui16VendorID, IMG_UINT16 ui16DeviceID, HOST_PCI_INIT_FLAGS eFlags); +PVRSRV_PCI_DEV_HANDLE OSPCISetDev(IMG_VOID *pvPCICookie, HOST_PCI_INIT_FLAGS eFlags); +PVRSRV_ERROR OSPCIReleaseDev(PVRSRV_PCI_DEV_HANDLE hPVRPCI); +PVRSRV_ERROR OSPCIIRQ(PVRSRV_PCI_DEV_HANDLE hPVRPCI, IMG_UINT32 *pui32IRQ); +IMG_UINT32 OSPCIAddrRangeLen(PVRSRV_PCI_DEV_HANDLE hPVRPCI, IMG_UINT32 ui32Index); +IMG_UINT32 OSPCIAddrRangeStart(PVRSRV_PCI_DEV_HANDLE hPVRPCI, IMG_UINT32 ui32Index); +IMG_UINT32 OSPCIAddrRangeEnd(PVRSRV_PCI_DEV_HANDLE hPVRPCI, IMG_UINT32 ui32Index); +PVRSRV_ERROR OSPCIRequestAddrRange(PVRSRV_PCI_DEV_HANDLE hPVRPCI, IMG_UINT32 ui32Index); +PVRSRV_ERROR OSPCIReleaseAddrRange(PVRSRV_PCI_DEV_HANDLE hPVRPCI, IMG_UINT32 ui32Index); +PVRSRV_ERROR OSPCISuspendDev(PVRSRV_PCI_DEV_HANDLE hPVRPCI); +PVRSRV_ERROR OSPCIResumeDev(PVRSRV_PCI_DEV_HANDLE hPVRPCI); + +PVRSRV_ERROR OSScheduleMISR(IMG_VOID *pvSysData); + +IMG_BOOL OSProcHasPrivSrvInit(IMG_VOID); + +typedef enum _img_verify_test +{ + PVR_VERIFY_WRITE = 0, + PVR_VERIFY_READ +} IMG_VERIFY_TEST; + +IMG_BOOL OSAccessOK(IMG_VERIFY_TEST eVerification, IMG_VOID *pvUserPtr, IMG_UINT32 ui32Bytes); + +PVRSRV_ERROR OSCopyToUser(IMG_PVOID pvProcess, IMG_VOID *pvDest, IMG_VOID *pvSrc, IMG_UINT32 ui32Bytes); +PVRSRV_ERROR OSCopyFromUser(IMG_PVOID pvProcess, IMG_VOID *pvDest, IMG_VOID *pvSrc, IMG_UINT32 ui32Bytes); + +#if defined(__linux__) +PVRSRV_ERROR OSAcquirePhysPageAddr(IMG_VOID* pvCPUVAddr, + IMG_UINT32 ui32Bytes, + IMG_SYS_PHYADDR *psSysPAddr, + IMG_HANDLE *phOSWrapMem); +PVRSRV_ERROR OSReleasePhysPageAddr(IMG_HANDLE hOSWrapMem); +#else +#ifdef INLINE_IS_PRAGMA +#pragma inline(OSAcquirePhysPageAddr) +#endif +static INLINE PVRSRV_ERROR OSAcquirePhysPageAddr(IMG_VOID* pvCPUVAddr, + IMG_UINT32 ui32Bytes, + IMG_SYS_PHYADDR *psSysPAddr, + IMG_HANDLE *phOSWrapMem) +{ + PVR_UNREFERENCED_PARAMETER(pvCPUVAddr); + PVR_UNREFERENCED_PARAMETER(ui32Bytes); + PVR_UNREFERENCED_PARAMETER(psSysPAddr); + PVR_UNREFERENCED_PARAMETER(phOSWrapMem); + return PVRSRV_OK; +} +#ifdef INLINE_IS_PRAGMA +#pragma inline(OSReleasePhysPageAddr) +#endif +static INLINE PVRSRV_ERROR OSReleasePhysPageAddr(IMG_HANDLE hOSWrapMem) +{ + PVR_UNREFERENCED_PARAMETER(hOSWrapMem); + return PVRSRV_OK; +} +#endif + +#if defined(__linux__) && defined(__KERNEL__) +#define OS_SUPPORTS_IN_LISR +static inline IMG_BOOL OSInLISR(IMG_VOID unref__ *pvSysData) +{ + return in_irq(); +} +#endif + +#if defined (__cplusplus) +} +#endif + +#endif + diff --git a/services4/srvkm/include/osperproc.h b/services4/srvkm/include/osperproc.h new file mode 100644 index 0000000..80a912f --- /dev/null +++ b/services4/srvkm/include/osperproc.h @@ -0,0 +1,76 @@ +/********************************************************************** + * + * Copyright(c) 2008 Imagination Technologies Ltd. All rights reserved. + * + * This program is free software; you can redistribute it and/or modify it + * under the terms and conditions of the GNU General Public License, + * version 2, as published by the Free Software Foundation. + * + * This program is distributed in the hope it will be useful but, except + * as otherwise stated in writing, without any warranty; without even the + * implied warranty of merchantability or fitness for a particular purpose. + * See the GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License along with + * this program; if not, write to the Free Software Foundation, Inc., + * 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA. + * + * The full GNU General Public License is included in this distribution in + * the file called "COPYING". + * + * Contact Information: + * Imagination Technologies Ltd. + * Home Park Estate, Kings Langley, Herts, WD4 8LZ, UK + * + ******************************************************************************/ + +#ifndef __OSPERPROC_H__ +#define __OSPERPROC_H__ + +#if defined (__cplusplus) +extern "C" { +#endif + +#if defined(__linux__) +PVRSRV_ERROR OSPerProcessPrivateDataInit(IMG_HANDLE *phOsPrivateData); +PVRSRV_ERROR OSPerProcessPrivateDataDeInit(IMG_HANDLE hOsPrivateData); + +PVRSRV_ERROR OSPerProcessSetHandleOptions(PVRSRV_HANDLE_BASE *psHandleBase); +#else +#ifdef INLINE_IS_PRAGMA +#pragma inline(OSPerProcessPrivateDataInit) +#endif +static INLINE PVRSRV_ERROR OSPerProcessPrivateDataInit(IMG_HANDLE *phOsPrivateData) +{ + PVR_UNREFERENCED_PARAMETER(phOsPrivateData); + + return PVRSRV_OK; +} + +#ifdef INLINE_IS_PRAGMA +#pragma inline(OSPerProcessPrivateDataDeInit) +#endif +static INLINE PVRSRV_ERROR OSPerProcessPrivateDataDeInit(IMG_HANDLE hOsPrivateData) +{ + PVR_UNREFERENCED_PARAMETER(hOsPrivateData); + + return PVRSRV_OK; +} + +#ifdef INLINE_IS_PRAGMA +#pragma inline(OSPerProcessSetHandleOptions) +#endif +static INLINE PVRSRV_ERROR OSPerProcessSetHandleOptions(PVRSRV_HANDLE_BASE *psHandleBase) +{ + PVR_UNREFERENCED_PARAMETER(psHandleBase); + + return PVRSRV_OK; +} +#endif + +#if defined (__cplusplus) +} +#endif + +#endif + diff --git a/services4/srvkm/include/pdump_km.h b/services4/srvkm/include/pdump_km.h new file mode 100644 index 0000000..106fd4e --- /dev/null +++ b/services4/srvkm/include/pdump_km.h @@ -0,0 +1,337 @@ +/********************************************************************** + * + * Copyright(c) 2008 Imagination Technologies Ltd. All rights reserved. + * + * This program is free software; you can redistribute it and/or modify it + * under the terms and conditions of the GNU General Public License, + * version 2, as published by the Free Software Foundation. + * + * This program is distributed in the hope it will be useful but, except + * as otherwise stated in writing, without any warranty; without even the + * implied warranty of merchantability or fitness for a particular purpose. + * See the GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License along with + * this program; if not, write to the Free Software Foundation, Inc., + * 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA. + * + * The full GNU General Public License is included in this distribution in + * the file called "COPYING". + * + * Contact Information: + * Imagination Technologies Ltd. + * Home Park Estate, Kings Langley, Herts, WD4 8LZ, UK + * + ******************************************************************************/ + +#ifndef _PDUMP_KM_H_ +#define _PDUMP_KM_H_ + +#if defined(__cplusplus) +extern "C" { +#endif + +#define PDUMP_FLAGS_NEVER 0x08000000 +#define PDUMP_FLAGS_TOOUT2MEM 0x10000000 +#define PDUMP_FLAGS_LASTFRAME 0x20000000 +#define PDUMP_FLAGS_RESETLFBUFFER 0x40000000 +#define PDUMP_FLAGS_CONTINUOUS 0x80000000 + +#define PDUMP_PD_UNIQUETAG (IMG_HANDLE)0 +#define PDUMP_PT_UNIQUETAG (IMG_HANDLE)0 + +#ifndef PDUMP +#define MAKEUNIQUETAG(hMemInfo) (0) +#endif + +#ifdef PDUMP + +#define MAKEUNIQUETAG(hMemInfo) (((BM_BUF *)(((PVRSRV_KERNEL_MEM_INFO *)hMemInfo)->sMemBlk.hBuffer))->pMapping) + + #define PDUMP_REG_FUNC_NAME PDumpReg + + IMG_IMPORT PVRSRV_ERROR PDumpMemPolKM(PVRSRV_KERNEL_MEM_INFO *psMemInfo, + IMG_UINT32 ui32Offset, + IMG_UINT32 ui32Value, + IMG_UINT32 ui32Mask, + PDUMP_POLL_OPERATOR eOperator, + IMG_BOOL bLastFrame, + IMG_BOOL bOverwrite, + IMG_HANDLE hUniqueTag); + + IMG_IMPORT PVRSRV_ERROR PDumpMemUM(PVRSRV_PER_PROCESS_DATA *psProcData, + IMG_PVOID pvAltLinAddr, + IMG_PVOID pvLinAddr, + PVRSRV_KERNEL_MEM_INFO *psMemInfo, + IMG_UINT32 ui32Offset, + IMG_UINT32 ui32Bytes, + IMG_UINT32 ui32Flags, + IMG_HANDLE hUniqueTag); + + IMG_IMPORT PVRSRV_ERROR PDumpMemKM(IMG_PVOID pvAltLinAddr, + PVRSRV_KERNEL_MEM_INFO *psMemInfo, + IMG_UINT32 ui32Offset, + IMG_UINT32 ui32Bytes, + IMG_UINT32 ui32Flags, + IMG_HANDLE hUniqueTag); + PVRSRV_ERROR PDumpMemPagesKM(PVRSRV_DEVICE_TYPE eDeviceType, + IMG_DEV_PHYADDR *pPages, + IMG_UINT32 ui32NumPages, + IMG_DEV_VIRTADDR sDevAddr, + IMG_UINT32 ui32Start, + IMG_UINT32 ui32Length, + IMG_UINT32 ui32Flags, + IMG_HANDLE hUniqueTag); + + PVRSRV_ERROR PDumpMem2KM(PVRSRV_DEVICE_TYPE eDeviceType, + IMG_CPU_VIRTADDR pvLinAddr, + IMG_UINT32 ui32Bytes, + IMG_UINT32 ui32Flags, + IMG_BOOL bInitialisePages, + IMG_HANDLE hUniqueTag1, + IMG_HANDLE hUniqueTag2); + IMG_VOID PDumpInitCommon(IMG_VOID); + IMG_VOID PDumpDeInitCommon(IMG_VOID); + IMG_VOID PDumpInit(IMG_VOID); + IMG_VOID PDumpDeInit(IMG_VOID); + PVRSRV_ERROR PDumpStartInitPhaseKM(IMG_VOID); + PVRSRV_ERROR PDumpStopInitPhaseKM(IMG_VOID); + IMG_IMPORT PVRSRV_ERROR PDumpSetFrameKM(IMG_UINT32 ui32Frame); + IMG_IMPORT PVRSRV_ERROR PDumpCommentKM(IMG_CHAR *pszComment, IMG_UINT32 ui32Flags); + IMG_IMPORT PVRSRV_ERROR PDumpDriverInfoKM(IMG_CHAR *pszString, IMG_UINT32 ui32Flags); + PVRSRV_ERROR PDumpRegWithFlagsKM(IMG_UINT32 ui32RegAddr, + IMG_UINT32 ui32RegValue, + IMG_UINT32 ui32Flags); + IMG_IMPORT PVRSRV_ERROR PDumpBitmapKM(IMG_CHAR *pszFileName, + IMG_UINT32 ui32FileOffset, + IMG_UINT32 ui32Width, + IMG_UINT32 ui32Height, + IMG_UINT32 ui32StrideInBytes, + IMG_DEV_VIRTADDR sDevBaseAddr, + IMG_UINT32 ui32Size, + PDUMP_PIXEL_FORMAT ePixelFormat, + PDUMP_MEM_FORMAT eMemFormat, + IMG_UINT32 ui32PDumpFlags); + IMG_IMPORT IMG_VOID PDumpHWPerfCBKM(IMG_CHAR *pszFileName, + IMG_UINT32 ui32FileOffset, + IMG_DEV_VIRTADDR sDevBaseAddr, + IMG_UINT32 ui32Size, + IMG_UINT32 ui32PDumpFlags); + IMG_IMPORT PVRSRV_ERROR PDumpReadRegKM(IMG_CHAR *pszFileName, + IMG_UINT32 ui32FileOffset, + IMG_UINT32 ui32Address, + IMG_UINT32 ui32Size, + IMG_UINT32 ui32PDumpFlags); + IMG_VOID PDUMP_REG_FUNC_NAME(IMG_UINT32 dwReg, + IMG_UINT32 dwData); + + IMG_VOID PDumpMsvdxRegRead(const IMG_CHAR* const pRegRegion, + const IMG_UINT32 dwRegOffset); + + IMG_VOID PDumpMsvdxRegWrite(const IMG_CHAR* const pRegRegion, + const IMG_UINT32 dwRegOffset, + const IMG_UINT32 dwData); + + PVRSRV_ERROR PDumpMsvdxRegPol(const IMG_CHAR* const pRegRegion, + const IMG_UINT32 ui32Offset, + const IMG_UINT32 ui32CheckFuncIdExt, + const IMG_UINT32 ui32RequValue, + const IMG_UINT32 ui32Enable, + const IMG_UINT32 ui32PollCount, + const IMG_UINT32 ui32TimeOut); + + PVRSRV_ERROR PDumpMsvdxWriteRef(const IMG_CHAR* const pRegRegion, + const IMG_UINT32 ui32VLROffset, + const IMG_UINT32 ui32Physical ); + + IMG_VOID PDumpComment(IMG_CHAR* pszFormat, ...); + IMG_VOID PDumpCommentWithFlags(IMG_UINT32 ui32Flags, + IMG_CHAR* pszFormat, + ...); + PVRSRV_ERROR PDumpRegPolKM(IMG_UINT32 ui32RegAddr, + IMG_UINT32 ui32RegValue, + IMG_UINT32 ui32Mask); + PVRSRV_ERROR PDumpRegPolWithFlagsKM(IMG_UINT32 ui32RegAddr, + IMG_UINT32 ui32RegValue, + IMG_UINT32 ui32Mask, + IMG_UINT32 ui32Flags); + IMG_BOOL PDumpIsLastCaptureFrameKM(IMG_VOID); + IMG_IMPORT IMG_BOOL PDumpIsCaptureFrameKM(IMG_VOID); + + IMG_VOID PDumpMallocPages(PVRSRV_DEVICE_TYPE eDeviceType, + IMG_UINT32 ui32DevVAddr, + IMG_CPU_VIRTADDR pvLinAddr, + IMG_HANDLE hOSMemHandle, + IMG_UINT32 ui32NumBytes, + IMG_UINT32 ui32PageSize, + IMG_HANDLE hUniqueTag); + IMG_VOID PDumpMallocPagesPhys(PVRSRV_DEVICE_TYPE eDeviceType, + IMG_UINT32 ui32DevVAddr, + IMG_PUINT32 pui32PhysPages, + IMG_UINT32 ui32NumPages, + IMG_HANDLE hUniqueTag); + IMG_VOID PDumpMallocPageTable(PVRSRV_DEVICE_TYPE eDeviceType, + IMG_CPU_VIRTADDR pvLinAddr, + IMG_UINT32 ui32NumBytes, + IMG_HANDLE hUniqueTag); + PVRSRV_ERROR PDumpSetMMUContext(PVRSRV_DEVICE_TYPE eDeviceType, + IMG_CHAR *pszMemSpace, + IMG_UINT32 *pui32MMUContextID, + IMG_UINT32 ui32MMUType, + IMG_HANDLE hUniqueTag1, + IMG_VOID *pvPDCPUAddr); + PVRSRV_ERROR PDumpClearMMUContext(PVRSRV_DEVICE_TYPE eDeviceType, + IMG_CHAR *pszMemSpace, + IMG_UINT32 ui32MMUContextID, + IMG_UINT32 ui32MMUType); + IMG_VOID PDumpFreePages(struct _BM_HEAP_ *psBMHeap, + IMG_DEV_VIRTADDR sDevVAddr, + IMG_UINT32 ui32NumBytes, + IMG_UINT32 ui32PageSize, + IMG_HANDLE hUniqueTag, + IMG_BOOL bInterleaved); + IMG_VOID PDumpFreePageTable(PVRSRV_DEVICE_TYPE eDeviceType, + IMG_CPU_VIRTADDR pvLinAddr, + IMG_UINT32 ui32NumBytes, + IMG_HANDLE hUniqueTag); + IMG_VOID PDumpPDReg(IMG_UINT32 ui32Reg, + IMG_UINT32 ui32dwData, + IMG_HANDLE hUniqueTag); + IMG_VOID PDumpPDRegWithFlags(IMG_UINT32 ui32Reg, + IMG_UINT32 ui32Data, + IMG_UINT32 ui32Flags, + IMG_HANDLE hUniqueTag); + + PVRSRV_ERROR PDumpPDDevPAddrKM(PVRSRV_KERNEL_MEM_INFO *psMemInfo, + IMG_UINT32 ui32Offset, + IMG_DEV_PHYADDR sPDDevPAddr, + IMG_HANDLE hUniqueTag1, + IMG_HANDLE hUniqueTag2); + + IMG_BOOL PDumpTestNextFrame(IMG_UINT32 ui32CurrentFrame); + + IMG_VOID PDumpTASignatureRegisters(IMG_UINT32 ui32DumpFrameNum, + IMG_UINT32 ui32TAKickCount, + IMG_BOOL bLastFrame, + IMG_UINT32 *pui32Registers, + IMG_UINT32 ui32NumRegisters); + + IMG_VOID PDump3DSignatureRegisters(IMG_UINT32 ui32DumpFrameNum, + IMG_BOOL bLastFrame, + IMG_UINT32 *pui32Registers, + IMG_UINT32 ui32NumRegisters); + + IMG_VOID PDumpRegRead(const IMG_UINT32 dwRegOffset, IMG_UINT32 ui32Flags); + + IMG_VOID PDumpCycleCountRegRead(const IMG_UINT32 dwRegOffset, IMG_BOOL bLastFrame); + + IMG_VOID PDumpCounterRegisters(IMG_UINT32 ui32DumpFrameNum, + IMG_BOOL bLastFrame, + IMG_UINT32 *pui32Registers, + IMG_UINT32 ui32NumRegisters); + + IMG_VOID PDumpCBP(PPVRSRV_KERNEL_MEM_INFO psROffMemInfo, + IMG_UINT32 ui32ROffOffset, + IMG_UINT32 ui32WPosVal, + IMG_UINT32 ui32PacketSize, + IMG_UINT32 ui32BufferSize, + IMG_UINT32 ui32Flags, + IMG_HANDLE hUniqueTag); + + IMG_VOID PDumpIDLWithFlags(IMG_UINT32 ui32Clocks, IMG_UINT32 ui32Flags); + IMG_VOID PDumpIDL(IMG_UINT32 ui32Clocks); + + IMG_VOID PDumpSuspendKM(IMG_VOID); + IMG_VOID PDumpResumeKM(IMG_VOID); + + #define PDUMPMEMPOL PDumpMemPolKM + #define PDUMPMEM PDumpMemKM + #define PDUMPMEM2 PDumpMem2KM + #define PDUMPMEMUM PDumpMemUM + #define PDUMPINIT PDumpInitCommon + #define PDUMPDEINIT PDumpDeInitCommon + #define PDUMPISLASTFRAME PDumpIsLastCaptureFrameKM + #define PDUMPTESTFRAME PDumpIsCaptureFrameKM + #define PDUMPTESTNEXTFRAME PDumpTestNextFrame + #define PDUMPREGWITHFLAGS PDumpRegWithFlagsKM + #define PDUMPREG PDUMP_REG_FUNC_NAME + #define PDUMPCOMMENT PDumpComment + #define PDUMPCOMMENTWITHFLAGS PDumpCommentWithFlags + #define PDUMPREGPOL PDumpRegPolKM + #define PDUMPREGPOLWITHFLAGS PDumpRegPolWithFlagsKM + #define PDUMPMALLOCPAGES PDumpMallocPages + #define PDUMPMALLOCPAGETABLE PDumpMallocPageTable + #define PDUMPSETMMUCONTEXT PDumpSetMMUContext + #define PDUMPCLEARMMUCONTEXT PDumpClearMMUContext + #define PDUMPFREEPAGES PDumpFreePages + #define PDUMPFREEPAGETABLE PDumpFreePageTable + #define PDUMPPDREG PDumpPDReg + #define PDUMPPDREGWITHFLAGS PDumpPDRegWithFlags + #define PDUMPCBP PDumpCBP + #define PDUMPMALLOCPAGESPHYS PDumpMallocPagesPhys + #define PDUMPENDINITPHASE PDumpStopInitPhaseKM + #define PDUMPMSVDXREGWRITE PDumpMsvdxRegWrite + #define PDUMPMSVDXREGREAD PDumpMsvdxRegRead + #define PDUMPMSVDXPOL PDumpMsvdxRegPol + #define PDUMPMSVDXWRITEREF PDumpMsvdxWriteRef + #define PDUMPBITMAPKM PDumpBitmapKM + #define PDUMPDRIVERINFO PDumpDriverInfoKM + #define PDUMPIDLWITHFLAGS PDumpIDLWithFlags + #define PDUMPIDL PDumpIDL + #define PDUMPSUSPEND PDumpSuspendKM + #define PDUMPRESUME PDumpResumeKM + +#else + #if ((defined(LINUX) || defined(GCC_IA32)) || defined(GCC_ARM)) + #define PDUMPMEMPOL(args...) + #define PDUMPMEM(args...) + #define PDUMPMEM2(args...) + #define PDUMPMEMUM(args...) + #define PDUMPINIT(args...) + #define PDUMPDEINIT(args...) + #define PDUMPISLASTFRAME(args...) + #define PDUMPTESTFRAME(args...) + #define PDUMPTESTNEXTFRAME(args...) + #define PDUMPREGWITHFLAGS(args...) + #define PDUMPREG(args...) + #define PDUMPCOMMENT(args...) + #define PDUMPREGPOL(args...) + #define PDUMPREGPOLWITHFLAGS(args...) + #define PDUMPMALLOCPAGES(args...) + #define PDUMPMALLOCPAGETABLE(args...) + #define PDUMPSETMMUCONTEXT(args...) + #define PDUMPCLEARMMUCONTEXT(args...) + #define PDUMPFREEPAGES(args...) + #define PDUMPFREEPAGETABLE(args...) + #define PDUMPPDREG(args...) + #define PDUMPPDREGWITHFLAGS(args...) + #define PDUMPSYNC(args...) + #define PDUMPCOPYTOMEM(args...) + #define PDUMPWRITE(args...) + #define PDUMPCBP(args...) + #define PDUMPCOMMENTWITHFLAGS(args...) + #define PDUMPMALLOCPAGESPHYS(args...) + #define PDUMPENDINITPHASE(args...) + #define PDUMPMSVDXREG(args...) + #define PDUMPMSVDXREGWRITE(args...) + #define PDUMPMSVDXREGREAD(args...) + #define PDUMPMSVDXPOLEQ(args...) + #define PDUMPMSVDXPOL(args...) + #define PDUMPBITMAPKM(args...) + #define PDUMPDRIVERINFO(args...) + #define PDUMPIDLWITHFLAGS(args...) + #define PDUMPIDL(args...) + #define PDUMPSUSPEND(args...) + #define PDUMPRESUME(args...) + #define PDUMPMSVDXWRITEREF(args...) + #else + #error Compiler not specified + #endif +#endif + +#if defined (__cplusplus) +} +#endif + +#endif + diff --git a/services4/srvkm/include/perproc.h b/services4/srvkm/include/perproc.h new file mode 100644 index 0000000..233bb59 --- /dev/null +++ b/services4/srvkm/include/perproc.h @@ -0,0 +1,110 @@ +/********************************************************************** + * + * Copyright(c) 2008 Imagination Technologies Ltd. All rights reserved. + * + * This program is free software; you can redistribute it and/or modify it + * under the terms and conditions of the GNU General Public License, + * version 2, as published by the Free Software Foundation. + * + * This program is distributed in the hope it will be useful but, except + * as otherwise stated in writing, without any warranty; without even the + * implied warranty of merchantability or fitness for a particular purpose. + * See the GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License along with + * this program; if not, write to the Free Software Foundation, Inc., + * 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA. + * + * The full GNU General Public License is included in this distribution in + * the file called "COPYING". + * + * Contact Information: + * Imagination Technologies Ltd. + * Home Park Estate, Kings Langley, Herts, WD4 8LZ, UK + * + ******************************************************************************/ + +#ifndef __PERPROC_H__ +#define __PERPROC_H__ + +#if defined (__cplusplus) +extern "C" { +#endif + +#include "img_types.h" +#include "resman.h" + +#include "handle.h" + +typedef struct _PVRSRV_PER_PROCESS_DATA_ +{ + IMG_UINT32 ui32PID; + IMG_HANDLE hBlockAlloc; + PRESMAN_CONTEXT hResManContext; + IMG_HANDLE hPerProcData; + PVRSRV_HANDLE_BASE *psHandleBase; +#if defined (PVR_SECURE_HANDLES) + + IMG_BOOL bHandlesBatched; +#endif + IMG_UINT32 ui32RefCount; + + + IMG_BOOL bInitProcess; + + + IMG_HANDLE hOsPrivateData; +} PVRSRV_PER_PROCESS_DATA; + +PVRSRV_PER_PROCESS_DATA *PVRSRVPerProcessData(IMG_UINT32 ui32PID); + +PVRSRV_ERROR PVRSRVPerProcessDataConnect(IMG_UINT32 ui32PID); +IMG_VOID PVRSRVPerProcessDataDisconnect(IMG_UINT32 ui32PID); + +PVRSRV_ERROR PVRSRVPerProcessDataInit(IMG_VOID); +PVRSRV_ERROR PVRSRVPerProcessDataDeInit(IMG_VOID); + +#ifdef INLINE_IS_PRAGMA +#pragma inline(PVRSRVFindPerProcessData) +#endif +static INLINE +PVRSRV_PER_PROCESS_DATA *PVRSRVFindPerProcessData(IMG_VOID) +{ + return PVRSRVPerProcessData(OSGetCurrentProcessIDKM()); +} + + +#ifdef INLINE_IS_PRAGMA +#pragma inline(PVRSRVProcessPrivateData) +#endif +static INLINE +IMG_HANDLE PVRSRVProcessPrivateData(PVRSRV_PER_PROCESS_DATA *psPerProc) +{ + return (psPerProc != IMG_NULL) ? psPerProc->hOsPrivateData : IMG_NULL; +} + + +#ifdef INLINE_IS_PRAGMA +#pragma inline(PVRSRVPerProcessPrivateData) +#endif +static INLINE +IMG_HANDLE PVRSRVPerProcessPrivateData(IMG_UINT32 ui32PID) +{ + return PVRSRVProcessPrivateData(PVRSRVPerProcessData(ui32PID)); +} + +#ifdef INLINE_IS_PRAGMA +#pragma inline(PVRSRVFindPerProcessPrivateData) +#endif +static INLINE +IMG_HANDLE PVRSRVFindPerProcessPrivateData(IMG_VOID) +{ + return PVRSRVProcessPrivateData(PVRSRVFindPerProcessData()); +} + +#if defined (__cplusplus) +} +#endif + +#endif + diff --git a/services4/srvkm/include/power.h b/services4/srvkm/include/power.h new file mode 100644 index 0000000..5d0f0c3 --- /dev/null +++ b/services4/srvkm/include/power.h @@ -0,0 +1,118 @@ +/********************************************************************** + * + * Copyright(c) 2008 Imagination Technologies Ltd. All rights reserved. + * + * This program is free software; you can redistribute it and/or modify it + * under the terms and conditions of the GNU General Public License, + * version 2, as published by the Free Software Foundation. + * + * This program is distributed in the hope it will be useful but, except + * as otherwise stated in writing, without any warranty; without even the + * implied warranty of merchantability or fitness for a particular purpose. + * See the GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License along with + * this program; if not, write to the Free Software Foundation, Inc., + * 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA. + * + * The full GNU General Public License is included in this distribution in + * the file called "COPYING". + * + * Contact Information: + * Imagination Technologies Ltd. + * Home Park Estate, Kings Langley, Herts, WD4 8LZ, UK + * + ******************************************************************************/ + +#ifndef POWER_H +#define POWER_H + +#if defined(__cplusplus) +extern "C" { +#endif + + +typedef struct _PVRSRV_POWER_DEV_TAG_ +{ + PFN_PRE_POWER pfnPrePower; + PFN_POST_POWER pfnPostPower; + PFN_PRE_CLOCKSPEED_CHANGE pfnPreClockSpeedChange; + PFN_POST_CLOCKSPEED_CHANGE pfnPostClockSpeedChange; + IMG_HANDLE hDevCookie; + IMG_UINT32 ui32DeviceIndex; + PVR_POWER_STATE eDefaultPowerState; + PVR_POWER_STATE eCurrentPowerState; + struct _PVRSRV_POWER_DEV_TAG_ *psNext; + +} PVRSRV_POWER_DEV; + +typedef enum _PVRSRV_INIT_SERVER_STATE_ +{ + PVRSRV_INIT_SERVER_Unspecified = -1, + PVRSRV_INIT_SERVER_RUNNING = 0, + PVRSRV_INIT_SERVER_RAN = 1, + PVRSRV_INIT_SERVER_SUCCESSFUL = 2, + PVRSRV_INIT_SERVER_NUM = 3, + PVRSRV_INIT_SERVER_FORCE_I32 = 0x7fffffff + +} PVRSRV_INIT_SERVER_STATE, *PPVRSRV_INIT_SERVER_STATE; + +IMG_IMPORT +IMG_BOOL PVRSRVGetInitServerState(PVRSRV_INIT_SERVER_STATE eInitServerState); + +IMG_IMPORT +PVRSRV_ERROR PVRSRVSetInitServerState(PVRSRV_INIT_SERVER_STATE eInitServerState, IMG_BOOL bState); + + + +IMG_IMPORT +PVRSRV_ERROR PVRSRVPowerLock(IMG_UINT32 ui32CallerID, + IMG_BOOL bSystemPowerEvent); +IMG_IMPORT +IMG_VOID PVRSRVPowerUnlock(IMG_UINT32 ui32CallerID); + +IMG_IMPORT +PVRSRV_ERROR PVRSRVSetDevicePowerStateKM(IMG_UINT32 ui32DeviceIndex, + PVR_POWER_STATE eNewPowerState, + IMG_UINT32 ui32CallerID, + IMG_BOOL bRetainMutex); + +IMG_IMPORT +PVRSRV_ERROR PVRSRVSystemPrePowerStateKM(PVR_POWER_STATE eNewPowerState); +IMG_IMPORT +PVRSRV_ERROR PVRSRVSystemPostPowerStateKM(PVR_POWER_STATE eNewPowerState); + +IMG_IMPORT +PVRSRV_ERROR PVRSRVSetPowerStateKM (PVR_POWER_STATE ePVRState); + +IMG_IMPORT +PVRSRV_ERROR PVRSRVRegisterPowerDevice(IMG_UINT32 ui32DeviceIndex, + PFN_PRE_POWER pfnPrePower, + PFN_POST_POWER pfnPostPower, + PFN_PRE_CLOCKSPEED_CHANGE pfnPreClockSpeedChange, + PFN_POST_CLOCKSPEED_CHANGE pfnPostClockSpeedChange, + IMG_HANDLE hDevCookie, + PVR_POWER_STATE eCurrentPowerState, + PVR_POWER_STATE eDefaultPowerState); + +IMG_IMPORT +PVRSRV_ERROR PVRSRVRemovePowerDevice (IMG_UINT32 ui32DeviceIndex); + +IMG_IMPORT +IMG_BOOL PVRSRVIsDevicePowered(IMG_UINT32 ui32DeviceIndex); + +IMG_IMPORT +PVRSRV_ERROR PVRSRVDevicePreClockSpeedChange(IMG_UINT32 ui32DeviceIndex, + IMG_BOOL bIdleDevice, + IMG_VOID *pvInfo); + +IMG_IMPORT +IMG_VOID PVRSRVDevicePostClockSpeedChange(IMG_UINT32 ui32DeviceIndex, + IMG_BOOL bIdleDevice, + IMG_VOID *pvInfo); + +#if defined (__cplusplus) +} +#endif +#endif + diff --git a/services4/srvkm/include/queue.h b/services4/srvkm/include/queue.h new file mode 100644 index 0000000..7926f05 --- /dev/null +++ b/services4/srvkm/include/queue.h @@ -0,0 +1,110 @@ +/********************************************************************** + * + * Copyright(c) 2008 Imagination Technologies Ltd. All rights reserved. + * + * This program is free software; you can redistribute it and/or modify it + * under the terms and conditions of the GNU General Public License, + * version 2, as published by the Free Software Foundation. + * + * This program is distributed in the hope it will be useful but, except + * as otherwise stated in writing, without any warranty; without even the + * implied warranty of merchantability or fitness for a particular purpose. + * See the GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License along with + * this program; if not, write to the Free Software Foundation, Inc., + * 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA. + * + * The full GNU General Public License is included in this distribution in + * the file called "COPYING". + * + * Contact Information: + * Imagination Technologies Ltd. + * Home Park Estate, Kings Langley, Herts, WD4 8LZ, UK + * + ******************************************************************************/ + +#ifndef QUEUE_H +#define QUEUE_H + + +#if defined(__cplusplus) +extern "C" { +#endif + +#define UPDATE_QUEUE_ROFF(psQueue, ui32Size) \ + psQueue->ui32ReadOffset = (psQueue->ui32ReadOffset + ui32Size) \ + & (psQueue->ui32QueueSize - 1); + + typedef struct _COMMAND_COMPLETE_DATA_ + { + IMG_BOOL bInUse; + + IMG_UINT32 ui32DstSyncCount; + IMG_UINT32 ui32SrcSyncCount; + PVRSRV_SYNC_OBJECT *psDstSync; + PVRSRV_SYNC_OBJECT *psSrcSync; + }COMMAND_COMPLETE_DATA, *PCOMMAND_COMPLETE_DATA; + +#if !defined(USE_CODE) + +IMG_IMPORT +PVRSRV_ERROR PVRSRVProcessQueues (IMG_UINT32 ui32CallerID, + IMG_BOOL bFlush); + +#if defined(__linux__) && defined(__KERNEL__) +#include +off_t +QueuePrintQueues (IMG_CHAR * buffer, size_t size, off_t off); +#endif + + +IMG_IMPORT +PVRSRV_ERROR IMG_CALLCONV PVRSRVCreateCommandQueueKM(IMG_UINT32 ui32QueueSize, + PVRSRV_QUEUE_INFO **ppsQueueInfo); +IMG_IMPORT +PVRSRV_ERROR IMG_CALLCONV PVRSRVDestroyCommandQueueKM(PVRSRV_QUEUE_INFO *psQueueInfo); + +IMG_IMPORT +PVRSRV_ERROR IMG_CALLCONV PVRSRVInsertCommandKM(PVRSRV_QUEUE_INFO *psQueue, + PVRSRV_COMMAND **ppsCommand, + IMG_UINT32 ui32DevIndex, + IMG_UINT16 CommandType, + IMG_UINT32 ui32DstSyncCount, + PVRSRV_KERNEL_SYNC_INFO *apsDstSync[], + IMG_UINT32 ui32SrcSyncCount, + PVRSRV_KERNEL_SYNC_INFO *apsSrcSync[], + IMG_UINT32 ui32DataByteSize ); + +IMG_IMPORT +PVRSRV_ERROR IMG_CALLCONV PVRSRVGetQueueSpaceKM(PVRSRV_QUEUE_INFO *psQueue, + IMG_UINT32 ui32ParamSize, + IMG_VOID **ppvSpace); + +IMG_IMPORT +PVRSRV_ERROR IMG_CALLCONV PVRSRVSubmitCommandKM(PVRSRV_QUEUE_INFO *psQueue, + PVRSRV_COMMAND *psCommand); + +IMG_IMPORT +IMG_VOID PVRSRVCommandCompleteKM(IMG_HANDLE hCmdCookie, IMG_BOOL bScheduleMISR); + +IMG_VOID PVRSRVCommandCompleteCallbacks(IMG_VOID); + +IMG_IMPORT +PVRSRV_ERROR PVRSRVRegisterCmdProcListKM(IMG_UINT32 ui32DevIndex, + PFN_CMD_PROC *ppfnCmdProcList, + IMG_UINT32 ui32MaxSyncsPerCmd[][2], + IMG_UINT32 ui32CmdCount); +IMG_IMPORT +PVRSRV_ERROR PVRSRVRemoveCmdProcListKM(IMG_UINT32 ui32DevIndex, + IMG_UINT32 ui32CmdCount); + +#endif + + +#if defined (__cplusplus) +} +#endif + +#endif + diff --git a/services4/srvkm/include/ra.h b/services4/srvkm/include/ra.h new file mode 100644 index 0000000..593f17f --- /dev/null +++ b/services4/srvkm/include/ra.h @@ -0,0 +1,155 @@ +/********************************************************************** + * + * Copyright(c) 2008 Imagination Technologies Ltd. All rights reserved. + * + * This program is free software; you can redistribute it and/or modify it + * under the terms and conditions of the GNU General Public License, + * version 2, as published by the Free Software Foundation. + * + * This program is distributed in the hope it will be useful but, except + * as otherwise stated in writing, without any warranty; without even the + * implied warranty of merchantability or fitness for a particular purpose. + * See the GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License along with + * this program; if not, write to the Free Software Foundation, Inc., + * 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA. + * + * The full GNU General Public License is included in this distribution in + * the file called "COPYING". + * + * Contact Information: + * Imagination Technologies Ltd. + * Home Park Estate, Kings Langley, Herts, WD4 8LZ, UK + * + ******************************************************************************/ + +#ifndef _RA_H_ +#define _RA_H_ + +#include "img_types.h" +#include "hash.h" +#include "osfunc.h" + +typedef struct _RA_ARENA_ RA_ARENA; +typedef struct _BM_MAPPING_ BM_MAPPING; + + + +#define RA_STATS + + +struct _RA_STATISTICS_ +{ + + IMG_UINT32 uSpanCount; + + + IMG_UINT32 uLiveSegmentCount; + + + IMG_UINT32 uFreeSegmentCount; + + + IMG_UINT32 uTotalResourceCount; + + + IMG_UINT32 uFreeResourceCount; + + + IMG_UINT32 uCumulativeAllocs; + + + IMG_UINT32 uCumulativeFrees; + + + IMG_UINT32 uImportCount; + + + IMG_UINT32 uExportCount; +}; +typedef struct _RA_STATISTICS_ RA_STATISTICS; + +struct _RA_SEGMENT_DETAILS_ +{ + IMG_UINT32 uiSize; + IMG_CPU_PHYADDR sCpuPhyAddr; + IMG_HANDLE hSegment; +}; +typedef struct _RA_SEGMENT_DETAILS_ RA_SEGMENT_DETAILS; + +RA_ARENA * +RA_Create (IMG_CHAR *name, + IMG_UINTPTR_T base, + IMG_SIZE_T uSize, + BM_MAPPING *psMapping, + IMG_SIZE_T uQuantum, + IMG_BOOL (*imp_alloc)(IMG_VOID *_h, + IMG_SIZE_T uSize, + IMG_SIZE_T *pActualSize, + BM_MAPPING **ppsMapping, + IMG_UINT32 uFlags, + IMG_UINTPTR_T *pBase), + IMG_VOID (*imp_free) (IMG_VOID *, + IMG_UINTPTR_T, + BM_MAPPING *), + IMG_VOID (*backingstore_free) (IMG_VOID *, + IMG_UINT32, + IMG_UINT32, + IMG_HANDLE), + IMG_VOID *import_handle); + +IMG_VOID +RA_Delete (RA_ARENA *pArena); + +IMG_BOOL +RA_TestDelete (RA_ARENA *pArena); + +IMG_BOOL +RA_Add (RA_ARENA *pArena, IMG_UINTPTR_T base, IMG_SIZE_T uSize); + +IMG_BOOL +RA_Alloc (RA_ARENA *pArena, + IMG_SIZE_T uSize, + IMG_SIZE_T *pActualSize, + BM_MAPPING **ppsMapping, + IMG_UINT32 uFlags, + IMG_UINT32 uAlignment, + IMG_UINT32 uAlignmentOffset, + IMG_UINTPTR_T *pBase); + +IMG_VOID +RA_Free (RA_ARENA *pArena, IMG_UINTPTR_T base, IMG_BOOL bFreeBackingStore); + + +#ifdef RA_STATS + +#define CHECK_SPACE(total) \ +{ \ + if(total<100) \ + return PVRSRV_ERROR_INVALID_PARAMS; \ +} + +#define UPDATE_SPACE(str, count, total) \ +{ \ + if(count == -1) \ + return PVRSRV_ERROR_INVALID_PARAMS; \ + else \ + { \ + str += count; \ + total -= count; \ + } \ +} + + +IMG_BOOL RA_GetNextLiveSegment(IMG_HANDLE hArena, RA_SEGMENT_DETAILS *psSegDetails); + + +PVRSRV_ERROR RA_GetStats(RA_ARENA *pArena, + IMG_CHAR **ppszStr, + IMG_UINT32 *pui32StrLen); + +#endif + +#endif + diff --git a/services4/srvkm/include/resman.h b/services4/srvkm/include/resman.h new file mode 100644 index 0000000..37d5e3e --- /dev/null +++ b/services4/srvkm/include/resman.h @@ -0,0 +1,112 @@ +/********************************************************************** + * + * Copyright(c) 2008 Imagination Technologies Ltd. All rights reserved. + * + * This program is free software; you can redistribute it and/or modify it + * under the terms and conditions of the GNU General Public License, + * version 2, as published by the Free Software Foundation. + * + * This program is distributed in the hope it will be useful but, except + * as otherwise stated in writing, without any warranty; without even the + * implied warranty of merchantability or fitness for a particular purpose. + * See the GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License along with + * this program; if not, write to the Free Software Foundation, Inc., + * 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA. + * + * The full GNU General Public License is included in this distribution in + * the file called "COPYING". + * + * Contact Information: + * Imagination Technologies Ltd. + * Home Park Estate, Kings Langley, Herts, WD4 8LZ, UK + * + ******************************************************************************/ + +#ifndef __RESMAN_H__ +#define __RESMAN_H__ + +#if defined (__cplusplus) +extern "C" { +#endif + +enum { + + RESMAN_TYPE_SHARED_PB_DESC = 1, + RESMAN_TYPE_SHARED_PB_DESC_CREATE_LOCK, + RESMAN_TYPE_HW_RENDER_CONTEXT, + RESMAN_TYPE_HW_TRANSFER_CONTEXT, + RESMAN_TYPE_HW_2D_CONTEXT, + RESMAN_TYPE_TRANSFER_CONTEXT, + + + + + + RESMAN_TYPE_DISPLAYCLASS_SWAPCHAIN, + RESMAN_TYPE_DISPLAYCLASS_DEVICE, + + + RESMAN_TYPE_BUFFERCLASS_DEVICE, + + + RESMAN_TYPE_OS_USERMODE_MAPPING, + + + RESMAN_TYPE_DEVICEMEM_CONTEXT, + RESMAN_TYPE_DEVICECLASSMEM_MAPPING, + RESMAN_TYPE_DEVICEMEM_MAPPING, + RESMAN_TYPE_DEVICEMEM_WRAP, + RESMAN_TYPE_DEVICEMEM_ALLOCATION, + RESMAN_TYPE_EVENT_OBJECT, + RESMAN_TYPE_SHARED_MEM_INFO, + + + RESMAN_TYPE_KERNEL_DEVICEMEM_ALLOCATION +}; + +#define RESMAN_CRITERIA_ALL 0x00000000 +#define RESMAN_CRITERIA_RESTYPE 0x00000001 +#define RESMAN_CRITERIA_PVOID_PARAM 0x00000002 +#define RESMAN_CRITERIA_UI32_PARAM 0x00000004 + +typedef PVRSRV_ERROR (*RESMAN_FREE_FN)(IMG_PVOID pvParam, IMG_UINT32 ui32Param); + +typedef struct _RESMAN_ITEM_ *PRESMAN_ITEM; +typedef struct _RESMAN_CONTEXT_ *PRESMAN_CONTEXT; + +PVRSRV_ERROR ResManInit(IMG_VOID); +IMG_VOID ResManDeInit(IMG_VOID); + +PRESMAN_ITEM ResManRegisterRes(PRESMAN_CONTEXT hResManContext, + IMG_UINT32 ui32ResType, + IMG_PVOID pvParam, + IMG_UINT32 ui32Param, + RESMAN_FREE_FN pfnFreeResource); + +PVRSRV_ERROR ResManFreeResByPtr(PRESMAN_ITEM psResItem); + +PVRSRV_ERROR ResManFreeResByCriteria(PRESMAN_CONTEXT hResManContext, + IMG_UINT32 ui32SearchCriteria, + IMG_UINT32 ui32ResType, + IMG_PVOID pvParam, + IMG_UINT32 ui32Param); + +PVRSRV_ERROR ResManDissociateRes(PRESMAN_ITEM psResItem, + PRESMAN_CONTEXT psNewResManContext); + +PVRSRV_ERROR ResManFindResourceByPtr(PRESMAN_CONTEXT hResManContext, + PRESMAN_ITEM psItem); + +PVRSRV_ERROR PVRSRVResManConnect(IMG_HANDLE hPerProc, + PRESMAN_CONTEXT *phResManContext); +IMG_VOID PVRSRVResManDisconnect(PRESMAN_CONTEXT hResManContext, + IMG_BOOL bKernelContext); + +#if defined (__cplusplus) +} +#endif + +#endif + diff --git a/services4/srvkm/include/services_headers.h b/services4/srvkm/include/services_headers.h new file mode 100644 index 0000000..eb00dbb --- /dev/null +++ b/services4/srvkm/include/services_headers.h @@ -0,0 +1,49 @@ +/********************************************************************** + * + * Copyright(c) 2008 Imagination Technologies Ltd. All rights reserved. + * + * This program is free software; you can redistribute it and/or modify it + * under the terms and conditions of the GNU General Public License, + * version 2, as published by the Free Software Foundation. + * + * This program is distributed in the hope it will be useful but, except + * as otherwise stated in writing, without any warranty; without even the + * implied warranty of merchantability or fitness for a particular purpose. + * See the GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License along with + * this program; if not, write to the Free Software Foundation, Inc., + * 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA. + * + * The full GNU General Public License is included in this distribution in + * the file called "COPYING". + * + * Contact Information: + * Imagination Technologies Ltd. + * Home Park Estate, Kings Langley, Herts, WD4 8LZ, UK + * + ******************************************************************************/ + +#ifndef SERVICES_HEADERS_H +#define SERVICES_HEADERS_H + +#ifdef DEBUG_RELEASE_BUILD +#pragma optimize( "", off ) +#define DEBUG 1 +#endif + +#include "img_defs.h" +#include "services.h" +#include "servicesint.h" +#include "power.h" +#include "resman.h" +#include "queue.h" +#include "srvkm.h" +#include "kerneldisplay.h" +#include "syscommon.h" +#include "pvr_debug.h" +#include "metrics.h" +#include "osfunc.h" + +#endif + diff --git a/services4/srvkm/include/srvkm.h b/services4/srvkm/include/srvkm.h new file mode 100644 index 0000000..0bb1116 --- /dev/null +++ b/services4/srvkm/include/srvkm.h @@ -0,0 +1,58 @@ +/********************************************************************** + * + * Copyright(c) 2008 Imagination Technologies Ltd. All rights reserved. + * + * This program is free software; you can redistribute it and/or modify it + * under the terms and conditions of the GNU General Public License, + * version 2, as published by the Free Software Foundation. + * + * This program is distributed in the hope it will be useful but, except + * as otherwise stated in writing, without any warranty; without even the + * implied warranty of merchantability or fitness for a particular purpose. + * See the GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License along with + * this program; if not, write to the Free Software Foundation, Inc., + * 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA. + * + * The full GNU General Public License is included in this distribution in + * the file called "COPYING". + * + * Contact Information: + * Imagination Technologies Ltd. + * Home Park Estate, Kings Langley, Herts, WD4 8LZ, UK + * + ******************************************************************************/ + +#ifndef SRVKM_H +#define SRVKM_H + + +#if defined(__cplusplus) +extern "C" { +#endif + +IMG_IMPORT PVRSRV_ERROR IMG_CALLCONV PVRSRVProcessConnect(IMG_UINT32 ui32PID); +IMG_IMPORT IMG_VOID IMG_CALLCONV PVRSRVProcessDisconnect(IMG_UINT32 ui32PID); + +IMG_VOID IMG_CALLCONV PVRSRVSetDCState(IMG_UINT32 ui32State); + +PVRSRV_ERROR IMG_CALLCONV PVRSRVSaveRestoreLiveSegments(IMG_HANDLE hArena, IMG_PBYTE pbyBuffer, IMG_UINT32 *puiBufSize, IMG_BOOL bSave); + +#if defined (__cplusplus) +} +#endif + +#define LOOP_UNTIL_TIMEOUT(TIMEOUT) \ +{\ + IMG_UINT32 uiOffset, uiStart, uiCurrent; \ + for(uiOffset = 0, uiStart = OSClockus(), uiCurrent = uiStart+1; \ + (uiCurrent - uiStart + uiOffset) < TIMEOUT; \ + uiCurrent = OSClockus(), \ + uiOffset = uiCurrent < uiStart ? IMG_UINT32_MAX - uiStart : uiOffset, \ + uiStart = uiCurrent < uiStart ? 0 : uiStart) + +#define END_LOOP_UNTIL_TIMEOUT() \ +} + +#endif diff --git a/services4/system/include/syscommon.h b/services4/system/include/syscommon.h new file mode 100644 index 0000000..a3675a7 --- /dev/null +++ b/services4/system/include/syscommon.h @@ -0,0 +1,217 @@ +/********************************************************************** + * + * Copyright(c) 2008 Imagination Technologies Ltd. All rights reserved. + * + * This program is free software; you can redistribute it and/or modify it + * under the terms and conditions of the GNU General Public License, + * version 2, as published by the Free Software Foundation. + * + * This program is distributed in the hope it will be useful but, except + * as otherwise stated in writing, without any warranty; without even the + * implied warranty of merchantability or fitness for a particular purpose. + * See the GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License along with + * this program; if not, write to the Free Software Foundation, Inc., + * 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA. + * + * The full GNU General Public License is included in this distribution in + * the file called "COPYING". + * + * Contact Information: + * Imagination Technologies Ltd. + * Home Park Estate, Kings Langley, Herts, WD4 8LZ, UK + * + ******************************************************************************/ + +#ifndef _SYSCOMMON_H +#define _SYSCOMMON_H + +#include "sysconfig.h" +#include "sysinfo.h" +#include "servicesint.h" +#include "queue.h" +#include "power.h" +#include "resman.h" +#include "ra.h" +#include "device.h" +#include "buffer_manager.h" + +#if defined(NO_HARDWARE) && defined(__linux__) && defined(__KERNEL__) +#include +#endif + +#if defined (__cplusplus) +extern "C" { +#endif + +typedef struct _SYS_DEVICE_ID_TAG +{ + IMG_UINT32 uiID; + IMG_BOOL bInUse; + +} SYS_DEVICE_ID; + + +#define SYS_MAX_LOCAL_DEVMEM_ARENAS 4 + +typedef struct _SYS_DATA_TAG_ +{ + IMG_UINT32 ui32NumDevices; + SYS_DEVICE_ID sDeviceID[SYS_DEVICE_COUNT]; + PVRSRV_DEVICE_NODE *psDeviceNodeList; + PVRSRV_POWER_DEV *psPowerDeviceList; + PVRSRV_RESOURCE sPowerStateChangeResource; + PVR_POWER_STATE eCurrentPowerState; + PVR_POWER_STATE eFailedPowerState; + IMG_UINT32 ui32CurrentOSPowerState; + PVRSRV_QUEUE_INFO *psQueueList; + PVRSRV_KERNEL_SYNC_INFO *psSharedSyncInfoList; + IMG_PVOID pvEnvSpecificData; + IMG_PVOID pvSysSpecificData; + PVRSRV_RESOURCE sQProcessResource; + IMG_VOID *pvSOCRegsBase; + IMG_HANDLE hSOCTimerRegisterOSMemHandle; + IMG_UINT32 *pvSOCTimerRegisterKM; + IMG_VOID *pvSOCClockGateRegsBase; + IMG_UINT32 ui32SOCClockGateRegsSize; + PFN_CMD_PROC *ppfnCmdProcList[SYS_DEVICE_COUNT]; + + + + PCOMMAND_COMPLETE_DATA *ppsCmdCompleteData[SYS_DEVICE_COUNT]; + + + IMG_BOOL bReProcessQueues; + + RA_ARENA *apsLocalDevMemArena[SYS_MAX_LOCAL_DEVMEM_ARENAS]; + + IMG_CHAR *pszVersionString; + PVRSRV_EVENTOBJECT *psGlobalEventObject; +#if defined(PDUMP) + IMG_BOOL bPowerUpPDumped; +#endif +} SYS_DATA; + + + +PVRSRV_ERROR SysInitialise(IMG_VOID); +PVRSRV_ERROR SysFinalise(IMG_VOID); + +PVRSRV_ERROR SysDeinitialise(SYS_DATA *psSysData); +PVRSRV_ERROR SysGetDeviceMemoryMap(PVRSRV_DEVICE_TYPE eDeviceType, + IMG_VOID **ppvDeviceMap); + +IMG_VOID SysRegisterExternalDevice(PVRSRV_DEVICE_NODE *psDeviceNode); +IMG_VOID SysRemoveExternalDevice(PVRSRV_DEVICE_NODE *psDeviceNode); + +IMG_UINT32 SysGetInterruptSource(SYS_DATA *psSysData, + PVRSRV_DEVICE_NODE *psDeviceNode); + +IMG_VOID SysClearInterrupts(SYS_DATA* psSysData, IMG_UINT32 ui32ClearBits); + +PVRSRV_ERROR SysResetDevice(IMG_UINT32 ui32DeviceIndex); + +PVRSRV_ERROR SysSystemPrePowerState(PVR_POWER_STATE eNewPowerState); +PVRSRV_ERROR SysSystemPostPowerState(PVR_POWER_STATE eNewPowerState); +PVRSRV_ERROR SysDevicePrePowerState(IMG_UINT32 ui32DeviceIndex, + PVR_POWER_STATE eNewPowerState, + PVR_POWER_STATE eCurrentPowerState); +PVRSRV_ERROR SysDevicePostPowerState(IMG_UINT32 ui32DeviceIndex, + PVR_POWER_STATE eNewPowerState, + PVR_POWER_STATE eCurrentPowerState); + +#if defined(SYS_CUSTOM_POWERLOCK_WRAP) +PVRSRV_ERROR SysPowerLockWrap(SYS_DATA *psSysData); +IMG_VOID SysPowerLockUnwrap(SYS_DATA *psSysData); +#endif + +PVRSRV_ERROR SysOEMFunction ( IMG_UINT32 ui32ID, + IMG_VOID *pvIn, + IMG_UINT32 ulInSize, + IMG_VOID *pvOut, + IMG_UINT32 ulOutSize); + + +IMG_DEV_PHYADDR SysCpuPAddrToDevPAddr (PVRSRV_DEVICE_TYPE eDeviceType, IMG_CPU_PHYADDR cpu_paddr); +IMG_DEV_PHYADDR SysSysPAddrToDevPAddr (PVRSRV_DEVICE_TYPE eDeviceType, IMG_SYS_PHYADDR SysPAddr); +IMG_SYS_PHYADDR SysDevPAddrToSysPAddr (PVRSRV_DEVICE_TYPE eDeviceType, IMG_DEV_PHYADDR SysPAddr); +IMG_CPU_PHYADDR SysSysPAddrToCpuPAddr (IMG_SYS_PHYADDR SysPAddr); +IMG_SYS_PHYADDR SysCpuPAddrToSysPAddr (IMG_CPU_PHYADDR cpu_paddr); +#if defined(PVR_LMA) +IMG_BOOL SysVerifyCpuPAddrToDevPAddr (PVRSRV_DEVICE_TYPE eDeviceType, IMG_CPU_PHYADDR CpuPAddr); +IMG_BOOL SysVerifySysPAddrToDevPAddr (PVRSRV_DEVICE_TYPE eDeviceType, IMG_SYS_PHYADDR SysPAddr); +#endif + +extern SYS_DATA* gpsSysData; + +#if !defined(USE_CODE) + +#ifdef INLINE_IS_PRAGMA +#pragma inline(SysAcquireData) +#endif +static INLINE PVRSRV_ERROR SysAcquireData(SYS_DATA **ppsSysData) +{ + + *ppsSysData = gpsSysData; + + + + + + if (!gpsSysData) + { + return PVRSRV_ERROR_GENERIC; + } + + return PVRSRV_OK; +} + + +#ifdef INLINE_IS_PRAGMA +#pragma inline(SysInitialiseCommon) +#endif +static INLINE PVRSRV_ERROR SysInitialiseCommon(SYS_DATA *psSysData) +{ + PVRSRV_ERROR eError; + + + eError = PVRSRVInit(psSysData); + + return eError; +} + +#ifdef INLINE_IS_PRAGMA +#pragma inline(SysDeinitialiseCommon) +#endif +static INLINE IMG_VOID SysDeinitialiseCommon(SYS_DATA *psSysData) +{ + + PVRSRVDeInit(psSysData); + + OSDestroyResource(&psSysData->sPowerStateChangeResource); +} +#endif + + +#if !(defined(NO_HARDWARE) && defined(__linux__) && defined(__KERNEL__)) +#define SysReadHWReg(p, o) OSReadHWReg(p, o) +#define SysWriteHWReg(p, o, v) OSWriteHWReg(p, o, v) +#else +static inline IMG_UINT32 SysReadHWReg(IMG_PVOID pvLinRegBaseAddr, IMG_UINT32 ui32Offset) +{ + return (IMG_UINT32) readl(pvLinRegBaseAddr + ui32Offset); +} + +static inline IMG_VOID SysWriteHWReg(IMG_PVOID pvLinRegBaseAddr, IMG_UINT32 ui32Offset, IMG_UINT32 ui32Value) +{ + writel(ui32Value, pvLinRegBaseAddr + ui32Offset); +} +#endif + +#if defined(__cplusplus) +} +#endif + +#endif + diff --git a/services4/system/omap3430/oemfuncs.h b/services4/system/omap3430/oemfuncs.h new file mode 100644 index 0000000..206f7fa --- /dev/null +++ b/services4/system/omap3430/oemfuncs.h @@ -0,0 +1,56 @@ +/********************************************************************** + * + * Copyright(c) 2008 Imagination Technologies Ltd. All rights reserved. + * + * This program is free software; you can redistribute it and/or modify it + * under the terms and conditions of the GNU General Public License, + * version 2, as published by the Free Software Foundation. + * + * This program is distributed in the hope it will be useful but, except + * as otherwise stated in writing, without any warranty; without even the + * implied warranty of merchantability or fitness for a particular purpose. + * See the GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License along with + * this program; if not, write to the Free Software Foundation, Inc., + * 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA. + * + * The full GNU General Public License is included in this distribution in + * the file called "COPYING". + * + * Contact Information: + * Imagination Technologies Ltd. + * Home Park Estate, Kings Langley, Herts, WD4 8LZ, UK + * + ******************************************************************************/ + +#if !defined(__OEMFUNCS_H__) +#define __OEMFUNCS_H__ + +#if defined (__cplusplus) +extern "C" { +#endif + +typedef IMG_UINT32 (*PFN_SRV_BRIDGEDISPATCH)( IMG_UINT32 Ioctl, + IMG_BYTE *pInBuf, + IMG_UINT32 InBufLen, + IMG_BYTE *pOutBuf, + IMG_UINT32 OutBufLen, + IMG_UINT32 *pdwBytesTransferred); +typedef struct PVRSRV_DC_OEM_JTABLE_TAG +{ + PFN_SRV_BRIDGEDISPATCH pfnOEMBridgeDispatch; + IMG_PVOID pvDummy1; + IMG_PVOID pvDummy2; + IMG_PVOID pvDummy3; + +} PVRSRV_DC_OEM_JTABLE; + +#define OEM_GET_EXT_FUNCS (1<<1) + +#if defined(__cplusplus) +} +#endif + +#endif + diff --git a/services4/system/omap3430/sysconfig.c b/services4/system/omap3430/sysconfig.c new file mode 100644 index 0000000..142ba41 --- /dev/null +++ b/services4/system/omap3430/sysconfig.c @@ -0,0 +1,799 @@ +/********************************************************************** + * + * Copyright(c) 2008 Imagination Technologies Ltd. All rights reserved. + * + * This program is free software; you can redistribute it and/or modify it + * under the terms and conditions of the GNU General Public License, + * version 2, as published by the Free Software Foundation. + * + * This program is distributed in the hope it will be useful but, except + * as otherwise stated in writing, without any warranty; without even the + * implied warranty of merchantability or fitness for a particular purpose. + * See the GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License along with + * this program; if not, write to the Free Software Foundation, Inc., + * 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA. + * + * The full GNU General Public License is included in this distribution in + * the file called "COPYING". + * + * Contact Information: + * Imagination Technologies Ltd. + * Home Park Estate, Kings Langley, Herts, WD4 8LZ, UK + * + ******************************************************************************/ + +#include "services_headers.h" +#include "kerneldisplay.h" +#include "oemfuncs.h" +#include "sgxinfo.h" +#include "pdump_km.h" +#include "sgxinfokm.h" +#include "syslocal.h" +#include "sysconfig.h" + +SYS_DATA* gpsSysData = (SYS_DATA*)IMG_NULL; +SYS_DATA gsSysData; + +static SYS_SPECIFIC_DATA gsSysSpecificData; +SYS_SPECIFIC_DATA *gpsSysSpecificData; + +static IMG_UINT32 gui32SGXDeviceID; +static SGX_DEVICE_MAP gsSGXDeviceMap; +static PVRSRV_DEVICE_NODE *gpsSGXDevNode; + +#define DEVICE_SGX_INTERRUPT (1 << 0) + +#if defined(NO_HARDWARE) +static IMG_CPU_VIRTADDR gsSGXRegsCPUVAddr; +#endif + +IMG_UINT32 PVRSRV_BridgeDispatchKM(IMG_UINT32 Ioctl, + IMG_BYTE *pInBuf, + IMG_UINT32 InBufLen, + IMG_BYTE *pOutBuf, + IMG_UINT32 OutBufLen, + IMG_UINT32 *pdwBytesTransferred); + +static PVRSRV_ERROR SysLocateDevices(SYS_DATA *psSysData) +{ +#if defined(NO_HARDWARE) + PVRSRV_ERROR eError; + IMG_CPU_PHYADDR sCpuPAddr; +#endif + + PVR_UNREFERENCED_PARAMETER(psSysData); + + + gsSGXDeviceMap.ui32Flags = 0x0; + +#if defined(NO_HARDWARE) + + + eError = OSBaseAllocContigMemory(SYS_OMAP3430_SGX_REGS_SIZE, + &gsSGXRegsCPUVAddr, + &sCpuPAddr); + if(eError != PVRSRV_OK) + { + return eError; + } + gsSGXDeviceMap.sRegsCpuPBase = sCpuPAddr; + gsSGXDeviceMap.sRegsSysPBase = SysCpuPAddrToSysPAddr(gsSGXDeviceMap.sRegsCpuPBase); + gsSGXDeviceMap.ui32RegsSize = SYS_OMAP3430_SGX_REGS_SIZE; +#if defined(__linux__) + + gsSGXDeviceMap.pvRegsCpuVBase = gsSGXRegsCPUVAddr; +#else + + gsSGXDeviceMap.pvRegsCpuVBase = IMG_NULL; +#endif + + OSMemSet(gsSGXRegsCPUVAddr, 0, SYS_OMAP3430_SGX_REGS_SIZE); + + + + + gsSGXDeviceMap.ui32IRQ = 0; + +#else + + gsSGXDeviceMap.sRegsSysPBase.uiAddr = SYS_OMAP3430_SGX_REGS_SYS_PHYS_BASE; + gsSGXDeviceMap.sRegsCpuPBase = SysSysPAddrToCpuPAddr(gsSGXDeviceMap.sRegsSysPBase); + gsSGXDeviceMap.ui32RegsSize = SYS_OMAP3430_SGX_REGS_SIZE; + + gsSGXDeviceMap.ui32IRQ = SYS_OMAP3430_SGX_IRQ; + +#endif + + + + + + return PVRSRV_OK; +} + + +IMG_CHAR *SysCreateVersionString(IMG_CPU_PHYADDR sRegRegion) +{ + static IMG_CHAR aszVersionString[100]; + SYS_DATA *psSysData; + IMG_UINT32 ui32SGXRevision; + IMG_INT32 i32Count; +#if !defined(NO_HARDWARE) + IMG_VOID *pvRegsLinAddr; + + pvRegsLinAddr = OSMapPhysToLin(sRegRegion, + SYS_OMAP3430_SGX_REGS_SIZE, + PVRSRV_HAP_UNCACHED|PVRSRV_HAP_KERNEL_ONLY, + IMG_NULL); + if(!pvRegsLinAddr) + { + return IMG_NULL; + } + + ui32SGXRevision = OSReadHWReg((IMG_PVOID)((IMG_PBYTE)pvRegsLinAddr), + EUR_CR_CORE_REVISION); +#else + ui32SGXRevision = 0; +#endif + + if (SysAcquireData(&psSysData) != PVRSRV_OK) + { + return IMG_NULL; + } + + i32Count = OSSNPrintf(aszVersionString, 100, + "SGX revision = %u.%u.%u", + (IMG_UINT)((ui32SGXRevision & EUR_CR_CORE_REVISION_MAJOR_MASK) + >> EUR_CR_CORE_REVISION_MAJOR_SHIFT), + (IMG_UINT)((ui32SGXRevision & EUR_CR_CORE_REVISION_MINOR_MASK) + >> EUR_CR_CORE_REVISION_MINOR_SHIFT), + (IMG_UINT)((ui32SGXRevision & EUR_CR_CORE_REVISION_MAINTENANCE_MASK) + >> EUR_CR_CORE_REVISION_MAINTENANCE_SHIFT) + ); + +#if !defined(NO_HARDWARE) + OSUnMapPhysToLin(pvRegsLinAddr, + SYS_OMAP3430_SGX_REGS_SIZE, + PVRSRV_HAP_UNCACHED|PVRSRV_HAP_KERNEL_ONLY, + IMG_NULL); +#endif + + if(i32Count == -1) + { + return IMG_NULL; + } + + return aszVersionString; +} + + +PVRSRV_ERROR SysInitialise(IMG_VOID) +{ + IMG_UINT32 i; + PVRSRV_ERROR eError; + PVRSRV_DEVICE_NODE *psDeviceNode; + IMG_CPU_PHYADDR TimerRegPhysBase; +#if !defined(SGX_DYNAMIC_TIMING_INFO) + SGX_TIMING_INFORMATION* psTimingInfo; +#endif + gpsSysData = &gsSysData; + OSMemSet(gpsSysData, 0, sizeof(SYS_DATA)); + + gpsSysSpecificData = &gsSysSpecificData; + OSMemSet(gpsSysSpecificData, 0, sizeof(SYS_SPECIFIC_DATA)); + + gpsSysData->pvSysSpecificData = gpsSysSpecificData; + + eError = OSInitEnvData(&gpsSysData->pvEnvSpecificData); + if (eError != PVRSRV_OK) + { + PVR_DPF((PVR_DBG_ERROR,"SysInitialise: Failed to setup env structure")); + SysDeinitialise(gpsSysData); + gpsSysData = IMG_NULL; + return eError; + } + SYS_SPECIFIC_DATA_SET(&gsSysSpecificData, SYS_SPECIFIC_DATA_ENABLE_ENVDATA); + + gpsSysData->ui32NumDevices = SYS_DEVICE_COUNT; + + + for(i=0; isDeviceID[i].uiID = i; + gpsSysData->sDeviceID[i].bInUse = IMG_FALSE; + } + + gpsSysData->psDeviceNodeList = IMG_NULL; + gpsSysData->psQueueList = IMG_NULL; + + eError = SysInitialiseCommon(gpsSysData); + if (eError != PVRSRV_OK) + { + PVR_DPF((PVR_DBG_ERROR,"SysInitialise: Failed in SysInitialiseCommon")); + SysDeinitialise(gpsSysData); + gpsSysData = IMG_NULL; + return eError; + } + + TimerRegPhysBase.uiAddr = SYS_OMAP3430_GP11TIMER_REGS_SYS_PHYS_BASE; + gpsSysData->pvSOCTimerRegisterKM = IMG_NULL; + gpsSysData->hSOCTimerRegisterOSMemHandle = 0; + OSReservePhys(TimerRegPhysBase, + 4, + PVRSRV_HAP_MULTI_PROCESS|PVRSRV_HAP_UNCACHED, + (IMG_VOID **)&gpsSysData->pvSOCTimerRegisterKM, + &gpsSysData->hSOCTimerRegisterOSMemHandle); + +#if !defined(SGX_DYNAMIC_TIMING_INFO) + + psTimingInfo = &gsSGXDeviceMap.sTimingInfo; + psTimingInfo->ui32CoreClockSpeed = SYS_SGX_CLOCK_SPEED; + psTimingInfo->ui32HWRecoveryFreq = SYS_SGX_HWRECOVERY_TIMEOUT_FREQ; + psTimingInfo->ui32ActivePowManLatencyms = SYS_SGX_ACTIVE_POWER_LATENCY_MS; + psTimingInfo->ui32uKernelFreq = SYS_SGX_PDS_TIMER_FREQ; +#endif + + + + gpsSysSpecificData->ui32SrcClockDiv = 3; + + + + + + eError = SysLocateDevices(gpsSysData); + if (eError != PVRSRV_OK) + { + PVR_DPF((PVR_DBG_ERROR,"SysInitialise: Failed to locate devices")); + SysDeinitialise(gpsSysData); + gpsSysData = IMG_NULL; + return eError; + } + SYS_SPECIFIC_DATA_SET(&gsSysSpecificData, SYS_SPECIFIC_DATA_ENABLE_LOCATEDEV); + + + + + eError = PVRSRVRegisterDevice(gpsSysData, SGXRegisterDevice, + DEVICE_SGX_INTERRUPT, &gui32SGXDeviceID); + if (eError != PVRSRV_OK) + { + PVR_DPF((PVR_DBG_ERROR,"SysInitialise: Failed to register device!")); + SysDeinitialise(gpsSysData); + gpsSysData = IMG_NULL; + return eError; + } + SYS_SPECIFIC_DATA_SET(&gsSysSpecificData, SYS_SPECIFIC_DATA_ENABLE_REGDEV); + + + + + + psDeviceNode = gpsSysData->psDeviceNodeList; + while(psDeviceNode) + { + + switch(psDeviceNode->sDevId.eDeviceType) + { + case PVRSRV_DEVICE_TYPE_SGX: + { + DEVICE_MEMORY_INFO *psDevMemoryInfo; + DEVICE_MEMORY_HEAP_INFO *psDeviceMemoryHeap; + + + + + psDeviceNode->psLocalDevMemArena = IMG_NULL; + + + psDevMemoryInfo = &psDeviceNode->sDevMemoryInfo; + psDeviceMemoryHeap = psDevMemoryInfo->psDeviceMemoryHeap; + + + for(i=0; iui32HeapCount; i++) + { + psDeviceMemoryHeap[i].ui32Attribs |= PVRSRV_BACKINGSTORE_SYSMEM_NONCONTIG; + } + + gpsSGXDevNode = psDeviceNode; + gsSysSpecificData.psSGXDevNode = psDeviceNode; + + break; + } + default: + PVR_DPF((PVR_DBG_ERROR,"SysInitialise: Failed to find SGX device node!")); + return PVRSRV_ERROR_INIT_FAILURE; + } + + + psDeviceNode = psDeviceNode->psNext; + } + + PDUMPINIT(); + SYS_SPECIFIC_DATA_SET(&gsSysSpecificData, SYS_SPECIFIC_DATA_ENABLE_PDUMPINIT); + + eError = EnableSystemClocks(gpsSysData); + if (eError != PVRSRV_OK) + { + PVR_DPF((PVR_DBG_ERROR,"SysInitialise: Failed to Enable system clocks (%d)", eError)); + SysDeinitialise(gpsSysData); + gpsSysData = IMG_NULL; + return eError; + } + SYS_SPECIFIC_DATA_SET(&gsSysSpecificData, SYS_SPECIFIC_DATA_ENABLE_SYSCLOCKS); +#if defined(SUPPORT_ACTIVE_POWER_MANAGEMENT) + eError = EnableSGXClocks(gpsSysData); + if (eError != PVRSRV_OK) + { + PVR_DPF((PVR_DBG_ERROR,"SysInitialise: Failed to Enable SGX clocks (%d)", eError)); + SysDeinitialise(gpsSysData); + gpsSysData = IMG_NULL; + return eError; + } +#endif + + eError = PVRSRVInitialiseDevice(gui32SGXDeviceID); + if (eError != PVRSRV_OK) + { + PVR_DPF((PVR_DBG_ERROR,"SysInitialise: Failed to initialise device!")); + SysDeinitialise(gpsSysData); + gpsSysData = IMG_NULL; + return eError; + } + SYS_SPECIFIC_DATA_SET(&gsSysSpecificData, SYS_SPECIFIC_DATA_ENABLE_INITDEV); + +#if defined(SUPPORT_ACTIVE_POWER_MANAGEMENT) + + DisableSGXClocks(gpsSysData); +#endif + + return PVRSRV_OK; +} + + +PVRSRV_ERROR SysFinalise(IMG_VOID) +{ + PVRSRV_ERROR eError = PVRSRV_OK; + +#if defined(SUPPORT_ACTIVE_POWER_MANAGEMENT) + eError = EnableSGXClocks(gpsSysData); + if (eError != PVRSRV_OK) + { + PVR_DPF((PVR_DBG_ERROR,"SysInitialise: Failed to Enable SGX clocks (%d)", eError)); + SysDeinitialise(gpsSysData); + gpsSysData = IMG_NULL; + return eError; + } +#endif + +#if defined(SYS_USING_INTERRUPTS) + + eError = OSInstallMISR(gpsSysData); + if (eError != PVRSRV_OK) + { + PVR_DPF((PVR_DBG_ERROR,"SysFinalise: Failed to install MISR")); + SysDeinitialise(gpsSysData); + gpsSysData = IMG_NULL; + return eError; + } + SYS_SPECIFIC_DATA_SET(&gsSysSpecificData, SYS_SPECIFIC_DATA_ENABLE_MISR); + + + eError = OSInstallDeviceLISR(gpsSysData, gsSGXDeviceMap.ui32IRQ, "SGX ISR", gpsSGXDevNode); + if (eError != PVRSRV_OK) + { + PVR_DPF((PVR_DBG_ERROR,"SysFinalise: Failed to install ISR")); + SysDeinitialise(gpsSysData); + gpsSysData = IMG_NULL; + return eError; + } + SYS_SPECIFIC_DATA_SET(&gsSysSpecificData, SYS_SPECIFIC_DATA_ENABLE_LISR); +#endif + + + gpsSysData->pszVersionString = SysCreateVersionString(gsSGXDeviceMap.sRegsCpuPBase); + if (!gpsSysData->pszVersionString) + { + PVR_DPF((PVR_DBG_ERROR,"SysFinalise: Failed to create a system version string")); + } + else + { + PVR_DPF((PVR_DBG_WARNING, "SysFinalise: Version string: %s", gpsSysData->pszVersionString)); + } + +#if defined(SUPPORT_ACTIVE_POWER_MANAGEMENT) + + DisableSGXClocks(gpsSysData); +#endif + + gpsSysSpecificData->bSGXInitComplete = IMG_TRUE; + + return eError; +} + + +PVRSRV_ERROR SysDeinitialise (SYS_DATA *psSysData) +{ + PVRSRV_ERROR eError; + +#if defined(SYS_USING_INTERRUPTS) + if (SYS_SPECIFIC_DATA_TEST(gpsSysSpecificData, SYS_SPECIFIC_DATA_ENABLE_LISR)) + { + eError = OSUninstallDeviceLISR(psSysData); + if (eError != PVRSRV_OK) + { + PVR_DPF((PVR_DBG_ERROR,"SysDeinitialise: OSUninstallDeviceLISR failed")); + return eError; + } + } + + if (SYS_SPECIFIC_DATA_TEST(gpsSysSpecificData, SYS_SPECIFIC_DATA_ENABLE_MISR)) + { + eError = OSUninstallMISR(psSysData); + if (eError != PVRSRV_OK) + { + PVR_DPF((PVR_DBG_ERROR,"SysDeinitialise: OSUninstallMISR failed")); + return eError; + } + } +#else + PVR_UNREFERENCED_PARAMETER(psSysData); +#endif + + if (SYS_SPECIFIC_DATA_TEST(gpsSysSpecificData, SYS_SPECIFIC_DATA_ENABLE_INITDEV)) + { +#if defined(SUPPORT_ACTIVE_POWER_MANAGEMENT) + PVR_ASSERT(SYS_SPECIFIC_DATA_TEST(gpsSysSpecificData, SYS_SPECIFIC_DATA_ENABLE_SYSCLOCKS)); + + eError = EnableSGXClocks(gpsSysData); + if (eError != PVRSRV_OK) + { + PVR_DPF((PVR_DBG_ERROR,"SysDeinitialise: EnableSGXClocks failed")); + return eError; + } +#endif + + + eError = PVRSRVDeinitialiseDevice (gui32SGXDeviceID); + if (eError != PVRSRV_OK) + { + PVR_DPF((PVR_DBG_ERROR,"SysDeinitialise: failed to de-init the device")); + return eError; + } + } + + + + if (SYS_SPECIFIC_DATA_TEST(gpsSysSpecificData, SYS_SPECIFIC_DATA_ENABLE_SYSCLOCKS)) + { + DisableSystemClocks(gpsSysData); + } + + if (SYS_SPECIFIC_DATA_TEST(gpsSysSpecificData, SYS_SPECIFIC_DATA_ENABLE_ENVDATA)) + { + eError = OSDeInitEnvData(gpsSysData->pvEnvSpecificData); + if (eError != PVRSRV_OK) + { + PVR_DPF((PVR_DBG_ERROR,"SysDeinitialise: failed to de-init env structure")); + return eError; + } + } + + if(gpsSysData->pvSOCTimerRegisterKM) + { + OSUnReservePhys(gpsSysData->pvSOCTimerRegisterKM, + 4, + PVRSRV_HAP_MULTI_PROCESS|PVRSRV_HAP_UNCACHED, + gpsSysData->hSOCTimerRegisterOSMemHandle); + } + + SysDeinitialiseCommon(gpsSysData); + +#if defined(NO_HARDWARE) + if(SYS_SPECIFIC_DATA_TEST(gpsSysSpecificData, SYS_SPECIFIC_DATA_ENABLE_LOCATEDEV)) + { + + OSBaseFreeContigMemory(SYS_OMAP3430_SGX_REGS_SIZE, gsSGXRegsCPUVAddr, gsSGXDeviceMap.sRegsCpuPBase); + } +#endif + + + if(SYS_SPECIFIC_DATA_TEST(gpsSysSpecificData, SYS_SPECIFIC_DATA_ENABLE_PDUMPINIT)) + { + PDUMPDEINIT(); + } + + gpsSysSpecificData->ui32SysSpecificData = 0; + gpsSysSpecificData->bSGXInitComplete = IMG_FALSE; + + gpsSysData = IMG_NULL; + + return PVRSRV_OK; +} + + +PVRSRV_ERROR SysGetDeviceMemoryMap(PVRSRV_DEVICE_TYPE eDeviceType, + IMG_VOID **ppvDeviceMap) +{ + + switch(eDeviceType) + { + case PVRSRV_DEVICE_TYPE_SGX: + { + + *ppvDeviceMap = (IMG_VOID*)&gsSGXDeviceMap; + + break; + } + default: + { + PVR_DPF((PVR_DBG_ERROR,"SysGetDeviceMemoryMap: unsupported device type")); + } + } + return PVRSRV_OK; +} + + +IMG_DEV_PHYADDR SysCpuPAddrToDevPAddr(PVRSRV_DEVICE_TYPE eDeviceType, + IMG_CPU_PHYADDR CpuPAddr) +{ + IMG_DEV_PHYADDR DevPAddr; + + PVR_UNREFERENCED_PARAMETER(eDeviceType); + + + DevPAddr.uiAddr = CpuPAddr.uiAddr; + + return DevPAddr; +} + +IMG_CPU_PHYADDR SysSysPAddrToCpuPAddr (IMG_SYS_PHYADDR sys_paddr) +{ + IMG_CPU_PHYADDR cpu_paddr; + + + cpu_paddr.uiAddr = sys_paddr.uiAddr; + return cpu_paddr; +} + +IMG_SYS_PHYADDR SysCpuPAddrToSysPAddr (IMG_CPU_PHYADDR cpu_paddr) +{ + IMG_SYS_PHYADDR sys_paddr; + + + sys_paddr.uiAddr = cpu_paddr.uiAddr; + return sys_paddr; +} + + +IMG_DEV_PHYADDR SysSysPAddrToDevPAddr(PVRSRV_DEVICE_TYPE eDeviceType, IMG_SYS_PHYADDR SysPAddr) +{ + IMG_DEV_PHYADDR DevPAddr; + + PVR_UNREFERENCED_PARAMETER(eDeviceType); + + + DevPAddr.uiAddr = SysPAddr.uiAddr; + + return DevPAddr; +} + + +IMG_SYS_PHYADDR SysDevPAddrToSysPAddr(PVRSRV_DEVICE_TYPE eDeviceType, IMG_DEV_PHYADDR DevPAddr) +{ + IMG_SYS_PHYADDR SysPAddr; + + PVR_UNREFERENCED_PARAMETER(eDeviceType); + + + SysPAddr.uiAddr = DevPAddr.uiAddr; + + return SysPAddr; +} + + +IMG_VOID SysRegisterExternalDevice(PVRSRV_DEVICE_NODE *psDeviceNode) +{ + PVR_UNREFERENCED_PARAMETER(psDeviceNode); +} + + +IMG_VOID SysRemoveExternalDevice(PVRSRV_DEVICE_NODE *psDeviceNode) +{ + PVR_UNREFERENCED_PARAMETER(psDeviceNode); +} + + +IMG_UINT32 SysGetInterruptSource(SYS_DATA *psSysData, + PVRSRV_DEVICE_NODE *psDeviceNode) +{ + PVR_UNREFERENCED_PARAMETER(psSysData); +#if defined(NO_HARDWARE) + + return 0xFFFFFFFF; +#else + + return psDeviceNode->ui32SOCInterruptBit; +#endif +} + + +IMG_VOID SysClearInterrupts(SYS_DATA* psSysData, IMG_UINT32 ui32ClearBits) +{ + PVR_UNREFERENCED_PARAMETER(psSysData); + PVR_UNREFERENCED_PARAMETER(ui32ClearBits); + + + OSReadHWReg(((PVRSRV_SGXDEV_INFO *)gpsSGXDevNode->pvDevice)->pvRegsBaseKM, + EUR_CR_EVENT_HOST_CLEAR); +} + + +PVRSRV_ERROR SysSystemPrePowerState(PVR_POWER_STATE eNewPowerState) +{ + PVRSRV_ERROR eError = PVRSRV_OK; + + if (eNewPowerState == PVRSRV_POWER_STATE_D3) + { + PVR_TRACE(("SysSystemPrePowerState: Entering state D3")); + +#if defined(SYS_USING_INTERRUPTS) + if (SYS_SPECIFIC_DATA_TEST(&gsSysSpecificData, SYS_SPECIFIC_DATA_ENABLE_LISR)) + { +#if defined(SYS_CUSTOM_POWERLOCK_WRAP) + IMG_BOOL bWrapped = WrapSystemPowerChange(&gsSysSpecificData); +#endif + eError = OSUninstallDeviceLISR(gpsSysData); +#if defined(SYS_CUSTOM_POWERLOCK_WRAP) + if (bWrapped) + { + UnwrapSystemPowerChange(&gsSysSpecificData); + } +#endif + if (eError != PVRSRV_OK) + { + PVR_DPF((PVR_DBG_ERROR,"SysSystemPrePowerState: OSUninstallDeviceLISR failed (%d)", eError)); + return eError; + } + SYS_SPECIFIC_DATA_SET(&gsSysSpecificData, SYS_SPECIFIC_DATA_PM_UNINSTALL_LISR); + SYS_SPECIFIC_DATA_CLEAR(&gsSysSpecificData, SYS_SPECIFIC_DATA_ENABLE_LISR); + } +#endif + + if (SYS_SPECIFIC_DATA_TEST(&gsSysSpecificData, SYS_SPECIFIC_DATA_ENABLE_SYSCLOCKS)) + { + DisableSystemClocks(gpsSysData); + + SYS_SPECIFIC_DATA_SET(&gsSysSpecificData, SYS_SPECIFIC_DATA_PM_DISABLE_SYSCLOCKS); + SYS_SPECIFIC_DATA_CLEAR(&gsSysSpecificData, SYS_SPECIFIC_DATA_ENABLE_SYSCLOCKS); + } + } + + return eError; +} + + +PVRSRV_ERROR SysSystemPostPowerState(PVR_POWER_STATE eNewPowerState) +{ + PVRSRV_ERROR eError = PVRSRV_OK; + + if (eNewPowerState == PVRSRV_POWER_STATE_D0) + { + PVR_TRACE(("SysSystemPostPowerState: Entering state D0")); + + if (SYS_SPECIFIC_DATA_TEST(&gsSysSpecificData, SYS_SPECIFIC_DATA_PM_DISABLE_SYSCLOCKS)) + { + eError = EnableSystemClocks(gpsSysData); + if (eError != PVRSRV_OK) + { + PVR_DPF((PVR_DBG_ERROR,"SysSystemPostPowerState: EnableSystemClocks failed (%d)", eError)); + return eError; + } + SYS_SPECIFIC_DATA_SET(&gsSysSpecificData, SYS_SPECIFIC_DATA_ENABLE_SYSCLOCKS); + SYS_SPECIFIC_DATA_CLEAR(&gsSysSpecificData, SYS_SPECIFIC_DATA_PM_DISABLE_SYSCLOCKS); + } + +#if defined(SYS_USING_INTERRUPTS) + if (SYS_SPECIFIC_DATA_TEST(&gsSysSpecificData, SYS_SPECIFIC_DATA_PM_UNINSTALL_LISR)) + { +#if defined(SYS_CUSTOM_POWERLOCK_WRAP) + IMG_BOOL bWrapped = WrapSystemPowerChange(&gsSysSpecificData); +#endif + + eError = OSInstallDeviceLISR(gpsSysData, gsSGXDeviceMap.ui32IRQ, "SGX ISR", gpsSGXDevNode); +#if defined(SYS_CUSTOM_POWERLOCK_WRAP) + if (bWrapped) + { + UnwrapSystemPowerChange(&gsSysSpecificData); + } +#endif + if (eError != PVRSRV_OK) + { + PVR_DPF((PVR_DBG_ERROR,"SysSystemPostPowerState: OSInstallDeviceLISR failed to install ISR (%d)", eError)); + return eError; + } + SYS_SPECIFIC_DATA_SET(&gsSysSpecificData, SYS_SPECIFIC_DATA_ENABLE_LISR); + SYS_SPECIFIC_DATA_CLEAR(&gsSysSpecificData, SYS_SPECIFIC_DATA_PM_UNINSTALL_LISR); + } +#endif + } + return eError; +} + + +PVRSRV_ERROR SysDevicePrePowerState(IMG_UINT32 ui32DeviceIndex, + PVR_POWER_STATE eNewPowerState, + PVR_POWER_STATE eCurrentPowerState) +{ + PVR_UNREFERENCED_PARAMETER(eCurrentPowerState); + + if (ui32DeviceIndex != gui32SGXDeviceID) + { + return PVRSRV_OK; + } + +#if defined(SUPPORT_ACTIVE_POWER_MANAGEMENT) + if (eNewPowerState == PVRSRV_POWER_STATE_D3) + { + PVR_DPF((PVR_DBG_MESSAGE, "SysDevicePrePowerState: SGX Entering state D3")); + DisableSGXClocks(gpsSysData); + } +#else + PVR_UNREFERENCED_PARAMETER(eNewPowerState ); +#endif + return PVRSRV_OK; +} + + +PVRSRV_ERROR SysDevicePostPowerState(IMG_UINT32 ui32DeviceIndex, + PVR_POWER_STATE eNewPowerState, + PVR_POWER_STATE eCurrentPowerState) +{ + PVRSRV_ERROR eError = PVRSRV_OK; + + PVR_UNREFERENCED_PARAMETER(eNewPowerState); + + if (ui32DeviceIndex != gui32SGXDeviceID) + { + return eError; + } + +#if defined(SUPPORT_ACTIVE_POWER_MANAGEMENT) + if (eCurrentPowerState == PVRSRV_POWER_STATE_D3) + { + PVR_DPF((PVR_DBG_MESSAGE, "SysDevicePostPowerState: SGX Leaving state D3")); + eError = EnableSGXClocks(gpsSysData); + } +#else + PVR_UNREFERENCED_PARAMETER(eCurrentPowerState); +#endif + + return eError; +} + + +PVRSRV_ERROR SysOEMFunction ( IMG_UINT32 ui32ID, + IMG_VOID *pvIn, + IMG_UINT32 ulInSize, + IMG_VOID *pvOut, + IMG_UINT32 ulOutSize) +{ + PVR_UNREFERENCED_PARAMETER(ui32ID); + PVR_UNREFERENCED_PARAMETER(pvIn); + PVR_UNREFERENCED_PARAMETER(ulInSize); + PVR_UNREFERENCED_PARAMETER(pvOut); + PVR_UNREFERENCED_PARAMETER(ulOutSize); + + if ((ui32ID == OEM_GET_EXT_FUNCS) && + (ulOutSize == sizeof(PVRSRV_DC_OEM_JTABLE))) + { + + PVRSRV_DC_OEM_JTABLE *psOEMJTable = (PVRSRV_DC_OEM_JTABLE*) pvOut; + psOEMJTable->pfnOEMBridgeDispatch = &PVRSRV_BridgeDispatchKM; + return PVRSRV_OK; + } + + return PVRSRV_ERROR_INVALID_PARAMS; +} diff --git a/services4/system/omap3430/sysconfig.h b/services4/system/omap3430/sysconfig.h new file mode 100644 index 0000000..d818f77 --- /dev/null +++ b/services4/system/omap3430/sysconfig.h @@ -0,0 +1,53 @@ +/********************************************************************** + * + * Copyright(c) 2008 Imagination Technologies Ltd. All rights reserved. + * + * This program is free software; you can redistribute it and/or modify it + * under the terms and conditions of the GNU General Public License, + * version 2, as published by the Free Software Foundation. + * + * This program is distributed in the hope it will be useful but, except + * as otherwise stated in writing, without any warranty; without even the + * implied warranty of merchantability or fitness for a particular purpose. + * See the GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License along with + * this program; if not, write to the Free Software Foundation, Inc., + * 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA. + * + * The full GNU General Public License is included in this distribution in + * the file called "COPYING". + * + * Contact Information: + * Imagination Technologies Ltd. + * Home Park Estate, Kings Langley, Herts, WD4 8LZ, UK + * + ******************************************************************************/ + +#if !defined(__SOCCONFIG_H__) +#define __SOCCONFIG_H__ + +#include "syscommon.h" + +#define VS_PRODUCT_NAME "OMAP3430" + +#define SYS_SGX_CLOCK_SPEED 110666666 +#define SYS_SGX_HWRECOVERY_TIMEOUT_FREQ (100) +#define SYS_SGX_PDS_TIMER_FREQ (1000) +#define SYS_SGX_ACTIVE_POWER_LATENCY_MS (1) + + +#define SYS_OMAP3430_VDD2_OPP3_SGX_CLOCK_SPEED SYS_SGX_CLOCK_SPEED +#define SYS_OMAP3430_VDD2_OPP2_SGX_CLOCK_SPEED (SYS_SGX_CLOCK_SPEED / 2) + +#define SYS_OMAP3430_SGX_REGS_SYS_PHYS_BASE 0x50000000 +#define SYS_OMAP3430_SGX_REGS_SIZE 0x4000 + +#define SYS_OMAP3430_SGX_IRQ 21 + +#define SYS_OMAP3430_GP11TIMER_ENABLE_SYS_PHYS_BASE 0x48088024 +#define SYS_OMAP3430_GP11TIMER_REGS_SYS_PHYS_BASE 0x48088028 +#define SYS_OMAP3430_GP11TIMER_TSICR_SYS_PHYS_BASE 0x48088040 + + +#endif diff --git a/services4/system/omap3430/sysinfo.h b/services4/system/omap3430/sysinfo.h new file mode 100644 index 0000000..89622fe --- /dev/null +++ b/services4/system/omap3430/sysinfo.h @@ -0,0 +1,98 @@ +/********************************************************************** + * + * Copyright(c) 2008 Imagination Technologies Ltd. All rights reserved. + * + * This program is free software; you can redistribute it and/or modify it + * under the terms and conditions of the GNU General Public License, + * version 2, as published by the Free Software Foundation. + * + * This program is distributed in the hope it will be useful but, except + * as otherwise stated in writing, without any warranty; without even the + * implied warranty of merchantability or fitness for a particular purpose. + * See the GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License along with + * this program; if not, write to the Free Software Foundation, Inc., + * 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA. + * + * The full GNU General Public License is included in this distribution in + * the file called "COPYING". + * + * Contact Information: + * Imagination Technologies Ltd. + * Home Park Estate, Kings Langley, Herts, WD4 8LZ, UK + * + ******************************************************************************/ + +#if !defined(__SYSINFO_H__) +#define __SYSINFO_H__ + +#define MAX_HW_TIME_US (500000) +#define WAIT_TRY_COUNT (10000) + +typedef enum _SYS_DEVICE_TYPE_ +{ + SYS_DEVICE_SGX = 0, + + SYS_DEVICE_FORCE_I16 = 0x7fff + +} SYS_DEVICE_TYPE; + +#define SYS_DEVICE_COUNT 3 + +#define PRM_REG32(offset) (offset) +#define CM_REG32(offset) (offset) + +#define CM_FCLKEN_SGX CM_REG32(0xB00) +#define CM_FCLKEN_SGX_EN_3D 0x00000002 + +#define CM_ICLKEN_SGX CM_REG32(0xB10) +#define CM_ICLKEN_SGX_EN_SGX 0x00000001 + +#define CM_IDLEST_SGX CM_REG32(0xB20) +#define CM_IDLEST_SGX_ST_SGX 0x00000001 + +#define CM_CLKSEL_SGX CM_REG32(0xB40) +#define CM_CLKSEL_SGX_MASK 0x0000000f +#define CM_CLKSEL_SGX_L3DIV3 0x00000000 +#define CM_CLKSEL_SGX_L3DIV4 0x00000001 +#define CM_CLKSEL_SGX_L3DIV6 0x00000002 +#define CM_CLKSEL_SGX_96M 0x00000003 + +#define CM_SLEEPDEP_SGX CM_REG32(0xB44) +#define CM_CLKSTCTRL_SGX CM_REG32(0xB48) +#define CM_CLKSTCTRL_SGX_AUTOSTATE 0x00008001 + +#define CM_CLKSTST_SGX CM_REG32(0xB4C) +#define CM_CLKSTST_SGX_STATUS_VALID 0x00000001 + +#define RM_RSTST_SGX PRM_REG32(0xB58) +#define RM_RSTST_SGX_RST_MASK 0x0000000F +#define RM_RSTST_SGX_COREDOMAINWKUP_RST 0x00000008 +#define RM_RSTST_SGX_DOMAINWKUP_RST 0x00000004 +#define RM_RSTST_SGX_GLOBALWARM_RST 0x00000002 +#define RM_RSTST_SGX_GLOBALCOLD_RST 0x00000001 + +#define PM_WKDEP_SGX PRM_REG32(0xBC8) +#define PM_WKDEP_SGX_EN_WAKEUP 0x00000010 +#define PM_WKDEP_SGX_EN_MPU 0x00000002 +#define PM_WKDEP_SGX_EN_CORE 0x00000001 + +#define PM_PWSTCTRL_SGX PRM_REG32(0xBE0) +#define PM_PWSTCTRL_SGX_POWERSTATE_MASK 0x00000003 +#define PM_PWSTCTRL_SGX_OFF 0x00000000 +#define PM_PWSTCTRL_SGX_RETENTION 0x00000001 +#define PM_PWSTCTRL_SGX_ON 0x00000003 + +#define PM_PWSTST_SGX PRM_REG32(0xBE4) +#define PM_PWSTST_SGX_INTRANSITION 0x00100000 +#define PM_PWSTST_SGX_CLKACTIVITY 0x00080000 +#define PM_PWSTST_SGX_POWERSTATE_MASK 0x00000003 +#define PM_PWSTST_SGX_OFF 0x00000003 +#define PM_PWSTST_SGX_RETENTION 0x00000001 +#define PM_PWSTST_SGX_ON 0x00000000 + +#define PM_PREPWSTST_SGX PRM_REG32(0xBE8) + + +#endif diff --git a/services4/system/omap3430/syslocal.h b/services4/system/omap3430/syslocal.h new file mode 100644 index 0000000..b97c0e2 --- /dev/null +++ b/services4/system/omap3430/syslocal.h @@ -0,0 +1,128 @@ +/********************************************************************** + * + * Copyright(c) 2008 Imagination Technologies Ltd. All rights reserved. + * + * This program is free software; you can redistribute it and/or modify it + * under the terms and conditions of the GNU General Public License, + * version 2, as published by the Free Software Foundation. + * + * This program is distributed in the hope it will be useful but, except + * as otherwise stated in writing, without any warranty; without even the + * implied warranty of merchantability or fitness for a particular purpose. + * See the GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License along with + * this program; if not, write to the Free Software Foundation, Inc., + * 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA. + * + * The full GNU General Public License is included in this distribution in + * the file called "COPYING". + * + * Contact Information: + * Imagination Technologies Ltd. + * Home Park Estate, Kings Langley, Herts, WD4 8LZ, UK + * + ******************************************************************************/ + +#if !defined(__SYSLOCAL_H__) +#define __SYSLOCAL_H__ + +#if defined(__linux__) + +#include +#include +#include +#include + +#if (LINUX_VERSION_CODE > KERNEL_VERSION(2,6,26)) +#include +#include +#else +#include +#if (LINUX_VERSION_CODE > KERNEL_VERSION(2,6,22)) +#include +#endif +#endif + +#endif + +#if defined (__cplusplus) +extern "C" { +#endif + + + +IMG_CHAR *SysCreateVersionString(IMG_CPU_PHYADDR sRegRegion); + +IMG_VOID DisableSystemClocks(SYS_DATA *psSysData); +PVRSRV_ERROR EnableSystemClocks(SYS_DATA *psSysData); + +IMG_VOID DisableSGXClocks(SYS_DATA *psSysData); +PVRSRV_ERROR EnableSGXClocks(SYS_DATA *psSysData); + +#define SYS_SPECIFIC_DATA_ENABLE_SYSCLOCKS 0x00000001 +#define SYS_SPECIFIC_DATA_ENABLE_LISR 0x00000002 +#define SYS_SPECIFIC_DATA_ENABLE_MISR 0x00000004 +#define SYS_SPECIFIC_DATA_ENABLE_ENVDATA 0x00000008 +#define SYS_SPECIFIC_DATA_ENABLE_LOCDEV 0x00000010 +#define SYS_SPECIFIC_DATA_ENABLE_REGDEV 0x00000020 +#define SYS_SPECIFIC_DATA_ENABLE_PDUMPINIT 0x00000040 +#define SYS_SPECIFIC_DATA_ENABLE_INITDEV 0x00000080 +#define SYS_SPECIFIC_DATA_ENABLE_LOCATEDEV 0x00000100 + +#define SYS_SPECIFIC_DATA_PM_UNINSTALL_LISR 0x00000200 +#define SYS_SPECIFIC_DATA_PM_DISABLE_SYSCLOCKS 0x00000400 + +#define SYS_SPECIFIC_DATA_SET(psSysSpecData, flag) ((IMG_VOID)((psSysSpecData)->ui32SysSpecificData |= (flag))) + +#define SYS_SPECIFIC_DATA_CLEAR(psSysSpecData, flag) ((IMG_VOID)((psSysSpecData)->ui32SysSpecificData &= ~(flag))) + +#define SYS_SPECIFIC_DATA_TEST(psSysSpecData, flag) (((psSysSpecData)->ui32SysSpecificData & (flag)) != 0) + +typedef struct _SYS_SPECIFIC_DATA_TAG_ +{ + IMG_UINT32 ui32SysSpecificData; + PVRSRV_DEVICE_NODE *psSGXDevNode; + IMG_BOOL bSGXInitComplete; +#if !defined(__linux__) + IMG_BOOL bSGXClocksEnabled; +#endif + IMG_UINT32 ui32SrcClockDiv; +#if defined(__linux__) + IMG_BOOL bSysClocksOneTimeInit; + IMG_BOOL bConstraintNotificationsEnabled; + atomic_t sSGXClocksEnabled; + spinlock_t sPowerLock; + atomic_t sPowerLockCPU; + spinlock_t sNotifyLock; + atomic_t sNotifyLockCPU; + IMG_BOOL bCallVDD2PostFunc; + + struct clk *psCORE_CK; + struct clk *psSGX_FCK; + struct clk *psSGX_ICK; + struct clk *psMPU_CK; +#if defined(DEBUG) || defined(TIMING) + struct clk *psGPT11_FCK; + struct clk *psGPT11_ICK; +#endif +#if (LINUX_VERSION_CODE > KERNEL_VERSION(2,6,22)) + struct constraint_handle *pVdd2Handle; +#endif +#endif +} SYS_SPECIFIC_DATA; + +extern SYS_SPECIFIC_DATA *gpsSysSpecificData; + +#if defined(SYS_CUSTOM_POWERLOCK_WRAP) +IMG_BOOL WrapSystemPowerChange(SYS_SPECIFIC_DATA *psSysSpecData); +IMG_VOID UnwrapSystemPowerChange(SYS_SPECIFIC_DATA *psSysSpecData); +#endif + +#if defined(__cplusplus) +} +#endif + +#endif + + diff --git a/services4/system/omap3430/sysutils.c b/services4/system/omap3430/sysutils.c new file mode 100644 index 0000000..3d3def0 --- /dev/null +++ b/services4/system/omap3430/sysutils.c @@ -0,0 +1,30 @@ +/********************************************************************** + * + * Copyright(c) 2008 Imagination Technologies Ltd. All rights reserved. + * + * This program is free software; you can redistribute it and/or modify it + * under the terms and conditions of the GNU General Public License, + * version 2, as published by the Free Software Foundation. + * + * This program is distributed in the hope it will be useful but, except + * as otherwise stated in writing, without any warranty; without even the + * implied warranty of merchantability or fitness for a particular purpose. + * See the GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License along with + * this program; if not, write to the Free Software Foundation, Inc., + * 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA. + * + * The full GNU General Public License is included in this distribution in + * the file called "COPYING". + * + * Contact Information: + * Imagination Technologies Ltd. + * Home Park Estate, Kings Langley, Herts, WD4 8LZ, UK + * + ******************************************************************************/ + +#if defined(__linux__) +#include "sysutils_linux.c" +#endif + diff --git a/services4/system/omap3430/sysutils_linux.c b/services4/system/omap3430/sysutils_linux.c new file mode 100644 index 0000000..6c3063e --- /dev/null +++ b/services4/system/omap3430/sysutils_linux.c @@ -0,0 +1,807 @@ +/********************************************************************** + * + * Copyright(c) 2008 Imagination Technologies Ltd. All rights reserved. + * + * This program is free software; you can redistribute it and/or modify it + * under the terms and conditions of the GNU General Public License, + * version 2, as published by the Free Software Foundation. + * + * This program is distributed in the hope it will be useful but, except + * as otherwise stated in writing, without any warranty; without even the + * implied warranty of merchantability or fitness for a particular purpose. + * See the GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License along with + * this program; if not, write to the Free Software Foundation, Inc., + * 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA. + * + * The full GNU General Public License is included in this distribution in + * the file called "COPYING". + * + * Contact Information: + * Imagination Technologies Ltd. + * Home Park Estate, Kings Langley, Herts, WD4 8LZ, UK + * + ******************************************************************************/ + +#include +#include +#include +#include +#include +#include + +#if (LINUX_VERSION_CODE > KERNEL_VERSION(2,6,31)) +#include +#include +#include +#else + +#if (LINUX_VERSION_CODE > KERNEL_VERSION(2,6,26)) +#include +#include +#include +#else +#include +#if (LINUX_VERSION_CODE > KERNEL_VERSION(2,6,22)) +#include +#endif +#endif +#endif + +#include "sgxdefs.h" +#include "services_headers.h" +#include "sysinfo.h" +#include "sgxapi_km.h" +#include "sysconfig.h" +#include "sgxinfokm.h" +#include "syslocal.h" + +#define ONE_MHZ 1000000 +#define HZ_TO_MHZ(m) ((m) / ONE_MHZ) + +#if defined(SUPPORT_OMAP3430_SGXFCLK_96M) +#define SGX_PARENT_CLOCK "cm_96m_fck" +#else +#define SGX_PARENT_CLOCK "core_ck" +#endif + +#if !defined(PDUMP) && !defined(NO_HARDWARE) +static IMG_BOOL PowerLockWrappedOnCPU(SYS_SPECIFIC_DATA *psSysSpecData) +{ + IMG_INT iCPU; + IMG_BOOL bLocked = IMG_FALSE; + + if (!in_interrupt()) + { + iCPU = get_cpu(); + bLocked = (iCPU == atomic_read(&psSysSpecData->sPowerLockCPU)); + + put_cpu(); + } + + return bLocked; +} + +static IMG_VOID PowerLockWrap(SYS_SPECIFIC_DATA *psSysSpecData) +{ + IMG_INT iCPU; + + if (!in_interrupt()) + { + + iCPU = get_cpu(); + + + PVR_ASSERT(iCPU != -1); + + PVR_ASSERT(!PowerLockWrappedOnCPU(psSysSpecData)); + + spin_lock(&psSysSpecData->sPowerLock); + + atomic_set(&psSysSpecData->sPowerLockCPU, iCPU); + } +} + +static IMG_VOID PowerLockUnwrap(SYS_SPECIFIC_DATA *psSysSpecData) +{ + if (!in_interrupt()) + { + PVR_ASSERT(PowerLockWrappedOnCPU(psSysSpecData)); + + spin_unlock(&psSysSpecData->sPowerLock); + + atomic_set(&psSysSpecData->sPowerLockCPU, -1); + + put_cpu(); + } +} + +PVRSRV_ERROR SysPowerLockWrap(SYS_DATA *psSysData) +{ + SYS_SPECIFIC_DATA *psSysSpecData = (SYS_SPECIFIC_DATA *) psSysData->pvSysSpecificData; + + PowerLockWrap(psSysSpecData); + + return PVRSRV_OK; +} + +IMG_VOID SysPowerLockUnwrap(SYS_DATA *psSysData) +{ + SYS_SPECIFIC_DATA *psSysSpecData = (SYS_SPECIFIC_DATA *) psSysData->pvSysSpecificData; + + PowerLockUnwrap(psSysSpecData); +} + +static IMG_BOOL NotifyLockedOnCPU(SYS_SPECIFIC_DATA *psSysSpecData) +{ + IMG_INT iCPU = get_cpu(); + IMG_BOOL bLocked = (iCPU == atomic_read(&psSysSpecData->sNotifyLockCPU)); + + put_cpu(); + + return bLocked; +} + +static IMG_VOID NotifyLock(SYS_SPECIFIC_DATA *psSysSpecData) +{ + IMG_INT iCPU; + + BUG_ON(in_interrupt()); + + + iCPU = get_cpu(); + + + PVR_ASSERT(iCPU != -1); + + PVR_ASSERT(!NotifyLockedOnCPU(psSysSpecData)); + + spin_lock(&psSysSpecData->sNotifyLock); + + atomic_set(&psSysSpecData->sNotifyLockCPU, iCPU); +} + +static IMG_VOID NotifyUnlock(SYS_SPECIFIC_DATA *psSysSpecData) +{ + PVR_ASSERT(NotifyLockedOnCPU(psSysSpecData)); + + spin_unlock(&psSysSpecData->sNotifyLock); + + atomic_set(&psSysSpecData->sNotifyLockCPU, -1); + + put_cpu(); +} +#else +static IMG_BOOL PowerLockWrappedOnCPU(SYS_SPECIFIC_DATA unref__ *psSysSpecData) +{ + return IMG_FALSE; +} + +static IMG_VOID PowerLockWrap(SYS_SPECIFIC_DATA unref__ *psSysSpecData) +{ +} + +static IMG_VOID PowerLockUnwrap(SYS_SPECIFIC_DATA unref__ *psSysSpecData) +{ +} + +PVRSRV_ERROR SysPowerLockWrap(SYS_DATA unref__ *psSysData) +{ + return PVRSRV_OK; +} + +IMG_VOID SysPowerLockUnwrap(SYS_DATA unref__ *psSysData) +{ +} +#endif + +IMG_BOOL WrapSystemPowerChange(SYS_SPECIFIC_DATA *psSysSpecData) +{ + IMG_BOOL bPowerLock = PowerLockWrappedOnCPU(psSysSpecData); + + if (bPowerLock) + { + PowerLockUnwrap(psSysSpecData); + } + + return bPowerLock; +} + +IMG_VOID UnwrapSystemPowerChange(SYS_SPECIFIC_DATA *psSysSpecData) +{ + PowerLockWrap(psSysSpecData); +} + +static inline IMG_UINT32 scale_by_rate(IMG_UINT32 val, IMG_UINT32 rate1, IMG_UINT32 rate2) +{ + if (rate1 >= rate2) + { + return val * (rate1 / rate2); + } + + return val / (rate2 / rate1); +} + +static inline IMG_UINT32 scale_prop_to_SGX_clock(IMG_UINT32 val, IMG_UINT32 rate) +{ + return scale_by_rate(val, rate, SYS_SGX_CLOCK_SPEED); +} + +static inline IMG_UINT32 scale_inv_prop_to_SGX_clock(IMG_UINT32 val, IMG_UINT32 rate) +{ + return scale_by_rate(val, SYS_SGX_CLOCK_SPEED, rate); +} + +IMG_VOID SysGetSGXTimingInformation(SGX_TIMING_INFORMATION *psTimingInfo) +{ + IMG_UINT32 rate; + +#if defined(NO_HARDWARE) + rate = SYS_SGX_CLOCK_SPEED; +#else + PVR_ASSERT(atomic_read(&gpsSysSpecificData->sSGXClocksEnabled) != 0); + + rate = clk_get_rate(gpsSysSpecificData->psSGX_FCK); + PVR_ASSERT(rate != 0); +#endif + psTimingInfo->ui32CoreClockSpeed = rate; + psTimingInfo->ui32HWRecoveryFreq = scale_prop_to_SGX_clock(SYS_SGX_HWRECOVERY_TIMEOUT_FREQ, rate); + psTimingInfo->ui32uKernelFreq = scale_prop_to_SGX_clock(SYS_SGX_PDS_TIMER_FREQ, rate); + psTimingInfo->ui32ActivePowManLatencyms = SYS_SGX_ACTIVE_POWER_LATENCY_MS; +} + +#if defined(CONSTRAINT_NOTIFICATIONS) +#if !defined(SGX_DYNAMIC_TIMING_INFO) +#error "SGX_DYNAMIC_TIMING_INFO must be defined for this platform" +#endif + +static struct constraint_id cnstr_id_vdd2 = { + .type = RES_OPP_CO, + .data = (IMG_VOID *)"vdd2_opp" +}; + +#if !defined(PDUMP) && !defined(NO_HARDWARE) +static inline IMG_BOOL ConstraintNotificationsEnabled(SYS_SPECIFIC_DATA *psSysSpecData) +{ + return (atomic_read(&psSysSpecData->sSGXClocksEnabled) != 0) && psSysSpecData->bSGXInitComplete && psSysSpecData->bConstraintNotificationsEnabled; + +} + +static IMG_INT VDD2PostFunc(struct notifier_block *n, IMG_UINT32 event, IMG_VOID *ptr) +{ + PVR_UNREFERENCED_PARAMETER(n); + PVR_UNREFERENCED_PARAMETER(event); + PVR_UNREFERENCED_PARAMETER(ptr); + + if (in_interrupt()) + { + PVR_DPF((PVR_DBG_ERROR, "%s Called in interrupt context. Ignoring.", __FUNCTION__)); + return 0; + } + + + if (!NotifyLockedOnCPU(gpsSysSpecificData)) + { + return 0; + } + +#if defined(DEBUG) + if (ConstraintNotificationsEnabled(gpsSysSpecificData)) + { + IMG_UINT32 rate; + + rate = clk_get_rate(gpsSysSpecificData->psSGX_FCK); + + PVR_ASSERT(rate != 0); + + PVR_DPF((PVR_DBG_MESSAGE, "%s: SGX clock rate: %dMHz", __FUNCTION__, HZ_TO_MHZ(rate))); + } +#endif + if (gpsSysSpecificData->bCallVDD2PostFunc) + { + PVRSRVDevicePostClockSpeedChange(gpsSysSpecificData->psSGXDevNode->sDevId.ui32DeviceIndex, IMG_TRUE, IMG_NULL); + + gpsSysSpecificData->bCallVDD2PostFunc = IMG_FALSE; + } + else + { + if (ConstraintNotificationsEnabled(gpsSysSpecificData)) + { + PVR_TRACE(("%s: Not calling PVR clock speed notification functions", __FUNCTION__)); + } + } + + NotifyUnlock(gpsSysSpecificData); + + return 0; +} + +static IMG_INT VDD2PreFunc(struct notifier_block *n, IMG_UINT32 event, IMG_VOID *ptr) +{ + PVR_UNREFERENCED_PARAMETER(n); + PVR_UNREFERENCED_PARAMETER(event); + PVR_UNREFERENCED_PARAMETER(ptr); + + if (in_interrupt()) + { + PVR_DPF((PVR_DBG_WARNING, "%s Called in interrupt context. Ignoring.", __FUNCTION__)); + return 0; + } + + if (PowerLockWrappedOnCPU(gpsSysSpecificData)) + { + PVR_DPF((PVR_DBG_WARNING, "%s Called from within a power transition. Ignoring.", __FUNCTION__)); + return 0; + } + + NotifyLock(gpsSysSpecificData); + + PVR_ASSERT(!gpsSysSpecificData->bCallVDD2PostFunc); + + if (ConstraintNotificationsEnabled(gpsSysSpecificData)) + { + PVRSRV_ERROR eError; + + eError = PVRSRVDevicePreClockSpeedChange(gpsSysSpecificData->psSGXDevNode->sDevId.ui32DeviceIndex, IMG_TRUE, IMG_NULL); + + gpsSysSpecificData->bCallVDD2PostFunc = (eError == PVRSRV_OK); + + } + + return 0; +} + +static struct notifier_block sVDD2Pre = { + VDD2PreFunc, + NULL +}; + +static struct notifier_block sVDD2Post = { + VDD2PostFunc, + NULL +}; + +static IMG_VOID RegisterConstraintNotifications(IMG_VOID) +{ + PVR_TRACE(("Registering constraint notifications")); + + PVR_ASSERT(!gpsSysSpecificData->bConstraintNotificationsEnabled); + + constraint_register_pre_notification(gpsSysSpecificData->pVdd2Handle, &sVDD2Pre, + max_vdd2_opp+1); + + constraint_register_post_notification(gpsSysSpecificData->pVdd2Handle, &sVDD2Post, + max_vdd2_opp+1); + + + NotifyLock(gpsSysSpecificData); + gpsSysSpecificData->bConstraintNotificationsEnabled = IMG_TRUE; + NotifyUnlock(gpsSysSpecificData); + + PVR_TRACE(("VDD2 constraint notifications registered")); +} + +static IMG_VOID UnRegisterConstraintNotifications(IMG_VOID) +{ + PVR_TRACE(("Unregistering constraint notifications")); + + + NotifyLock(gpsSysSpecificData); + gpsSysSpecificData->bConstraintNotificationsEnabled = IMG_FALSE; + NotifyUnlock(gpsSysSpecificData); + + + constraint_unregister_pre_notification(gpsSysSpecificData->pVdd2Handle, &sVDD2Pre, + max_vdd2_opp+1); + + constraint_unregister_post_notification(gpsSysSpecificData->pVdd2Handle, &sVDD2Post, + max_vdd2_opp+1); +} +#else +static IMG_VOID RegisterConstraintNotifications(IMG_VOID) +{ +} + +static IMG_VOID UnRegisterConstraintNotifications(IMG_VOID) +{ +} +#endif +#endif + +PVRSRV_ERROR EnableSGXClocks(SYS_DATA *psSysData) +{ +#if !defined(NO_HARDWARE) + SYS_SPECIFIC_DATA *psSysSpecData = (SYS_SPECIFIC_DATA *) psSysData->pvSysSpecificData; + long lNewRate; + IMG_INT res; + + + if (atomic_read(&psSysSpecData->sSGXClocksEnabled) != 0) + { + return PVRSRV_OK; + } + + PVR_DPF((PVR_DBG_MESSAGE, "EnableSGXClocks: Enabling SGX Clocks")); + +#if defined(DEBUG) + { + + IMG_UINT32 rate = clk_get_rate(psSysSpecData->psMPU_CK); + PVR_DPF((PVR_DBG_MESSAGE, "EnableSGXClocks: CPU Clock is %dMhz", HZ_TO_MHZ(rate))); + } +#endif + + res = clk_enable(psSysSpecData->psSGX_FCK); + if (res < 0) + { + PVR_DPF((PVR_DBG_ERROR, "EnableSGXClocks: Couldn't enable SGX functional clock (%d)", res)); + return PVRSRV_ERROR_GENERIC; + } + + res = clk_enable(psSysSpecData->psSGX_ICK); + if (res < 0) + { + PVR_DPF((PVR_DBG_ERROR, "EnableSGXClocks: Couldn't enable SGX interface clock (%d)", res)); + + clk_disable(psSysSpecData->psSGX_FCK); + return PVRSRV_ERROR_GENERIC; + } + + lNewRate = clk_round_rate(psSysSpecData->psSGX_FCK, SYS_SGX_CLOCK_SPEED + ONE_MHZ); + if (lNewRate <= 0) + { + PVR_DPF((PVR_DBG_ERROR, "EnableSGXClocks: Couldn't round SGX functional clock rate")); + return PVRSRV_ERROR_GENERIC; + } + + res = clk_set_rate(psSysSpecData->psSGX_FCK, lNewRate); + if (res < 0) + { + PVR_DPF((PVR_DBG_ERROR, "EnableSGXClocks: Couldn't set SGX function clock rate (%d)", res)); + return PVRSRV_ERROR_GENERIC; + } + +#if defined(DEBUG) + { + + IMG_UINT32 rate = clk_get_rate(psSysSpecData->psSGX_FCK); + PVR_DPF((PVR_DBG_MESSAGE, "EnableSGXClocks: SGX Functional Clock is %dMhz", HZ_TO_MHZ(rate))); + } +#endif + + + atomic_set(&psSysSpecData->sSGXClocksEnabled, 1); + +#else + PVR_UNREFERENCED_PARAMETER(psSysData); +#endif + return PVRSRV_OK; +} + + +IMG_VOID DisableSGXClocks(SYS_DATA *psSysData) +{ +#if !defined(NO_HARDWARE) + SYS_SPECIFIC_DATA *psSysSpecData = (SYS_SPECIFIC_DATA *) psSysData->pvSysSpecificData; + + + if (atomic_read(&psSysSpecData->sSGXClocksEnabled) == 0) + { + return; + } + + PVR_DPF((PVR_DBG_MESSAGE, "DisableSGXClocks: Disabling SGX Clocks")); + + if (psSysSpecData->psSGX_ICK) + { + clk_disable(psSysSpecData->psSGX_ICK); + } + + if (psSysSpecData->psSGX_FCK) + { + clk_disable(psSysSpecData->psSGX_FCK); + } + + + atomic_set(&psSysSpecData->sSGXClocksEnabled, 0); + +#else + PVR_UNREFERENCED_PARAMETER(psSysData); +#endif +} + +PVRSRV_ERROR EnableSystemClocks(SYS_DATA *psSysData) +{ + SYS_SPECIFIC_DATA *psSysSpecData = (SYS_SPECIFIC_DATA *) psSysData->pvSysSpecificData; + struct clk *psCLK; + IMG_INT res; + PVRSRV_ERROR eError; + IMG_BOOL bPowerLock; + +#if defined(DEBUG) || defined(TIMING) + IMG_INT rate; + struct clk *sys_ck; + IMG_CPU_PHYADDR TimerRegPhysBase; + IMG_HANDLE hTimerEnable; + IMG_UINT32 *pui32TimerEnable; + +#endif + + PVR_TRACE(("EnableSystemClocks: Enabling System Clocks")); + + if (!psSysSpecData->bSysClocksOneTimeInit) + { + bPowerLock = IMG_FALSE; + + spin_lock_init(&psSysSpecData->sPowerLock); + atomic_set(&psSysSpecData->sPowerLockCPU, -1); + spin_lock_init(&psSysSpecData->sNotifyLock); + atomic_set(&psSysSpecData->sNotifyLockCPU, -1); + + atomic_set(&psSysSpecData->sSGXClocksEnabled, 0); + + psCLK = clk_get(NULL, SGX_PARENT_CLOCK); + if (IS_ERR(psCLK)) + { + PVR_DPF((PVR_DBG_ERROR, "EnableSsystemClocks: Couldn't get Core Clock")); + goto ExitError; + } + psSysSpecData->psCORE_CK = psCLK; + + psCLK = clk_get(NULL, "sgx_fck"); + if (IS_ERR(psCLK)) + { + PVR_DPF((PVR_DBG_ERROR, "EnableSsystemClocks: Couldn't get SGX Functional Clock")); + goto ExitError; + } + psSysSpecData->psSGX_FCK = psCLK; + + psCLK = clk_get(NULL, "sgx_ick"); + if (IS_ERR(psCLK)) + { + PVR_DPF((PVR_DBG_ERROR, "EnableSystemClocks: Couldn't get SGX Interface Clock")); + goto ExitError; + } + psSysSpecData->psSGX_ICK = psCLK; + +#if defined(DEBUG) + psCLK = clk_get(NULL, "mpu_ck"); + if (IS_ERR(psCLK)) + { + PVR_DPF((PVR_DBG_ERROR, "EnableSystemClocks: Couldn't get MPU Clock")); + goto ExitError; + } + psSysSpecData->psMPU_CK = psCLK; +#endif + res = clk_set_parent(psSysSpecData->psSGX_FCK, psSysSpecData->psCORE_CK); + if (res < 0) + { + PVR_DPF((PVR_DBG_ERROR, "EnableSystemClocks: Couldn't set SGX parent clock (%d)", res)); + goto ExitError; + } + + psSysSpecData->bSysClocksOneTimeInit = IMG_TRUE; + } + else + { + + bPowerLock = PowerLockWrappedOnCPU(psSysSpecData); + if (bPowerLock) + { + PowerLockUnwrap(psSysSpecData); + } + } + +#if defined(CONSTRAINT_NOTIFICATIONS) + + RegisterConstraintNotifications(); +#endif + +#if defined(DEBUG) || defined(TIMING) + + psCLK = clk_get(NULL, "gpt11_fck"); + if (IS_ERR(psCLK)) + { + PVR_DPF((PVR_DBG_ERROR, "EnableSystemClocks: Couldn't get GPTIMER11 functional clock")); + goto ExitUnRegisterConstraintNotifications; + } + psSysSpecData->psGPT11_FCK = psCLK; + + psCLK = clk_get(NULL, "gpt11_ick"); + if (IS_ERR(psCLK)) + { + PVR_DPF((PVR_DBG_ERROR, "EnableSystemClocks: Couldn't get GPTIMER11 interface clock")); + goto ExitUnRegisterConstraintNotifications; + } + psSysSpecData->psGPT11_ICK = psCLK; + + sys_ck = clk_get(NULL, "sys_ck"); + if (IS_ERR(sys_ck)) + { + PVR_DPF((PVR_DBG_ERROR, "EnableSystemClocks: Couldn't get System clock")); + goto ExitUnRegisterConstraintNotifications; + } + + if(clk_get_parent(psSysSpecData->psGPT11_FCK) != sys_ck) + { + PVR_TRACE(("Setting GPTIMER11 parent to System Clock")); + res = clk_set_parent(psSysSpecData->psGPT11_FCK, sys_ck); + if (res < 0) + { + PVR_DPF((PVR_DBG_ERROR, "EnableSystemClocks: Couldn't set GPTIMER11 parent clock (%d)", res)); + goto ExitUnRegisterConstraintNotifications; + } + } + + rate = clk_get_rate(psSysSpecData->psGPT11_FCK); + PVR_TRACE(("GPTIMER11 clock is %dMHz", HZ_TO_MHZ(rate))); + + res = clk_enable(psSysSpecData->psGPT11_FCK); + if (res < 0) + { + PVR_DPF((PVR_DBG_ERROR, "EnableSystemClocks: Couldn't enable GPTIMER11 functional clock (%d)", res)); + goto ExitUnRegisterConstraintNotifications; + } + + res = clk_enable(psSysSpecData->psGPT11_ICK); + if (res < 0) + { + PVR_DPF((PVR_DBG_ERROR, "EnableSystemClocks: Couldn't enable GPTIMER11 interface clock (%d)", res)); + goto ExitDisableGPT11FCK; + } + + + TimerRegPhysBase.uiAddr = SYS_OMAP3430_GP11TIMER_TSICR_SYS_PHYS_BASE; + pui32TimerEnable = OSMapPhysToLin(TimerRegPhysBase, + 4, + PVRSRV_HAP_KERNEL_ONLY|PVRSRV_HAP_UNCACHED, + &hTimerEnable); + + if (pui32TimerEnable == IMG_NULL) + { + PVR_DPF((PVR_DBG_ERROR, "EnableSystemClocks: OSMapPhysToLin failed")); + goto ExitDisableGPT11ICK; + } + + rate = *pui32TimerEnable; + if(!(rate & 4)) + { + PVR_TRACE(("Setting GPTIMER11 mode to posted (currently is non-posted)")); + + + *pui32TimerEnable = rate | 4; + } + + OSUnMapPhysToLin(pui32TimerEnable, + 4, + PVRSRV_HAP_KERNEL_ONLY|PVRSRV_HAP_UNCACHED, + hTimerEnable); + + + TimerRegPhysBase.uiAddr = SYS_OMAP3430_GP11TIMER_ENABLE_SYS_PHYS_BASE; + pui32TimerEnable = OSMapPhysToLin(TimerRegPhysBase, + 4, + PVRSRV_HAP_KERNEL_ONLY|PVRSRV_HAP_UNCACHED, + &hTimerEnable); + + if (pui32TimerEnable == IMG_NULL) + { + PVR_DPF((PVR_DBG_ERROR, "EnableSystemClocks: OSMapPhysToLin failed")); + goto ExitDisableGPT11ICK; + } + + + *pui32TimerEnable = 3; + + OSUnMapPhysToLin(pui32TimerEnable, + 4, + PVRSRV_HAP_KERNEL_ONLY|PVRSRV_HAP_UNCACHED, + hTimerEnable); + +#endif + +#if defined(PDUMP) && !defined(NO_HARDWARE) && (LINUX_VERSION_CODE > KERNEL_VERSION(2,6,22)) + PVR_TRACE(("EnableSystemClocks: Setting SGX OPP constraint")); + + + res = constraint_set(psSysSpecData->pVdd2Handle, max_vdd2_opp); + if (res != 0) + { + PVR_DPF((PVR_DBG_ERROR, "EnableSystemClocks: constraint_set failed (%d)", res)); + goto ExitConstraintSetFailed; + } +#endif + eError = PVRSRV_OK; + goto Exit; + +#if defined(PDUMP) && !defined(NO_HARDWARE) && (LINUX_VERSION_CODE > KERNEL_VERSION(2,6,22)) +ExitConstraintSetFailed: +#endif +#if defined(DEBUG) || defined(TIMING) +ExitDisableGPT11ICK: + clk_disable(psSysSpecData->psGPT11_ICK); +ExitDisableGPT11FCK: + clk_disable(psSysSpecData->psGPT11_FCK); +ExitUnRegisterConstraintNotifications: +#endif +#if defined(CONSTRAINT_NOTIFICATIONS) + UnRegisterConstraintNotifications(); + +#endif +ExitError: + eError = PVRSRV_ERROR_GENERIC; +Exit: + if (bPowerLock) + { + PowerLockWrap(psSysSpecData); + } + +#if !defined(SUPPORT_ACTIVE_POWER_MANAGEMENT) + if (eError == PVRSRV_OK) + { + + eError = EnableSGXClocks(psSysData); + } +#endif + return eError; +} + +IMG_VOID DisableSystemClocks(SYS_DATA *psSysData) +{ + SYS_SPECIFIC_DATA *psSysSpecData = (SYS_SPECIFIC_DATA *) psSysData->pvSysSpecificData; + IMG_BOOL bPowerLock; +#if defined(DEBUG) || defined(TIMING) + IMG_CPU_PHYADDR TimerRegPhysBase; + IMG_HANDLE hTimerDisable; + IMG_UINT32 *pui32TimerDisable; +#endif + + PVR_TRACE(("DisableSystemClocks: Disabling System Clocks")); + + + DisableSGXClocks(psSysData); + + bPowerLock = PowerLockWrappedOnCPU(psSysSpecData); + if (bPowerLock) + { + + PowerLockUnwrap(psSysSpecData); + } + +#if defined(CONSTRAINT_NOTIFICATIONS) + UnRegisterConstraintNotifications(); +#endif + +#if defined(DEBUG) || defined(TIMING) + + TimerRegPhysBase.uiAddr = SYS_OMAP3430_GP11TIMER_ENABLE_SYS_PHYS_BASE; + pui32TimerDisable = OSMapPhysToLin(TimerRegPhysBase, + 4, + PVRSRV_HAP_KERNEL_ONLY|PVRSRV_HAP_UNCACHED, + &hTimerDisable); + + if (pui32TimerDisable == IMG_NULL) + { + PVR_DPF((PVR_DBG_ERROR, "DisableSystemClocks: OSMapPhysToLin failed")); + } + else + { + *pui32TimerDisable = 0; + + OSUnMapPhysToLin(pui32TimerDisable, + 4, + PVRSRV_HAP_KERNEL_ONLY|PVRSRV_HAP_UNCACHED, + hTimerDisable); + } + + clk_disable(psSysSpecData->psGPT11_ICK); + + clk_disable(psSysSpecData->psGPT11_FCK); + +#endif + if (bPowerLock) + { + PowerLockWrap(psSysSpecData); + } +} diff --git a/services4/system/omap3630/oemfuncs.h b/services4/system/omap3630/oemfuncs.h new file mode 100644 index 0000000..1131534 --- /dev/null +++ b/services4/system/omap3630/oemfuncs.h @@ -0,0 +1,56 @@ +/********************************************************************** + * + * Copyright(c) 2008 Imagination Technologies Ltd. All rights reserved. + * + * This program is free software; you can redistribute it and/or modify it + * under the terms and conditions of the GNU General Public License, + * version 2, as published by the Free Software Foundation. + * + * This program is distributed in the hope it will be useful but, except + * as otherwise stated in writing, without any warranty; without even the + * implied warranty of merchantability or fitness for a particular purpose. + * See the GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License along with + * this program; if not, write to the Free Software Foundation, Inc., + * 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA. + * + * The full GNU General Public License is included in this distribution in + * the file called "COPYING". + * + * Contact Information: + * Imagination Technologies Ltd. + * Home Park Estate, Kings Langley, Herts, WD4 8LZ, UK + * + ******************************************************************************/ + +#if !defined(__OEMFUNCS_H__) +#define __OEMFUNCS_H__ + +#if defined (__cplusplus) +extern "C" { +#endif + +typedef IMG_UINT32 (*PFN_SRV_BRIDGEDISPATCH)( IMG_UINT32 Ioctl, + IMG_BYTE *pInBuf, + IMG_UINT32 InBufLen, + IMG_BYTE *pOutBuf, + IMG_UINT32 OutBufLen, + IMG_UINT32 *pdwBytesTransferred); +typedef struct PVRSRV_DC_OEM_JTABLE_TAG +{ + PFN_SRV_BRIDGEDISPATCH pfnOEMBridgeDispatch; + IMG_PVOID pvDummy1; + IMG_PVOID pvDummy2; + IMG_PVOID pvDummy3; + +} PVRSRV_DC_OEM_JTABLE; + +#define OEM_GET_EXT_FUNCS (1<<1) + +#if defined(__cplusplus) +} +#endif + +#endif + diff --git a/services4/system/omap3630/sysconfig.c b/services4/system/omap3630/sysconfig.c new file mode 100644 index 0000000..38f3e4b --- /dev/null +++ b/services4/system/omap3630/sysconfig.c @@ -0,0 +1,807 @@ +/********************************************************************** + * + * Copyright(c) 2008 Imagination Technologies Ltd. All rights reserved. + * + * This program is free software; you can redistribute it and/or modify it + * under the terms and conditions of the GNU General Public License, + * version 2, as published by the Free Software Foundation. + * + * This program is distributed in the hope it will be useful but, except + * as otherwise stated in writing, without any warranty; without even the + * implied warranty of merchantability or fitness for a particular purpose. + * See the GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License along with + * this program; if not, write to the Free Software Foundation, Inc., + * 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA. + * + * The full GNU General Public License is included in this distribution in + * the file called "COPYING". + * + * Contact Information: + * Imagination Technologies Ltd. + * Home Park Estate, Kings Langley, Herts, WD4 8LZ, UK + * + ******************************************************************************/ + +#include "services_headers.h" +#include "kerneldisplay.h" +#include "oemfuncs.h" +#include "sgxinfo.h" +#include "pdump_km.h" +#include "sgxinfokm.h" +#include "syslocal.h" +#include "sysconfig.h" + +SYS_DATA* gpsSysData = (SYS_DATA*)IMG_NULL; +SYS_DATA gsSysData; + +static SYS_SPECIFIC_DATA gsSysSpecificData; +SYS_SPECIFIC_DATA *gpsSysSpecificData; + +static IMG_UINT32 gui32SGXDeviceID; +static SGX_DEVICE_MAP gsSGXDeviceMap; +static PVRSRV_DEVICE_NODE *gpsSGXDevNode; + +#define DEVICE_SGX_INTERRUPT (1 << 0) + +#if defined(NO_HARDWARE) +static IMG_CPU_VIRTADDR gsSGXRegsCPUVAddr; +#endif + +IMG_UINT32 PVRSRV_BridgeDispatchKM(IMG_UINT32 Ioctl, + IMG_BYTE *pInBuf, + IMG_UINT32 InBufLen, + IMG_BYTE *pOutBuf, + IMG_UINT32 OutBufLen, + IMG_UINT32 *pdwBytesTransferred); + +static PVRSRV_ERROR SysLocateDevices(SYS_DATA *psSysData) +{ +#if defined(NO_HARDWARE) + PVRSRV_ERROR eError; + IMG_CPU_PHYADDR sCpuPAddr; +#endif + + PVR_UNREFERENCED_PARAMETER(psSysData); + + + gsSGXDeviceMap.ui32Flags = 0x0; + +#if defined(NO_HARDWARE) + + + eError = OSBaseAllocContigMemory(SYS_OMAP3430_SGX_REGS_SIZE, + &gsSGXRegsCPUVAddr, + &sCpuPAddr); + if(eError != PVRSRV_OK) + { + return eError; + } + gsSGXDeviceMap.sRegsCpuPBase = sCpuPAddr; + gsSGXDeviceMap.sRegsSysPBase = SysCpuPAddrToSysPAddr(gsSGXDeviceMap.sRegsCpuPBase); + gsSGXDeviceMap.ui32RegsSize = SYS_OMAP3430_SGX_REGS_SIZE; +#if defined(__linux__) + + gsSGXDeviceMap.pvRegsCpuVBase = gsSGXRegsCPUVAddr; +#else + + gsSGXDeviceMap.pvRegsCpuVBase = IMG_NULL; +#endif + + OSMemSet(gsSGXRegsCPUVAddr, 0, SYS_OMAP3430_SGX_REGS_SIZE); + + + + + gsSGXDeviceMap.ui32IRQ = 0; + +#else + + gsSGXDeviceMap.sRegsSysPBase.uiAddr = SYS_OMAP3430_SGX_REGS_SYS_PHYS_BASE; + gsSGXDeviceMap.sRegsCpuPBase = SysSysPAddrToCpuPAddr(gsSGXDeviceMap.sRegsSysPBase); + gsSGXDeviceMap.ui32RegsSize = SYS_OMAP3430_SGX_REGS_SIZE; + + gsSGXDeviceMap.ui32IRQ = SYS_OMAP3430_SGX_IRQ; + +#endif + + + + + + return PVRSRV_OK; +} + + +IMG_CHAR *SysCreateVersionString(IMG_CPU_PHYADDR sRegRegion) +{ + static IMG_CHAR aszVersionString[100]; + SYS_DATA *psSysData; + IMG_UINT32 ui32SGXRevision; + IMG_INT32 i32Count; +#if !defined(NO_HARDWARE) + IMG_VOID *pvRegsLinAddr; + + pvRegsLinAddr = OSMapPhysToLin(sRegRegion, + SYS_OMAP3430_SGX_REGS_SIZE, + PVRSRV_HAP_UNCACHED|PVRSRV_HAP_KERNEL_ONLY, + IMG_NULL); + if(!pvRegsLinAddr) + { + return IMG_NULL; + } + + ui32SGXRevision = OSReadHWReg((IMG_PVOID)((IMG_PBYTE)pvRegsLinAddr), + EUR_CR_CORE_REVISION); +#else + ui32SGXRevision = 0; +#endif + + if (SysAcquireData(&psSysData) != PVRSRV_OK) + { + return IMG_NULL; + } + + i32Count = OSSNPrintf(aszVersionString, 100, + "SGX revision = %u.%u.%u", + (IMG_UINT)((ui32SGXRevision & EUR_CR_CORE_REVISION_MAJOR_MASK) + >> EUR_CR_CORE_REVISION_MAJOR_SHIFT), + (IMG_UINT)((ui32SGXRevision & EUR_CR_CORE_REVISION_MINOR_MASK) + >> EUR_CR_CORE_REVISION_MINOR_SHIFT), + (IMG_UINT)((ui32SGXRevision & EUR_CR_CORE_REVISION_MAINTENANCE_MASK) + >> EUR_CR_CORE_REVISION_MAINTENANCE_SHIFT) + ); + +#if !defined(NO_HARDWARE) + OSUnMapPhysToLin(pvRegsLinAddr, + SYS_OMAP3430_SGX_REGS_SIZE, + PVRSRV_HAP_UNCACHED|PVRSRV_HAP_KERNEL_ONLY, + IMG_NULL); +#endif + + if(i32Count == -1) + { + return IMG_NULL; + } + + return aszVersionString; +} + + +PVRSRV_ERROR SysInitialise(IMG_VOID) +{ + IMG_UINT32 i; + PVRSRV_ERROR eError; + PVRSRV_DEVICE_NODE *psDeviceNode; + IMG_CPU_PHYADDR TimerRegPhysBase; + +#if defined(DEBUG) + PVR_DPF((PVR_DBG_WARNING,"SysInitialise: Entering...")); +#endif + +#if !defined(SGX_DYNAMIC_TIMING_INFO) + SGX_TIMING_INFORMATION* psTimingInfo; +#endif + gpsSysData = &gsSysData; + OSMemSet(gpsSysData, 0, sizeof(SYS_DATA)); + + gpsSysSpecificData = &gsSysSpecificData; + OSMemSet(gpsSysSpecificData, 0, sizeof(SYS_SPECIFIC_DATA)); + + gpsSysData->pvSysSpecificData = gpsSysSpecificData; + + eError = OSInitEnvData(&gpsSysData->pvEnvSpecificData); + if (eError != PVRSRV_OK) + { + PVR_DPF((PVR_DBG_ERROR,"SysInitialise: Failed to setup env structure")); + SysDeinitialise(gpsSysData); + gpsSysData = IMG_NULL; + return eError; + } + SYS_SPECIFIC_DATA_SET(&gsSysSpecificData, SYS_SPECIFIC_DATA_ENABLE_ENVDATA); + + gpsSysData->ui32NumDevices = SYS_DEVICE_COUNT; + + + for(i=0; isDeviceID[i].uiID = i; + gpsSysData->sDeviceID[i].bInUse = IMG_FALSE; + } + + gpsSysData->psDeviceNodeList = IMG_NULL; + gpsSysData->psQueueList = IMG_NULL; + + eError = SysInitialiseCommon(gpsSysData); + if (eError != PVRSRV_OK) + { + PVR_DPF((PVR_DBG_ERROR,"SysInitialise: Failed in SysInitialiseCommon")); + SysDeinitialise(gpsSysData); + gpsSysData = IMG_NULL; + return eError; + } + + TimerRegPhysBase.uiAddr = SYS_OMAP3430_GP11TIMER_REGS_SYS_PHYS_BASE; + gpsSysData->pvSOCTimerRegisterKM = IMG_NULL; + gpsSysData->hSOCTimerRegisterOSMemHandle = 0; + OSReservePhys(TimerRegPhysBase, + 4, + PVRSRV_HAP_MULTI_PROCESS|PVRSRV_HAP_UNCACHED, + (IMG_VOID **)&gpsSysData->pvSOCTimerRegisterKM, + &gpsSysData->hSOCTimerRegisterOSMemHandle); + +#if !defined(SGX_DYNAMIC_TIMING_INFO) + + psTimingInfo = &gsSGXDeviceMap.sTimingInfo; + psTimingInfo->ui32CoreClockSpeed = SYS_SGX_CLOCK_SPEED; + psTimingInfo->ui32HWRecoveryFreq = SYS_SGX_HWRECOVERY_TIMEOUT_FREQ; + psTimingInfo->ui32ActivePowManLatencyms = SYS_SGX_ACTIVE_POWER_LATENCY_MS; + psTimingInfo->ui32uKernelFreq = SYS_SGX_PDS_TIMER_FREQ; +#endif + + + + gpsSysSpecificData->ui32SrcClockDiv = 3; + + + + + + eError = SysLocateDevices(gpsSysData); + if (eError != PVRSRV_OK) + { + PVR_DPF((PVR_DBG_ERROR,"SysInitialise: Failed to locate devices")); + SysDeinitialise(gpsSysData); + gpsSysData = IMG_NULL; + return eError; + } + SYS_SPECIFIC_DATA_SET(&gsSysSpecificData, SYS_SPECIFIC_DATA_ENABLE_LOCATEDEV); + + + + + eError = PVRSRVRegisterDevice(gpsSysData, SGXRegisterDevice, + DEVICE_SGX_INTERRUPT, &gui32SGXDeviceID); + if (eError != PVRSRV_OK) + { + PVR_DPF((PVR_DBG_ERROR,"SysInitialise: Failed to register device!")); + SysDeinitialise(gpsSysData); + gpsSysData = IMG_NULL; + return eError; + } + SYS_SPECIFIC_DATA_SET(&gsSysSpecificData, SYS_SPECIFIC_DATA_ENABLE_REGDEV); + + + + + + psDeviceNode = gpsSysData->psDeviceNodeList; + while(psDeviceNode) + { + + switch(psDeviceNode->sDevId.eDeviceType) + { + case PVRSRV_DEVICE_TYPE_SGX: + { + DEVICE_MEMORY_INFO *psDevMemoryInfo; + DEVICE_MEMORY_HEAP_INFO *psDeviceMemoryHeap; + + + + + psDeviceNode->psLocalDevMemArena = IMG_NULL; + + + psDevMemoryInfo = &psDeviceNode->sDevMemoryInfo; + psDeviceMemoryHeap = psDevMemoryInfo->psDeviceMemoryHeap; + + + for(i=0; iui32HeapCount; i++) + { + psDeviceMemoryHeap[i].ui32Attribs |= PVRSRV_BACKINGSTORE_SYSMEM_NONCONTIG; + } + + gpsSGXDevNode = psDeviceNode; + gsSysSpecificData.psSGXDevNode = psDeviceNode; + + break; + } + default: + PVR_DPF((PVR_DBG_ERROR,"SysInitialise: Failed to find SGX device node!")); + return PVRSRV_ERROR_INIT_FAILURE; + } + + + psDeviceNode = psDeviceNode->psNext; + } + + PDUMPINIT(); + SYS_SPECIFIC_DATA_SET(&gsSysSpecificData, SYS_SPECIFIC_DATA_ENABLE_PDUMPINIT); + + eError = EnableSystemClocks(gpsSysData); + if (eError != PVRSRV_OK) + { + PVR_DPF((PVR_DBG_ERROR,"SysInitialise: Failed to Enable system clocks (%d)", eError)); + SysDeinitialise(gpsSysData); + gpsSysData = IMG_NULL; + return eError; + } + SYS_SPECIFIC_DATA_SET(&gsSysSpecificData, SYS_SPECIFIC_DATA_ENABLE_SYSCLOCKS); + +#if defined(SUPPORT_ACTIVE_POWER_MANAGEMENT) + eError = EnableSGXClocks(gpsSysData); + if (eError != PVRSRV_OK) + { + PVR_DPF((PVR_DBG_ERROR,"SysInitialise: Failed to Enable SGX clocks (%d)", eError)); + SysDeinitialise(gpsSysData); + gpsSysData = IMG_NULL; + return eError; + } +#endif + + eError = PVRSRVInitialiseDevice(gui32SGXDeviceID); + if (eError != PVRSRV_OK) + { + PVR_DPF((PVR_DBG_ERROR,"SysInitialise: Failed to initialise device!")); + SysDeinitialise(gpsSysData); + gpsSysData = IMG_NULL; + return eError; + } + SYS_SPECIFIC_DATA_SET(&gsSysSpecificData, SYS_SPECIFIC_DATA_ENABLE_INITDEV); + +#if defined(SUPPORT_ACTIVE_POWER_MANAGEMENT) + + DisableSGXClocks(gpsSysData); +#endif + + return PVRSRV_OK; +} + + +PVRSRV_ERROR SysFinalise(IMG_VOID) +{ + PVRSRV_ERROR eError = PVRSRV_OK; + +#if defined(SUPPORT_ACTIVE_POWER_MANAGEMENT) + eError = EnableSGXClocks(gpsSysData); + if (eError != PVRSRV_OK) + { + PVR_DPF((PVR_DBG_ERROR,"SysInitialise: Failed to Enable SGX clocks (%d)", eError)); + SysDeinitialise(gpsSysData); + gpsSysData = IMG_NULL; + return eError; + } +#endif + +#if defined(SYS_USING_INTERRUPTS) + + eError = OSInstallMISR(gpsSysData); + if (eError != PVRSRV_OK) + { + PVR_DPF((PVR_DBG_ERROR,"SysFinalise: Failed to install MISR")); + SysDeinitialise(gpsSysData); + gpsSysData = IMG_NULL; + return eError; + } + SYS_SPECIFIC_DATA_SET(&gsSysSpecificData, SYS_SPECIFIC_DATA_ENABLE_MISR); + + + eError = OSInstallDeviceLISR(gpsSysData, gsSGXDeviceMap.ui32IRQ, "SGX ISR", gpsSGXDevNode); + if (eError != PVRSRV_OK) + { + PVR_DPF((PVR_DBG_ERROR,"SysFinalise: Failed to install ISR")); + SysDeinitialise(gpsSysData); + gpsSysData = IMG_NULL; + return eError; + } + SYS_SPECIFIC_DATA_SET(&gsSysSpecificData, SYS_SPECIFIC_DATA_ENABLE_LISR); +#endif + + + gpsSysData->pszVersionString = SysCreateVersionString(gsSGXDeviceMap.sRegsCpuPBase); + if (!gpsSysData->pszVersionString) + { + PVR_DPF((PVR_DBG_ERROR,"SysFinalise: Failed to create a system version string")); + } + else + { + PVR_DPF((PVR_DBG_WARNING, "SysFinalise: Version string: %s", gpsSysData->pszVersionString)); + } + +#if defined(SUPPORT_ACTIVE_POWER_MANAGEMENT) + + DisableSGXClocks(gpsSysData); +#endif + + gpsSysSpecificData->bSGXInitComplete = IMG_TRUE; + + return eError; +} + + +PVRSRV_ERROR SysDeinitialise (SYS_DATA *psSysData) +{ + PVRSRV_ERROR eError; + +#if defined(SYS_USING_INTERRUPTS) + if (SYS_SPECIFIC_DATA_TEST(gpsSysSpecificData, SYS_SPECIFIC_DATA_ENABLE_LISR)) + { + eError = OSUninstallDeviceLISR(psSysData); + if (eError != PVRSRV_OK) + { + PVR_DPF((PVR_DBG_ERROR,"SysDeinitialise: OSUninstallDeviceLISR failed")); + return eError; + } + } + + if (SYS_SPECIFIC_DATA_TEST(gpsSysSpecificData, SYS_SPECIFIC_DATA_ENABLE_MISR)) + { + eError = OSUninstallMISR(psSysData); + if (eError != PVRSRV_OK) + { + PVR_DPF((PVR_DBG_ERROR,"SysDeinitialise: OSUninstallMISR failed")); + return eError; + } + } +#else + PVR_UNREFERENCED_PARAMETER(psSysData); +#endif + + if (SYS_SPECIFIC_DATA_TEST(gpsSysSpecificData, SYS_SPECIFIC_DATA_ENABLE_INITDEV)) + { +#if defined(SUPPORT_ACTIVE_POWER_MANAGEMENT) + PVR_ASSERT(SYS_SPECIFIC_DATA_TEST(gpsSysSpecificData, SYS_SPECIFIC_DATA_ENABLE_SYSCLOCKS)); + + eError = EnableSGXClocks(gpsSysData); + if (eError != PVRSRV_OK) + { + PVR_DPF((PVR_DBG_ERROR,"SysDeinitialise: EnableSGXClocks failed")); + return eError; + } +#endif + + + eError = PVRSRVDeinitialiseDevice (gui32SGXDeviceID); + if (eError != PVRSRV_OK) + { + PVR_DPF((PVR_DBG_ERROR,"SysDeinitialise: failed to de-init the device")); + return eError; + } + } + + + + if (SYS_SPECIFIC_DATA_TEST(gpsSysSpecificData, SYS_SPECIFIC_DATA_ENABLE_SYSCLOCKS)) + { + DisableSystemClocks(gpsSysData); + } + + if (SYS_SPECIFIC_DATA_TEST(gpsSysSpecificData, SYS_SPECIFIC_DATA_ENABLE_ENVDATA)) + { + eError = OSDeInitEnvData(gpsSysData->pvEnvSpecificData); + if (eError != PVRSRV_OK) + { + PVR_DPF((PVR_DBG_ERROR,"SysDeinitialise: failed to de-init env structure")); + return eError; + } + } + + if(gpsSysData->pvSOCTimerRegisterKM) + { + OSUnReservePhys(gpsSysData->pvSOCTimerRegisterKM, + 4, + PVRSRV_HAP_MULTI_PROCESS|PVRSRV_HAP_UNCACHED, + gpsSysData->hSOCTimerRegisterOSMemHandle); + } + + SysDeinitialiseCommon(gpsSysData); + +#if defined(NO_HARDWARE) + if(SYS_SPECIFIC_DATA_TEST(gpsSysSpecificData, SYS_SPECIFIC_DATA_ENABLE_LOCATEDEV)) + { + + OSBaseFreeContigMemory(SYS_OMAP3430_SGX_REGS_SIZE, gsSGXRegsCPUVAddr, gsSGXDeviceMap.sRegsCpuPBase); + } +#endif + + + if(SYS_SPECIFIC_DATA_TEST(gpsSysSpecificData, SYS_SPECIFIC_DATA_ENABLE_PDUMPINIT)) + { + PDUMPDEINIT(); + } + + gpsSysSpecificData->ui32SysSpecificData = 0; + gpsSysSpecificData->bSGXInitComplete = IMG_FALSE; + + gpsSysData = IMG_NULL; + + return PVRSRV_OK; +} + + +PVRSRV_ERROR SysGetDeviceMemoryMap(PVRSRV_DEVICE_TYPE eDeviceType, + IMG_VOID **ppvDeviceMap) +{ + + switch(eDeviceType) + { + case PVRSRV_DEVICE_TYPE_SGX: + { + + *ppvDeviceMap = (IMG_VOID*)&gsSGXDeviceMap; + + break; + } + default: + { + PVR_DPF((PVR_DBG_ERROR,"SysGetDeviceMemoryMap: unsupported device type")); + } + } + return PVRSRV_OK; +} + + +IMG_DEV_PHYADDR SysCpuPAddrToDevPAddr(PVRSRV_DEVICE_TYPE eDeviceType, + IMG_CPU_PHYADDR CpuPAddr) +{ + IMG_DEV_PHYADDR DevPAddr; + + PVR_UNREFERENCED_PARAMETER(eDeviceType); + + + DevPAddr.uiAddr = CpuPAddr.uiAddr; + + return DevPAddr; +} + +IMG_CPU_PHYADDR SysSysPAddrToCpuPAddr (IMG_SYS_PHYADDR sys_paddr) +{ + IMG_CPU_PHYADDR cpu_paddr; + + + cpu_paddr.uiAddr = sys_paddr.uiAddr; + return cpu_paddr; +} + +IMG_SYS_PHYADDR SysCpuPAddrToSysPAddr (IMG_CPU_PHYADDR cpu_paddr) +{ + IMG_SYS_PHYADDR sys_paddr; + + + sys_paddr.uiAddr = cpu_paddr.uiAddr; + return sys_paddr; +} + + +IMG_DEV_PHYADDR SysSysPAddrToDevPAddr(PVRSRV_DEVICE_TYPE eDeviceType, IMG_SYS_PHYADDR SysPAddr) +{ + IMG_DEV_PHYADDR DevPAddr; + + PVR_UNREFERENCED_PARAMETER(eDeviceType); + + + DevPAddr.uiAddr = SysPAddr.uiAddr; + + return DevPAddr; +} + + +IMG_SYS_PHYADDR SysDevPAddrToSysPAddr(PVRSRV_DEVICE_TYPE eDeviceType, IMG_DEV_PHYADDR DevPAddr) +{ + IMG_SYS_PHYADDR SysPAddr; + + PVR_UNREFERENCED_PARAMETER(eDeviceType); + + + SysPAddr.uiAddr = DevPAddr.uiAddr; + + return SysPAddr; +} + + +IMG_VOID SysRegisterExternalDevice(PVRSRV_DEVICE_NODE *psDeviceNode) +{ + PVR_UNREFERENCED_PARAMETER(psDeviceNode); +} + + +IMG_VOID SysRemoveExternalDevice(PVRSRV_DEVICE_NODE *psDeviceNode) +{ + PVR_UNREFERENCED_PARAMETER(psDeviceNode); +} + + +IMG_UINT32 SysGetInterruptSource(SYS_DATA *psSysData, + PVRSRV_DEVICE_NODE *psDeviceNode) +{ + PVR_UNREFERENCED_PARAMETER(psSysData); +#if defined(NO_HARDWARE) + + return 0xFFFFFFFF; +#else + + return psDeviceNode->ui32SOCInterruptBit; +#endif +} + + +IMG_VOID SysClearInterrupts(SYS_DATA* psSysData, IMG_UINT32 ui32ClearBits) +{ + PVR_UNREFERENCED_PARAMETER(psSysData); + PVR_UNREFERENCED_PARAMETER(ui32ClearBits); + + + OSReadHWReg(((PVRSRV_SGXDEV_INFO *)gpsSGXDevNode->pvDevice)->pvRegsBaseKM, + EUR_CR_EVENT_HOST_CLEAR); +} + + +PVRSRV_ERROR SysSystemPrePowerState(PVR_POWER_STATE eNewPowerState) +{ + PVRSRV_ERROR eError = PVRSRV_OK; + + if (eNewPowerState == PVRSRV_POWER_STATE_D3) + { + PVR_TRACE(("SysSystemPrePowerState: Entering state D3")); + +#if defined(SYS_USING_INTERRUPTS) + if (SYS_SPECIFIC_DATA_TEST(&gsSysSpecificData, SYS_SPECIFIC_DATA_ENABLE_LISR)) + { +#if defined(SYS_CUSTOM_POWERLOCK_WRAP) + IMG_BOOL bWrapped = WrapSystemPowerChange(&gsSysSpecificData); +#endif + eError = OSUninstallDeviceLISR(gpsSysData); +#if defined(SYS_CUSTOM_POWERLOCK_WRAP) + if (bWrapped) + { + UnwrapSystemPowerChange(&gsSysSpecificData); + } +#endif + if (eError != PVRSRV_OK) + { + PVR_DPF((PVR_DBG_ERROR,"SysSystemPrePowerState: OSUninstallDeviceLISR failed (%d)", eError)); + return eError; + } + SYS_SPECIFIC_DATA_SET(&gsSysSpecificData, SYS_SPECIFIC_DATA_PM_UNINSTALL_LISR); + SYS_SPECIFIC_DATA_CLEAR(&gsSysSpecificData, SYS_SPECIFIC_DATA_ENABLE_LISR); + } +#endif + + if (SYS_SPECIFIC_DATA_TEST(&gsSysSpecificData, SYS_SPECIFIC_DATA_ENABLE_SYSCLOCKS)) + { + DisableSystemClocks(gpsSysData); + + SYS_SPECIFIC_DATA_SET(&gsSysSpecificData, SYS_SPECIFIC_DATA_PM_DISABLE_SYSCLOCKS); + SYS_SPECIFIC_DATA_CLEAR(&gsSysSpecificData, SYS_SPECIFIC_DATA_ENABLE_SYSCLOCKS); + } + } + + return eError; +} + + +PVRSRV_ERROR SysSystemPostPowerState(PVR_POWER_STATE eNewPowerState) +{ + PVRSRV_ERROR eError = PVRSRV_OK; + + if (eNewPowerState == PVRSRV_POWER_STATE_D0) + { + PVR_TRACE(("SysSystemPostPowerState: Entering state D0")); + + if (SYS_SPECIFIC_DATA_TEST(&gsSysSpecificData, SYS_SPECIFIC_DATA_PM_DISABLE_SYSCLOCKS)) + { + eError = EnableSystemClocks(gpsSysData); + if (eError != PVRSRV_OK) + { + PVR_DPF((PVR_DBG_ERROR,"SysSystemPostPowerState: EnableSystemClocks failed (%d)", eError)); + return eError; + } + SYS_SPECIFIC_DATA_SET(&gsSysSpecificData, SYS_SPECIFIC_DATA_ENABLE_SYSCLOCKS); + SYS_SPECIFIC_DATA_CLEAR(&gsSysSpecificData, SYS_SPECIFIC_DATA_PM_DISABLE_SYSCLOCKS); + } + +#if defined(SYS_USING_INTERRUPTS) + if (SYS_SPECIFIC_DATA_TEST(&gsSysSpecificData, SYS_SPECIFIC_DATA_PM_UNINSTALL_LISR)) + { +#if defined(SYS_CUSTOM_POWERLOCK_WRAP) + IMG_BOOL bWrapped = WrapSystemPowerChange(&gsSysSpecificData); +#endif + + eError = OSInstallDeviceLISR(gpsSysData, gsSGXDeviceMap.ui32IRQ, "SGX ISR", gpsSGXDevNode); +#if defined(SYS_CUSTOM_POWERLOCK_WRAP) + if (bWrapped) + { + UnwrapSystemPowerChange(&gsSysSpecificData); + } +#endif + if (eError != PVRSRV_OK) + { + PVR_DPF((PVR_DBG_ERROR,"SysSystemPostPowerState: OSInstallDeviceLISR failed to install ISR (%d)", eError)); + return eError; + } + SYS_SPECIFIC_DATA_SET(&gsSysSpecificData, SYS_SPECIFIC_DATA_ENABLE_LISR); + SYS_SPECIFIC_DATA_CLEAR(&gsSysSpecificData, SYS_SPECIFIC_DATA_PM_UNINSTALL_LISR); + } +#endif + } + return eError; +} + + +PVRSRV_ERROR SysDevicePrePowerState(IMG_UINT32 ui32DeviceIndex, + PVR_POWER_STATE eNewPowerState, + PVR_POWER_STATE eCurrentPowerState) +{ + PVR_UNREFERENCED_PARAMETER(eCurrentPowerState); + + if (ui32DeviceIndex != gui32SGXDeviceID) + { + return PVRSRV_OK; + } + +#if defined(SUPPORT_ACTIVE_POWER_MANAGEMENT) + if (eNewPowerState == PVRSRV_POWER_STATE_D3) + { + PVR_DPF((PVR_DBG_MESSAGE, "SysDevicePrePowerState: SGX Entering state D3")); + DisableSGXClocks(gpsSysData); + PVRSRVSetDCState(DC_STATE_SUSPEND_COMMANDS); + } +#else + PVR_UNREFERENCED_PARAMETER(eNewPowerState ); +#endif + return PVRSRV_OK; +} + + +PVRSRV_ERROR SysDevicePostPowerState(IMG_UINT32 ui32DeviceIndex, + PVR_POWER_STATE eNewPowerState, + PVR_POWER_STATE eCurrentPowerState) +{ + PVRSRV_ERROR eError = PVRSRV_OK; + + PVR_UNREFERENCED_PARAMETER(eNewPowerState); + + if (ui32DeviceIndex != gui32SGXDeviceID) + { + return eError; + } + +#if defined(SUPPORT_ACTIVE_POWER_MANAGEMENT) + if (eCurrentPowerState == PVRSRV_POWER_STATE_D3) + { + PVR_DPF((PVR_DBG_MESSAGE, "SysDevicePostPowerState: SGX Leaving state D3")); + PVRSRVSetDCState(DC_STATE_RESUME_COMMANDS); + eError = EnableSGXClocks(gpsSysData); + } +#else + PVR_UNREFERENCED_PARAMETER(eCurrentPowerState); +#endif + + return eError; +} + + +PVRSRV_ERROR SysOEMFunction ( IMG_UINT32 ui32ID, + IMG_VOID *pvIn, + IMG_UINT32 ulInSize, + IMG_VOID *pvOut, + IMG_UINT32 ulOutSize) +{ + PVR_UNREFERENCED_PARAMETER(ui32ID); + PVR_UNREFERENCED_PARAMETER(pvIn); + PVR_UNREFERENCED_PARAMETER(ulInSize); + PVR_UNREFERENCED_PARAMETER(pvOut); + PVR_UNREFERENCED_PARAMETER(ulOutSize); + + if ((ui32ID == OEM_GET_EXT_FUNCS) && + (ulOutSize == sizeof(PVRSRV_DC_OEM_JTABLE))) + { + + PVRSRV_DC_OEM_JTABLE *psOEMJTable = (PVRSRV_DC_OEM_JTABLE*) pvOut; + psOEMJTable->pfnOEMBridgeDispatch = &PVRSRV_BridgeDispatchKM; + return PVRSRV_OK; + } + + return PVRSRV_ERROR_INVALID_PARAMS; +} diff --git a/services4/system/omap3630/sysconfig.h b/services4/system/omap3630/sysconfig.h new file mode 100644 index 0000000..22852f5 --- /dev/null +++ b/services4/system/omap3630/sysconfig.h @@ -0,0 +1,53 @@ +/********************************************************************** + * + * Copyright(c) 2008 Imagination Technologies Ltd. All rights reserved. + * + * This program is free software; you can redistribute it and/or modify it + * under the terms and conditions of the GNU General Public License, + * version 2, as published by the Free Software Foundation. + * + * This program is distributed in the hope it will be useful but, except + * as otherwise stated in writing, without any warranty; without even the + * implied warranty of merchantability or fitness for a particular purpose. + * See the GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License along with + * this program; if not, write to the Free Software Foundation, Inc., + * 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA. + * + * The full GNU General Public License is included in this distribution in + * the file called "COPYING". + * + * Contact Information: + * Imagination Technologies Ltd. + * Home Park Estate, Kings Langley, Herts, WD4 8LZ, UK + * + ******************************************************************************/ + +#if !defined(__SOCCONFIG_H__) +#define __SOCCONFIG_H__ + +#include "syscommon.h" + +#define VS_PRODUCT_NAME "OMAP3630" + +#define SYS_SGX_CLOCK_SPEED 200000000 +#define SYS_SGX_HWRECOVERY_TIMEOUT_FREQ (100) +#define SYS_SGX_PDS_TIMER_FREQ (1000) +#define SYS_SGX_ACTIVE_POWER_LATENCY_MS (1) + + +#define SYS_OMAP3430_VDD2_OPP3_SGX_CLOCK_SPEED SYS_SGX_CLOCK_SPEED +#define SYS_OMAP3430_VDD2_OPP2_SGX_CLOCK_SPEED (SYS_SGX_CLOCK_SPEED / 2) + +#define SYS_OMAP3430_SGX_REGS_SYS_PHYS_BASE 0x50000000 +#define SYS_OMAP3430_SGX_REGS_SIZE 0x10000 + +#define SYS_OMAP3430_SGX_IRQ 21 + +#define SYS_OMAP3430_GP11TIMER_ENABLE_SYS_PHYS_BASE 0x48088024 +#define SYS_OMAP3430_GP11TIMER_REGS_SYS_PHYS_BASE 0x48088028 +#define SYS_OMAP3430_GP11TIMER_TSICR_SYS_PHYS_BASE 0x48088040 + + +#endif diff --git a/services4/system/omap3630/sysinfo.h b/services4/system/omap3630/sysinfo.h new file mode 100644 index 0000000..88e3096 --- /dev/null +++ b/services4/system/omap3630/sysinfo.h @@ -0,0 +1,98 @@ +/********************************************************************** + * + * Copyright(c) 2008 Imagination Technologies Ltd. All rights reserved. + * + * This program is free software; you can redistribute it and/or modify it + * under the terms and conditions of the GNU General Public License, + * version 2, as published by the Free Software Foundation. + * + * This program is distributed in the hope it will be useful but, except + * as otherwise stated in writing, without any warranty; without even the + * implied warranty of merchantability or fitness for a particular purpose. + * See the GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License along with + * this program; if not, write to the Free Software Foundation, Inc., + * 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA. + * + * The full GNU General Public License is included in this distribution in + * the file called "COPYING". + * + * Contact Information: + * Imagination Technologies Ltd. + * Home Park Estate, Kings Langley, Herts, WD4 8LZ, UK + * + ******************************************************************************/ + +#if !defined(__SYSINFO_H__) +#define __SYSINFO_H__ + +#define MAX_HW_TIME_US (500000) +#define WAIT_TRY_COUNT (10000) + +typedef enum _SYS_DEVICE_TYPE_ +{ + SYS_DEVICE_SGX = 0, + + SYS_DEVICE_FORCE_I16 = 0x7fff + +} SYS_DEVICE_TYPE; + +#define SYS_DEVICE_COUNT 3 + +#define PRM_REG32(offset) (offset) +#define CM_REG32(offset) (offset) + +#define CM_FCLKEN_SGX CM_REG32(0xB00) +#define CM_FCLKEN_SGX_EN_3D 0x00000002 + +#define CM_ICLKEN_SGX CM_REG32(0xB10) +#define CM_ICLKEN_SGX_EN_SGX 0x00000001 + +#define CM_IDLEST_SGX CM_REG32(0xB20) +#define CM_IDLEST_SGX_ST_SGX 0x00000001 + +#define CM_CLKSEL_SGX CM_REG32(0xB40) +#define CM_CLKSEL_SGX_MASK 0x0000000f +#define CM_CLKSEL_SGX_L3DIV3 0x00000000 +#define CM_CLKSEL_SGX_L3DIV4 0x00000001 +#define CM_CLKSEL_SGX_L3DIV6 0x00000002 +#define CM_CLKSEL_SGX_96M 0x00000003 + +#define CM_SLEEPDEP_SGX CM_REG32(0xB44) +#define CM_CLKSTCTRL_SGX CM_REG32(0xB48) +#define CM_CLKSTCTRL_SGX_AUTOSTATE 0x00008001 + +#define CM_CLKSTST_SGX CM_REG32(0xB4C) +#define CM_CLKSTST_SGX_STATUS_VALID 0x00000001 + +#define RM_RSTST_SGX PRM_REG32(0xB58) +#define RM_RSTST_SGX_RST_MASK 0x0000000F +#define RM_RSTST_SGX_COREDOMAINWKUP_RST 0x00000008 +#define RM_RSTST_SGX_DOMAINWKUP_RST 0x00000004 +#define RM_RSTST_SGX_GLOBALWARM_RST 0x00000002 +#define RM_RSTST_SGX_GLOBALCOLD_RST 0x00000001 + +#define PM_WKDEP_SGX PRM_REG32(0xBC8) +#define PM_WKDEP_SGX_EN_WAKEUP 0x00000010 +#define PM_WKDEP_SGX_EN_MPU 0x00000002 +#define PM_WKDEP_SGX_EN_CORE 0x00000001 + +#define PM_PWSTCTRL_SGX PRM_REG32(0xBE0) +#define PM_PWSTCTRL_SGX_POWERSTATE_MASK 0x00000003 +#define PM_PWSTCTRL_SGX_OFF 0x00000000 +#define PM_PWSTCTRL_SGX_RETENTION 0x00000001 +#define PM_PWSTCTRL_SGX_ON 0x00000003 + +#define PM_PWSTST_SGX PRM_REG32(0xBE4) +#define PM_PWSTST_SGX_INTRANSITION 0x00100000 +#define PM_PWSTST_SGX_CLKACTIVITY 0x00080000 +#define PM_PWSTST_SGX_POWERSTATE_MASK 0x00000003 +#define PM_PWSTST_SGX_OFF 0x00000003 +#define PM_PWSTST_SGX_RETENTION 0x00000001 +#define PM_PWSTST_SGX_ON 0x00000000 + +#define PM_PREPWSTST_SGX PRM_REG32(0xBE8) + + +#endif diff --git a/services4/system/omap3630/syslocal.h b/services4/system/omap3630/syslocal.h new file mode 100644 index 0000000..74de28f --- /dev/null +++ b/services4/system/omap3630/syslocal.h @@ -0,0 +1,128 @@ +/********************************************************************** + * + * Copyright(c) 2008 Imagination Technologies Ltd. All rights reserved. + * + * This program is free software; you can redistribute it and/or modify it + * under the terms and conditions of the GNU General Public License, + * version 2, as published by the Free Software Foundation. + * + * This program is distributed in the hope it will be useful but, except + * as otherwise stated in writing, without any warranty; without even the + * implied warranty of merchantability or fitness for a particular purpose. + * See the GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License along with + * this program; if not, write to the Free Software Foundation, Inc., + * 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA. + * + * The full GNU General Public License is included in this distribution in + * the file called "COPYING". + * + * Contact Information: + * Imagination Technologies Ltd. + * Home Park Estate, Kings Langley, Herts, WD4 8LZ, UK + * + ******************************************************************************/ + +#if !defined(__SYSLOCAL_H__) +#define __SYSLOCAL_H__ + +#if defined(__linux__) + +#include +#include +#include +#include + +#if (LINUX_VERSION_CODE > KERNEL_VERSION(2,6,26)) +#include +#include +#else +#include +#if (LINUX_VERSION_CODE > KERNEL_VERSION(2,6,22)) +#include +#endif +#endif + +#endif + +#if defined (__cplusplus) +extern "C" { +#endif + + + +IMG_CHAR *SysCreateVersionString(IMG_CPU_PHYADDR sRegRegion); + +IMG_VOID DisableSystemClocks(SYS_DATA *psSysData); +PVRSRV_ERROR EnableSystemClocks(SYS_DATA *psSysData); + +IMG_VOID DisableSGXClocks(SYS_DATA *psSysData); +PVRSRV_ERROR EnableSGXClocks(SYS_DATA *psSysData); + +#define SYS_SPECIFIC_DATA_ENABLE_SYSCLOCKS 0x00000001 +#define SYS_SPECIFIC_DATA_ENABLE_LISR 0x00000002 +#define SYS_SPECIFIC_DATA_ENABLE_MISR 0x00000004 +#define SYS_SPECIFIC_DATA_ENABLE_ENVDATA 0x00000008 +#define SYS_SPECIFIC_DATA_ENABLE_LOCDEV 0x00000010 +#define SYS_SPECIFIC_DATA_ENABLE_REGDEV 0x00000020 +#define SYS_SPECIFIC_DATA_ENABLE_PDUMPINIT 0x00000040 +#define SYS_SPECIFIC_DATA_ENABLE_INITDEV 0x00000080 +#define SYS_SPECIFIC_DATA_ENABLE_LOCATEDEV 0x00000100 + +#define SYS_SPECIFIC_DATA_PM_UNINSTALL_LISR 0x00000200 +#define SYS_SPECIFIC_DATA_PM_DISABLE_SYSCLOCKS 0x00000400 + +#define SYS_SPECIFIC_DATA_SET(psSysSpecData, flag) ((IMG_VOID)((psSysSpecData)->ui32SysSpecificData |= (flag))) + +#define SYS_SPECIFIC_DATA_CLEAR(psSysSpecData, flag) ((IMG_VOID)((psSysSpecData)->ui32SysSpecificData &= ~(flag))) + +#define SYS_SPECIFIC_DATA_TEST(psSysSpecData, flag) (((psSysSpecData)->ui32SysSpecificData & (flag)) != 0) + +typedef struct _SYS_SPECIFIC_DATA_TAG_ +{ + IMG_UINT32 ui32SysSpecificData; + PVRSRV_DEVICE_NODE *psSGXDevNode; + IMG_BOOL bSGXInitComplete; +#if !defined(__linux__) + IMG_BOOL bSGXClocksEnabled; +#endif + IMG_UINT32 ui32SrcClockDiv; +#if defined(__linux__) + IMG_BOOL bSysClocksOneTimeInit; + IMG_BOOL bConstraintNotificationsEnabled; + atomic_t sSGXClocksEnabled; + spinlock_t sPowerLock; + atomic_t sPowerLockCPU; + spinlock_t sNotifyLock; + atomic_t sNotifyLockCPU; + IMG_BOOL bCallVDD2PostFunc; + + struct clk *psCORE_CK; + struct clk *psSGX_FCK; + struct clk *psSGX_ICK; + struct clk *psMPU_CK; +#if defined(DEBUG) || defined(TIMING) + struct clk *psGPT11_FCK; + struct clk *psGPT11_ICK; +#endif +#if (LINUX_VERSION_CODE > KERNEL_VERSION(2,6,22)) + struct constraint_handle *pVdd2Handle; +#endif +#endif +} SYS_SPECIFIC_DATA; + +extern SYS_SPECIFIC_DATA *gpsSysSpecificData; + +#if defined(SYS_CUSTOM_POWERLOCK_WRAP) +IMG_BOOL WrapSystemPowerChange(SYS_SPECIFIC_DATA *psSysSpecData); +IMG_VOID UnwrapSystemPowerChange(SYS_SPECIFIC_DATA *psSysSpecData); +#endif + +#if defined(__cplusplus) +} +#endif + +#endif + + diff --git a/services4/system/omap3630/sysutils.c b/services4/system/omap3630/sysutils.c new file mode 100644 index 0000000..cb3cee7 --- /dev/null +++ b/services4/system/omap3630/sysutils.c @@ -0,0 +1,30 @@ +/********************************************************************** + * + * Copyright(c) 2008 Imagination Technologies Ltd. All rights reserved. + * + * This program is free software; you can redistribute it and/or modify it + * under the terms and conditions of the GNU General Public License, + * version 2, as published by the Free Software Foundation. + * + * This program is distributed in the hope it will be useful but, except + * as otherwise stated in writing, without any warranty; without even the + * implied warranty of merchantability or fitness for a particular purpose. + * See the GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License along with + * this program; if not, write to the Free Software Foundation, Inc., + * 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA. + * + * The full GNU General Public License is included in this distribution in + * the file called "COPYING". + * + * Contact Information: + * Imagination Technologies Ltd. + * Home Park Estate, Kings Langley, Herts, WD4 8LZ, UK + * + ******************************************************************************/ + +#if defined(__linux__) +#include "sysutils_linux.c" +#endif + diff --git a/services4/system/omap3630/sysutils_linux.c b/services4/system/omap3630/sysutils_linux.c new file mode 100644 index 0000000..159b4da --- /dev/null +++ b/services4/system/omap3630/sysutils_linux.c @@ -0,0 +1,810 @@ +/********************************************************************** + * + * Copyright(c) 2008 Imagination Technologies Ltd. All rights reserved. + * + * This program is free software; you can redistribute it and/or modify it + * under the terms and conditions of the GNU General Public License, + * version 2, as published by the Free Software Foundation. + * + * This program is distributed in the hope it will be useful but, except + * as otherwise stated in writing, without any warranty; without even the + * implied warranty of merchantability or fitness for a particular purpose. + * See the GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License along with + * this program; if not, write to the Free Software Foundation, Inc., + * 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA. + * + * The full GNU General Public License is included in this distribution in + * the file called "COPYING". + * + * Contact Information: + * Imagination Technologies Ltd. + * Home Park Estate, Kings Langley, Herts, WD4 8LZ, UK + * + ******************************************************************************/ + +#include +#include +#include +#include +#include +#include +#include + +#if (LINUX_VERSION_CODE > KERNEL_VERSION(2,6,31)) +#include +#include +#include +#else + +#if (LINUX_VERSION_CODE > KERNEL_VERSION(2,6,26)) +#include +#include +#include +#else +#include +#if (LINUX_VERSION_CODE > KERNEL_VERSION(2,6,22)) +#include +#endif +#endif +#endif + +#if (LINUX_VERSION_CODE > KERNEL_VERSION(2,6,27)) && \ + (LINUX_VERSION_CODE <= KERNEL_VERSION(2,6,29)) +#define CONSTRAINT_NOTIFICATIONS +#endif +#include "sgxdefs.h" +#include "services_headers.h" +#include "sysinfo.h" +#include "sgxapi_km.h" +#include "sysconfig.h" +#include "sgxinfokm.h" +#include "syslocal.h" +void set_vdd2_constraint(void); +void remove_vdd2_constraint(void); +#define ONE_MHZ 1000000 +#define HZ_TO_MHZ(m) ((m) / ONE_MHZ) + +#if defined(SUPPORT_OMAP3630_SGXFCLK_96M) +#define SGX_PARENT_CLOCK "cm_96m_fck" +#elif defined(SUPPORT_OMAP3630_SGXFCLK_192M) +#define SGX_PARENT_CLOCK "omap_192m_alwon_ck" +#elif defined(SUPPORT_OMAP3630_SGXFCLK_corex2) +#define SGX_PARENT_CLOCK "corex2_fck" +#else +#define SGX_PARENT_CLOCK "core_ck" +#endif + +#if !defined(PDUMP) && !defined(NO_HARDWARE) +struct sgx_platform_data { + void(*set_min_bus_tput)(struct device *dev, u8 agent_id, unsigned long r); +}; + +static struct sgx_platform_data pdata = { + + //.set_min_bus_tput = &omap_pm_set_min_bus_tput, + .set_min_bus_tput = NULL, +}; + +static struct platform_device sgx_dev = { + .name = "sgx_dev", + .id = 1, + .dev.platform_data = &pdata, +}; +void set_vdd2_constraint(void) +{ + if(pdata.set_min_bus_tput){ + pdata.set_min_bus_tput(&(sgx_dev.dev), OCP_INITIATOR_AGENT,800000); + } +} + +void remove_vdd2_constraint(void) +{ + if(pdata.set_min_bus_tput) + pdata.set_min_bus_tput(&(sgx_dev.dev), OCP_INITIATOR_AGENT, 0); + +} +#endif +#if !defined(PDUMP) && !defined(NO_HARDWARE) +static IMG_BOOL PowerLockWrappedOnCPU(SYS_SPECIFIC_DATA *psSysSpecData) +{ + IMG_INT iCPU; + IMG_BOOL bLocked = IMG_FALSE; + + if (!in_interrupt()) + { + iCPU = get_cpu(); + bLocked = (iCPU == atomic_read(&psSysSpecData->sPowerLockCPU)); + + put_cpu(); + } + + return bLocked; +} + +static IMG_VOID PowerLockWrap(SYS_SPECIFIC_DATA *psSysSpecData) +{ + IMG_INT iCPU; + + if (!in_interrupt()) + { + + iCPU = get_cpu(); + + + PVR_ASSERT(iCPU != -1); + + PVR_ASSERT(!PowerLockWrappedOnCPU(psSysSpecData)); + + spin_lock(&psSysSpecData->sPowerLock); + + atomic_set(&psSysSpecData->sPowerLockCPU, iCPU); + } +} + +static IMG_VOID PowerLockUnwrap(SYS_SPECIFIC_DATA *psSysSpecData) +{ + if (!in_interrupt()) + { + PVR_ASSERT(PowerLockWrappedOnCPU(psSysSpecData)); + + atomic_set(&psSysSpecData->sPowerLockCPU, -1); + + spin_unlock(&psSysSpecData->sPowerLock); + + put_cpu(); + } +} + +PVRSRV_ERROR SysPowerLockWrap(SYS_DATA *psSysData) +{ + SYS_SPECIFIC_DATA *psSysSpecData = (SYS_SPECIFIC_DATA *) psSysData->pvSysSpecificData; + + PowerLockWrap(psSysSpecData); + + return PVRSRV_OK; +} + +IMG_VOID SysPowerLockUnwrap(SYS_DATA *psSysData) +{ + SYS_SPECIFIC_DATA *psSysSpecData = (SYS_SPECIFIC_DATA *) psSysData->pvSysSpecificData; + + PowerLockUnwrap(psSysSpecData); +} +#else +static IMG_BOOL PowerLockWrappedOnCPU(SYS_SPECIFIC_DATA unref__ *psSysSpecData) +{ + return IMG_FALSE; +} + +static IMG_VOID PowerLockWrap(SYS_SPECIFIC_DATA unref__ *psSysSpecData) +{ +} + +static IMG_VOID PowerLockUnwrap(SYS_SPECIFIC_DATA unref__ *psSysSpecData) +{ +} + +PVRSRV_ERROR SysPowerLockWrap(SYS_DATA unref__ *psSysData) +{ + return PVRSRV_OK; +} + +IMG_VOID SysPowerLockUnwrap(SYS_DATA unref__ *psSysData) +{ +} +#endif + +IMG_BOOL WrapSystemPowerChange(SYS_SPECIFIC_DATA *psSysSpecData) +{ + IMG_BOOL bPowerLock = PowerLockWrappedOnCPU(psSysSpecData); + + if (bPowerLock) + { + PowerLockUnwrap(psSysSpecData); + } + + return bPowerLock; +} + +IMG_VOID UnwrapSystemPowerChange(SYS_SPECIFIC_DATA *psSysSpecData) +{ + PowerLockWrap(psSysSpecData); +} + +static inline IMG_UINT32 scale_by_rate(IMG_UINT32 val, IMG_UINT32 rate1, IMG_UINT32 rate2) +{ + if (rate1 >= rate2) + { + return val * (rate1 / rate2); + } + + return val / (rate2 / rate1); +} + +static inline IMG_UINT32 scale_prop_to_SGX_clock(IMG_UINT32 val, IMG_UINT32 rate) +{ + return scale_by_rate(val, rate, SYS_SGX_CLOCK_SPEED); +} + +static inline IMG_UINT32 scale_inv_prop_to_SGX_clock(IMG_UINT32 val, IMG_UINT32 rate) +{ + return scale_by_rate(val, SYS_SGX_CLOCK_SPEED, rate); +} + +IMG_VOID SysGetSGXTimingInformation(SGX_TIMING_INFORMATION *psTimingInfo) +{ + IMG_UINT32 rate; + +#if defined(NO_HARDWARE) + rate = SYS_SGX_CLOCK_SPEED; +#else + PVR_ASSERT(atomic_read(&gpsSysSpecificData->sSGXClocksEnabled) != 0); + + rate = clk_get_rate(gpsSysSpecificData->psSGX_FCK); + PVR_ASSERT(rate != 0); +#endif + psTimingInfo->ui32CoreClockSpeed = rate; + psTimingInfo->ui32HWRecoveryFreq = scale_prop_to_SGX_clock(SYS_SGX_HWRECOVERY_TIMEOUT_FREQ, rate); + psTimingInfo->ui32uKernelFreq = scale_prop_to_SGX_clock(SYS_SGX_PDS_TIMER_FREQ, rate); + psTimingInfo->ui32ActivePowManLatencyms = SYS_SGX_ACTIVE_POWER_LATENCY_MS; +} + +#if defined(CONSTRAINT_NOTIFICATIONS) +#if !defined(SGX_DYNAMIC_TIMING_INFO) +#error "SGX_DYNAMIC_TIMING_INFO must be defined for this platform" +#endif + +#if !defined(PDUMP) && !defined(NO_HARDWARE) +static inline IMG_BOOL ConstraintNotificationsEnabled(SYS_SPECIFIC_DATA *psSysSpecData) +{ + return (atomic_read(&psSysSpecData->sSGXClocksEnabled) != 0) && psSysSpecData->bSGXInitComplete && psSysSpecData->bConstraintNotificationsEnabled; + +} + +static IMG_BOOL NotifyLockedOnCPU(SYS_SPECIFIC_DATA *psSysSpecData) +{ + IMG_INT iCPU = get_cpu(); + IMG_BOOL bLocked = (iCPU == atomic_read(&psSysSpecData->sNotifyLockCPU)); + + put_cpu(); + + return bLocked; +} + +static IMG_VOID NotifyLock(SYS_SPECIFIC_DATA *psSysSpecData) +{ + IMG_INT iCPU; + + BUG_ON(in_interrupt()); + + + iCPU = get_cpu(); + + + PVR_ASSERT(iCPU != -1); + + PVR_ASSERT(!NotifyLockedOnCPU(psSysSpecData)); + + spin_lock(&psSysSpecData->sNotifyLock); + + atomic_set(&psSysSpecData->sNotifyLockCPU, iCPU); + +} + +static IMG_VOID NotifyUnlock(SYS_SPECIFIC_DATA *psSysSpecData) +{ + PVR_ASSERT(NotifyLockedOnCPU(psSysSpecData)); + + atomic_set(&psSysSpecData->sNotifyLockCPU, -1); + + spin_unlock(&psSysSpecData->sNotifyLock); + + put_cpu(); +} + +static IMG_INT VDD2PostFunc(struct notifier_block *n, IMG_UINT32 event, IMG_VOID *ptr) +{ + PVR_UNREFERENCED_PARAMETER(n); + PVR_UNREFERENCED_PARAMETER(event); + PVR_UNREFERENCED_PARAMETER(ptr); + + if (in_interrupt()) + { + PVR_DPF((PVR_DBG_ERROR, "%s Called in interrupt context. Ignoring.", __FUNCTION__)); + return 0; + } + + + if (!NotifyLockedOnCPU(gpsSysSpecificData)) + { + return 0; + } + +#if defined(DEBUG) + if (ConstraintNotificationsEnabled(gpsSysSpecificData)) + { + IMG_UINT32 rate; + + rate = clk_get_rate(gpsSysSpecificData->psSGX_FCK); + + PVR_ASSERT(rate != 0); + + PVR_DPF((PVR_DBG_MESSAGE, "%s: SGX clock rate: %dMHz", __FUNCTION__, HZ_TO_MHZ(rate))); + } +#endif + if (gpsSysSpecificData->bCallVDD2PostFunc) + { + PVRSRVDevicePostClockSpeedChange(gpsSysSpecificData->psSGXDevNode->sDevId.ui32DeviceIndex, IMG_TRUE, IMG_NULL); + + gpsSysSpecificData->bCallVDD2PostFunc = IMG_FALSE; + } + else + { + if (ConstraintNotificationsEnabled(gpsSysSpecificData)) + { + PVR_TRACE(("%s: Not calling PVR clock speed notification functions", __FUNCTION__)); + } + } + + NotifyUnlock(gpsSysSpecificData); + + return 0; +} + +static IMG_INT VDD2PreFunc(struct notifier_block *n, IMG_UINT32 event, IMG_VOID *ptr) +{ + PVR_UNREFERENCED_PARAMETER(n); + PVR_UNREFERENCED_PARAMETER(event); + PVR_UNREFERENCED_PARAMETER(ptr); + + if (in_interrupt()) + { + PVR_DPF((PVR_DBG_WARNING, "%s Called in interrupt context. Ignoring.", __FUNCTION__)); + return 0; + } + + if (PowerLockWrappedOnCPU(gpsSysSpecificData)) + { + PVR_DPF((PVR_DBG_WARNING, "%s Called from within a power transition. Ignoring.", __FUNCTION__)); + return 0; + } + + NotifyLock(gpsSysSpecificData); + + PVR_ASSERT(!gpsSysSpecificData->bCallVDD2PostFunc); + + if (ConstraintNotificationsEnabled(gpsSysSpecificData)) + { + PVRSRV_ERROR eError; + + eError = PVRSRVDevicePreClockSpeedChange(gpsSysSpecificData->psSGXDevNode->sDevId.ui32DeviceIndex, IMG_TRUE, IMG_NULL); + + gpsSysSpecificData->bCallVDD2PostFunc = (eError == PVRSRV_OK); + + } + + return 0; +} +static IMG_VOID RegisterConstraintNotifications(IMG_VOID) +{ + PVR_TRACE(("Registering constraint notifications")); + + PVR_ASSERT(!gpsSysSpecificData->bConstraintNotificationsEnabled); + + + NotifyLock(gpsSysSpecificData); + gpsSysSpecificData->bConstraintNotificationsEnabled = IMG_TRUE; + NotifyUnlock(gpsSysSpecificData); + + PVR_TRACE(("VDD2 constraint notifications registered")); +} + +static IMG_VOID UnRegisterConstraintNotifications(IMG_VOID) +{ + PVR_TRACE(("Unregistering constraint notifications")); + + + NotifyLock(gpsSysSpecificData); + gpsSysSpecificData->bConstraintNotificationsEnabled = IMG_FALSE; + NotifyUnlock(gpsSysSpecificData); + +} +#else +static IMG_VOID RegisterConstraintNotifications(IMG_VOID) +{ +} + +static IMG_VOID UnRegisterConstraintNotifications(IMG_VOID) +{ +} +#endif +#endif + +PVRSRV_ERROR EnableSGXClocks(SYS_DATA *psSysData) +{ +#if !defined(NO_HARDWARE) + SYS_SPECIFIC_DATA *psSysSpecData = (SYS_SPECIFIC_DATA *) psSysData->pvSysSpecificData; + long lNewRate; + IMG_INT res; + + + if (atomic_read(&psSysSpecData->sSGXClocksEnabled) != 0) + { + return PVRSRV_OK; + } + + PVR_DPF((PVR_DBG_MESSAGE, "EnableSGXClocks: Enabling SGX Clocks")); + +#if defined(DEBUG) + { + + IMG_UINT32 rate = clk_get_rate(psSysSpecData->psMPU_CK); + PVR_DPF((PVR_DBG_MESSAGE, "EnableSGXClocks: CPU Clock is %dMhz", HZ_TO_MHZ(rate))); + } +#endif + + res = clk_enable(psSysSpecData->psSGX_FCK); + if (res < 0) + { + PVR_DPF((PVR_DBG_ERROR, "EnableSGXClocks: Couldn't enable SGX functional clock (%d)", res)); + return PVRSRV_ERROR_GENERIC; + } + + res = clk_enable(psSysSpecData->psSGX_ICK); + if (res < 0) + { + PVR_DPF((PVR_DBG_ERROR, "EnableSGXClocks: Couldn't enable SGX interface clock (%d)", res)); + + clk_disable(psSysSpecData->psSGX_FCK); + return PVRSRV_ERROR_GENERIC; + } + + lNewRate = clk_round_rate(psSysSpecData->psSGX_FCK, SYS_SGX_CLOCK_SPEED + ONE_MHZ); + //PVR_DPF((PVR_DBG_WARNING, "EnableSGXClocks: New SGX Func Clk = (%d)", lNewRate)); + if (lNewRate <= 0) + { + PVR_DPF((PVR_DBG_ERROR, "EnableSGXClocks: Couldn't round SGX functional clock rate")); + return PVRSRV_ERROR_GENERIC; + } + + res = clk_set_rate(psSysSpecData->psSGX_FCK, lNewRate); + if (res < 0) + { + PVR_DPF((PVR_DBG_ERROR, "EnableSGXClocks: Couldn't set SGX function clock rate (%d)", res)); + return PVRSRV_ERROR_GENERIC; + } + + +#if defined(DEBUG) + { + + IMG_UINT32 rate = clk_get_rate(psSysSpecData->psSGX_FCK); + PVR_DPF((PVR_DBG_MESSAGE, "EnableSGXClocks: SGX Functional Clock is %dMhz", HZ_TO_MHZ(rate))); + } +#endif + + set_vdd2_constraint(); + + lNewRate = clk_get_rate(psSysSpecData->psSGX_FCK); + atomic_set(&psSysSpecData->sSGXClocksEnabled, 1); + //PVR_DPF((PVR_DBG_WARNING, "EnableSGXClocks: Final SGX Func Clk = (%d)", lNewRate)); + +#else + PVR_UNREFERENCED_PARAMETER(psSysData); +#endif + return PVRSRV_OK; +} + + +IMG_VOID DisableSGXClocks(SYS_DATA *psSysData) +{ +#if !defined(NO_HARDWARE) + SYS_SPECIFIC_DATA *psSysSpecData = (SYS_SPECIFIC_DATA *) psSysData->pvSysSpecificData; + + if (atomic_read(&psSysSpecData->sSGXClocksEnabled) == 0) + { + return; + } + + PVR_DPF((PVR_DBG_MESSAGE, "DisableSGXClocks: Disabling SGX Clocks")); + + if (psSysSpecData->psSGX_ICK) + { + clk_disable(psSysSpecData->psSGX_ICK); + } + + if (psSysSpecData->psSGX_FCK) + { + clk_disable(psSysSpecData->psSGX_FCK); + } + + remove_vdd2_constraint(); + + atomic_set(&psSysSpecData->sSGXClocksEnabled, 0); + +#else + PVR_UNREFERENCED_PARAMETER(psSysData); +#endif +} + +PVRSRV_ERROR EnableSystemClocks(SYS_DATA *psSysData) +{ + SYS_SPECIFIC_DATA *psSysSpecData = (SYS_SPECIFIC_DATA *) psSysData->pvSysSpecificData; + struct clk *psCLK; + IMG_INT res; + PVRSRV_ERROR eError; + IMG_BOOL bPowerLock; + +#if defined(DEBUG) || defined(TIMING) + IMG_INT rate; + struct clk *sys_ck; + IMG_CPU_PHYADDR TimerRegPhysBase; + IMG_HANDLE hTimerEnable; + IMG_UINT32 *pui32TimerEnable; + +#endif + + PVR_TRACE(("EnableSystemClocks: Enabling System Clocks")); + + if (!psSysSpecData->bSysClocksOneTimeInit) + { + bPowerLock = IMG_FALSE; + + spin_lock_init(&psSysSpecData->sPowerLock); + atomic_set(&psSysSpecData->sPowerLockCPU, -1); + spin_lock_init(&psSysSpecData->sNotifyLock); + atomic_set(&psSysSpecData->sNotifyLockCPU, -1); + + atomic_set(&psSysSpecData->sSGXClocksEnabled, 0); + + psCLK = clk_get(NULL, SGX_PARENT_CLOCK); + if (IS_ERR(psCLK)) + { + PVR_DPF((PVR_DBG_ERROR, "EnableSsystemClocks: Couldn't get Core Clock")); + goto ExitError; + } + psSysSpecData->psCORE_CK = psCLK; + + psCLK = clk_get(NULL, "sgx_fck"); + if (IS_ERR(psCLK)) + { + PVR_DPF((PVR_DBG_ERROR, "EnableSsystemClocks: Couldn't get SGX Functional Clock")); + goto ExitError; + } + psSysSpecData->psSGX_FCK = psCLK; + + psCLK = clk_get(NULL, "sgx_ick"); + if (IS_ERR(psCLK)) + { + PVR_DPF((PVR_DBG_ERROR, "EnableSystemClocks: Couldn't get SGX Interface Clock")); + goto ExitError; + } + psSysSpecData->psSGX_ICK = psCLK; + +#if defined(DEBUG) + psCLK = clk_get(NULL, "mpu_ck"); + if (IS_ERR(psCLK)) + { + PVR_DPF((PVR_DBG_ERROR, "EnableSystemClocks: Couldn't get MPU Clock")); + goto ExitError; + } + psSysSpecData->psMPU_CK = psCLK; +#endif + res = clk_set_parent(psSysSpecData->psSGX_FCK, psSysSpecData->psCORE_CK); + if (res < 0) + { + PVR_DPF((PVR_DBG_ERROR, "EnableSystemClocks: Couldn't set SGX parent clock (%d)", res)); + goto ExitError; + } + + psSysSpecData->bSysClocksOneTimeInit = IMG_TRUE; + } + else + { + + bPowerLock = PowerLockWrappedOnCPU(psSysSpecData); + if (bPowerLock) + { + PowerLockUnwrap(psSysSpecData); + } + } + +#if defined(CONSTRAINT_NOTIFICATIONS) + + RegisterConstraintNotifications(); +#endif + +#if defined(DEBUG) || defined(TIMING) + + psCLK = clk_get(NULL, "gpt11_fck"); + if (IS_ERR(psCLK)) + { + PVR_DPF((PVR_DBG_ERROR, "EnableSystemClocks: Couldn't get GPTIMER11 functional clock")); + goto ExitUnRegisterConstraintNotifications; + } + psSysSpecData->psGPT11_FCK = psCLK; + + psCLK = clk_get(NULL, "gpt11_ick"); + if (IS_ERR(psCLK)) + { + PVR_DPF((PVR_DBG_ERROR, "EnableSystemClocks: Couldn't get GPTIMER11 interface clock")); + goto ExitUnRegisterConstraintNotifications; + } + psSysSpecData->psGPT11_ICK = psCLK; + + sys_ck = clk_get(NULL, "sys_ck"); + if (IS_ERR(sys_ck)) + { + PVR_DPF((PVR_DBG_ERROR, "EnableSystemClocks: Couldn't get System clock")); + goto ExitUnRegisterConstraintNotifications; + } + + if(clk_get_parent(psSysSpecData->psGPT11_FCK) != sys_ck) + { + PVR_TRACE(("Setting GPTIMER11 parent to System Clock")); + res = clk_set_parent(psSysSpecData->psGPT11_FCK, sys_ck); + if (res < 0) + { + PVR_DPF((PVR_DBG_ERROR, "EnableSystemClocks: Couldn't set GPTIMER11 parent clock (%d)", res)); + goto ExitUnRegisterConstraintNotifications; + } + } + + rate = clk_get_rate(psSysSpecData->psGPT11_FCK); + PVR_TRACE(("GPTIMER11 clock is %dMHz", HZ_TO_MHZ(rate))); + + res = clk_enable(psSysSpecData->psGPT11_FCK); + if (res < 0) + { + PVR_DPF((PVR_DBG_ERROR, "EnableSystemClocks: Couldn't enable GPTIMER11 functional clock (%d)", res)); + goto ExitUnRegisterConstraintNotifications; + } + + res = clk_enable(psSysSpecData->psGPT11_ICK); + if (res < 0) + { + PVR_DPF((PVR_DBG_ERROR, "EnableSystemClocks: Couldn't enable GPTIMER11 interface clock (%d)", res)); + goto ExitDisableGPT11FCK; + } + + + TimerRegPhysBase.uiAddr = SYS_OMAP3430_GP11TIMER_TSICR_SYS_PHYS_BASE; + pui32TimerEnable = OSMapPhysToLin(TimerRegPhysBase, + 4, + PVRSRV_HAP_KERNEL_ONLY|PVRSRV_HAP_UNCACHED, + &hTimerEnable); + + if (pui32TimerEnable == IMG_NULL) + { + PVR_DPF((PVR_DBG_ERROR, "EnableSystemClocks: OSMapPhysToLin failed")); + goto ExitDisableGPT11ICK; + } + + rate = *pui32TimerEnable; + if(!(rate & 4)) + { + PVR_TRACE(("Setting GPTIMER11 mode to posted (currently is non-posted)")); + + + *pui32TimerEnable = rate | 4; + } + + OSUnMapPhysToLin(pui32TimerEnable, + 4, + PVRSRV_HAP_KERNEL_ONLY|PVRSRV_HAP_UNCACHED, + hTimerEnable); + + + TimerRegPhysBase.uiAddr = SYS_OMAP3430_GP11TIMER_ENABLE_SYS_PHYS_BASE; + pui32TimerEnable = OSMapPhysToLin(TimerRegPhysBase, + 4, + PVRSRV_HAP_KERNEL_ONLY|PVRSRV_HAP_UNCACHED, + &hTimerEnable); + + if (pui32TimerEnable == IMG_NULL) + { + PVR_DPF((PVR_DBG_ERROR, "EnableSystemClocks: OSMapPhysToLin failed")); + goto ExitDisableGPT11ICK; + } + + + *pui32TimerEnable = 3; + + OSUnMapPhysToLin(pui32TimerEnable, + 4, + PVRSRV_HAP_KERNEL_ONLY|PVRSRV_HAP_UNCACHED, + hTimerEnable); + +#endif + + eError = PVRSRV_OK; + goto Exit; + +#if defined(DEBUG) || defined(TIMING) +ExitDisableGPT11ICK: + clk_disable(psSysSpecData->psGPT11_ICK); +ExitDisableGPT11FCK: + clk_disable(psSysSpecData->psGPT11_FCK); +ExitUnRegisterConstraintNotifications: +#endif +#if defined(CONSTRAINT_NOTIFICATIONS) + UnRegisterConstraintNotifications(); + +#endif +ExitError: + eError = PVRSRV_ERROR_GENERIC; +Exit: + if (bPowerLock) + { + PowerLockWrap(psSysSpecData); + } + +#if !defined(SUPPORT_ACTIVE_POWER_MANAGEMENT) + if (eError == PVRSRV_OK) + { + + eError = EnableSGXClocks(psSysData); + } +#endif + return eError; +} + +IMG_VOID DisableSystemClocks(SYS_DATA *psSysData) +{ + SYS_SPECIFIC_DATA *psSysSpecData = (SYS_SPECIFIC_DATA *) psSysData->pvSysSpecificData; + IMG_BOOL bPowerLock; +#if defined(DEBUG) || defined(TIMING) + IMG_CPU_PHYADDR TimerRegPhysBase; + IMG_HANDLE hTimerDisable; + IMG_UINT32 *pui32TimerDisable; +#endif + + PVR_TRACE(("DisableSystemClocks: Disabling System Clocks")); + + DisableSGXClocks(psSysData); + + bPowerLock = PowerLockWrappedOnCPU(psSysSpecData); + if (bPowerLock) + { + + PowerLockUnwrap(psSysSpecData); + } + +#if defined(CONSTRAINT_NOTIFICATIONS) + UnRegisterConstraintNotifications(); +#endif + +#if defined(DEBUG) || defined(TIMING) + + TimerRegPhysBase.uiAddr = SYS_OMAP3430_GP11TIMER_ENABLE_SYS_PHYS_BASE; + pui32TimerDisable = OSMapPhysToLin(TimerRegPhysBase, + 4, + PVRSRV_HAP_KERNEL_ONLY|PVRSRV_HAP_UNCACHED, + &hTimerDisable); + + if (pui32TimerDisable == IMG_NULL) + { + PVR_DPF((PVR_DBG_ERROR, "DisableSystemClocks: OSMapPhysToLin failed")); + } + else + { + *pui32TimerDisable = 0; + + OSUnMapPhysToLin(pui32TimerDisable, + 4, + PVRSRV_HAP_KERNEL_ONLY|PVRSRV_HAP_UNCACHED, + hTimerDisable); + } + + clk_disable(psSysSpecData->psGPT11_ICK); + + clk_disable(psSysSpecData->psGPT11_FCK); + +#endif + if (bPowerLock) + { + PowerLockWrap(psSysSpecData); + } +} diff --git a/services4/system/ti8168/oemfuncs.h b/services4/system/ti8168/oemfuncs.h new file mode 100644 index 0000000..1131534 --- /dev/null +++ b/services4/system/ti8168/oemfuncs.h @@ -0,0 +1,56 @@ +/********************************************************************** + * + * Copyright(c) 2008 Imagination Technologies Ltd. All rights reserved. + * + * This program is free software; you can redistribute it and/or modify it + * under the terms and conditions of the GNU General Public License, + * version 2, as published by the Free Software Foundation. + * + * This program is distributed in the hope it will be useful but, except + * as otherwise stated in writing, without any warranty; without even the + * implied warranty of merchantability or fitness for a particular purpose. + * See the GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License along with + * this program; if not, write to the Free Software Foundation, Inc., + * 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA. + * + * The full GNU General Public License is included in this distribution in + * the file called "COPYING". + * + * Contact Information: + * Imagination Technologies Ltd. + * Home Park Estate, Kings Langley, Herts, WD4 8LZ, UK + * + ******************************************************************************/ + +#if !defined(__OEMFUNCS_H__) +#define __OEMFUNCS_H__ + +#if defined (__cplusplus) +extern "C" { +#endif + +typedef IMG_UINT32 (*PFN_SRV_BRIDGEDISPATCH)( IMG_UINT32 Ioctl, + IMG_BYTE *pInBuf, + IMG_UINT32 InBufLen, + IMG_BYTE *pOutBuf, + IMG_UINT32 OutBufLen, + IMG_UINT32 *pdwBytesTransferred); +typedef struct PVRSRV_DC_OEM_JTABLE_TAG +{ + PFN_SRV_BRIDGEDISPATCH pfnOEMBridgeDispatch; + IMG_PVOID pvDummy1; + IMG_PVOID pvDummy2; + IMG_PVOID pvDummy3; + +} PVRSRV_DC_OEM_JTABLE; + +#define OEM_GET_EXT_FUNCS (1<<1) + +#if defined(__cplusplus) +} +#endif + +#endif + diff --git a/services4/system/ti8168/sysconfig.c b/services4/system/ti8168/sysconfig.c new file mode 100644 index 0000000..38f3e4b --- /dev/null +++ b/services4/system/ti8168/sysconfig.c @@ -0,0 +1,807 @@ +/********************************************************************** + * + * Copyright(c) 2008 Imagination Technologies Ltd. All rights reserved. + * + * This program is free software; you can redistribute it and/or modify it + * under the terms and conditions of the GNU General Public License, + * version 2, as published by the Free Software Foundation. + * + * This program is distributed in the hope it will be useful but, except + * as otherwise stated in writing, without any warranty; without even the + * implied warranty of merchantability or fitness for a particular purpose. + * See the GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License along with + * this program; if not, write to the Free Software Foundation, Inc., + * 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA. + * + * The full GNU General Public License is included in this distribution in + * the file called "COPYING". + * + * Contact Information: + * Imagination Technologies Ltd. + * Home Park Estate, Kings Langley, Herts, WD4 8LZ, UK + * + ******************************************************************************/ + +#include "services_headers.h" +#include "kerneldisplay.h" +#include "oemfuncs.h" +#include "sgxinfo.h" +#include "pdump_km.h" +#include "sgxinfokm.h" +#include "syslocal.h" +#include "sysconfig.h" + +SYS_DATA* gpsSysData = (SYS_DATA*)IMG_NULL; +SYS_DATA gsSysData; + +static SYS_SPECIFIC_DATA gsSysSpecificData; +SYS_SPECIFIC_DATA *gpsSysSpecificData; + +static IMG_UINT32 gui32SGXDeviceID; +static SGX_DEVICE_MAP gsSGXDeviceMap; +static PVRSRV_DEVICE_NODE *gpsSGXDevNode; + +#define DEVICE_SGX_INTERRUPT (1 << 0) + +#if defined(NO_HARDWARE) +static IMG_CPU_VIRTADDR gsSGXRegsCPUVAddr; +#endif + +IMG_UINT32 PVRSRV_BridgeDispatchKM(IMG_UINT32 Ioctl, + IMG_BYTE *pInBuf, + IMG_UINT32 InBufLen, + IMG_BYTE *pOutBuf, + IMG_UINT32 OutBufLen, + IMG_UINT32 *pdwBytesTransferred); + +static PVRSRV_ERROR SysLocateDevices(SYS_DATA *psSysData) +{ +#if defined(NO_HARDWARE) + PVRSRV_ERROR eError; + IMG_CPU_PHYADDR sCpuPAddr; +#endif + + PVR_UNREFERENCED_PARAMETER(psSysData); + + + gsSGXDeviceMap.ui32Flags = 0x0; + +#if defined(NO_HARDWARE) + + + eError = OSBaseAllocContigMemory(SYS_OMAP3430_SGX_REGS_SIZE, + &gsSGXRegsCPUVAddr, + &sCpuPAddr); + if(eError != PVRSRV_OK) + { + return eError; + } + gsSGXDeviceMap.sRegsCpuPBase = sCpuPAddr; + gsSGXDeviceMap.sRegsSysPBase = SysCpuPAddrToSysPAddr(gsSGXDeviceMap.sRegsCpuPBase); + gsSGXDeviceMap.ui32RegsSize = SYS_OMAP3430_SGX_REGS_SIZE; +#if defined(__linux__) + + gsSGXDeviceMap.pvRegsCpuVBase = gsSGXRegsCPUVAddr; +#else + + gsSGXDeviceMap.pvRegsCpuVBase = IMG_NULL; +#endif + + OSMemSet(gsSGXRegsCPUVAddr, 0, SYS_OMAP3430_SGX_REGS_SIZE); + + + + + gsSGXDeviceMap.ui32IRQ = 0; + +#else + + gsSGXDeviceMap.sRegsSysPBase.uiAddr = SYS_OMAP3430_SGX_REGS_SYS_PHYS_BASE; + gsSGXDeviceMap.sRegsCpuPBase = SysSysPAddrToCpuPAddr(gsSGXDeviceMap.sRegsSysPBase); + gsSGXDeviceMap.ui32RegsSize = SYS_OMAP3430_SGX_REGS_SIZE; + + gsSGXDeviceMap.ui32IRQ = SYS_OMAP3430_SGX_IRQ; + +#endif + + + + + + return PVRSRV_OK; +} + + +IMG_CHAR *SysCreateVersionString(IMG_CPU_PHYADDR sRegRegion) +{ + static IMG_CHAR aszVersionString[100]; + SYS_DATA *psSysData; + IMG_UINT32 ui32SGXRevision; + IMG_INT32 i32Count; +#if !defined(NO_HARDWARE) + IMG_VOID *pvRegsLinAddr; + + pvRegsLinAddr = OSMapPhysToLin(sRegRegion, + SYS_OMAP3430_SGX_REGS_SIZE, + PVRSRV_HAP_UNCACHED|PVRSRV_HAP_KERNEL_ONLY, + IMG_NULL); + if(!pvRegsLinAddr) + { + return IMG_NULL; + } + + ui32SGXRevision = OSReadHWReg((IMG_PVOID)((IMG_PBYTE)pvRegsLinAddr), + EUR_CR_CORE_REVISION); +#else + ui32SGXRevision = 0; +#endif + + if (SysAcquireData(&psSysData) != PVRSRV_OK) + { + return IMG_NULL; + } + + i32Count = OSSNPrintf(aszVersionString, 100, + "SGX revision = %u.%u.%u", + (IMG_UINT)((ui32SGXRevision & EUR_CR_CORE_REVISION_MAJOR_MASK) + >> EUR_CR_CORE_REVISION_MAJOR_SHIFT), + (IMG_UINT)((ui32SGXRevision & EUR_CR_CORE_REVISION_MINOR_MASK) + >> EUR_CR_CORE_REVISION_MINOR_SHIFT), + (IMG_UINT)((ui32SGXRevision & EUR_CR_CORE_REVISION_MAINTENANCE_MASK) + >> EUR_CR_CORE_REVISION_MAINTENANCE_SHIFT) + ); + +#if !defined(NO_HARDWARE) + OSUnMapPhysToLin(pvRegsLinAddr, + SYS_OMAP3430_SGX_REGS_SIZE, + PVRSRV_HAP_UNCACHED|PVRSRV_HAP_KERNEL_ONLY, + IMG_NULL); +#endif + + if(i32Count == -1) + { + return IMG_NULL; + } + + return aszVersionString; +} + + +PVRSRV_ERROR SysInitialise(IMG_VOID) +{ + IMG_UINT32 i; + PVRSRV_ERROR eError; + PVRSRV_DEVICE_NODE *psDeviceNode; + IMG_CPU_PHYADDR TimerRegPhysBase; + +#if defined(DEBUG) + PVR_DPF((PVR_DBG_WARNING,"SysInitialise: Entering...")); +#endif + +#if !defined(SGX_DYNAMIC_TIMING_INFO) + SGX_TIMING_INFORMATION* psTimingInfo; +#endif + gpsSysData = &gsSysData; + OSMemSet(gpsSysData, 0, sizeof(SYS_DATA)); + + gpsSysSpecificData = &gsSysSpecificData; + OSMemSet(gpsSysSpecificData, 0, sizeof(SYS_SPECIFIC_DATA)); + + gpsSysData->pvSysSpecificData = gpsSysSpecificData; + + eError = OSInitEnvData(&gpsSysData->pvEnvSpecificData); + if (eError != PVRSRV_OK) + { + PVR_DPF((PVR_DBG_ERROR,"SysInitialise: Failed to setup env structure")); + SysDeinitialise(gpsSysData); + gpsSysData = IMG_NULL; + return eError; + } + SYS_SPECIFIC_DATA_SET(&gsSysSpecificData, SYS_SPECIFIC_DATA_ENABLE_ENVDATA); + + gpsSysData->ui32NumDevices = SYS_DEVICE_COUNT; + + + for(i=0; isDeviceID[i].uiID = i; + gpsSysData->sDeviceID[i].bInUse = IMG_FALSE; + } + + gpsSysData->psDeviceNodeList = IMG_NULL; + gpsSysData->psQueueList = IMG_NULL; + + eError = SysInitialiseCommon(gpsSysData); + if (eError != PVRSRV_OK) + { + PVR_DPF((PVR_DBG_ERROR,"SysInitialise: Failed in SysInitialiseCommon")); + SysDeinitialise(gpsSysData); + gpsSysData = IMG_NULL; + return eError; + } + + TimerRegPhysBase.uiAddr = SYS_OMAP3430_GP11TIMER_REGS_SYS_PHYS_BASE; + gpsSysData->pvSOCTimerRegisterKM = IMG_NULL; + gpsSysData->hSOCTimerRegisterOSMemHandle = 0; + OSReservePhys(TimerRegPhysBase, + 4, + PVRSRV_HAP_MULTI_PROCESS|PVRSRV_HAP_UNCACHED, + (IMG_VOID **)&gpsSysData->pvSOCTimerRegisterKM, + &gpsSysData->hSOCTimerRegisterOSMemHandle); + +#if !defined(SGX_DYNAMIC_TIMING_INFO) + + psTimingInfo = &gsSGXDeviceMap.sTimingInfo; + psTimingInfo->ui32CoreClockSpeed = SYS_SGX_CLOCK_SPEED; + psTimingInfo->ui32HWRecoveryFreq = SYS_SGX_HWRECOVERY_TIMEOUT_FREQ; + psTimingInfo->ui32ActivePowManLatencyms = SYS_SGX_ACTIVE_POWER_LATENCY_MS; + psTimingInfo->ui32uKernelFreq = SYS_SGX_PDS_TIMER_FREQ; +#endif + + + + gpsSysSpecificData->ui32SrcClockDiv = 3; + + + + + + eError = SysLocateDevices(gpsSysData); + if (eError != PVRSRV_OK) + { + PVR_DPF((PVR_DBG_ERROR,"SysInitialise: Failed to locate devices")); + SysDeinitialise(gpsSysData); + gpsSysData = IMG_NULL; + return eError; + } + SYS_SPECIFIC_DATA_SET(&gsSysSpecificData, SYS_SPECIFIC_DATA_ENABLE_LOCATEDEV); + + + + + eError = PVRSRVRegisterDevice(gpsSysData, SGXRegisterDevice, + DEVICE_SGX_INTERRUPT, &gui32SGXDeviceID); + if (eError != PVRSRV_OK) + { + PVR_DPF((PVR_DBG_ERROR,"SysInitialise: Failed to register device!")); + SysDeinitialise(gpsSysData); + gpsSysData = IMG_NULL; + return eError; + } + SYS_SPECIFIC_DATA_SET(&gsSysSpecificData, SYS_SPECIFIC_DATA_ENABLE_REGDEV); + + + + + + psDeviceNode = gpsSysData->psDeviceNodeList; + while(psDeviceNode) + { + + switch(psDeviceNode->sDevId.eDeviceType) + { + case PVRSRV_DEVICE_TYPE_SGX: + { + DEVICE_MEMORY_INFO *psDevMemoryInfo; + DEVICE_MEMORY_HEAP_INFO *psDeviceMemoryHeap; + + + + + psDeviceNode->psLocalDevMemArena = IMG_NULL; + + + psDevMemoryInfo = &psDeviceNode->sDevMemoryInfo; + psDeviceMemoryHeap = psDevMemoryInfo->psDeviceMemoryHeap; + + + for(i=0; iui32HeapCount; i++) + { + psDeviceMemoryHeap[i].ui32Attribs |= PVRSRV_BACKINGSTORE_SYSMEM_NONCONTIG; + } + + gpsSGXDevNode = psDeviceNode; + gsSysSpecificData.psSGXDevNode = psDeviceNode; + + break; + } + default: + PVR_DPF((PVR_DBG_ERROR,"SysInitialise: Failed to find SGX device node!")); + return PVRSRV_ERROR_INIT_FAILURE; + } + + + psDeviceNode = psDeviceNode->psNext; + } + + PDUMPINIT(); + SYS_SPECIFIC_DATA_SET(&gsSysSpecificData, SYS_SPECIFIC_DATA_ENABLE_PDUMPINIT); + + eError = EnableSystemClocks(gpsSysData); + if (eError != PVRSRV_OK) + { + PVR_DPF((PVR_DBG_ERROR,"SysInitialise: Failed to Enable system clocks (%d)", eError)); + SysDeinitialise(gpsSysData); + gpsSysData = IMG_NULL; + return eError; + } + SYS_SPECIFIC_DATA_SET(&gsSysSpecificData, SYS_SPECIFIC_DATA_ENABLE_SYSCLOCKS); + +#if defined(SUPPORT_ACTIVE_POWER_MANAGEMENT) + eError = EnableSGXClocks(gpsSysData); + if (eError != PVRSRV_OK) + { + PVR_DPF((PVR_DBG_ERROR,"SysInitialise: Failed to Enable SGX clocks (%d)", eError)); + SysDeinitialise(gpsSysData); + gpsSysData = IMG_NULL; + return eError; + } +#endif + + eError = PVRSRVInitialiseDevice(gui32SGXDeviceID); + if (eError != PVRSRV_OK) + { + PVR_DPF((PVR_DBG_ERROR,"SysInitialise: Failed to initialise device!")); + SysDeinitialise(gpsSysData); + gpsSysData = IMG_NULL; + return eError; + } + SYS_SPECIFIC_DATA_SET(&gsSysSpecificData, SYS_SPECIFIC_DATA_ENABLE_INITDEV); + +#if defined(SUPPORT_ACTIVE_POWER_MANAGEMENT) + + DisableSGXClocks(gpsSysData); +#endif + + return PVRSRV_OK; +} + + +PVRSRV_ERROR SysFinalise(IMG_VOID) +{ + PVRSRV_ERROR eError = PVRSRV_OK; + +#if defined(SUPPORT_ACTIVE_POWER_MANAGEMENT) + eError = EnableSGXClocks(gpsSysData); + if (eError != PVRSRV_OK) + { + PVR_DPF((PVR_DBG_ERROR,"SysInitialise: Failed to Enable SGX clocks (%d)", eError)); + SysDeinitialise(gpsSysData); + gpsSysData = IMG_NULL; + return eError; + } +#endif + +#if defined(SYS_USING_INTERRUPTS) + + eError = OSInstallMISR(gpsSysData); + if (eError != PVRSRV_OK) + { + PVR_DPF((PVR_DBG_ERROR,"SysFinalise: Failed to install MISR")); + SysDeinitialise(gpsSysData); + gpsSysData = IMG_NULL; + return eError; + } + SYS_SPECIFIC_DATA_SET(&gsSysSpecificData, SYS_SPECIFIC_DATA_ENABLE_MISR); + + + eError = OSInstallDeviceLISR(gpsSysData, gsSGXDeviceMap.ui32IRQ, "SGX ISR", gpsSGXDevNode); + if (eError != PVRSRV_OK) + { + PVR_DPF((PVR_DBG_ERROR,"SysFinalise: Failed to install ISR")); + SysDeinitialise(gpsSysData); + gpsSysData = IMG_NULL; + return eError; + } + SYS_SPECIFIC_DATA_SET(&gsSysSpecificData, SYS_SPECIFIC_DATA_ENABLE_LISR); +#endif + + + gpsSysData->pszVersionString = SysCreateVersionString(gsSGXDeviceMap.sRegsCpuPBase); + if (!gpsSysData->pszVersionString) + { + PVR_DPF((PVR_DBG_ERROR,"SysFinalise: Failed to create a system version string")); + } + else + { + PVR_DPF((PVR_DBG_WARNING, "SysFinalise: Version string: %s", gpsSysData->pszVersionString)); + } + +#if defined(SUPPORT_ACTIVE_POWER_MANAGEMENT) + + DisableSGXClocks(gpsSysData); +#endif + + gpsSysSpecificData->bSGXInitComplete = IMG_TRUE; + + return eError; +} + + +PVRSRV_ERROR SysDeinitialise (SYS_DATA *psSysData) +{ + PVRSRV_ERROR eError; + +#if defined(SYS_USING_INTERRUPTS) + if (SYS_SPECIFIC_DATA_TEST(gpsSysSpecificData, SYS_SPECIFIC_DATA_ENABLE_LISR)) + { + eError = OSUninstallDeviceLISR(psSysData); + if (eError != PVRSRV_OK) + { + PVR_DPF((PVR_DBG_ERROR,"SysDeinitialise: OSUninstallDeviceLISR failed")); + return eError; + } + } + + if (SYS_SPECIFIC_DATA_TEST(gpsSysSpecificData, SYS_SPECIFIC_DATA_ENABLE_MISR)) + { + eError = OSUninstallMISR(psSysData); + if (eError != PVRSRV_OK) + { + PVR_DPF((PVR_DBG_ERROR,"SysDeinitialise: OSUninstallMISR failed")); + return eError; + } + } +#else + PVR_UNREFERENCED_PARAMETER(psSysData); +#endif + + if (SYS_SPECIFIC_DATA_TEST(gpsSysSpecificData, SYS_SPECIFIC_DATA_ENABLE_INITDEV)) + { +#if defined(SUPPORT_ACTIVE_POWER_MANAGEMENT) + PVR_ASSERT(SYS_SPECIFIC_DATA_TEST(gpsSysSpecificData, SYS_SPECIFIC_DATA_ENABLE_SYSCLOCKS)); + + eError = EnableSGXClocks(gpsSysData); + if (eError != PVRSRV_OK) + { + PVR_DPF((PVR_DBG_ERROR,"SysDeinitialise: EnableSGXClocks failed")); + return eError; + } +#endif + + + eError = PVRSRVDeinitialiseDevice (gui32SGXDeviceID); + if (eError != PVRSRV_OK) + { + PVR_DPF((PVR_DBG_ERROR,"SysDeinitialise: failed to de-init the device")); + return eError; + } + } + + + + if (SYS_SPECIFIC_DATA_TEST(gpsSysSpecificData, SYS_SPECIFIC_DATA_ENABLE_SYSCLOCKS)) + { + DisableSystemClocks(gpsSysData); + } + + if (SYS_SPECIFIC_DATA_TEST(gpsSysSpecificData, SYS_SPECIFIC_DATA_ENABLE_ENVDATA)) + { + eError = OSDeInitEnvData(gpsSysData->pvEnvSpecificData); + if (eError != PVRSRV_OK) + { + PVR_DPF((PVR_DBG_ERROR,"SysDeinitialise: failed to de-init env structure")); + return eError; + } + } + + if(gpsSysData->pvSOCTimerRegisterKM) + { + OSUnReservePhys(gpsSysData->pvSOCTimerRegisterKM, + 4, + PVRSRV_HAP_MULTI_PROCESS|PVRSRV_HAP_UNCACHED, + gpsSysData->hSOCTimerRegisterOSMemHandle); + } + + SysDeinitialiseCommon(gpsSysData); + +#if defined(NO_HARDWARE) + if(SYS_SPECIFIC_DATA_TEST(gpsSysSpecificData, SYS_SPECIFIC_DATA_ENABLE_LOCATEDEV)) + { + + OSBaseFreeContigMemory(SYS_OMAP3430_SGX_REGS_SIZE, gsSGXRegsCPUVAddr, gsSGXDeviceMap.sRegsCpuPBase); + } +#endif + + + if(SYS_SPECIFIC_DATA_TEST(gpsSysSpecificData, SYS_SPECIFIC_DATA_ENABLE_PDUMPINIT)) + { + PDUMPDEINIT(); + } + + gpsSysSpecificData->ui32SysSpecificData = 0; + gpsSysSpecificData->bSGXInitComplete = IMG_FALSE; + + gpsSysData = IMG_NULL; + + return PVRSRV_OK; +} + + +PVRSRV_ERROR SysGetDeviceMemoryMap(PVRSRV_DEVICE_TYPE eDeviceType, + IMG_VOID **ppvDeviceMap) +{ + + switch(eDeviceType) + { + case PVRSRV_DEVICE_TYPE_SGX: + { + + *ppvDeviceMap = (IMG_VOID*)&gsSGXDeviceMap; + + break; + } + default: + { + PVR_DPF((PVR_DBG_ERROR,"SysGetDeviceMemoryMap: unsupported device type")); + } + } + return PVRSRV_OK; +} + + +IMG_DEV_PHYADDR SysCpuPAddrToDevPAddr(PVRSRV_DEVICE_TYPE eDeviceType, + IMG_CPU_PHYADDR CpuPAddr) +{ + IMG_DEV_PHYADDR DevPAddr; + + PVR_UNREFERENCED_PARAMETER(eDeviceType); + + + DevPAddr.uiAddr = CpuPAddr.uiAddr; + + return DevPAddr; +} + +IMG_CPU_PHYADDR SysSysPAddrToCpuPAddr (IMG_SYS_PHYADDR sys_paddr) +{ + IMG_CPU_PHYADDR cpu_paddr; + + + cpu_paddr.uiAddr = sys_paddr.uiAddr; + return cpu_paddr; +} + +IMG_SYS_PHYADDR SysCpuPAddrToSysPAddr (IMG_CPU_PHYADDR cpu_paddr) +{ + IMG_SYS_PHYADDR sys_paddr; + + + sys_paddr.uiAddr = cpu_paddr.uiAddr; + return sys_paddr; +} + + +IMG_DEV_PHYADDR SysSysPAddrToDevPAddr(PVRSRV_DEVICE_TYPE eDeviceType, IMG_SYS_PHYADDR SysPAddr) +{ + IMG_DEV_PHYADDR DevPAddr; + + PVR_UNREFERENCED_PARAMETER(eDeviceType); + + + DevPAddr.uiAddr = SysPAddr.uiAddr; + + return DevPAddr; +} + + +IMG_SYS_PHYADDR SysDevPAddrToSysPAddr(PVRSRV_DEVICE_TYPE eDeviceType, IMG_DEV_PHYADDR DevPAddr) +{ + IMG_SYS_PHYADDR SysPAddr; + + PVR_UNREFERENCED_PARAMETER(eDeviceType); + + + SysPAddr.uiAddr = DevPAddr.uiAddr; + + return SysPAddr; +} + + +IMG_VOID SysRegisterExternalDevice(PVRSRV_DEVICE_NODE *psDeviceNode) +{ + PVR_UNREFERENCED_PARAMETER(psDeviceNode); +} + + +IMG_VOID SysRemoveExternalDevice(PVRSRV_DEVICE_NODE *psDeviceNode) +{ + PVR_UNREFERENCED_PARAMETER(psDeviceNode); +} + + +IMG_UINT32 SysGetInterruptSource(SYS_DATA *psSysData, + PVRSRV_DEVICE_NODE *psDeviceNode) +{ + PVR_UNREFERENCED_PARAMETER(psSysData); +#if defined(NO_HARDWARE) + + return 0xFFFFFFFF; +#else + + return psDeviceNode->ui32SOCInterruptBit; +#endif +} + + +IMG_VOID SysClearInterrupts(SYS_DATA* psSysData, IMG_UINT32 ui32ClearBits) +{ + PVR_UNREFERENCED_PARAMETER(psSysData); + PVR_UNREFERENCED_PARAMETER(ui32ClearBits); + + + OSReadHWReg(((PVRSRV_SGXDEV_INFO *)gpsSGXDevNode->pvDevice)->pvRegsBaseKM, + EUR_CR_EVENT_HOST_CLEAR); +} + + +PVRSRV_ERROR SysSystemPrePowerState(PVR_POWER_STATE eNewPowerState) +{ + PVRSRV_ERROR eError = PVRSRV_OK; + + if (eNewPowerState == PVRSRV_POWER_STATE_D3) + { + PVR_TRACE(("SysSystemPrePowerState: Entering state D3")); + +#if defined(SYS_USING_INTERRUPTS) + if (SYS_SPECIFIC_DATA_TEST(&gsSysSpecificData, SYS_SPECIFIC_DATA_ENABLE_LISR)) + { +#if defined(SYS_CUSTOM_POWERLOCK_WRAP) + IMG_BOOL bWrapped = WrapSystemPowerChange(&gsSysSpecificData); +#endif + eError = OSUninstallDeviceLISR(gpsSysData); +#if defined(SYS_CUSTOM_POWERLOCK_WRAP) + if (bWrapped) + { + UnwrapSystemPowerChange(&gsSysSpecificData); + } +#endif + if (eError != PVRSRV_OK) + { + PVR_DPF((PVR_DBG_ERROR,"SysSystemPrePowerState: OSUninstallDeviceLISR failed (%d)", eError)); + return eError; + } + SYS_SPECIFIC_DATA_SET(&gsSysSpecificData, SYS_SPECIFIC_DATA_PM_UNINSTALL_LISR); + SYS_SPECIFIC_DATA_CLEAR(&gsSysSpecificData, SYS_SPECIFIC_DATA_ENABLE_LISR); + } +#endif + + if (SYS_SPECIFIC_DATA_TEST(&gsSysSpecificData, SYS_SPECIFIC_DATA_ENABLE_SYSCLOCKS)) + { + DisableSystemClocks(gpsSysData); + + SYS_SPECIFIC_DATA_SET(&gsSysSpecificData, SYS_SPECIFIC_DATA_PM_DISABLE_SYSCLOCKS); + SYS_SPECIFIC_DATA_CLEAR(&gsSysSpecificData, SYS_SPECIFIC_DATA_ENABLE_SYSCLOCKS); + } + } + + return eError; +} + + +PVRSRV_ERROR SysSystemPostPowerState(PVR_POWER_STATE eNewPowerState) +{ + PVRSRV_ERROR eError = PVRSRV_OK; + + if (eNewPowerState == PVRSRV_POWER_STATE_D0) + { + PVR_TRACE(("SysSystemPostPowerState: Entering state D0")); + + if (SYS_SPECIFIC_DATA_TEST(&gsSysSpecificData, SYS_SPECIFIC_DATA_PM_DISABLE_SYSCLOCKS)) + { + eError = EnableSystemClocks(gpsSysData); + if (eError != PVRSRV_OK) + { + PVR_DPF((PVR_DBG_ERROR,"SysSystemPostPowerState: EnableSystemClocks failed (%d)", eError)); + return eError; + } + SYS_SPECIFIC_DATA_SET(&gsSysSpecificData, SYS_SPECIFIC_DATA_ENABLE_SYSCLOCKS); + SYS_SPECIFIC_DATA_CLEAR(&gsSysSpecificData, SYS_SPECIFIC_DATA_PM_DISABLE_SYSCLOCKS); + } + +#if defined(SYS_USING_INTERRUPTS) + if (SYS_SPECIFIC_DATA_TEST(&gsSysSpecificData, SYS_SPECIFIC_DATA_PM_UNINSTALL_LISR)) + { +#if defined(SYS_CUSTOM_POWERLOCK_WRAP) + IMG_BOOL bWrapped = WrapSystemPowerChange(&gsSysSpecificData); +#endif + + eError = OSInstallDeviceLISR(gpsSysData, gsSGXDeviceMap.ui32IRQ, "SGX ISR", gpsSGXDevNode); +#if defined(SYS_CUSTOM_POWERLOCK_WRAP) + if (bWrapped) + { + UnwrapSystemPowerChange(&gsSysSpecificData); + } +#endif + if (eError != PVRSRV_OK) + { + PVR_DPF((PVR_DBG_ERROR,"SysSystemPostPowerState: OSInstallDeviceLISR failed to install ISR (%d)", eError)); + return eError; + } + SYS_SPECIFIC_DATA_SET(&gsSysSpecificData, SYS_SPECIFIC_DATA_ENABLE_LISR); + SYS_SPECIFIC_DATA_CLEAR(&gsSysSpecificData, SYS_SPECIFIC_DATA_PM_UNINSTALL_LISR); + } +#endif + } + return eError; +} + + +PVRSRV_ERROR SysDevicePrePowerState(IMG_UINT32 ui32DeviceIndex, + PVR_POWER_STATE eNewPowerState, + PVR_POWER_STATE eCurrentPowerState) +{ + PVR_UNREFERENCED_PARAMETER(eCurrentPowerState); + + if (ui32DeviceIndex != gui32SGXDeviceID) + { + return PVRSRV_OK; + } + +#if defined(SUPPORT_ACTIVE_POWER_MANAGEMENT) + if (eNewPowerState == PVRSRV_POWER_STATE_D3) + { + PVR_DPF((PVR_DBG_MESSAGE, "SysDevicePrePowerState: SGX Entering state D3")); + DisableSGXClocks(gpsSysData); + PVRSRVSetDCState(DC_STATE_SUSPEND_COMMANDS); + } +#else + PVR_UNREFERENCED_PARAMETER(eNewPowerState ); +#endif + return PVRSRV_OK; +} + + +PVRSRV_ERROR SysDevicePostPowerState(IMG_UINT32 ui32DeviceIndex, + PVR_POWER_STATE eNewPowerState, + PVR_POWER_STATE eCurrentPowerState) +{ + PVRSRV_ERROR eError = PVRSRV_OK; + + PVR_UNREFERENCED_PARAMETER(eNewPowerState); + + if (ui32DeviceIndex != gui32SGXDeviceID) + { + return eError; + } + +#if defined(SUPPORT_ACTIVE_POWER_MANAGEMENT) + if (eCurrentPowerState == PVRSRV_POWER_STATE_D3) + { + PVR_DPF((PVR_DBG_MESSAGE, "SysDevicePostPowerState: SGX Leaving state D3")); + PVRSRVSetDCState(DC_STATE_RESUME_COMMANDS); + eError = EnableSGXClocks(gpsSysData); + } +#else + PVR_UNREFERENCED_PARAMETER(eCurrentPowerState); +#endif + + return eError; +} + + +PVRSRV_ERROR SysOEMFunction ( IMG_UINT32 ui32ID, + IMG_VOID *pvIn, + IMG_UINT32 ulInSize, + IMG_VOID *pvOut, + IMG_UINT32 ulOutSize) +{ + PVR_UNREFERENCED_PARAMETER(ui32ID); + PVR_UNREFERENCED_PARAMETER(pvIn); + PVR_UNREFERENCED_PARAMETER(ulInSize); + PVR_UNREFERENCED_PARAMETER(pvOut); + PVR_UNREFERENCED_PARAMETER(ulOutSize); + + if ((ui32ID == OEM_GET_EXT_FUNCS) && + (ulOutSize == sizeof(PVRSRV_DC_OEM_JTABLE))) + { + + PVRSRV_DC_OEM_JTABLE *psOEMJTable = (PVRSRV_DC_OEM_JTABLE*) pvOut; + psOEMJTable->pfnOEMBridgeDispatch = &PVRSRV_BridgeDispatchKM; + return PVRSRV_OK; + } + + return PVRSRV_ERROR_INVALID_PARAMS; +} diff --git a/services4/system/ti8168/sysconfig.h b/services4/system/ti8168/sysconfig.h new file mode 100644 index 0000000..516155e --- /dev/null +++ b/services4/system/ti8168/sysconfig.h @@ -0,0 +1,53 @@ +/********************************************************************** + * + * Copyright(c) 2008 Imagination Technologies Ltd. All rights reserved. + * + * This program is free software; you can redistribute it and/or modify it + * under the terms and conditions of the GNU General Public License, + * version 2, as published by the Free Software Foundation. + * + * This program is distributed in the hope it will be useful but, except + * as otherwise stated in writing, without any warranty; without even the + * implied warranty of merchantability or fitness for a particular purpose. + * See the GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License along with + * this program; if not, write to the Free Software Foundation, Inc., + * 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA. + * + * The full GNU General Public License is included in this distribution in + * the file called "COPYING". + * + * Contact Information: + * Imagination Technologies Ltd. + * Home Park Estate, Kings Langley, Herts, WD4 8LZ, UK + * + ******************************************************************************/ + +#if !defined(__SOCCONFIG_H__) +#define __SOCCONFIG_H__ + +#include "syscommon.h" + +#define VS_PRODUCT_NAME "OMAP3630" + +#define SYS_SGX_CLOCK_SPEED 330000000 +#define SYS_SGX_HWRECOVERY_TIMEOUT_FREQ (100) +#define SYS_SGX_PDS_TIMER_FREQ (1000) +#define SYS_SGX_ACTIVE_POWER_LATENCY_MS (1) + + +#define SYS_OMAP3430_VDD2_OPP3_SGX_CLOCK_SPEED SYS_SGX_CLOCK_SPEED +#define SYS_OMAP3430_VDD2_OPP2_SGX_CLOCK_SPEED (SYS_SGX_CLOCK_SPEED / 2) + +#define SYS_OMAP3430_SGX_REGS_SYS_PHYS_BASE 0x56000000 +#define SYS_OMAP3430_SGX_REGS_SIZE 0x10000 + +#define SYS_OMAP3430_SGX_IRQ 37 + +#define SYS_OMAP3430_GP11TIMER_ENABLE_SYS_PHYS_BASE 0x48048038 +#define SYS_OMAP3430_GP11TIMER_REGS_SYS_PHYS_BASE 0x4804803C +#define SYS_OMAP3430_GP11TIMER_TSICR_SYS_PHYS_BASE 0x48048054 + + +#endif diff --git a/services4/system/ti8168/sysinfo.h b/services4/system/ti8168/sysinfo.h new file mode 100644 index 0000000..88e3096 --- /dev/null +++ b/services4/system/ti8168/sysinfo.h @@ -0,0 +1,98 @@ +/********************************************************************** + * + * Copyright(c) 2008 Imagination Technologies Ltd. All rights reserved. + * + * This program is free software; you can redistribute it and/or modify it + * under the terms and conditions of the GNU General Public License, + * version 2, as published by the Free Software Foundation. + * + * This program is distributed in the hope it will be useful but, except + * as otherwise stated in writing, without any warranty; without even the + * implied warranty of merchantability or fitness for a particular purpose. + * See the GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License along with + * this program; if not, write to the Free Software Foundation, Inc., + * 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA. + * + * The full GNU General Public License is included in this distribution in + * the file called "COPYING". + * + * Contact Information: + * Imagination Technologies Ltd. + * Home Park Estate, Kings Langley, Herts, WD4 8LZ, UK + * + ******************************************************************************/ + +#if !defined(__SYSINFO_H__) +#define __SYSINFO_H__ + +#define MAX_HW_TIME_US (500000) +#define WAIT_TRY_COUNT (10000) + +typedef enum _SYS_DEVICE_TYPE_ +{ + SYS_DEVICE_SGX = 0, + + SYS_DEVICE_FORCE_I16 = 0x7fff + +} SYS_DEVICE_TYPE; + +#define SYS_DEVICE_COUNT 3 + +#define PRM_REG32(offset) (offset) +#define CM_REG32(offset) (offset) + +#define CM_FCLKEN_SGX CM_REG32(0xB00) +#define CM_FCLKEN_SGX_EN_3D 0x00000002 + +#define CM_ICLKEN_SGX CM_REG32(0xB10) +#define CM_ICLKEN_SGX_EN_SGX 0x00000001 + +#define CM_IDLEST_SGX CM_REG32(0xB20) +#define CM_IDLEST_SGX_ST_SGX 0x00000001 + +#define CM_CLKSEL_SGX CM_REG32(0xB40) +#define CM_CLKSEL_SGX_MASK 0x0000000f +#define CM_CLKSEL_SGX_L3DIV3 0x00000000 +#define CM_CLKSEL_SGX_L3DIV4 0x00000001 +#define CM_CLKSEL_SGX_L3DIV6 0x00000002 +#define CM_CLKSEL_SGX_96M 0x00000003 + +#define CM_SLEEPDEP_SGX CM_REG32(0xB44) +#define CM_CLKSTCTRL_SGX CM_REG32(0xB48) +#define CM_CLKSTCTRL_SGX_AUTOSTATE 0x00008001 + +#define CM_CLKSTST_SGX CM_REG32(0xB4C) +#define CM_CLKSTST_SGX_STATUS_VALID 0x00000001 + +#define RM_RSTST_SGX PRM_REG32(0xB58) +#define RM_RSTST_SGX_RST_MASK 0x0000000F +#define RM_RSTST_SGX_COREDOMAINWKUP_RST 0x00000008 +#define RM_RSTST_SGX_DOMAINWKUP_RST 0x00000004 +#define RM_RSTST_SGX_GLOBALWARM_RST 0x00000002 +#define RM_RSTST_SGX_GLOBALCOLD_RST 0x00000001 + +#define PM_WKDEP_SGX PRM_REG32(0xBC8) +#define PM_WKDEP_SGX_EN_WAKEUP 0x00000010 +#define PM_WKDEP_SGX_EN_MPU 0x00000002 +#define PM_WKDEP_SGX_EN_CORE 0x00000001 + +#define PM_PWSTCTRL_SGX PRM_REG32(0xBE0) +#define PM_PWSTCTRL_SGX_POWERSTATE_MASK 0x00000003 +#define PM_PWSTCTRL_SGX_OFF 0x00000000 +#define PM_PWSTCTRL_SGX_RETENTION 0x00000001 +#define PM_PWSTCTRL_SGX_ON 0x00000003 + +#define PM_PWSTST_SGX PRM_REG32(0xBE4) +#define PM_PWSTST_SGX_INTRANSITION 0x00100000 +#define PM_PWSTST_SGX_CLKACTIVITY 0x00080000 +#define PM_PWSTST_SGX_POWERSTATE_MASK 0x00000003 +#define PM_PWSTST_SGX_OFF 0x00000003 +#define PM_PWSTST_SGX_RETENTION 0x00000001 +#define PM_PWSTST_SGX_ON 0x00000000 + +#define PM_PREPWSTST_SGX PRM_REG32(0xBE8) + + +#endif diff --git a/services4/system/ti8168/syslocal.h b/services4/system/ti8168/syslocal.h new file mode 100644 index 0000000..74de28f --- /dev/null +++ b/services4/system/ti8168/syslocal.h @@ -0,0 +1,128 @@ +/********************************************************************** + * + * Copyright(c) 2008 Imagination Technologies Ltd. All rights reserved. + * + * This program is free software; you can redistribute it and/or modify it + * under the terms and conditions of the GNU General Public License, + * version 2, as published by the Free Software Foundation. + * + * This program is distributed in the hope it will be useful but, except + * as otherwise stated in writing, without any warranty; without even the + * implied warranty of merchantability or fitness for a particular purpose. + * See the GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License along with + * this program; if not, write to the Free Software Foundation, Inc., + * 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA. + * + * The full GNU General Public License is included in this distribution in + * the file called "COPYING". + * + * Contact Information: + * Imagination Technologies Ltd. + * Home Park Estate, Kings Langley, Herts, WD4 8LZ, UK + * + ******************************************************************************/ + +#if !defined(__SYSLOCAL_H__) +#define __SYSLOCAL_H__ + +#if defined(__linux__) + +#include +#include +#include +#include + +#if (LINUX_VERSION_CODE > KERNEL_VERSION(2,6,26)) +#include +#include +#else +#include +#if (LINUX_VERSION_CODE > KERNEL_VERSION(2,6,22)) +#include +#endif +#endif + +#endif + +#if defined (__cplusplus) +extern "C" { +#endif + + + +IMG_CHAR *SysCreateVersionString(IMG_CPU_PHYADDR sRegRegion); + +IMG_VOID DisableSystemClocks(SYS_DATA *psSysData); +PVRSRV_ERROR EnableSystemClocks(SYS_DATA *psSysData); + +IMG_VOID DisableSGXClocks(SYS_DATA *psSysData); +PVRSRV_ERROR EnableSGXClocks(SYS_DATA *psSysData); + +#define SYS_SPECIFIC_DATA_ENABLE_SYSCLOCKS 0x00000001 +#define SYS_SPECIFIC_DATA_ENABLE_LISR 0x00000002 +#define SYS_SPECIFIC_DATA_ENABLE_MISR 0x00000004 +#define SYS_SPECIFIC_DATA_ENABLE_ENVDATA 0x00000008 +#define SYS_SPECIFIC_DATA_ENABLE_LOCDEV 0x00000010 +#define SYS_SPECIFIC_DATA_ENABLE_REGDEV 0x00000020 +#define SYS_SPECIFIC_DATA_ENABLE_PDUMPINIT 0x00000040 +#define SYS_SPECIFIC_DATA_ENABLE_INITDEV 0x00000080 +#define SYS_SPECIFIC_DATA_ENABLE_LOCATEDEV 0x00000100 + +#define SYS_SPECIFIC_DATA_PM_UNINSTALL_LISR 0x00000200 +#define SYS_SPECIFIC_DATA_PM_DISABLE_SYSCLOCKS 0x00000400 + +#define SYS_SPECIFIC_DATA_SET(psSysSpecData, flag) ((IMG_VOID)((psSysSpecData)->ui32SysSpecificData |= (flag))) + +#define SYS_SPECIFIC_DATA_CLEAR(psSysSpecData, flag) ((IMG_VOID)((psSysSpecData)->ui32SysSpecificData &= ~(flag))) + +#define SYS_SPECIFIC_DATA_TEST(psSysSpecData, flag) (((psSysSpecData)->ui32SysSpecificData & (flag)) != 0) + +typedef struct _SYS_SPECIFIC_DATA_TAG_ +{ + IMG_UINT32 ui32SysSpecificData; + PVRSRV_DEVICE_NODE *psSGXDevNode; + IMG_BOOL bSGXInitComplete; +#if !defined(__linux__) + IMG_BOOL bSGXClocksEnabled; +#endif + IMG_UINT32 ui32SrcClockDiv; +#if defined(__linux__) + IMG_BOOL bSysClocksOneTimeInit; + IMG_BOOL bConstraintNotificationsEnabled; + atomic_t sSGXClocksEnabled; + spinlock_t sPowerLock; + atomic_t sPowerLockCPU; + spinlock_t sNotifyLock; + atomic_t sNotifyLockCPU; + IMG_BOOL bCallVDD2PostFunc; + + struct clk *psCORE_CK; + struct clk *psSGX_FCK; + struct clk *psSGX_ICK; + struct clk *psMPU_CK; +#if defined(DEBUG) || defined(TIMING) + struct clk *psGPT11_FCK; + struct clk *psGPT11_ICK; +#endif +#if (LINUX_VERSION_CODE > KERNEL_VERSION(2,6,22)) + struct constraint_handle *pVdd2Handle; +#endif +#endif +} SYS_SPECIFIC_DATA; + +extern SYS_SPECIFIC_DATA *gpsSysSpecificData; + +#if defined(SYS_CUSTOM_POWERLOCK_WRAP) +IMG_BOOL WrapSystemPowerChange(SYS_SPECIFIC_DATA *psSysSpecData); +IMG_VOID UnwrapSystemPowerChange(SYS_SPECIFIC_DATA *psSysSpecData); +#endif + +#if defined(__cplusplus) +} +#endif + +#endif + + diff --git a/services4/system/ti8168/sysutils.c b/services4/system/ti8168/sysutils.c new file mode 100644 index 0000000..cb3cee7 --- /dev/null +++ b/services4/system/ti8168/sysutils.c @@ -0,0 +1,30 @@ +/********************************************************************** + * + * Copyright(c) 2008 Imagination Technologies Ltd. All rights reserved. + * + * This program is free software; you can redistribute it and/or modify it + * under the terms and conditions of the GNU General Public License, + * version 2, as published by the Free Software Foundation. + * + * This program is distributed in the hope it will be useful but, except + * as otherwise stated in writing, without any warranty; without even the + * implied warranty of merchantability or fitness for a particular purpose. + * See the GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License along with + * this program; if not, write to the Free Software Foundation, Inc., + * 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA. + * + * The full GNU General Public License is included in this distribution in + * the file called "COPYING". + * + * Contact Information: + * Imagination Technologies Ltd. + * Home Park Estate, Kings Langley, Herts, WD4 8LZ, UK + * + ******************************************************************************/ + +#if defined(__linux__) +#include "sysutils_linux.c" +#endif + diff --git a/services4/system/ti8168/sysutils_linux.c b/services4/system/ti8168/sysutils_linux.c new file mode 100644 index 0000000..17be8f3 --- /dev/null +++ b/services4/system/ti8168/sysutils_linux.c @@ -0,0 +1,738 @@ +/********************************************************************** + * + * Copyright(c) 2008 Imagination Technologies Ltd. All rights reserved. + * + * This program is free software; you can redistribute it and/or modify it + * under the terms and conditions of the GNU General Public License, + * version 2, as published by the Free Software Foundation. + * + * This program is distributed in the hope it will be useful but, except + * as otherwise stated in writing, without any warranty; without even the + * implied warranty of merchantability or fitness for a particular purpose. + * See the GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License along with + * this program; if not, write to the Free Software Foundation, Inc., + * 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA. + * + * The full GNU General Public License is included in this distribution in + * the file called "COPYING". + * + * Contact Information: + * Imagination Technologies Ltd. + * Home Park Estate, Kings Langley, Herts, WD4 8LZ, UK + * + ******************************************************************************/ + +#include +#include +#include +#include +#include +#include +#include + +#if (LINUX_VERSION_CODE > KERNEL_VERSION(2,6,31)) +#include +//#include +#include +#else + +#if (LINUX_VERSION_CODE > KERNEL_VERSION(2,6,26)) +#include +#include +#include +#else +#include +#if (LINUX_VERSION_CODE > KERNEL_VERSION(2,6,22)) +#include +#endif +#endif +#endif + +#if (LINUX_VERSION_CODE > KERNEL_VERSION(2,6,27)) && \ + (LINUX_VERSION_CODE <= KERNEL_VERSION(2,6,29)) +#define CONSTRAINT_NOTIFICATIONS +#endif +#include "sgxdefs.h" +#include "services_headers.h" +#include "sysinfo.h" +#include "sgxapi_km.h" +#include "sysconfig.h" +#include "sgxinfokm.h" +#include "syslocal.h" +void set_vdd2_constraint(void); +void remove_vdd2_constraint(void); +#define ONE_MHZ 1000000 +#define HZ_TO_MHZ(m) ((m) / ONE_MHZ) + +#if defined(SUPPORT_OMAP3630_SGXFCLK_96M) +#define SGX_PARENT_CLOCK "cm_96m_fck" +#elif defined(SUPPORT_OMAP3630_SGXFCLK_192M) +#define SGX_PARENT_CLOCK "omap_192m_alwon_ck" +#elif defined(SUPPORT_OMAP3630_SGXFCLK_corex2) +#define SGX_PARENT_CLOCK "corex2_fck" +#else +#define SGX_PARENT_CLOCK "core_ck" +#endif + +#if !defined(PDUMP) && !defined(NO_HARDWARE) +struct sgx_platform_data { + void(*set_min_bus_tput)(struct device *dev, u8 agent_id, unsigned long r); +}; + +static struct sgx_platform_data pdata = { + + //.set_min_bus_tput = &omap_pm_set_min_bus_tput, + .set_min_bus_tput = NULL, +}; + +static struct platform_device sgx_dev = { + .name = "sgx_dev", + .id = 1, + .dev.platform_data = &pdata, +}; +void set_vdd2_constraint(void) +{ + if(pdata.set_min_bus_tput){ + pdata.set_min_bus_tput(&(sgx_dev.dev), OCP_INITIATOR_AGENT,800000); + } +} + +void remove_vdd2_constraint(void) +{ + if(pdata.set_min_bus_tput) + pdata.set_min_bus_tput(&(sgx_dev.dev), OCP_INITIATOR_AGENT, 0); + +} +#endif +#if !defined(PDUMP) && !defined(NO_HARDWARE) +static IMG_BOOL PowerLockWrappedOnCPU(SYS_SPECIFIC_DATA *psSysSpecData) +{ + IMG_INT iCPU; + IMG_BOOL bLocked = IMG_FALSE; + + if (!in_interrupt()) + { + iCPU = get_cpu(); + bLocked = (iCPU == atomic_read(&psSysSpecData->sPowerLockCPU)); + + put_cpu(); + } + + return bLocked; +} + +static IMG_VOID PowerLockWrap(SYS_SPECIFIC_DATA *psSysSpecData) +{ + IMG_INT iCPU; + + if (!in_interrupt()) + { + + iCPU = get_cpu(); + + + PVR_ASSERT(iCPU != -1); + + PVR_ASSERT(!PowerLockWrappedOnCPU(psSysSpecData)); + + spin_lock(&psSysSpecData->sPowerLock); + + atomic_set(&psSysSpecData->sPowerLockCPU, iCPU); + } +} + +static IMG_VOID PowerLockUnwrap(SYS_SPECIFIC_DATA *psSysSpecData) +{ + if (!in_interrupt()) + { + PVR_ASSERT(PowerLockWrappedOnCPU(psSysSpecData)); + + atomic_set(&psSysSpecData->sPowerLockCPU, -1); + + spin_unlock(&psSysSpecData->sPowerLock); + + put_cpu(); + } +} + +PVRSRV_ERROR SysPowerLockWrap(SYS_DATA *psSysData) +{ + SYS_SPECIFIC_DATA *psSysSpecData = (SYS_SPECIFIC_DATA *) psSysData->pvSysSpecificData; + + PowerLockWrap(psSysSpecData); + + return PVRSRV_OK; +} + +IMG_VOID SysPowerLockUnwrap(SYS_DATA *psSysData) +{ + SYS_SPECIFIC_DATA *psSysSpecData = (SYS_SPECIFIC_DATA *) psSysData->pvSysSpecificData; + + PowerLockUnwrap(psSysSpecData); +} +#else +static IMG_BOOL PowerLockWrappedOnCPU(SYS_SPECIFIC_DATA unref__ *psSysSpecData) +{ + return IMG_FALSE; +} + +static IMG_VOID PowerLockWrap(SYS_SPECIFIC_DATA unref__ *psSysSpecData) +{ +} + +static IMG_VOID PowerLockUnwrap(SYS_SPECIFIC_DATA unref__ *psSysSpecData) +{ +} + +PVRSRV_ERROR SysPowerLockWrap(SYS_DATA unref__ *psSysData) +{ + return PVRSRV_OK; +} + +IMG_VOID SysPowerLockUnwrap(SYS_DATA unref__ *psSysData) +{ +} +#endif + +IMG_BOOL WrapSystemPowerChange(SYS_SPECIFIC_DATA *psSysSpecData) +{ + IMG_BOOL bPowerLock = PowerLockWrappedOnCPU(psSysSpecData); + + if (bPowerLock) + { + PowerLockUnwrap(psSysSpecData); + } + + return bPowerLock; +} + +IMG_VOID UnwrapSystemPowerChange(SYS_SPECIFIC_DATA *psSysSpecData) +{ + PowerLockWrap(psSysSpecData); +} + +static inline IMG_UINT32 scale_by_rate(IMG_UINT32 val, IMG_UINT32 rate1, IMG_UINT32 rate2) +{ + if (rate1 >= rate2) + { + return val * (rate1 / rate2); + } + + return val / (rate2 / rate1); +} + +static inline IMG_UINT32 scale_prop_to_SGX_clock(IMG_UINT32 val, IMG_UINT32 rate) +{ + return scale_by_rate(val, rate, SYS_SGX_CLOCK_SPEED); +} + +static inline IMG_UINT32 scale_inv_prop_to_SGX_clock(IMG_UINT32 val, IMG_UINT32 rate) +{ + return scale_by_rate(val, SYS_SGX_CLOCK_SPEED, rate); +} + +IMG_VOID SysGetSGXTimingInformation(SGX_TIMING_INFORMATION *psTimingInfo) +{ + IMG_UINT32 rate; + +#if defined(NO_HARDWARE) + rate = SYS_SGX_CLOCK_SPEED; +#else + PVR_ASSERT(atomic_read(&gpsSysSpecificData->sSGXClocksEnabled) != 0); + + rate = clk_get_rate(gpsSysSpecificData->psSGX_FCK); + PVR_ASSERT(rate != 0); +#endif + psTimingInfo->ui32CoreClockSpeed = rate; + psTimingInfo->ui32HWRecoveryFreq = scale_prop_to_SGX_clock(SYS_SGX_HWRECOVERY_TIMEOUT_FREQ, rate); + psTimingInfo->ui32uKernelFreq = scale_prop_to_SGX_clock(SYS_SGX_PDS_TIMER_FREQ, rate); + psTimingInfo->ui32ActivePowManLatencyms = SYS_SGX_ACTIVE_POWER_LATENCY_MS; +} + +#if defined(CONSTRAINT_NOTIFICATIONS) +#if !defined(SGX_DYNAMIC_TIMING_INFO) +#error "SGX_DYNAMIC_TIMING_INFO must be defined for this platform" +#endif + +#if !defined(PDUMP) && !defined(NO_HARDWARE) +static inline IMG_BOOL ConstraintNotificationsEnabled(SYS_SPECIFIC_DATA *psSysSpecData) +{ + return (atomic_read(&psSysSpecData->sSGXClocksEnabled) != 0) && psSysSpecData->bSGXInitComplete && psSysSpecData->bConstraintNotificationsEnabled; + +} + +static IMG_BOOL NotifyLockedOnCPU(SYS_SPECIFIC_DATA *psSysSpecData) +{ + IMG_INT iCPU = get_cpu(); + IMG_BOOL bLocked = (iCPU == atomic_read(&psSysSpecData->sNotifyLockCPU)); + + put_cpu(); + + return bLocked; +} + +static IMG_VOID NotifyLock(SYS_SPECIFIC_DATA *psSysSpecData) +{ + IMG_INT iCPU; + + BUG_ON(in_interrupt()); + + + iCPU = get_cpu(); + + + PVR_ASSERT(iCPU != -1); + + PVR_ASSERT(!NotifyLockedOnCPU(psSysSpecData)); + + spin_lock(&psSysSpecData->sNotifyLock); + + atomic_set(&psSysSpecData->sNotifyLockCPU, iCPU); + +} + +static IMG_VOID NotifyUnlock(SYS_SPECIFIC_DATA *psSysSpecData) +{ + PVR_ASSERT(NotifyLockedOnCPU(psSysSpecData)); + + atomic_set(&psSysSpecData->sNotifyLockCPU, -1); + + spin_unlock(&psSysSpecData->sNotifyLock); + + put_cpu(); +} + +static IMG_INT VDD2PostFunc(struct notifier_block *n, IMG_UINT32 event, IMG_VOID *ptr) +{ + PVR_UNREFERENCED_PARAMETER(n); + PVR_UNREFERENCED_PARAMETER(event); + PVR_UNREFERENCED_PARAMETER(ptr); + + if (in_interrupt()) + { + PVR_DPF((PVR_DBG_ERROR, "%s Called in interrupt context. Ignoring.", __FUNCTION__)); + return 0; + } + + + if (!NotifyLockedOnCPU(gpsSysSpecificData)) + { + return 0; + } + +#if defined(DEBUG) + if (ConstraintNotificationsEnabled(gpsSysSpecificData)) + { + IMG_UINT32 rate; + + rate = clk_get_rate(gpsSysSpecificData->psSGX_FCK); + + PVR_ASSERT(rate != 0); + + PVR_DPF((PVR_DBG_MESSAGE, "%s: SGX clock rate: %dMHz", __FUNCTION__, HZ_TO_MHZ(rate))); + } +#endif + if (gpsSysSpecificData->bCallVDD2PostFunc) + { + PVRSRVDevicePostClockSpeedChange(gpsSysSpecificData->psSGXDevNode->sDevId.ui32DeviceIndex, IMG_TRUE, IMG_NULL); + + gpsSysSpecificData->bCallVDD2PostFunc = IMG_FALSE; + } + else + { + if (ConstraintNotificationsEnabled(gpsSysSpecificData)) + { + PVR_TRACE(("%s: Not calling PVR clock speed notification functions", __FUNCTION__)); + } + } + + NotifyUnlock(gpsSysSpecificData); + + return 0; +} + +static IMG_INT VDD2PreFunc(struct notifier_block *n, IMG_UINT32 event, IMG_VOID *ptr) +{ + PVR_UNREFERENCED_PARAMETER(n); + PVR_UNREFERENCED_PARAMETER(event); + PVR_UNREFERENCED_PARAMETER(ptr); + + if (in_interrupt()) + { + PVR_DPF((PVR_DBG_WARNING, "%s Called in interrupt context. Ignoring.", __FUNCTION__)); + return 0; + } + + if (PowerLockWrappedOnCPU(gpsSysSpecificData)) + { + PVR_DPF((PVR_DBG_WARNING, "%s Called from within a power transition. Ignoring.", __FUNCTION__)); + return 0; + } + + NotifyLock(gpsSysSpecificData); + + PVR_ASSERT(!gpsSysSpecificData->bCallVDD2PostFunc); + + if (ConstraintNotificationsEnabled(gpsSysSpecificData)) + { + PVRSRV_ERROR eError; + + eError = PVRSRVDevicePreClockSpeedChange(gpsSysSpecificData->psSGXDevNode->sDevId.ui32DeviceIndex, IMG_TRUE, IMG_NULL); + + gpsSysSpecificData->bCallVDD2PostFunc = (eError == PVRSRV_OK); + + } + + return 0; +} +static IMG_VOID RegisterConstraintNotifications(IMG_VOID) +{ + PVR_TRACE(("Registering constraint notifications")); + + PVR_ASSERT(!gpsSysSpecificData->bConstraintNotificationsEnabled); + + + NotifyLock(gpsSysSpecificData); + gpsSysSpecificData->bConstraintNotificationsEnabled = IMG_TRUE; + NotifyUnlock(gpsSysSpecificData); + + PVR_TRACE(("VDD2 constraint notifications registered")); +} + +static IMG_VOID UnRegisterConstraintNotifications(IMG_VOID) +{ + PVR_TRACE(("Unregistering constraint notifications")); + + + NotifyLock(gpsSysSpecificData); + gpsSysSpecificData->bConstraintNotificationsEnabled = IMG_FALSE; + NotifyUnlock(gpsSysSpecificData); + +} +#else +static IMG_VOID RegisterConstraintNotifications(IMG_VOID) +{ +} + +static IMG_VOID UnRegisterConstraintNotifications(IMG_VOID) +{ +} +#endif +#endif + +PVRSRV_ERROR EnableSGXClocks(SYS_DATA *psSysData) +{ +#if !defined(NO_HARDWARE) + SYS_SPECIFIC_DATA *psSysSpecData = (SYS_SPECIFIC_DATA *) psSysData->pvSysSpecificData; + long lNewRate; + IMG_INT res; + + + if (atomic_read(&psSysSpecData->sSGXClocksEnabled) != 0) + { + return PVRSRV_OK; + } + + PVR_DPF((PVR_DBG_MESSAGE, "EnableSGXClocks: Enabling SGX Clocks")); + + res = clk_enable(psSysSpecData->psSGX_FCK); + if (res < 0) + { + PVR_DPF((PVR_DBG_ERROR, "EnableSGXClocks: Couldn't enable SGX functional clock (%d)", res)); + return PVRSRV_ERROR_GENERIC; + } + +#if 0 + lNewRate = clk_round_rate(psSysSpecData->psSGX_FCK, SYS_SGX_CLOCK_SPEED + ONE_MHZ); + PVR_DPF((PVR_DBG_MESSAGE, "New SGXClocks: CPU Clock is %dMhz", HZ_TO_MHZ(lNewRate))); + //PVR_DPF((PVR_DBG_WARNING, "EnableSGXClocks: New SGX Func Clk = (%d)", lNewRate)); + if (lNewRate <= 0) + { + PVR_DPF((PVR_DBG_ERROR, "EnableSGXClocks: Couldn't round SGX functional clock rate")); + return PVRSRV_ERROR_GENERIC; + } + + res = clk_set_rate(psSysSpecData->psSGX_FCK, lNewRate); + if (res < 0) + { + PVR_DPF((PVR_DBG_ERROR, "EnableSGXClocks: Couldn't set SGX function clock rate (%d)", res)); + return PVRSRV_ERROR_GENERIC; + } +#endif +#if defined(DEBUG) + { + + IMG_UINT32 rate = clk_get_rate(psSysSpecData->psSGX_FCK); + PVR_DPF((PVR_DBG_MESSAGE, "EnableSGXClocks: SGX Functional Clock is %dMhz", HZ_TO_MHZ(rate))); + } +#endif + + set_vdd2_constraint(); + + lNewRate = clk_get_rate(psSysSpecData->psSGX_FCK); + atomic_set(&psSysSpecData->sSGXClocksEnabled, 1); + PVR_DPF((PVR_DBG_ERROR, "EnableSGXClocks: Final SGX Func Clk = (%d)", lNewRate)); +#else + PVR_UNREFERENCED_PARAMETER(psSysData); +#endif + return PVRSRV_OK; +} + + +IMG_VOID DisableSGXClocks(SYS_DATA *psSysData) +{ +#if !defined(NO_HARDWARE) + SYS_SPECIFIC_DATA *psSysSpecData = (SYS_SPECIFIC_DATA *) psSysData->pvSysSpecificData; + + if (atomic_read(&psSysSpecData->sSGXClocksEnabled) == 0) + { + return; + } + + PVR_DPF((PVR_DBG_MESSAGE, "DisableSGXClocks: Disabling SGX Clocks")); + + if (psSysSpecData->psSGX_FCK) + { + clk_disable(psSysSpecData->psSGX_FCK); + } + + remove_vdd2_constraint(); + + atomic_set(&psSysSpecData->sSGXClocksEnabled, 0); + +#else + PVR_UNREFERENCED_PARAMETER(psSysData); +#endif +} + +PVRSRV_ERROR EnableSystemClocks(SYS_DATA *psSysData) +{ + SYS_SPECIFIC_DATA *psSysSpecData = (SYS_SPECIFIC_DATA *) psSysData->pvSysSpecificData; + struct clk *psCLK; + IMG_INT res; + PVRSRV_ERROR eError; + IMG_BOOL bPowerLock; + +#if defined(DEBUG) || defined(TIMING) + IMG_INT rate; + struct clk *sys_ck; + IMG_CPU_PHYADDR TimerRegPhysBase; + IMG_HANDLE hTimerEnable; + IMG_UINT32 *pui32TimerEnable; + +#endif + + PVR_TRACE(("EnableSystemClocks: Enabling System Clocks")); + + if (!psSysSpecData->bSysClocksOneTimeInit) + { + bPowerLock = IMG_FALSE; + + spin_lock_init(&psSysSpecData->sPowerLock); + atomic_set(&psSysSpecData->sPowerLockCPU, -1); + spin_lock_init(&psSysSpecData->sNotifyLock); + atomic_set(&psSysSpecData->sNotifyLockCPU, -1); + + atomic_set(&psSysSpecData->sSGXClocksEnabled, 0); + + psCLK = clk_get(NULL, "sgx_ck"); + if (IS_ERR(psCLK)) + { + PVR_DPF((PVR_DBG_ERROR, "EnableSsystemClocks: Couldn't get SGX Functional Clock")); + goto ExitError; + } + psSysSpecData->psSGX_FCK = psCLK; + + psSysSpecData->bSysClocksOneTimeInit = IMG_TRUE; + } + else + { + + bPowerLock = PowerLockWrappedOnCPU(psSysSpecData); + if (bPowerLock) + { + PowerLockUnwrap(psSysSpecData); + } + } + +#if defined(CONSTRAINT_NOTIFICATIONS) + + RegisterConstraintNotifications(); +#endif + +#if defined(DEBUG) || defined(TIMING) + + psCLK = clk_get(NULL, "gpt7_fck"); + if (IS_ERR(psCLK)) + { + PVR_DPF((PVR_DBG_ERROR, "EnableSystemClocks: Couldn't get GPTIMER11 functional clock")); + goto ExitUnRegisterConstraintNotifications; + } + psSysSpecData->psGPT11_FCK = psCLK; + + psCLK = clk_get(NULL, "gpt7_ick"); + if (IS_ERR(psCLK)) + { + PVR_DPF((PVR_DBG_ERROR, "EnableSystemClocks: Couldn't get GPTIMER11 interface clock")); + goto ExitUnRegisterConstraintNotifications; + } + psSysSpecData->psGPT11_ICK = psCLK; + + rate = clk_get_rate(psSysSpecData->psGPT11_FCK); + PVR_TRACE(("GPTIMER11 clock is %dMHz", HZ_TO_MHZ(rate))); + + res = clk_enable(psSysSpecData->psGPT11_FCK); + if (res < 0) + { + PVR_DPF((PVR_DBG_ERROR, "EnableSystemClocks: Couldn't enable GPTIMER11 functional clock (%d)", res)); + goto ExitUnRegisterConstraintNotifications; + } + + res = clk_enable(psSysSpecData->psGPT11_ICK); + if (res < 0) + { + PVR_DPF((PVR_DBG_ERROR, "EnableSystemClocks: Couldn't enable GPTIMER11 interface clock (%d)", res)); + goto ExitDisableGPT11FCK; + } + + + TimerRegPhysBase.uiAddr = SYS_OMAP3430_GP11TIMER_TSICR_SYS_PHYS_BASE; + pui32TimerEnable = OSMapPhysToLin(TimerRegPhysBase, + 4, + PVRSRV_HAP_KERNEL_ONLY|PVRSRV_HAP_UNCACHED, + &hTimerEnable); + + if (pui32TimerEnable == IMG_NULL) + { + PVR_DPF((PVR_DBG_ERROR, "EnableSystemClocks: OSMapPhysToLin failed")); + goto ExitDisableGPT11ICK; + } + + rate = *pui32TimerEnable; + if(!(rate & 4)) + { + PVR_TRACE(("Setting GPTIMER11 mode to posted (currently is non-posted)")); + + + *pui32TimerEnable = rate | 4; + } + + OSUnMapPhysToLin(pui32TimerEnable, + 4, + PVRSRV_HAP_KERNEL_ONLY|PVRSRV_HAP_UNCACHED, + hTimerEnable); + + + TimerRegPhysBase.uiAddr = SYS_OMAP3430_GP11TIMER_ENABLE_SYS_PHYS_BASE; + pui32TimerEnable = OSMapPhysToLin(TimerRegPhysBase, + 4, + PVRSRV_HAP_KERNEL_ONLY|PVRSRV_HAP_UNCACHED, + &hTimerEnable); + + if (pui32TimerEnable == IMG_NULL) + { + PVR_DPF((PVR_DBG_ERROR, "EnableSystemClocks: OSMapPhysToLin failed")); + goto ExitDisableGPT11ICK; + } + + + *pui32TimerEnable = 3; + + OSUnMapPhysToLin(pui32TimerEnable, + 4, + PVRSRV_HAP_KERNEL_ONLY|PVRSRV_HAP_UNCACHED, + hTimerEnable); + +#endif + + eError = PVRSRV_OK; + goto Exit; + +#if defined(DEBUG) || defined(TIMING) +ExitDisableGPT11ICK: + clk_disable(psSysSpecData->psGPT11_ICK); +ExitDisableGPT11FCK: + clk_disable(psSysSpecData->psGPT11_FCK); +ExitUnRegisterConstraintNotifications: +#endif +#if defined(CONSTRAINT_NOTIFICATIONS) + UnRegisterConstraintNotifications(); + +#endif +ExitError: + eError = PVRSRV_ERROR_GENERIC; +Exit: + if (bPowerLock) + { + PowerLockWrap(psSysSpecData); + } + +#if !defined(SUPPORT_ACTIVE_POWER_MANAGEMENT) + if (eError == PVRSRV_OK) + { + + eError = EnableSGXClocks(psSysData); + } +#endif + return eError; +} + +IMG_VOID DisableSystemClocks(SYS_DATA *psSysData) +{ + SYS_SPECIFIC_DATA *psSysSpecData = (SYS_SPECIFIC_DATA *) psSysData->pvSysSpecificData; + IMG_BOOL bPowerLock; +#if defined(DEBUG) || defined(TIMING) + IMG_CPU_PHYADDR TimerRegPhysBase; + IMG_HANDLE hTimerDisable; + IMG_UINT32 *pui32TimerDisable; +#endif + + PVR_TRACE(("DisableSystemClocks: Disabling System Clocks")); + + DisableSGXClocks(psSysData); + + bPowerLock = PowerLockWrappedOnCPU(psSysSpecData); + if (bPowerLock) + { + + PowerLockUnwrap(psSysSpecData); + } + +#if defined(CONSTRAINT_NOTIFICATIONS) + UnRegisterConstraintNotifications(); +#endif + +#if defined(DEBUG) || defined(TIMING) + + TimerRegPhysBase.uiAddr = SYS_OMAP3430_GP11TIMER_ENABLE_SYS_PHYS_BASE; + pui32TimerDisable = OSMapPhysToLin(TimerRegPhysBase, + 4, + PVRSRV_HAP_KERNEL_ONLY|PVRSRV_HAP_UNCACHED, + &hTimerDisable); + + if (pui32TimerDisable == IMG_NULL) + { + PVR_DPF((PVR_DBG_ERROR, "DisableSystemClocks: OSMapPhysToLin failed")); + } + else + { + *pui32TimerDisable = 0; + + OSUnMapPhysToLin(pui32TimerDisable, + 4, + PVRSRV_HAP_KERNEL_ONLY|PVRSRV_HAP_UNCACHED, + hTimerDisable); + } + + clk_disable(psSysSpecData->psGPT11_ICK); + + clk_disable(psSysSpecData->psGPT11_FCK); + +#endif + if (bPowerLock) + { + PowerLockWrap(psSysSpecData); + } +} diff --git a/tools/intern/debug/client/linuxsrv.h b/tools/intern/debug/client/linuxsrv.h new file mode 100644 index 0000000..adfcd75 --- /dev/null +++ b/tools/intern/debug/client/linuxsrv.h @@ -0,0 +1,48 @@ +/********************************************************************** + * + * Copyright(c) 2008 Imagination Technologies Ltd. All rights reserved. + * + * This program is free software; you can redistribute it and/or modify it + * under the terms and conditions of the GNU General Public License, + * version 2, as published by the Free Software Foundation. + * + * This program is distributed in the hope it will be useful but, except + * as otherwise stated in writing, without any warranty; without even the + * implied warranty of merchantability or fitness for a particular purpose. + * See the GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License along with + * this program; if not, write to the Free Software Foundation, Inc., + * 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA. + * + * The full GNU General Public License is included in this distribution in + * the file called "COPYING". + * + * Contact Information: + * Imagination Technologies Ltd. + * Home Park Estate, Kings Langley, Herts, WD4 8LZ, UK + * + ******************************************************************************/ + +#ifndef _LINUXSRV_H__ +#define _LINUXSRV_H__ + +typedef struct tagIOCTL_PACKAGE +{ + IMG_UINT32 ui32Cmd; + IMG_UINT32 ui32Size; + IMG_VOID *pInBuffer; + IMG_UINT32 ui32InBufferSize; + IMG_VOID *pOutBuffer; + IMG_UINT32 ui32OutBufferSize; +} IOCTL_PACKAGE; + +IMG_UINT32 DeviceIoControl(IMG_UINT32 hDevice, + IMG_UINT32 ui32ControlCode, + IMG_VOID *pInBuffer, + IMG_UINT32 ui32InBufferSize, + IMG_VOID *pOutBuffer, + IMG_UINT32 ui32OutBufferSize, + IMG_UINT32 *pui32BytesReturned); + +#endif diff --git a/tools/intern/debug/dbgdriv/common/dbgdriv.c b/tools/intern/debug/dbgdriv/common/dbgdriv.c new file mode 100644 index 0000000..f8f3bdb --- /dev/null +++ b/tools/intern/debug/dbgdriv/common/dbgdriv.c @@ -0,0 +1,2075 @@ +/********************************************************************** + * + * Copyright(c) 2008 Imagination Technologies Ltd. All rights reserved. + * + * This program is free software; you can redistribute it and/or modify it + * under the terms and conditions of the GNU General Public License, + * version 2, as published by the Free Software Foundation. + * + * This program is distributed in the hope it will be useful but, except + * as otherwise stated in writing, without any warranty; without even the + * implied warranty of merchantability or fitness for a particular purpose. + * See the GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License along with + * this program; if not, write to the Free Software Foundation, Inc., + * 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA. + * + * The full GNU General Public License is included in this distribution in + * the file called "COPYING". + * + * Contact Information: + * Imagination Technologies Ltd. + * Home Park Estate, Kings Langley, Herts, WD4 8LZ, UK + * + ******************************************************************************/ + + +#ifdef LINUX +#include +#endif + +#include "img_types.h" +#include "pvr_debug.h" +#include "dbgdrvif.h" +#include "dbgdriv.h" +#include "hotkey.h" +#include "hostfunc.h" + + + + +#define LAST_FRAME_BUF_SIZE 1024 + +typedef struct _DBG_LASTFRAME_BUFFER_ +{ + PDBG_STREAM psStream; + IMG_UINT8 ui8Buffer[LAST_FRAME_BUF_SIZE]; + IMG_UINT32 ui32BufLen; + struct _DBG_LASTFRAME_BUFFER_ *psNext; +} DBG_LASTFRAME_BUFFER, *PDBG_LASTFRAME_BUFFER; + + +static PDBG_STREAM g_psStreamList = 0; +static PDBG_LASTFRAME_BUFFER g_psLFBufferList; + +static IMG_UINT32 g_ui32LOff = 0; +static IMG_UINT32 g_ui32Line = 0; +static IMG_UINT32 g_ui32MonoLines = 25; + +static IMG_BOOL g_bHotkeyMiddump = IMG_FALSE; +static IMG_UINT32 g_ui32HotkeyMiddumpStart = 0xffffffff; +static IMG_UINT32 g_ui32HotkeyMiddumpEnd = 0xffffffff; + +IMG_VOID * g_pvAPIMutex=IMG_NULL; + +extern IMG_UINT32 g_ui32HotKeyFrame; +extern IMG_BOOL g_bHotKeyPressed; +extern IMG_BOOL g_bHotKeyRegistered; + +IMG_BOOL gbDumpThisFrame = IMG_FALSE; + + +IMG_UINT32 SpaceInStream(PDBG_STREAM psStream); +IMG_BOOL ExpandStreamBuffer(PDBG_STREAM psStream, IMG_UINT32 ui32NewSize); +PDBG_LASTFRAME_BUFFER FindLFBuf(PDBG_STREAM psStream); + +DBGKM_SERVICE_TABLE g_sDBGKMServices = +{ + sizeof (DBGKM_SERVICE_TABLE), + ExtDBGDrivCreateStream, + ExtDBGDrivDestroyStream, + ExtDBGDrivFindStream, + ExtDBGDrivWriteString, + ExtDBGDrivReadString, + ExtDBGDrivWrite, + ExtDBGDrivRead, + ExtDBGDrivSetCaptureMode, + ExtDBGDrivSetOutputMode, + ExtDBGDrivSetDebugLevel, + ExtDBGDrivSetFrame, + ExtDBGDrivGetFrame, + ExtDBGDrivOverrideMode, + ExtDBGDrivDefaultMode, + ExtDBGDrivWrite2, + ExtDBGDrivWriteStringCM, + ExtDBGDrivWriteCM, + ExtDBGDrivSetMarker, + ExtDBGDrivGetMarker, + ExtDBGDrivStartInitPhase, + ExtDBGDrivStopInitPhase, + ExtDBGDrivIsCaptureFrame, + ExtDBGDrivWriteLF, + ExtDBGDrivReadLF, + ExtDBGDrivGetStreamOffset, + ExtDBGDrivSetStreamOffset, + ExtDBGDrivIsLastCaptureFrame, + ExtDBGDrivWaitForEvent +}; + + + + + +IMG_VOID * IMG_CALLCONV ExtDBGDrivCreateStream(IMG_CHAR * pszName, IMG_UINT32 ui32CapMode, IMG_UINT32 ui32OutMode, IMG_UINT32 ui32Flags, IMG_UINT32 ui32Size) +{ + IMG_VOID * pvRet; + + + HostAquireMutex(g_pvAPIMutex); + + pvRet=DBGDrivCreateStream(pszName, ui32CapMode, ui32OutMode, ui32Flags, ui32Size); + + + HostReleaseMutex(g_pvAPIMutex); + + return pvRet; +} + +void IMG_CALLCONV ExtDBGDrivDestroyStream(PDBG_STREAM psStream) +{ + + HostAquireMutex(g_pvAPIMutex); + + DBGDrivDestroyStream(psStream); + + + HostReleaseMutex(g_pvAPIMutex); + + return; +} + +IMG_VOID * IMG_CALLCONV ExtDBGDrivFindStream(IMG_CHAR * pszName, IMG_BOOL bResetStream) +{ + IMG_VOID * pvRet; + + + HostAquireMutex(g_pvAPIMutex); + + pvRet=DBGDrivFindStream(pszName, bResetStream); + + + HostReleaseMutex(g_pvAPIMutex); + + return pvRet; +} + +IMG_UINT32 IMG_CALLCONV ExtDBGDrivWriteString(PDBG_STREAM psStream,IMG_CHAR * pszString,IMG_UINT32 ui32Level) +{ + IMG_UINT32 ui32Ret; + + + HostAquireMutex(g_pvAPIMutex); + + ui32Ret=DBGDrivWriteString(psStream, pszString, ui32Level); + + + HostReleaseMutex(g_pvAPIMutex); + + return ui32Ret; +} + +IMG_UINT32 IMG_CALLCONV ExtDBGDrivReadString(PDBG_STREAM psStream,IMG_CHAR * pszString,IMG_UINT32 ui32Limit) +{ + IMG_UINT32 ui32Ret; + + + HostAquireMutex(g_pvAPIMutex); + + ui32Ret=DBGDrivReadString(psStream, pszString, ui32Limit); + + + HostReleaseMutex(g_pvAPIMutex); + + return ui32Ret; +} + +IMG_UINT32 IMG_CALLCONV ExtDBGDrivWrite(PDBG_STREAM psStream,IMG_UINT8 * pui8InBuf,IMG_UINT32 ui32InBuffSize,IMG_UINT32 ui32Level) +{ + IMG_UINT32 ui32Ret; + + + HostAquireMutex(g_pvAPIMutex); + + ui32Ret=DBGDrivWrite(psStream, pui8InBuf, ui32InBuffSize, ui32Level); + + + HostReleaseMutex(g_pvAPIMutex); + + return ui32Ret; +} + +IMG_UINT32 IMG_CALLCONV ExtDBGDrivRead(PDBG_STREAM psStream, IMG_BOOL bReadInitBuffer, IMG_UINT32 ui32OutBuffSize,IMG_UINT8 * pui8OutBuf) +{ + IMG_UINT32 ui32Ret; + + + HostAquireMutex(g_pvAPIMutex); + + ui32Ret=DBGDrivRead(psStream, bReadInitBuffer, ui32OutBuffSize, pui8OutBuf); + + + HostReleaseMutex(g_pvAPIMutex); + + return ui32Ret; +} + +void IMG_CALLCONV ExtDBGDrivSetCaptureMode(PDBG_STREAM psStream,IMG_UINT32 ui32Mode,IMG_UINT32 ui32Start,IMG_UINT32 ui32End,IMG_UINT32 ui32SampleRate) +{ + + HostAquireMutex(g_pvAPIMutex); + + DBGDrivSetCaptureMode(psStream, ui32Mode, ui32Start, ui32End, ui32SampleRate); + + + HostReleaseMutex(g_pvAPIMutex); + + return; +} + +void IMG_CALLCONV ExtDBGDrivSetOutputMode(PDBG_STREAM psStream,IMG_UINT32 ui32OutMode) +{ + + HostAquireMutex(g_pvAPIMutex); + + DBGDrivSetOutputMode(psStream, ui32OutMode); + + + HostReleaseMutex(g_pvAPIMutex); + + return; +} + +void IMG_CALLCONV ExtDBGDrivSetDebugLevel(PDBG_STREAM psStream,IMG_UINT32 ui32DebugLevel) +{ + + HostAquireMutex(g_pvAPIMutex); + + DBGDrivSetDebugLevel(psStream, ui32DebugLevel); + + + HostReleaseMutex(g_pvAPIMutex); + + return; +} + +void IMG_CALLCONV ExtDBGDrivSetFrame(PDBG_STREAM psStream,IMG_UINT32 ui32Frame) +{ + + HostAquireMutex(g_pvAPIMutex); + + DBGDrivSetFrame(psStream, ui32Frame); + + + HostReleaseMutex(g_pvAPIMutex); + + return; +} + +IMG_UINT32 IMG_CALLCONV ExtDBGDrivGetFrame(PDBG_STREAM psStream) +{ + IMG_UINT32 ui32Ret; + + + HostAquireMutex(g_pvAPIMutex); + + ui32Ret=DBGDrivGetFrame(psStream); + + + HostReleaseMutex(g_pvAPIMutex); + + return ui32Ret; +} + +IMG_UINT32 IMG_CALLCONV ExtDBGDrivIsLastCaptureFrame(PDBG_STREAM psStream) +{ + IMG_UINT32 ui32Ret; + + + HostAquireMutex(g_pvAPIMutex); + + ui32Ret = DBGDrivIsLastCaptureFrame(psStream); + + + HostReleaseMutex(g_pvAPIMutex); + + return ui32Ret; +} + +IMG_UINT32 IMG_CALLCONV ExtDBGDrivIsCaptureFrame(PDBG_STREAM psStream, IMG_BOOL bCheckPreviousFrame) +{ + IMG_UINT32 ui32Ret; + + + HostAquireMutex(g_pvAPIMutex); + + ui32Ret = DBGDrivIsCaptureFrame(psStream, bCheckPreviousFrame); + + + HostReleaseMutex(g_pvAPIMutex); + + return ui32Ret; +} + +void IMG_CALLCONV ExtDBGDrivOverrideMode(PDBG_STREAM psStream,IMG_UINT32 ui32Mode) +{ + + HostAquireMutex(g_pvAPIMutex); + + DBGDrivOverrideMode(psStream, ui32Mode); + + + HostReleaseMutex(g_pvAPIMutex); + + return; +} + +void IMG_CALLCONV ExtDBGDrivDefaultMode(PDBG_STREAM psStream) +{ + + HostAquireMutex(g_pvAPIMutex); + + DBGDrivDefaultMode(psStream); + + + HostReleaseMutex(g_pvAPIMutex); + + return; +} + +IMG_UINT32 IMG_CALLCONV ExtDBGDrivWrite2(PDBG_STREAM psStream,IMG_UINT8 * pui8InBuf,IMG_UINT32 ui32InBuffSize,IMG_UINT32 ui32Level) +{ + IMG_UINT32 ui32Ret; + + + HostAquireMutex(g_pvAPIMutex); + + ui32Ret=DBGDrivWrite2(psStream, pui8InBuf, ui32InBuffSize, ui32Level); + + + HostReleaseMutex(g_pvAPIMutex); + + return ui32Ret; +} + +IMG_UINT32 IMG_CALLCONV ExtDBGDrivWriteStringCM(PDBG_STREAM psStream,IMG_CHAR * pszString,IMG_UINT32 ui32Level) +{ + IMG_UINT32 ui32Ret; + + + HostAquireMutex(g_pvAPIMutex); + + ui32Ret=DBGDrivWriteStringCM(psStream, pszString, ui32Level); + + + HostReleaseMutex(g_pvAPIMutex); + + return ui32Ret; +} + +IMG_UINT32 IMG_CALLCONV ExtDBGDrivWriteCM(PDBG_STREAM psStream,IMG_UINT8 * pui8InBuf,IMG_UINT32 ui32InBuffSize,IMG_UINT32 ui32Level) +{ + IMG_UINT32 ui32Ret; + + + HostAquireMutex(g_pvAPIMutex); + + ui32Ret=DBGDrivWriteCM(psStream, pui8InBuf, ui32InBuffSize, ui32Level); + + + HostReleaseMutex(g_pvAPIMutex); + + return ui32Ret; +} + +void IMG_CALLCONV ExtDBGDrivSetMarker(PDBG_STREAM psStream, IMG_UINT32 ui32Marker) +{ + + HostAquireMutex(g_pvAPIMutex); + + DBGDrivSetMarker(psStream, ui32Marker); + + + HostReleaseMutex(g_pvAPIMutex); + + return; +} + +IMG_UINT32 IMG_CALLCONV ExtDBGDrivGetMarker(PDBG_STREAM psStream) +{ + IMG_UINT32 ui32Marker; + + + HostAquireMutex(g_pvAPIMutex); + + ui32Marker = DBGDrivGetMarker(psStream); + + + HostReleaseMutex(g_pvAPIMutex); + + return ui32Marker; +} + +IMG_UINT32 IMG_CALLCONV ExtDBGDrivWriteLF(PDBG_STREAM psStream, IMG_UINT8 * pui8InBuf, IMG_UINT32 ui32InBuffSize, IMG_UINT32 ui32Level, IMG_UINT32 ui32Flags) +{ + IMG_UINT32 ui32Ret; + + + HostAquireMutex(g_pvAPIMutex); + + ui32Ret = DBGDrivWriteLF(psStream, pui8InBuf, ui32InBuffSize, ui32Level, ui32Flags); + + + HostReleaseMutex(g_pvAPIMutex); + + return ui32Ret; +} + +IMG_UINT32 IMG_CALLCONV ExtDBGDrivReadLF(PDBG_STREAM psStream, IMG_UINT32 ui32OutBuffSize, IMG_UINT8 * pui8OutBuf) +{ + IMG_UINT32 ui32Ret; + + + HostAquireMutex(g_pvAPIMutex); + + ui32Ret = DBGDrivReadLF(psStream, ui32OutBuffSize, pui8OutBuf); + + + HostReleaseMutex(g_pvAPIMutex); + + return ui32Ret; +} + + +IMG_VOID IMG_CALLCONV ExtDBGDrivStartInitPhase(PDBG_STREAM psStream) +{ + + HostAquireMutex(g_pvAPIMutex); + + DBGDrivStartInitPhase(psStream); + + + HostReleaseMutex(g_pvAPIMutex); + + return; +} + +IMG_VOID IMG_CALLCONV ExtDBGDrivStopInitPhase(PDBG_STREAM psStream) +{ + + HostAquireMutex(g_pvAPIMutex); + + DBGDrivStopInitPhase(psStream); + + + HostReleaseMutex(g_pvAPIMutex); + + return; +} + +IMG_UINT32 IMG_CALLCONV ExtDBGDrivGetStreamOffset(PDBG_STREAM psStream) +{ + IMG_UINT32 ui32Ret; + + + HostAquireMutex(g_pvAPIMutex); + + ui32Ret = DBGDrivGetStreamOffset(psStream); + + + HostReleaseMutex(g_pvAPIMutex); + + return ui32Ret; +} + +IMG_VOID IMG_CALLCONV ExtDBGDrivSetStreamOffset(PDBG_STREAM psStream, IMG_UINT32 ui32StreamOffset) +{ + + HostAquireMutex(g_pvAPIMutex); + + DBGDrivSetStreamOffset(psStream, ui32StreamOffset); + + + HostReleaseMutex(g_pvAPIMutex); +} + +IMG_VOID IMG_CALLCONV ExtDBGDrivWaitForEvent(DBG_EVENT eEvent) +{ +#if defined(SUPPORT_DBGDRV_EVENT_OBJECTS) + DBGDrivWaitForEvent(eEvent); +#else + PVR_UNREFERENCED_PARAMETER(eEvent); +#endif +} + +IMG_UINT32 AtoI(char *szIn) +{ + IMG_UINT32 ui32Len = 0; + IMG_UINT32 ui32Value = 0; + IMG_UINT32 ui32Digit=1; + IMG_UINT32 ui32Base=10; + int iPos; + char bc; + + + while (szIn[ui32Len] > 0) + { + ui32Len ++; + } + + + if (ui32Len == 0) + { + return (0); + } + + + iPos=0; + while (szIn[iPos] == '0') + { + iPos++; + } + if (szIn[iPos] == '\0') + { + return 0; + } + if (szIn[iPos] == 'x' || szIn[iPos] == 'X') + { + ui32Base=16; + szIn[iPos]='0'; + } + + + for (iPos = ui32Len - 1; iPos >= 0; iPos --) + { + bc = szIn[iPos]; + + if ( (bc >= 'a') && (bc <= 'f') && ui32Base == 16) + { + bc -= 'a' - 0xa; + } + else + if ( (bc >= 'A') && (bc <= 'F') && ui32Base == 16) + { + bc -= 'A' - 0xa; + } + else + if ((bc >= '0') && (bc <= '9')) + { + bc -= '0'; + } + else + return (0); + + ui32Value += bc * ui32Digit; + + ui32Digit = ui32Digit * ui32Base; + } + return (ui32Value); +} + + +IMG_BOOL StreamValid(PDBG_STREAM psStream) +{ + PDBG_STREAM psThis; + + psThis = g_psStreamList; + + while (psThis) + { + if (psStream && (psThis == psStream)) + { + return(IMG_TRUE); + } + else + { + psThis = psThis->psNext; + } + } + + return(IMG_FALSE); +} + + +void Write(PDBG_STREAM psStream,IMG_UINT8 * pui8Data,IMG_UINT32 ui32InBuffSize) +{ + + + if ((psStream->ui32WPtr + ui32InBuffSize) > psStream->ui32Size) + { + IMG_UINT32 ui32B1 = psStream->ui32Size - psStream->ui32WPtr; + IMG_UINT32 ui32B2 = ui32InBuffSize - ui32B1; + + + HostMemCopy((IMG_VOID *)(psStream->ui32Base + psStream->ui32WPtr), + (IMG_VOID *) pui8Data, + ui32B1); + + + HostMemCopy((IMG_VOID *)psStream->ui32Base, + (IMG_VOID *)((IMG_UINT32) pui8Data + ui32B1), + ui32B2); + + + psStream->ui32WPtr = ui32B2; + } + else + { + HostMemCopy((IMG_VOID *)(psStream->ui32Base + psStream->ui32WPtr), + (IMG_VOID *) pui8Data, + ui32InBuffSize); + + psStream->ui32WPtr += ui32InBuffSize; + + if (psStream->ui32WPtr == psStream->ui32Size) + { + psStream->ui32WPtr = 0; + } + } + psStream->ui32DataWritten += ui32InBuffSize; +} + + +void MonoOut(IMG_CHAR * pszString,IMG_BOOL bNewLine) +{ + IMG_UINT32 i; + IMG_CHAR * pScreen; + + pScreen = (char *) DBGDRIV_MONOBASE; + + pScreen += g_ui32Line * 160; + + + + i=0; + do + { + pScreen[g_ui32LOff + (i*2)] = pszString[i]; + pScreen[g_ui32LOff + (i*2)+1] = 127; + i++; + } + while ((pszString[i] != 0) && (i < 4096)); + + g_ui32LOff += i * 2; + + if (bNewLine) + { + g_ui32LOff = 0; + g_ui32Line++; + } + + + + if (g_ui32Line == g_ui32MonoLines) + { + g_ui32Line = g_ui32MonoLines - 1; + + HostMemCopy((IMG_VOID *)DBGDRIV_MONOBASE,(IMG_VOID *)(DBGDRIV_MONOBASE + 160),160 * (g_ui32MonoLines - 1)); + + HostMemSet((IMG_VOID *)(DBGDRIV_MONOBASE + (160 * (g_ui32MonoLines - 1))),0,160); + } +} + + + +void AppendName(IMG_CHAR * pszOut,IMG_CHAR * pszBase,IMG_CHAR * pszName) +{ + IMG_UINT32 i; + IMG_UINT32 ui32Off; + + i = 0; + + while (pszBase[i] != 0) + { + pszOut[i] = pszBase[i]; + i++; + } + + ui32Off = i; + i = 0; + + while (pszName[i] != 0) + { + pszOut[ui32Off+i] = pszName[i]; + i++; + } + + pszOut[ui32Off+i] = pszName[i]; +} + + +IMG_VOID * IMG_CALLCONV DBGDrivCreateStream(IMG_CHAR * pszName, + IMG_UINT32 ui32CapMode, + IMG_UINT32 ui32OutMode, + IMG_UINT32 ui32Flags, + IMG_UINT32 ui32Size) +{ + PDBG_STREAM psStream; + PDBG_STREAM psInitStream; + PDBG_LASTFRAME_BUFFER psLFBuffer; + IMG_UINT32 ui32Off; + IMG_VOID * pvBase; + + + + + psStream = (PDBG_STREAM) DBGDrivFindStream(pszName, IMG_FALSE); + + if (psStream) + { + return ((IMG_VOID *) psStream); + } + + + + psStream = HostNonPageablePageAlloc(1); + psInitStream = HostNonPageablePageAlloc(1); + psLFBuffer = HostNonPageablePageAlloc(1); + if ( + (!psStream) || + (!psInitStream) || + (!psLFBuffer) + ) + { + PVR_DPF((PVR_DBG_ERROR,"DBGDriv: Couldn't create buffer !!!!!\n\r")); + return((IMG_VOID *) 0); + } + + + if ((ui32Flags & DEBUG_FLAGS_USE_NONPAGED_MEM) != 0) + { + pvBase = HostNonPageablePageAlloc(ui32Size); + } + else + { + pvBase = HostPageablePageAlloc(ui32Size); + } + + if (!pvBase) + { + PVR_DPF((PVR_DBG_ERROR,"DBGDriv: Couldn't create buffer !!!!!\n\r")); + HostNonPageablePageFree(psStream); + return((IMG_VOID *) 0); + } + + + + psStream->psNext = 0; + psStream->ui32Flags = ui32Flags; + psStream->ui32Base = (IMG_UINT32)pvBase; + psStream->ui32Size = ui32Size * 4096; + psStream->ui32RPtr = 0; + psStream->ui32WPtr = 0; + psStream->ui32DataWritten = 0; + psStream->ui32CapMode = ui32CapMode; + psStream->ui32OutMode = ui32OutMode; + psStream->ui32DebugLevel = DEBUG_LEVEL_0; + psStream->ui32DefaultMode = ui32CapMode; + psStream->ui32Start = 0; + psStream->ui32End = 0; + psStream->ui32Current = 0; + psStream->ui32SampleRate = 1; + psStream->ui32Access = 0; + psStream->ui32Timeout = 0; + psStream->ui32Marker = 0; + psStream->bInitPhaseComplete = IMG_FALSE; + + + if ((ui32Flags & DEBUG_FLAGS_USE_NONPAGED_MEM) != 0) + { + pvBase = HostNonPageablePageAlloc(ui32Size); + } + else + { + pvBase = HostPageablePageAlloc(ui32Size); + } + + if (!pvBase) + { + PVR_DPF((PVR_DBG_ERROR,"DBGDriv: Couldn't create buffer !!!!!\n\r")); + + if ((psStream->ui32Flags & DEBUG_FLAGS_USE_NONPAGED_MEM) != 0) + { + HostNonPageablePageFree((IMG_VOID *)psStream->ui32Base); + } + else + { + HostPageablePageFree((IMG_VOID *)psStream->ui32Base); + } + HostNonPageablePageFree(psStream); + return((IMG_VOID *) 0); + } + + psInitStream->psNext = 0; + psInitStream->ui32Flags = ui32Flags; + psInitStream->ui32Base = (IMG_UINT32)pvBase; + psInitStream->ui32Size = ui32Size * 4096; + psInitStream->ui32RPtr = 0; + psInitStream->ui32WPtr = 0; + psInitStream->ui32DataWritten = 0; + psInitStream->ui32CapMode = ui32CapMode; + psInitStream->ui32OutMode = ui32OutMode; + psInitStream->ui32DebugLevel = DEBUG_LEVEL_0; + psInitStream->ui32DefaultMode = ui32CapMode; + psInitStream->ui32Start = 0; + psInitStream->ui32End = 0; + psInitStream->ui32Current = 0; + psInitStream->ui32SampleRate = 1; + psInitStream->ui32Access = 0; + psInitStream->ui32Timeout = 0; + psInitStream->ui32Marker = 0; + psInitStream->bInitPhaseComplete = IMG_FALSE; + + psStream->psInitStream = psInitStream; + + + psLFBuffer->psStream = psStream; + psLFBuffer->ui32BufLen = 0; + + g_bHotkeyMiddump = IMG_FALSE; + g_ui32HotkeyMiddumpStart = 0xffffffff; + g_ui32HotkeyMiddumpEnd = 0xffffffff; + + + + ui32Off = 0; + + do + { + psStream->szName[ui32Off] = pszName[ui32Off]; + + ui32Off++; + } + while ((pszName[ui32Off] != 0) && (ui32Off < (4096 - sizeof(DBG_STREAM)))); + + psStream->szName[ui32Off] = pszName[ui32Off]; + + + + psStream->psNext = g_psStreamList; + g_psStreamList = psStream; + + psLFBuffer->psNext = g_psLFBufferList; + g_psLFBufferList = psLFBuffer; + + + return((IMG_VOID *) psStream); +} + +void IMG_CALLCONV DBGDrivDestroyStream(PDBG_STREAM psStream) +{ + PDBG_STREAM psStreamThis; + PDBG_STREAM psStreamPrev; + PDBG_LASTFRAME_BUFFER psLFBuffer; + PDBG_LASTFRAME_BUFFER psLFThis; + PDBG_LASTFRAME_BUFFER psLFPrev; + + PVR_DPF((PVR_DBG_MESSAGE, "DBGDriv: Destroying stream %s\r\n", psStream->szName )); + + + + if (!StreamValid(psStream)) + { + return; + } + + psLFBuffer = FindLFBuf(psStream); + + + + psStreamThis = g_psStreamList; + psStreamPrev = 0; + + while (psStreamThis) + { + if (psStreamThis == psStream) + { + if (psStreamPrev) + { + psStreamPrev->psNext = psStreamThis->psNext; + } + else + { + g_psStreamList = psStreamThis->psNext; + } + + psStreamThis = 0; + } + else + { + psStreamPrev = psStreamThis; + psStreamThis = psStreamThis->psNext; + } + } + + psLFThis = g_psLFBufferList; + psLFPrev = 0; + + while (psLFThis) + { + if (psLFThis == psLFBuffer) + { + if (psLFPrev) + { + psLFPrev->psNext = psLFThis->psNext; + } + else + { + g_psLFBufferList = psLFThis->psNext; + } + + psLFThis = 0; + } + else + { + psLFPrev = psLFThis; + psLFThis = psLFThis->psNext; + } + } + + + if (psStream->ui32CapMode & DEBUG_CAPMODE_HOTKEY) + { + DeactivateHotKeys(); + } + + + + if ((psStream->ui32Flags & DEBUG_FLAGS_USE_NONPAGED_MEM) != 0) + { + HostNonPageablePageFree((IMG_VOID *)psStream->ui32Base); + HostNonPageablePageFree((IMG_VOID *)psStream->psInitStream->ui32Base); + } + else + { + HostPageablePageFree((IMG_VOID *)psStream->ui32Base); + HostPageablePageFree((IMG_VOID *)psStream->psInitStream->ui32Base); + } + + HostNonPageablePageFree(psStream->psInitStream); + HostNonPageablePageFree(psStream); + HostNonPageablePageFree(psLFBuffer); + + if (g_psStreamList == 0) + { + PVR_DPF((PVR_DBG_MESSAGE,"DBGDriv: Stream list now empty" )); + } + + return; +} + +IMG_VOID * IMG_CALLCONV DBGDrivFindStream(IMG_CHAR * pszName, IMG_BOOL bResetStream) +{ + PDBG_STREAM psStream; + PDBG_STREAM psThis; + IMG_UINT32 ui32Off; + IMG_BOOL bAreSame; + + psStream = 0; + + + + for (psThis = g_psStreamList; psThis != IMG_NULL; psThis = psThis->psNext) + { + bAreSame = IMG_TRUE; + ui32Off = 0; + + if (strlen(psThis->szName) == strlen(pszName)) + { + while ((psThis->szName[ui32Off] != 0) && (pszName[ui32Off] != 0) && (ui32Off < 128) && bAreSame) + { + if (psThis->szName[ui32Off] != pszName[ui32Off]) + { + bAreSame = IMG_FALSE; + } + + ui32Off++; + } + } + else + { + bAreSame = IMG_FALSE; + } + + if (bAreSame) + { + psStream = psThis; + break; + } + } + + if(bResetStream && psStream) + { + static char szComment[] = "-- Init phase terminated\r\n"; + psStream->psInitStream->ui32RPtr = 0; + psStream->ui32RPtr = 0; + psStream->ui32WPtr = 0; + psStream->ui32DataWritten = psStream->psInitStream->ui32DataWritten; + if (psStream->bInitPhaseComplete == IMG_FALSE) + { + if (psStream->ui32Flags & DEBUG_FLAGS_TEXTSTREAM) + { + DBGDrivWrite2(psStream, (IMG_UINT8 *)szComment, sizeof(szComment) - 1, 0x01); + } + psStream->bInitPhaseComplete = IMG_TRUE; + } + } + + return((IMG_VOID *) psStream); +} + +IMG_UINT32 IMG_CALLCONV DBGDrivWriteStringCM(PDBG_STREAM psStream,IMG_CHAR * pszString,IMG_UINT32 ui32Level) +{ + + + if (!StreamValid(psStream)) + { + return(0xFFFFFFFF); + } + + + + if (psStream->ui32CapMode & DEBUG_CAPMODE_FRAMED) + { + if (!(psStream->ui32Flags & DEBUG_FLAGS_ENABLESAMPLE)) + { + return(0); + } + } + else + { + if (psStream->ui32CapMode == DEBUG_CAPMODE_HOTKEY) + { + if ((psStream->ui32Current != g_ui32HotKeyFrame) || (g_bHotKeyPressed == IMG_FALSE)) + { + return(0); + } + } + } + + return(DBGDrivWriteString(psStream,pszString,ui32Level)); + +} + +IMG_UINT32 IMG_CALLCONV DBGDrivWriteString(PDBG_STREAM psStream,IMG_CHAR * pszString,IMG_UINT32 ui32Level) +{ + IMG_UINT32 ui32Len; + IMG_UINT32 ui32Space; + IMG_UINT32 ui32WPtr; + IMG_UINT8 * pui8Buffer; + + + + if (!StreamValid(psStream)) + { + return(0xFFFFFFFF); + } + + + + if (!(psStream->ui32DebugLevel & ui32Level)) + { + return(0xFFFFFFFF); + } + + + + + if (!(psStream->ui32OutMode & DEBUG_OUTMODE_ASYNC)) + { + if (psStream->ui32OutMode & DEBUG_OUTMODE_STANDARDDBG) + { + PVR_DPF((PVR_DBG_MESSAGE,"%s: %s\r\n",psStream->szName, pszString)); + } + + + + if (psStream->ui32OutMode & DEBUG_OUTMODE_MONO) + { + MonoOut(psStream->szName,IMG_FALSE); + MonoOut(": ",IMG_FALSE); + MonoOut(pszString,IMG_TRUE); + } + } + + + + if ( + !( + (psStream->ui32OutMode & DEBUG_OUTMODE_STREAMENABLE) || + (psStream->ui32OutMode & DEBUG_OUTMODE_ASYNC) + ) + ) + { + return(0xFFFFFFFF); + } + + + + ui32Space=SpaceInStream(psStream); + + if(ui32Space > 0) + { + ui32Space--; + } + + ui32Len = 0; + ui32WPtr = psStream->ui32WPtr; + pui8Buffer = (IMG_UINT8 *) psStream->ui32Base; + + while((pszString[ui32Len] != 0) && (ui32Len < ui32Space)) + { + pui8Buffer[ui32WPtr] = pszString[ui32Len]; + ui32Len++; + ui32WPtr++; + if (ui32WPtr == psStream->ui32Size) + { + ui32WPtr = 0; + } + } + + if (ui32Len < ui32Space) + { + + pui8Buffer[ui32WPtr] = pszString[ui32Len]; + ui32Len++; + ui32WPtr++; + if (ui32WPtr == psStream->ui32Size) + { + ui32WPtr = 0; + } + + + psStream->ui32WPtr = ui32WPtr; + psStream->ui32DataWritten+= ui32Len; + } else + { + ui32Len = 0; + } + +#if defined(SUPPORT_DBGDRV_EVENT_OBJECTS) + if (ui32Len) + { + HostSignalEvent(DBG_EVENT_STREAM_DATA); + } +#endif + + return(ui32Len); +} + +IMG_UINT32 IMG_CALLCONV DBGDrivReadString(PDBG_STREAM psStream,IMG_CHAR * pszString,IMG_UINT32 ui32Limit) +{ + IMG_UINT32 ui32OutLen; + IMG_UINT32 ui32Len; + IMG_UINT32 ui32Offset; + IMG_UINT8 *pui8Buff; + + + + if (!StreamValid(psStream)) + { + return(0); + } + + + + pui8Buff = (IMG_UINT8 *) psStream->ui32Base; + ui32Offset = psStream->ui32RPtr; + + if (psStream->ui32RPtr == psStream->ui32WPtr) + { + return(0); + } + + + + ui32Len = 0; + while((pui8Buff[ui32Offset] != 0) && (ui32Offset != psStream->ui32WPtr)) + { + ui32Offset++; + ui32Len++; + + + + if (ui32Offset == psStream->ui32Size) + { + ui32Offset = 0; + } + } + + ui32OutLen = ui32Len + 1; + + + + if (ui32Len > ui32Limit) + { + return(0); + } + + + + ui32Offset = psStream->ui32RPtr; + ui32Len = 0; + + while ((pui8Buff[ui32Offset] != 0) && (ui32Len < ui32Limit)) + { + pszString[ui32Len] = pui8Buff[ui32Offset]; + ui32Offset++; + ui32Len++; + + + + if (ui32Offset == psStream->ui32Size) + { + ui32Offset = 0; + } + } + + pszString[ui32Len] = pui8Buff[ui32Offset]; + + psStream->ui32RPtr = ui32Offset + 1; + + if (psStream->ui32RPtr == psStream->ui32Size) + { + psStream->ui32RPtr = 0; + } + + return(ui32OutLen); +} + +IMG_UINT32 IMG_CALLCONV DBGDrivWrite(PDBG_STREAM psMainStream,IMG_UINT8 * pui8InBuf,IMG_UINT32 ui32InBuffSize,IMG_UINT32 ui32Level) +{ + IMG_UINT32 ui32Space; + DBG_STREAM *psStream; + + + + if (!StreamValid(psMainStream)) + { + return(0xFFFFFFFF); + } + + + + if (!(psMainStream->ui32DebugLevel & ui32Level)) + { + return(0xFFFFFFFF); + } + + + + if (psMainStream->ui32CapMode & DEBUG_CAPMODE_FRAMED) + { + if (!(psMainStream->ui32Flags & DEBUG_FLAGS_ENABLESAMPLE)) + { + return(0xFFFFFFFF); + } + } + else if (psMainStream->ui32CapMode == DEBUG_CAPMODE_HOTKEY) + { + if ((psMainStream->ui32Current != g_ui32HotKeyFrame) || (g_bHotKeyPressed == IMG_FALSE)) + return(0xFFFFFFFF); + } + + if(psMainStream->bInitPhaseComplete) + { + psStream = psMainStream; + } + else + { + psStream = psMainStream->psInitStream; + } + + + + ui32Space=SpaceInStream(psStream); + + + + if (!(psStream->ui32OutMode & DEBUG_OUTMODE_STREAMENABLE)) + { + return(0); + } + + if (ui32Space < 8) + { + return(0); + } + + + + if (ui32Space <= (ui32InBuffSize + 4)) + { + ui32InBuffSize = ui32Space - 8; + } + + + + Write(psStream,(IMG_UINT8 *) &ui32InBuffSize,4); + Write(psStream,pui8InBuf,ui32InBuffSize); + +#if defined(SUPPORT_DBGDRV_EVENT_OBJECTS) + if (ui32InBuffSize) + { + HostSignalEvent(DBG_EVENT_STREAM_DATA); + } +#endif + return(ui32InBuffSize); +} + +IMG_UINT32 IMG_CALLCONV DBGDrivWriteCM(PDBG_STREAM psStream,IMG_UINT8 * pui8InBuf,IMG_UINT32 ui32InBuffSize,IMG_UINT32 ui32Level) +{ + + + if (!StreamValid(psStream)) + { + return(0xFFFFFFFF); + } + + + + if (psStream->ui32CapMode & DEBUG_CAPMODE_FRAMED) + { + if (!(psStream->ui32Flags & DEBUG_FLAGS_ENABLESAMPLE)) + { + return(0xFFFFFFFF); + } + } + else + { + if (psStream->ui32CapMode == DEBUG_CAPMODE_HOTKEY) + { + if ((psStream->ui32Current != g_ui32HotKeyFrame) || (g_bHotKeyPressed == IMG_FALSE)) + { + return(0xFFFFFFFF); + } + } + } + + return(DBGDrivWrite2(psStream,pui8InBuf,ui32InBuffSize,ui32Level)); +} + +IMG_UINT32 IMG_CALLCONV DBGDrivWrite2(PDBG_STREAM psMainStream,IMG_UINT8 * pui8InBuf,IMG_UINT32 ui32InBuffSize,IMG_UINT32 ui32Level) +{ + IMG_UINT32 ui32Space; + DBG_STREAM *psStream; + + + + if (!StreamValid(psMainStream)) + { + return(0xFFFFFFFF); + } + + + + if (!(psMainStream->ui32DebugLevel & ui32Level)) + { + return(0xFFFFFFFF); + } + + if(psMainStream->bInitPhaseComplete) + { + psStream = psMainStream; + } + else + { + psStream = psMainStream->psInitStream; + } + + + + ui32Space=SpaceInStream(psStream); + + + + if (!(psStream->ui32OutMode & DEBUG_OUTMODE_STREAMENABLE)) + { + return(0); + } + + + + if (psStream->ui32Flags & DEBUG_FLAGS_NO_BUF_EXPANDSION) + { + + + + if (ui32Space < 32) + { + return(0); + } + } + else + { + if ((ui32Space < 32) || (ui32Space <= (ui32InBuffSize + 4))) + { + IMG_UINT32 ui32NewBufSize; + + + + ui32NewBufSize = 2 * psStream->ui32Size; + + if (ui32InBuffSize > psStream->ui32Size) + { + ui32NewBufSize += ui32InBuffSize; + } + + + + if (!ExpandStreamBuffer(psStream,ui32NewBufSize)) + { + if (ui32Space < 32) + { + return(0); + } + } + + + + ui32Space = SpaceInStream(psStream); + } + } + + + + if (ui32Space <= (ui32InBuffSize + 4)) + { + ui32InBuffSize = ui32Space - 4; + } + + + + Write(psStream,pui8InBuf,ui32InBuffSize); + +#if defined(SUPPORT_DBGDRV_EVENT_OBJECTS) + if (ui32InBuffSize) + { + HostSignalEvent(DBG_EVENT_STREAM_DATA); + } +#endif + return(ui32InBuffSize); +} + +IMG_UINT32 IMG_CALLCONV DBGDrivRead(PDBG_STREAM psMainStream, IMG_BOOL bReadInitBuffer, IMG_UINT32 ui32OutBuffSize,IMG_UINT8 * pui8OutBuf) +{ + IMG_UINT32 ui32Data; + DBG_STREAM *psStream; + + + + if (!StreamValid(psMainStream)) + { + return(0); + } + + if(bReadInitBuffer) + { + psStream = psMainStream->psInitStream; + } + else + { + psStream = psMainStream; + } + + if (psStream->ui32RPtr == psStream->ui32WPtr) + { + return(0); + } + + + + if (psStream->ui32RPtr <= psStream->ui32WPtr) + { + ui32Data = psStream->ui32WPtr - psStream->ui32RPtr; + } + else + { + ui32Data = psStream->ui32WPtr + (psStream->ui32Size - psStream->ui32RPtr); + } + + + + if (ui32Data > ui32OutBuffSize) + { + ui32Data = ui32OutBuffSize; + } + + + + if ((psStream->ui32RPtr + ui32Data) > psStream->ui32Size) + { + IMG_UINT32 ui32B1 = psStream->ui32Size - psStream->ui32RPtr; + IMG_UINT32 ui32B2 = ui32Data - ui32B1; + + + HostMemCopy((IMG_VOID *) pui8OutBuf, + (IMG_VOID *)(psStream->ui32Base + psStream->ui32RPtr), + ui32B1); + + + HostMemCopy((IMG_VOID *)((IMG_UINT32) pui8OutBuf + ui32B1), + (IMG_VOID *)psStream->ui32Base, + ui32B2); + + + psStream->ui32RPtr = ui32B2; + } + else + { + HostMemCopy((IMG_VOID *) pui8OutBuf, + (IMG_VOID *)(psStream->ui32Base + psStream->ui32RPtr), + ui32Data); + + + psStream->ui32RPtr += ui32Data; + + + if (psStream->ui32RPtr == psStream->ui32Size) + { + psStream->ui32RPtr = 0; + } + } + + return(ui32Data); +} + +void IMG_CALLCONV DBGDrivSetCaptureMode(PDBG_STREAM psStream,IMG_UINT32 ui32Mode,IMG_UINT32 ui32Start,IMG_UINT32 ui32End,IMG_UINT32 ui32SampleRate) +{ + + + if (!StreamValid(psStream)) + { + return; + } + + psStream->ui32CapMode = ui32Mode; + psStream->ui32DefaultMode = ui32Mode; + psStream->ui32Start = ui32Start; + psStream->ui32End = ui32End; + psStream->ui32SampleRate = ui32SampleRate; + + + + if (psStream->ui32CapMode & DEBUG_CAPMODE_HOTKEY) + { + ActivateHotKeys(psStream); + } +} + +void IMG_CALLCONV DBGDrivSetOutputMode(PDBG_STREAM psStream,IMG_UINT32 ui32OutMode) +{ + + + if (!StreamValid(psStream)) + { + return; + } + + psStream->ui32OutMode = ui32OutMode; +} + +void IMG_CALLCONV DBGDrivSetDebugLevel(PDBG_STREAM psStream,IMG_UINT32 ui32DebugLevel) +{ + + + if (!StreamValid(psStream)) + { + return; + } + + psStream->ui32DebugLevel = ui32DebugLevel; +} + +void IMG_CALLCONV DBGDrivSetFrame(PDBG_STREAM psStream,IMG_UINT32 ui32Frame) +{ + + + if (!StreamValid(psStream)) + { + return; + } + + psStream->ui32Current = ui32Frame; + + if ((ui32Frame >= psStream->ui32Start) && + (ui32Frame <= psStream->ui32End) && + (((ui32Frame - psStream->ui32Start) % psStream->ui32SampleRate) == 0)) + { + psStream->ui32Flags |= DEBUG_FLAGS_ENABLESAMPLE; + } + else + { + psStream->ui32Flags &= ~DEBUG_FLAGS_ENABLESAMPLE; + } + + if (g_bHotkeyMiddump) + { + if ((ui32Frame >= g_ui32HotkeyMiddumpStart) && + (ui32Frame <= g_ui32HotkeyMiddumpEnd) && + (((ui32Frame - g_ui32HotkeyMiddumpStart) % psStream->ui32SampleRate) == 0)) + { + psStream->ui32Flags |= DEBUG_FLAGS_ENABLESAMPLE; + } + else + { + psStream->ui32Flags &= ~DEBUG_FLAGS_ENABLESAMPLE; + if (psStream->ui32Current > g_ui32HotkeyMiddumpEnd) + { + g_bHotkeyMiddump = IMG_FALSE; + } + } + } + + + if (g_bHotKeyRegistered) + { + g_bHotKeyRegistered = IMG_FALSE; + + PVR_DPF((PVR_DBG_MESSAGE,"Hotkey pressed (%08x)!\n",psStream)); + + if (!g_bHotKeyPressed) + { + + + g_ui32HotKeyFrame = psStream->ui32Current + 2; + + + + g_bHotKeyPressed = IMG_TRUE; + } + + + + if ((psStream->ui32CapMode & DEBUG_CAPMODE_FRAMED) && (psStream->ui32CapMode & DEBUG_CAPMODE_HOTKEY)) + { + if (!g_bHotkeyMiddump) + { + + g_ui32HotkeyMiddumpStart = g_ui32HotKeyFrame + 1; + g_ui32HotkeyMiddumpEnd = 0xffffffff; + g_bHotkeyMiddump = IMG_TRUE; + PVR_DPF((PVR_DBG_MESSAGE,"Sampling every %d frame(s)\n", psStream->ui32SampleRate)); + } + else + { + + g_ui32HotkeyMiddumpEnd = g_ui32HotKeyFrame; + PVR_DPF((PVR_DBG_MESSAGE,"Turning off sampling\n")); + } + } + + } + + + + if (psStream->ui32Current > g_ui32HotKeyFrame) + { + g_bHotKeyPressed = IMG_FALSE; + } +} + +IMG_UINT32 IMG_CALLCONV DBGDrivGetFrame(PDBG_STREAM psStream) +{ + + + if (!StreamValid(psStream)) + { + return(0); + } + + return(psStream->ui32Current); +} + +IMG_UINT32 IMG_CALLCONV DBGDrivIsLastCaptureFrame(PDBG_STREAM psStream) +{ + IMG_UINT32 ui32NextFrame; + + + + if (!StreamValid(psStream)) + { + return IMG_FALSE; + } + + if (psStream->ui32CapMode & DEBUG_CAPMODE_FRAMED) + { + ui32NextFrame = psStream->ui32Current + psStream->ui32SampleRate; + if (ui32NextFrame > psStream->ui32End) + { + return IMG_TRUE; + } + } + return IMG_FALSE; +} + +IMG_UINT32 IMG_CALLCONV DBGDrivIsCaptureFrame(PDBG_STREAM psStream, IMG_BOOL bCheckPreviousFrame) +{ + IMG_UINT32 ui32FrameShift = bCheckPreviousFrame ? 1 : 0; + + + + if (!StreamValid(psStream)) + { + return IMG_FALSE; + } + + if (psStream->ui32CapMode & DEBUG_CAPMODE_FRAMED) + { + + if (g_bHotkeyMiddump) + { + if ((psStream->ui32Current >= (g_ui32HotkeyMiddumpStart - ui32FrameShift)) && + (psStream->ui32Current <= (g_ui32HotkeyMiddumpEnd - ui32FrameShift)) && + ((((psStream->ui32Current + ui32FrameShift) - g_ui32HotkeyMiddumpStart) % psStream->ui32SampleRate) == 0)) + { + return IMG_TRUE; + } + } + else + { + if ((psStream->ui32Current >= (psStream->ui32Start - ui32FrameShift)) && + (psStream->ui32Current <= (psStream->ui32End - ui32FrameShift)) && + ((((psStream->ui32Current + ui32FrameShift) - psStream->ui32Start) % psStream->ui32SampleRate) == 0)) + { + return IMG_TRUE; + } + } + } + else if (psStream->ui32CapMode == DEBUG_CAPMODE_HOTKEY) + { + if ((psStream->ui32Current == (g_ui32HotKeyFrame-ui32FrameShift)) && (g_bHotKeyPressed)) + { + return IMG_TRUE; + } + } + return IMG_FALSE; +} + +void IMG_CALLCONV DBGDrivOverrideMode(PDBG_STREAM psStream,IMG_UINT32 ui32Mode) +{ + + + if (!StreamValid(psStream)) + { + return; + } + + psStream->ui32CapMode = ui32Mode; +} + +void IMG_CALLCONV DBGDrivDefaultMode(PDBG_STREAM psStream) +{ + + + if (!StreamValid(psStream)) + { + return; + } + + psStream->ui32CapMode = psStream->ui32DefaultMode; +} + +void IMG_CALLCONV DBGDrivSetMarker(PDBG_STREAM psStream, IMG_UINT32 ui32Marker) +{ + + + if (!StreamValid(psStream)) + { + return; + } + + psStream->ui32Marker = ui32Marker; +} + +IMG_UINT32 IMG_CALLCONV DBGDrivGetMarker(PDBG_STREAM psStream) +{ + + + if (!StreamValid(psStream)) + { + return 0; + } + + return psStream->ui32Marker; +} + + +IMG_UINT32 IMG_CALLCONV DBGDrivGetStreamOffset(PDBG_STREAM psMainStream) +{ + PDBG_STREAM psStream; + + + + if (!StreamValid(psMainStream)) + { + return 0; + } + + if(psMainStream->bInitPhaseComplete) + { + psStream = psMainStream; + } + else + { + psStream = psMainStream->psInitStream; + } + + return psStream->ui32DataWritten; +} + +IMG_VOID IMG_CALLCONV DBGDrivSetStreamOffset(PDBG_STREAM psMainStream, IMG_UINT32 ui32StreamOffset) +{ + PDBG_STREAM psStream; + + + + if (!StreamValid(psMainStream)) + { + return; + } + + if(psMainStream->bInitPhaseComplete) + { + psStream = psMainStream; + } + else + { + psStream = psMainStream->psInitStream; + } + + psStream->ui32DataWritten = ui32StreamOffset; +} + +IMG_UINT32 IMG_CALLCONV DBGDrivGetServiceTable(void) +{ + return((IMG_UINT32) &g_sDBGKMServices); +} + +IMG_UINT32 IMG_CALLCONV DBGDrivWriteLF(PDBG_STREAM psStream, IMG_UINT8 * pui8InBuf, IMG_UINT32 ui32InBuffSize, IMG_UINT32 ui32Level, IMG_UINT32 ui32Flags) +{ + PDBG_LASTFRAME_BUFFER psLFBuffer; + + + + if (!StreamValid(psStream)) + { + return(0xFFFFFFFF); + } + + + + if (!(psStream->ui32DebugLevel & ui32Level)) + { + return(0xFFFFFFFF); + } + + + + if (psStream->ui32CapMode & DEBUG_CAPMODE_FRAMED) + { + if (!(psStream->ui32Flags & DEBUG_FLAGS_ENABLESAMPLE)) + { + return(0xFFFFFFFF); + } + } + else if (psStream->ui32CapMode == DEBUG_CAPMODE_HOTKEY) + { + if ((psStream->ui32Current != g_ui32HotKeyFrame) || (g_bHotKeyPressed == IMG_FALSE)) + return(0xFFFFFFFF); + } + + psLFBuffer = FindLFBuf(psStream); + + if (ui32Flags & WRITELF_FLAGS_RESETBUF) + { + + + ui32InBuffSize = (ui32InBuffSize > LAST_FRAME_BUF_SIZE) ? LAST_FRAME_BUF_SIZE : ui32InBuffSize; + HostMemCopy((IMG_VOID *)psLFBuffer->ui8Buffer, (IMG_VOID *)pui8InBuf, ui32InBuffSize); + psLFBuffer->ui32BufLen = ui32InBuffSize; + } + else + { + + + ui32InBuffSize = ((psLFBuffer->ui32BufLen + ui32InBuffSize) > LAST_FRAME_BUF_SIZE) ? (LAST_FRAME_BUF_SIZE - psLFBuffer->ui32BufLen) : ui32InBuffSize; + HostMemCopy((IMG_VOID *)(&psLFBuffer->ui8Buffer[psLFBuffer->ui32BufLen]), (IMG_VOID *)pui8InBuf, ui32InBuffSize); + psLFBuffer->ui32BufLen += ui32InBuffSize; + } + + return(ui32InBuffSize); +} + +IMG_UINT32 IMG_CALLCONV DBGDrivReadLF(PDBG_STREAM psStream, IMG_UINT32 ui32OutBuffSize, IMG_UINT8 * pui8OutBuf) +{ + PDBG_LASTFRAME_BUFFER psLFBuffer; + IMG_UINT32 ui32Data; + + + + if (!StreamValid(psStream)) + { + return(0); + } + + psLFBuffer = FindLFBuf(psStream); + + + + ui32Data = (ui32OutBuffSize < psLFBuffer->ui32BufLen) ? ui32OutBuffSize : psLFBuffer->ui32BufLen; + + + + HostMemCopy((IMG_VOID *)pui8OutBuf, (IMG_VOID *)psLFBuffer->ui8Buffer, ui32Data); + + return ui32Data; +} + +IMG_VOID IMG_CALLCONV DBGDrivStartInitPhase(PDBG_STREAM psStream) +{ + psStream->bInitPhaseComplete = IMG_FALSE; +} + +IMG_VOID IMG_CALLCONV DBGDrivStopInitPhase(PDBG_STREAM psStream) +{ + psStream->bInitPhaseComplete = IMG_TRUE; +} + +#if defined(SUPPORT_DBGDRV_EVENT_OBJECTS) +IMG_VOID IMG_CALLCONV DBGDrivWaitForEvent(DBG_EVENT eEvent) +{ + HostWaitForEvent(eEvent); +} +#endif + +IMG_BOOL ExpandStreamBuffer(PDBG_STREAM psStream, IMG_UINT32 ui32NewSize) +{ + IMG_VOID * pvNewBuf; + IMG_UINT32 ui32NewSizeInPages; + IMG_UINT32 ui32NewWOffset; + IMG_UINT32 ui32SpaceInOldBuf; + + + + if (psStream->ui32Size >= ui32NewSize) + { + return IMG_FALSE; + } + + + + ui32SpaceInOldBuf = SpaceInStream(psStream); + + + + ui32NewSizeInPages = ((ui32NewSize + 0xfff) & ~0xfff) / 4096; + + if ((psStream->ui32Flags & DEBUG_FLAGS_USE_NONPAGED_MEM) != 0) + { + pvNewBuf = HostNonPageablePageAlloc(ui32NewSizeInPages); + } + else + { + pvNewBuf = HostPageablePageAlloc(ui32NewSizeInPages); + } + + if (pvNewBuf == IMG_NULL) + { + return IMG_FALSE; + } + + + + + if (psStream->ui32RPtr <= psStream->ui32WPtr) + { + + + HostMemCopy((IMG_VOID *)pvNewBuf, (IMG_VOID *)(psStream->ui32Base + psStream->ui32RPtr), psStream->ui32WPtr - psStream->ui32RPtr); + } + else + { + IMG_UINT32 ui32FirstCopySize; + + + + ui32FirstCopySize = psStream->ui32Size - psStream->ui32RPtr; + + HostMemCopy((IMG_VOID *)pvNewBuf, (IMG_VOID *)(psStream->ui32Base + psStream->ui32RPtr), ui32FirstCopySize); + + + + HostMemCopy((IMG_VOID *)((IMG_UINT32)pvNewBuf + ui32FirstCopySize), (IMG_VOID *)psStream->ui32Base, psStream->ui32WPtr); + } + + + + ui32NewWOffset = psStream->ui32Size - ui32SpaceInOldBuf; + + + + if ((psStream->ui32Flags & DEBUG_FLAGS_USE_NONPAGED_MEM) != 0) + { + HostNonPageablePageFree((IMG_VOID *)psStream->ui32Base); + } + else + { + HostPageablePageFree((IMG_VOID *)psStream->ui32Base); + } + + + + psStream->ui32Base = (IMG_UINT32)pvNewBuf; + psStream->ui32RPtr = 0; + psStream->ui32WPtr = ui32NewWOffset; + psStream->ui32Size = ui32NewSizeInPages * 4096; + + return IMG_TRUE; +} + +IMG_UINT32 SpaceInStream(PDBG_STREAM psStream) +{ + IMG_UINT32 ui32Space; + + if (psStream->ui32RPtr > psStream->ui32WPtr) + { + ui32Space = psStream->ui32RPtr - psStream->ui32WPtr; + } + else + { + ui32Space = psStream->ui32RPtr + (psStream->ui32Size - psStream->ui32WPtr); + } + + return ui32Space; +} + + +void DestroyAllStreams(void) +{ + while (g_psStreamList != IMG_NULL) + { + DBGDrivDestroyStream(g_psStreamList); + } + return; +} + +PDBG_LASTFRAME_BUFFER FindLFBuf(PDBG_STREAM psStream) +{ + PDBG_LASTFRAME_BUFFER psLFBuffer; + + psLFBuffer = g_psLFBufferList; + + while (psLFBuffer) + { + if (psLFBuffer->psStream == psStream) + { + break; + } + + psLFBuffer = psLFBuffer->psNext; + } + + return psLFBuffer; +} + diff --git a/tools/intern/debug/dbgdriv/common/dbgdriv.h b/tools/intern/debug/dbgdriv/common/dbgdriv.h new file mode 100644 index 0000000..cdd9312 --- /dev/null +++ b/tools/intern/debug/dbgdriv/common/dbgdriv.h @@ -0,0 +1,116 @@ +/********************************************************************** + * + * Copyright(c) 2008 Imagination Technologies Ltd. All rights reserved. + * + * This program is free software; you can redistribute it and/or modify it + * under the terms and conditions of the GNU General Public License, + * version 2, as published by the Free Software Foundation. + * + * This program is distributed in the hope it will be useful but, except + * as otherwise stated in writing, without any warranty; without even the + * implied warranty of merchantability or fitness for a particular purpose. + * See the GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License along with + * this program; if not, write to the Free Software Foundation, Inc., + * 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA. + * + * The full GNU General Public License is included in this distribution in + * the file called "COPYING". + * + * Contact Information: + * Imagination Technologies Ltd. + * Home Park Estate, Kings Langley, Herts, WD4 8LZ, UK + * + ******************************************************************************/ + +#ifndef _DBGDRIV_ +#define _DBGDRIV_ + +#define BUFFER_SIZE 64*PAGESIZE + +#define DBGDRIV_VERSION 0x100 +#define MAX_PROCESSES 2 +#define BLOCK_USED 0x01 +#define BLOCK_LOCKED 0x02 +#define DBGDRIV_MONOBASE 0x000B0000 + + +extern IMG_VOID * g_pvAPIMutex; + +IMG_VOID * IMG_CALLCONV DBGDrivCreateStream(IMG_CHAR * pszName, + IMG_UINT32 ui32CapMode, + IMG_UINT32 ui32OutMode, + IMG_UINT32 ui32Flags, + IMG_UINT32 ui32Pages); +IMG_VOID IMG_CALLCONV DBGDrivDestroyStream(PDBG_STREAM psStream); +IMG_VOID * IMG_CALLCONV DBGDrivFindStream(IMG_CHAR * pszName, IMG_BOOL bResetStream); +IMG_UINT32 IMG_CALLCONV DBGDrivWriteString(PDBG_STREAM psStream,IMG_CHAR * pszString,IMG_UINT32 ui32Level); +IMG_UINT32 IMG_CALLCONV DBGDrivReadString(PDBG_STREAM psStream,IMG_CHAR * pszString,IMG_UINT32 ui32Limit); +IMG_UINT32 IMG_CALLCONV DBGDrivWrite(PDBG_STREAM psStream,IMG_UINT8 *pui8InBuf,IMG_UINT32 ui32InBuffSize,IMG_UINT32 ui32Level); +IMG_UINT32 IMG_CALLCONV DBGDrivWrite2(PDBG_STREAM psStream,IMG_UINT8 *pui8InBuf,IMG_UINT32 ui32InBuffSize,IMG_UINT32 ui32Level); +IMG_UINT32 IMG_CALLCONV DBGDrivRead(PDBG_STREAM psStream, IMG_BOOL bReadInitBuffer, IMG_UINT32 ui32OutBufferSize,IMG_UINT8 *pui8OutBuf); +IMG_VOID IMG_CALLCONV DBGDrivSetCaptureMode(PDBG_STREAM psStream,IMG_UINT32 ui32Mode,IMG_UINT32 ui32Start,IMG_UINT32 ui32Stop,IMG_UINT32 ui32SampleRate); +IMG_VOID IMG_CALLCONV DBGDrivSetOutputMode(PDBG_STREAM psStream,IMG_UINT32 ui32OutMode); +IMG_VOID IMG_CALLCONV DBGDrivSetDebugLevel(PDBG_STREAM psStream,IMG_UINT32 ui32DebugLevel); +IMG_VOID IMG_CALLCONV DBGDrivSetFrame(PDBG_STREAM psStream,IMG_UINT32 ui32Frame); +IMG_UINT32 IMG_CALLCONV DBGDrivGetFrame(PDBG_STREAM psStream); +IMG_VOID IMG_CALLCONV DBGDrivOverrideMode(PDBG_STREAM psStream,IMG_UINT32 ui32Mode); +IMG_VOID IMG_CALLCONV DBGDrivDefaultMode(PDBG_STREAM psStream); +IMG_UINT32 IMG_CALLCONV DBGDrivGetServiceTable(IMG_VOID); +IMG_UINT32 IMG_CALLCONV DBGDrivWriteStringCM(PDBG_STREAM psStream,IMG_CHAR * pszString,IMG_UINT32 ui32Level); +IMG_UINT32 IMG_CALLCONV DBGDrivWriteCM(PDBG_STREAM psStream,IMG_UINT8 *pui8InBuf,IMG_UINT32 ui32InBuffSize,IMG_UINT32 ui32Level); +IMG_VOID IMG_CALLCONV DBGDrivSetMarker(PDBG_STREAM psStream, IMG_UINT32 ui32Marker); +IMG_UINT32 IMG_CALLCONV DBGDrivGetMarker(PDBG_STREAM psStream); +IMG_UINT32 IMG_CALLCONV DBGDrivIsLastCaptureFrame(PDBG_STREAM psStream); +IMG_UINT32 IMG_CALLCONV DBGDrivIsCaptureFrame(PDBG_STREAM psStream, IMG_BOOL bCheckPreviousFrame); +IMG_UINT32 IMG_CALLCONV DBGDrivWriteLF(PDBG_STREAM psStream, IMG_UINT8 *pui8InBuf, IMG_UINT32 ui32InBuffSize, IMG_UINT32 ui32Level, IMG_UINT32 ui32Flags); +IMG_UINT32 IMG_CALLCONV DBGDrivReadLF(PDBG_STREAM psStream, IMG_UINT32 ui32OutBuffSize, IMG_UINT8 *pui8OutBuf); +IMG_VOID IMG_CALLCONV DBGDrivStartInitPhase(PDBG_STREAM psStream); +IMG_VOID IMG_CALLCONV DBGDrivStopInitPhase(PDBG_STREAM psStream); +IMG_UINT32 IMG_CALLCONV DBGDrivGetStreamOffset(PDBG_STREAM psStream); +IMG_VOID IMG_CALLCONV DBGDrivSetStreamOffset(PDBG_STREAM psStream, IMG_UINT32 ui32StreamOffset); +IMG_VOID IMG_CALLCONV DBGDrivWaitForEvent(DBG_EVENT eEvent); + +IMG_VOID DestroyAllStreams(IMG_VOID); + +IMG_UINT32 AtoI(char *szIn); + +IMG_VOID HostMemSet(IMG_VOID *pvDest,IMG_UINT8 ui8Value,IMG_UINT32 ui32Size); +IMG_VOID HostMemCopy(IMG_VOID *pvDest,IMG_VOID *pvSrc,IMG_UINT32 ui32Size); +IMG_BOOL StreamValid(PDBG_STREAM psStream); +IMG_VOID Write(PDBG_STREAM psStream,IMG_UINT8 *pui8Data,IMG_UINT32 ui32InBuffSize); +IMG_VOID MonoOut(IMG_CHAR * pszString,IMG_BOOL bNewLine); + + +IMG_VOID * IMG_CALLCONV ExtDBGDrivCreateStream(IMG_CHAR * pszName, IMG_UINT32 ui32CapMode, IMG_UINT32 ui32OutMode, IMG_UINT32 ui32Flags, IMG_UINT32 ui32Size); +IMG_VOID IMG_CALLCONV ExtDBGDrivDestroyStream(PDBG_STREAM psStream); +IMG_VOID * IMG_CALLCONV ExtDBGDrivFindStream(IMG_CHAR * pszName, IMG_BOOL bResetStream); +IMG_UINT32 IMG_CALLCONV ExtDBGDrivWriteString(PDBG_STREAM psStream,IMG_CHAR * pszString,IMG_UINT32 ui32Level); +IMG_UINT32 IMG_CALLCONV ExtDBGDrivReadString(PDBG_STREAM psStream,IMG_CHAR * pszString,IMG_UINT32 ui32Limit); +IMG_UINT32 IMG_CALLCONV ExtDBGDrivWrite(PDBG_STREAM psStream,IMG_UINT8 *pui8InBuf,IMG_UINT32 ui32InBuffSize,IMG_UINT32 ui32Level); +IMG_UINT32 IMG_CALLCONV ExtDBGDrivRead(PDBG_STREAM psStream, IMG_BOOL bReadInitBuffer, IMG_UINT32 ui32OutBuffSize,IMG_UINT8 *pui8OutBuf); +IMG_VOID IMG_CALLCONV ExtDBGDrivSetCaptureMode(PDBG_STREAM psStream,IMG_UINT32 ui32Mode,IMG_UINT32 ui32Start,IMG_UINT32 ui32End,IMG_UINT32 ui32SampleRate); +IMG_VOID IMG_CALLCONV ExtDBGDrivSetOutputMode(PDBG_STREAM psStream,IMG_UINT32 ui32OutMode); +IMG_VOID IMG_CALLCONV ExtDBGDrivSetDebugLevel(PDBG_STREAM psStream,IMG_UINT32 ui32DebugLevel); +IMG_VOID IMG_CALLCONV ExtDBGDrivSetFrame(PDBG_STREAM psStream,IMG_UINT32 ui32Frame); +IMG_UINT32 IMG_CALLCONV ExtDBGDrivGetFrame(PDBG_STREAM psStream); +IMG_VOID IMG_CALLCONV ExtDBGDrivOverrideMode(PDBG_STREAM psStream,IMG_UINT32 ui32Mode); +IMG_VOID IMG_CALLCONV ExtDBGDrivDefaultMode(PDBG_STREAM psStream); +IMG_UINT32 IMG_CALLCONV ExtDBGDrivWrite2(PDBG_STREAM psStream,IMG_UINT8 *pui8InBuf,IMG_UINT32 ui32InBuffSize,IMG_UINT32 ui32Level); +IMG_UINT32 IMG_CALLCONV ExtDBGDrivWriteStringCM(PDBG_STREAM psStream,IMG_CHAR * pszString,IMG_UINT32 ui32Level); +IMG_UINT32 IMG_CALLCONV ExtDBGDrivWriteCM(PDBG_STREAM psStream,IMG_UINT8 *pui8InBuf,IMG_UINT32 ui32InBuffSize,IMG_UINT32 ui32Level); +IMG_VOID IMG_CALLCONV ExtDBGDrivSetMarker(PDBG_STREAM psStream, IMG_UINT32 ui32Marker); +IMG_UINT32 IMG_CALLCONV ExtDBGDrivGetMarker(PDBG_STREAM psStream); +IMG_VOID IMG_CALLCONV ExtDBGDrivStartInitPhase(PDBG_STREAM psStream); +IMG_VOID IMG_CALLCONV ExtDBGDrivStopInitPhase(PDBG_STREAM psStream); +IMG_UINT32 IMG_CALLCONV ExtDBGDrivIsLastCaptureFrame(PDBG_STREAM psStream); +IMG_UINT32 IMG_CALLCONV ExtDBGDrivIsCaptureFrame(PDBG_STREAM psStream, IMG_BOOL bCheckPreviousFrame); +IMG_UINT32 IMG_CALLCONV ExtDBGDrivWriteLF(PDBG_STREAM psStream, IMG_UINT8 *pui8InBuf, IMG_UINT32 ui32InBuffSize, IMG_UINT32 ui32Level, IMG_UINT32 ui32Flags); +IMG_UINT32 IMG_CALLCONV ExtDBGDrivReadLF(PDBG_STREAM psStream, IMG_UINT32 ui32OutBuffSize, IMG_UINT8 *pui8OutBuf); +IMG_UINT32 IMG_CALLCONV ExtDBGDrivGetStreamOffset(PDBG_STREAM psStream); +IMG_VOID IMG_CALLCONV ExtDBGDrivSetStreamOffset(PDBG_STREAM psStream, IMG_UINT32 ui32StreamOffset); +IMG_VOID IMG_CALLCONV ExtDBGDrivWaitForEvent(DBG_EVENT eEvent); + +#endif + diff --git a/tools/intern/debug/dbgdriv/common/hostfunc.h b/tools/intern/debug/dbgdriv/common/hostfunc.h new file mode 100644 index 0000000..7b588b5 --- /dev/null +++ b/tools/intern/debug/dbgdriv/common/hostfunc.h @@ -0,0 +1,58 @@ +/********************************************************************** + * + * Copyright(c) 2008 Imagination Technologies Ltd. All rights reserved. + * + * This program is free software; you can redistribute it and/or modify it + * under the terms and conditions of the GNU General Public License, + * version 2, as published by the Free Software Foundation. + * + * This program is distributed in the hope it will be useful but, except + * as otherwise stated in writing, without any warranty; without even the + * implied warranty of merchantability or fitness for a particular purpose. + * See the GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License along with + * this program; if not, write to the Free Software Foundation, Inc., + * 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA. + * + * The full GNU General Public License is included in this distribution in + * the file called "COPYING". + * + * Contact Information: + * Imagination Technologies Ltd. + * Home Park Estate, Kings Langley, Herts, WD4 8LZ, UK + * + ******************************************************************************/ + +#ifndef _HOSTFUNC_ +#define _HOSTFUNC_ + +#define HOST_PAGESIZE (4096) +#define DBG_MEMORY_INITIALIZER (0xe2) + +IMG_UINT32 HostReadRegistryDWORDFromString(char *pcKey, char *pcValueName, IMG_UINT32 *pui32Data); + +IMG_VOID * HostPageablePageAlloc(IMG_UINT32 ui32Pages); +IMG_VOID HostPageablePageFree(IMG_VOID * pvBase); +IMG_VOID * HostNonPageablePageAlloc(IMG_UINT32 ui32Pages); +IMG_VOID HostNonPageablePageFree(IMG_VOID * pvBase); + +IMG_VOID * HostMapKrnBufIntoUser(IMG_VOID * pvKrnAddr, IMG_UINT32 ui32Size, IMG_VOID * *ppvMdl); +IMG_VOID HostUnMapKrnBufFromUser(IMG_VOID * pvUserAddr, IMG_VOID * pvMdl, IMG_VOID * pvProcess); + +IMG_VOID HostCreateRegDeclStreams(IMG_VOID); + +IMG_VOID * HostCreateMutex(IMG_VOID); +IMG_VOID HostAquireMutex(IMG_VOID * pvMutex); +IMG_VOID HostReleaseMutex(IMG_VOID * pvMutex); +IMG_VOID HostDestroyMutex(IMG_VOID * pvMutex); + +#if defined(SUPPORT_DBGDRV_EVENT_OBJECTS) +IMG_INT32 HostCreateEventObjects(IMG_VOID); +IMG_VOID HostWaitForEvent(DBG_EVENT eEvent); +IMG_VOID HostSignalEvent(DBG_EVENT eEvent); +IMG_VOID HostDestroyEventObjects(IMG_VOID); +#endif + +#endif + diff --git a/tools/intern/debug/dbgdriv/common/hotkey.c b/tools/intern/debug/dbgdriv/common/hotkey.c new file mode 100644 index 0000000..734de26 --- /dev/null +++ b/tools/intern/debug/dbgdriv/common/hotkey.c @@ -0,0 +1,135 @@ +/********************************************************************** + * + * Copyright(c) 2008 Imagination Technologies Ltd. All rights reserved. + * + * This program is free software; you can redistribute it and/or modify it + * under the terms and conditions of the GNU General Public License, + * version 2, as published by the Free Software Foundation. + * + * This program is distributed in the hope it will be useful but, except + * as otherwise stated in writing, without any warranty; without even the + * implied warranty of merchantability or fitness for a particular purpose. + * See the GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License along with + * this program; if not, write to the Free Software Foundation, Inc., + * 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA. + * + * The full GNU General Public License is included in this distribution in + * the file called "COPYING". + * + * Contact Information: + * Imagination Technologies Ltd. + * Home Park Estate, Kings Langley, Herts, WD4 8LZ, UK + * + ******************************************************************************/ + + +#if !defined(LINUX) +#include +#include +#endif + +#include "img_types.h" +#include "pvr_debug.h" +#include "dbgdrvif.h" +#include "dbgdriv.h" +#include "hotkey.h" +#include "hostfunc.h" + + + + + +IMG_UINT32 g_ui32HotKeyFrame = 0xFFFFFFFF; +IMG_BOOL g_bHotKeyPressed = IMG_FALSE; +IMG_BOOL g_bHotKeyRegistered = IMG_FALSE; + +PRIVATEHOTKEYDATA g_PrivateHotKeyData; + + +IMG_VOID ReadInHotKeys(IMG_VOID) +{ + g_PrivateHotKeyData.ui32ScanCode = 0x58; + g_PrivateHotKeyData.ui32ShiftState = 0x0; + + + +#if 0 + if (_RegOpenKey(HKEY_LOCAL_MACHINE,pszRegPath,&hKey) == ERROR_SUCCESS) + { + + + QueryReg(hKey,"ui32ScanCode",&g_PrivateHotKeyData.ui32ScanCode); + QueryReg(hKey,"ui32ShiftState",&g_PrivateHotKeyData.ui32ShiftState); + } +#else + HostReadRegistryDWORDFromString("DEBUG\\Streams", "ui32ScanCode" , &g_PrivateHotKeyData.ui32ScanCode); + HostReadRegistryDWORDFromString("DEBUG\\Streams", "ui32ShiftState", &g_PrivateHotKeyData.ui32ShiftState); +#endif +} + +IMG_VOID RegisterKeyPressed(IMG_UINT32 dwui32ScanCode, PHOTKEYINFO pInfo) +{ + PDBG_STREAM psStream; + + PVR_UNREFERENCED_PARAMETER(pInfo); + + if (dwui32ScanCode == g_PrivateHotKeyData.ui32ScanCode) + { + PVR_DPF((PVR_DBG_MESSAGE,"PDUMP Hotkey pressed !\n")); + + psStream = (PDBG_STREAM) g_PrivateHotKeyData.sHotKeyInfo.pvStream; + + if (!g_bHotKeyPressed) + { + + + g_ui32HotKeyFrame = psStream->ui32Current + 2; + + + + g_bHotKeyPressed = IMG_TRUE; + } + } +} + +IMG_VOID ActivateHotKeys(PDBG_STREAM psStream) +{ + + + ReadInHotKeys(); + + + + if (!g_PrivateHotKeyData.sHotKeyInfo.hHotKey) + { + if (g_PrivateHotKeyData.ui32ScanCode != 0) + { + PVR_DPF((PVR_DBG_MESSAGE,"Activate HotKey for PDUMP.\n")); + + + + g_PrivateHotKeyData.sHotKeyInfo.pvStream = psStream; + + DefineHotKey(g_PrivateHotKeyData.ui32ScanCode, g_PrivateHotKeyData.ui32ShiftState, &g_PrivateHotKeyData.sHotKeyInfo); + } + else + { + g_PrivateHotKeyData.sHotKeyInfo.hHotKey = 0; + } + } +} + +IMG_VOID DeactivateHotKeys(IMG_VOID) +{ + if (g_PrivateHotKeyData.sHotKeyInfo.hHotKey != 0) + { + PVR_DPF((PVR_DBG_MESSAGE,"Deactivate HotKey.\n")); + + RemoveHotKey(g_PrivateHotKeyData.sHotKeyInfo.hHotKey); + g_PrivateHotKeyData.sHotKeyInfo.hHotKey = 0; + } +} + + diff --git a/tools/intern/debug/dbgdriv/common/hotkey.h b/tools/intern/debug/dbgdriv/common/hotkey.h new file mode 100644 index 0000000..499d64e --- /dev/null +++ b/tools/intern/debug/dbgdriv/common/hotkey.h @@ -0,0 +1,60 @@ +/********************************************************************** + * + * Copyright(c) 2008 Imagination Technologies Ltd. All rights reserved. + * + * This program is free software; you can redistribute it and/or modify it + * under the terms and conditions of the GNU General Public License, + * version 2, as published by the Free Software Foundation. + * + * This program is distributed in the hope it will be useful but, except + * as otherwise stated in writing, without any warranty; without even the + * implied warranty of merchantability or fitness for a particular purpose. + * See the GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License along with + * this program; if not, write to the Free Software Foundation, Inc., + * 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA. + * + * The full GNU General Public License is included in this distribution in + * the file called "COPYING". + * + * Contact Information: + * Imagination Technologies Ltd. + * Home Park Estate, Kings Langley, Herts, WD4 8LZ, UK + * + ******************************************************************************/ + +#ifndef _HOTKEY_ +#define _HOTKEY_ + + +typedef struct _hotkeyinfo +{ + IMG_UINT8 ui8ScanCode; + IMG_UINT8 ui8Type; + IMG_UINT8 ui8Flag; + IMG_UINT8 ui8Filler1; + IMG_UINT32 ui32ShiftState; + IMG_UINT32 ui32HotKeyProc; + IMG_VOID *pvStream; + IMG_UINT32 hHotKey; +} HOTKEYINFO, *PHOTKEYINFO; + +typedef struct _privatehotkeydata +{ + IMG_UINT32 ui32ScanCode; + IMG_UINT32 ui32ShiftState; + HOTKEYINFO sHotKeyInfo; +} PRIVATEHOTKEYDATA, *PPRIVATEHOTKEYDATA; + + +IMG_VOID ReadInHotKeys (IMG_VOID); +IMG_VOID ActivateHotKeys(PDBG_STREAM psStream); +IMG_VOID DeactivateHotKeys(IMG_VOID); + +IMG_VOID RemoveHotKey (IMG_UINT32 hHotKey); +IMG_VOID DefineHotKey (IMG_UINT32 ui32ScanCode, IMG_UINT32 ui32ShiftState, PHOTKEYINFO psInfo); +IMG_VOID RegisterKeyPressed (IMG_UINT32 ui32ScanCode, PHOTKEYINFO psInfo); + +#endif + diff --git a/tools/intern/debug/dbgdriv/common/ioctl.c b/tools/intern/debug/dbgdriv/common/ioctl.c new file mode 100644 index 0000000..8ef809f --- /dev/null +++ b/tools/intern/debug/dbgdriv/common/ioctl.c @@ -0,0 +1,368 @@ +/********************************************************************** + * + * Copyright(c) 2008 Imagination Technologies Ltd. All rights reserved. + * + * This program is free software; you can redistribute it and/or modify it + * under the terms and conditions of the GNU General Public License, + * version 2, as published by the Free Software Foundation. + * + * This program is distributed in the hope it will be useful but, except + * as otherwise stated in writing, without any warranty; without even the + * implied warranty of merchantability or fitness for a particular purpose. + * See the GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License along with + * this program; if not, write to the Free Software Foundation, Inc., + * 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA. + * + * The full GNU General Public License is included in this distribution in + * the file called "COPYING". + * + * Contact Information: + * Imagination Technologies Ltd. + * Home Park Estate, Kings Langley, Herts, WD4 8LZ, UK + * + ******************************************************************************/ + + + +#ifdef LINUX +#include +#endif + +#include "img_types.h" +#include "dbgdrvif.h" +#include "dbgdriv.h" +#include "hotkey.h" + + +IMG_UINT32 DBGDIOCDrivCreateStream(IMG_VOID * pvInBuffer, IMG_VOID * pvOutBuffer) +{ + PDBG_IN_CREATESTREAM psIn; + IMG_VOID * *ppvOut; + #ifdef LINUX + static char name[32]; + #endif + + psIn = (PDBG_IN_CREATESTREAM) pvInBuffer; + ppvOut = (IMG_VOID * *) pvOutBuffer; + + #ifdef LINUX + + if(copy_from_user(name, psIn->pszName, 32) != 0) + return IMG_FALSE; + *ppvOut = ExtDBGDrivCreateStream(name, psIn->ui32CapMode, psIn->ui32OutMode, 0, psIn->ui32Pages); + + #else + *ppvOut = ExtDBGDrivCreateStream(psIn->pszName, psIn->ui32CapMode, psIn->ui32OutMode, DEBUG_FLAGS_NO_BUF_EXPANDSION, psIn->ui32Pages); + #endif + + + return(IMG_TRUE); +} + +IMG_UINT32 DBGDIOCDrivDestroyStream(IMG_VOID * pvInBuffer, IMG_VOID * pvOutBuffer) +{ + IMG_UINT32 * pStream; + PDBG_STREAM psStream; + + pStream = (IMG_UINT32 *) pvInBuffer; + psStream = (PDBG_STREAM) *pStream; + + PVR_UNREFERENCED_PARAMETER( pvOutBuffer); + + ExtDBGDrivDestroyStream(psStream); + + return(IMG_TRUE); +} + +IMG_UINT32 DBGDIOCDrivGetStream(IMG_VOID * pvInBuffer, IMG_VOID * pvOutBuffer) +{ + PDBG_IN_FINDSTREAM psParams; + IMG_UINT32 * pui32Stream; + + psParams = (PDBG_IN_FINDSTREAM)pvInBuffer; + pui32Stream = (IMG_UINT32 *)pvOutBuffer; + + *pui32Stream = (IMG_UINT32)ExtDBGDrivFindStream(psParams->pszName, psParams->bResetStream); + + return(IMG_TRUE); +} + +IMG_UINT32 DBGDIOCDrivWriteString(IMG_VOID * pvInBuffer, IMG_VOID * pvOutBuffer) +{ + PDBG_IN_WRITESTRING psParams; + IMG_UINT32 * pui32OutLen; + + psParams = (PDBG_IN_WRITESTRING) pvInBuffer; + pui32OutLen = (IMG_UINT32 *) pvOutBuffer; + + *pui32OutLen = ExtDBGDrivWriteString((PDBG_STREAM) psParams->pvStream,psParams->pszString,psParams->ui32Level); + + return(IMG_TRUE); +} + +IMG_UINT32 DBGDIOCDrivWriteStringCM(IMG_VOID * pvInBuffer, IMG_VOID * pvOutBuffer) +{ + PDBG_IN_WRITESTRING psParams; + IMG_UINT32 * pui32OutLen; + + psParams = (PDBG_IN_WRITESTRING) pvInBuffer; + pui32OutLen = (IMG_UINT32 *) pvOutBuffer; + + *pui32OutLen = ExtDBGDrivWriteStringCM((PDBG_STREAM) psParams->pvStream,psParams->pszString,psParams->ui32Level); + + return(IMG_TRUE); +} + +IMG_UINT32 DBGDIOCDrivReadString(IMG_VOID * pvInBuffer, IMG_VOID * pvOutBuffer) +{ + IMG_UINT32 * pui32OutLen; + PDBG_IN_READSTRING psParams; + + psParams = (PDBG_IN_READSTRING) pvInBuffer; + pui32OutLen = (IMG_UINT32 *) pvOutBuffer; + + *pui32OutLen = ExtDBGDrivReadString(psParams->pvStream,psParams->pszString,psParams->ui32StringLen); + + return(IMG_TRUE); +} + +IMG_UINT32 DBGDIOCDrivWrite(IMG_VOID * pvInBuffer, IMG_VOID * pvOutBuffer) +{ + IMG_UINT32 * pui32BytesCopied; + PDBG_IN_WRITE psInParams; + + psInParams = (PDBG_IN_WRITE) pvInBuffer; + pui32BytesCopied = (IMG_UINT32 *) pvOutBuffer; + + *pui32BytesCopied = ExtDBGDrivWrite((PDBG_STREAM) psInParams->pvStream,psInParams->pui8InBuffer,psInParams->ui32TransferSize,psInParams->ui32Level); + + return(IMG_TRUE); +} + +IMG_UINT32 DBGDIOCDrivWrite2(IMG_VOID * pvInBuffer, IMG_VOID * pvOutBuffer) +{ + IMG_UINT32 * pui32BytesCopied; + PDBG_IN_WRITE psInParams; + + psInParams = (PDBG_IN_WRITE) pvInBuffer; + pui32BytesCopied = (IMG_UINT32 *) pvOutBuffer; + + *pui32BytesCopied = ExtDBGDrivWrite2((PDBG_STREAM) psInParams->pvStream,psInParams->pui8InBuffer,psInParams->ui32TransferSize,psInParams->ui32Level); + + return(IMG_TRUE); +} + +IMG_UINT32 DBGDIOCDrivWriteCM(IMG_VOID * pvInBuffer, IMG_VOID * pvOutBuffer) +{ + IMG_UINT32 * pui32BytesCopied; + PDBG_IN_WRITE psInParams; + + psInParams = (PDBG_IN_WRITE) pvInBuffer; + pui32BytesCopied = (IMG_UINT32 *) pvOutBuffer; + + *pui32BytesCopied = ExtDBGDrivWriteCM((PDBG_STREAM) psInParams->pvStream,psInParams->pui8InBuffer,psInParams->ui32TransferSize,psInParams->ui32Level); + + return(IMG_TRUE); +} + +IMG_UINT32 DBGDIOCDrivRead(IMG_VOID * pvInBuffer, IMG_VOID * pvOutBuffer) +{ + IMG_UINT32 * pui32BytesCopied; + PDBG_IN_READ psInParams; + + psInParams = (PDBG_IN_READ) pvInBuffer; + pui32BytesCopied = (IMG_UINT32 *) pvOutBuffer; + + *pui32BytesCopied = ExtDBGDrivRead((PDBG_STREAM) psInParams->pvStream,psInParams->bReadInitBuffer, psInParams->ui32OutBufferSize,psInParams->pui8OutBuffer); + + return(IMG_TRUE); +} + +IMG_UINT32 DBGDIOCDrivSetCaptureMode(IMG_VOID * pvInBuffer, IMG_VOID * pvOutBuffer) +{ + PDBG_IN_SETDEBUGMODE psParams; + + psParams = (PDBG_IN_SETDEBUGMODE) pvInBuffer; + PVR_UNREFERENCED_PARAMETER(pvOutBuffer); + + ExtDBGDrivSetCaptureMode((PDBG_STREAM) psParams->pvStream, + psParams->ui32Mode, + psParams->ui32Start, + psParams->ui32End, + psParams->ui32SampleRate); + + return(IMG_TRUE); +} + +IMG_UINT32 DBGDIOCDrivSetOutMode(IMG_VOID * pvInBuffer, IMG_VOID * pvOutBuffer) +{ + PDBG_IN_SETDEBUGOUTMODE psParams; + + psParams = (PDBG_IN_SETDEBUGOUTMODE) pvInBuffer; + PVR_UNREFERENCED_PARAMETER(pvOutBuffer); + + ExtDBGDrivSetOutputMode((PDBG_STREAM) psParams->pvStream,psParams->ui32Mode); + + return(IMG_TRUE); +} + +IMG_UINT32 DBGDIOCDrivSetDebugLevel(IMG_VOID * pvInBuffer, IMG_VOID * pvOutBuffer) +{ + PDBG_IN_SETDEBUGLEVEL psParams; + + psParams = (PDBG_IN_SETDEBUGLEVEL) pvInBuffer; + PVR_UNREFERENCED_PARAMETER(pvOutBuffer); + + ExtDBGDrivSetDebugLevel((PDBG_STREAM) psParams->pvStream,psParams->ui32Level); + + return(IMG_TRUE); +} + +IMG_UINT32 DBGDIOCDrivSetFrame(IMG_VOID * pvInBuffer, IMG_VOID * pvOutBuffer) +{ + PDBG_IN_SETFRAME psParams; + + psParams = (PDBG_IN_SETFRAME) pvInBuffer; + PVR_UNREFERENCED_PARAMETER(pvOutBuffer); + + ExtDBGDrivSetFrame((PDBG_STREAM) psParams->pvStream,psParams->ui32Frame); + + return(IMG_TRUE); +} + +IMG_UINT32 DBGDIOCDrivGetFrame(IMG_VOID * pvInBuffer, IMG_VOID * pvOutBuffer) +{ + IMG_UINT32 * pStream; + PDBG_STREAM psStream; + IMG_UINT32 * pui32Current; + + pStream = (IMG_UINT32 *) pvInBuffer; + psStream = (PDBG_STREAM) *pStream; + pui32Current = (IMG_UINT32 *) pvOutBuffer; + + *pui32Current = ExtDBGDrivGetFrame(psStream); + + return(IMG_TRUE); +} + +IMG_UINT32 DBGDIOCDrivIsCaptureFrame(IMG_VOID * pvInBuffer, IMG_VOID * pvOutBuffer) +{ + PDBG_IN_ISCAPTUREFRAME psParams; + IMG_UINT32 * pui32Current; + + psParams = (PDBG_IN_ISCAPTUREFRAME) pvInBuffer; + pui32Current = (IMG_UINT32 *) pvOutBuffer; + + *pui32Current = ExtDBGDrivIsCaptureFrame((PDBG_STREAM) psParams->pvStream, psParams->bCheckPreviousFrame); + + return(IMG_TRUE); +} + +IMG_UINT32 DBGDIOCDrivOverrideMode(IMG_VOID * pvInBuffer, IMG_VOID * pvOutBuffer) +{ + PDBG_IN_OVERRIDEMODE psParams; + + psParams = (PDBG_IN_OVERRIDEMODE) pvInBuffer; + PVR_UNREFERENCED_PARAMETER( pvOutBuffer); + + ExtDBGDrivOverrideMode((PDBG_STREAM) psParams->pvStream,psParams->ui32Mode); + + return(IMG_TRUE); +} + +IMG_UINT32 DBGDIOCDrivDefaultMode(IMG_VOID * pvInBuffer, IMG_VOID * pvOutBuffer) +{ + IMG_UINT32 * pStream; + PDBG_STREAM psStream; + + pStream = (IMG_UINT32 *) pvInBuffer; + psStream = (PDBG_STREAM) *pStream; + + PVR_UNREFERENCED_PARAMETER(pvOutBuffer); + + ExtDBGDrivDefaultMode(psStream); + + return(IMG_TRUE); +} + +IMG_UINT32 DBGDIOCDrivSetMarker(IMG_VOID * pvInBuffer, IMG_VOID * pvOutBuffer) +{ + PDBG_IN_SETMARKER psParams; + + psParams = (PDBG_IN_SETMARKER) pvInBuffer; + PVR_UNREFERENCED_PARAMETER(pvOutBuffer); + + ExtDBGDrivSetMarker((PDBG_STREAM) psParams->pvStream, psParams->ui32Marker); + + return(IMG_TRUE); +} + +IMG_UINT32 DBGDIOCDrivGetMarker(IMG_VOID * pvInBuffer, IMG_VOID * pvOutBuffer) +{ + IMG_UINT32 * pStream; + PDBG_STREAM psStream; + IMG_UINT32 * pui32Current; + + pStream = (IMG_UINT32 *) pvInBuffer; + psStream = (PDBG_STREAM) *pStream; + pui32Current = (IMG_UINT32 *) pvOutBuffer; + + *pui32Current = ExtDBGDrivGetMarker(psStream); + + return(IMG_TRUE); +} + +IMG_UINT32 DBGDIOCDrivGetServiceTable(IMG_VOID * pvInBuffer, IMG_VOID * pvOutBuffer) +{ + IMG_UINT32 * pui32Out; + + PVR_UNREFERENCED_PARAMETER(pvInBuffer); + pui32Out = (IMG_UINT32 *) pvOutBuffer; + + *pui32Out = DBGDrivGetServiceTable(); + + return(IMG_TRUE); +} + +IMG_UINT32 DBGDIOCDrivWriteLF(IMG_VOID * pvInBuffer, IMG_VOID * pvOutBuffer) +{ + PDBG_IN_WRITE_LF psInParams; + IMG_UINT32 * pui32BytesCopied; + + psInParams = (PDBG_IN_WRITE_LF) pvInBuffer; + pui32BytesCopied = (IMG_UINT32 *) pvOutBuffer; + + *pui32BytesCopied = ExtDBGDrivWriteLF(psInParams->pvStream, + psInParams->pui8InBuffer, + psInParams->ui32BufferSize, + psInParams->ui32Level, + psInParams->ui32Flags); + + return IMG_TRUE; +} + +IMG_UINT32 DBGDIOCDrivReadLF(IMG_VOID * pvInBuffer, IMG_VOID * pvOutBuffer) +{ + IMG_UINT32 * pui32BytesCopied; + PDBG_IN_READ psInParams; + + psInParams = (PDBG_IN_READ) pvInBuffer; + pui32BytesCopied = (IMG_UINT32 *) pvOutBuffer; + + *pui32BytesCopied = ExtDBGDrivReadLF((PDBG_STREAM) psInParams->pvStream,psInParams->ui32OutBufferSize,psInParams->pui8OutBuffer); + + return(IMG_TRUE); +} + +IMG_UINT32 DBGDIOCDrivWaitForEvent(IMG_VOID * pvInBuffer, IMG_VOID * pvOutBuffer) +{ + DBG_EVENT eEvent = (DBG_EVENT)(*(IMG_UINT32 *)pvInBuffer); + + PVR_UNREFERENCED_PARAMETER(pvOutBuffer); + + ExtDBGDrivWaitForEvent(eEvent); + + return(IMG_TRUE); +} diff --git a/tools/intern/debug/dbgdriv/common/ioctl.h b/tools/intern/debug/dbgdriv/common/ioctl.h new file mode 100644 index 0000000..061be9a --- /dev/null +++ b/tools/intern/debug/dbgdriv/common/ioctl.h @@ -0,0 +1,87 @@ +/********************************************************************** + * + * Copyright(c) 2008 Imagination Technologies Ltd. All rights reserved. + * + * This program is free software; you can redistribute it and/or modify it + * under the terms and conditions of the GNU General Public License, + * version 2, as published by the Free Software Foundation. + * + * This program is distributed in the hope it will be useful but, except + * as otherwise stated in writing, without any warranty; without even the + * implied warranty of merchantability or fitness for a particular purpose. + * See the GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License along with + * this program; if not, write to the Free Software Foundation, Inc., + * 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA. + * + * The full GNU General Public License is included in this distribution in + * the file called "COPYING". + * + * Contact Information: + * Imagination Technologies Ltd. + * Home Park Estate, Kings Langley, Herts, WD4 8LZ, UK + * + ******************************************************************************/ + +#ifndef _IOCTL_ +#define _IOCTL_ + + +IMG_UINT32 DBGDIOCDrivCreateStream(IMG_VOID *, IMG_VOID *); +IMG_UINT32 DBGDIOCDrivDestroyStream(IMG_VOID *, IMG_VOID *); +IMG_UINT32 DBGDIOCDrivGetStream(IMG_VOID *, IMG_VOID *); +IMG_UINT32 DBGDIOCDrivWriteString(IMG_VOID *, IMG_VOID *); +IMG_UINT32 DBGDIOCDrivReadString(IMG_VOID *, IMG_VOID *); +IMG_UINT32 DBGDIOCDrivWrite(IMG_VOID *, IMG_VOID *); +IMG_UINT32 DBGDIOCDrivWrite2(IMG_VOID *, IMG_VOID *); +IMG_UINT32 DBGDIOCDrivRead(IMG_VOID *, IMG_VOID *); +IMG_UINT32 DBGDIOCDrivSetCaptureMode(IMG_VOID *, IMG_VOID *); +IMG_UINT32 DBGDIOCDrivSetOutMode(IMG_VOID *, IMG_VOID *); +IMG_UINT32 DBGDIOCDrivSetDebugLevel(IMG_VOID *, IMG_VOID *); +IMG_UINT32 DBGDIOCDrivSetFrame(IMG_VOID *, IMG_VOID *); +IMG_UINT32 DBGDIOCDrivGetFrame(IMG_VOID *, IMG_VOID *); +IMG_UINT32 DBGDIOCDrivOverrideMode(IMG_VOID *, IMG_VOID *); +IMG_UINT32 DBGDIOCDrivDefaultMode(IMG_VOID *, IMG_VOID *); +IMG_UINT32 DBGDIOCDrivGetServiceTable(IMG_VOID *, IMG_VOID *); +IMG_UINT32 DBGDIOCDrivWriteStringCM(IMG_VOID *, IMG_VOID *); +IMG_UINT32 DBGDIOCDrivWriteCM(IMG_VOID *, IMG_VOID *); +IMG_UINT32 DBGDIOCDrivSetMarker(IMG_VOID *, IMG_VOID *); +IMG_UINT32 DBGDIOCDrivGetMarker(IMG_VOID *, IMG_VOID *); +IMG_UINT32 DBGDIOCDrivIsCaptureFrame(IMG_VOID *, IMG_VOID *); +IMG_UINT32 DBGDIOCDrivWriteLF(IMG_VOID *, IMG_VOID *); +IMG_UINT32 DBGDIOCDrivReadLF(IMG_VOID *, IMG_VOID *); +IMG_UINT32 DBGDIOCDrivWaitForEvent(IMG_VOID*, IMG_VOID *); + +IMG_UINT32 (*g_DBGDrivProc[])(IMG_VOID *, IMG_VOID *) = +{ + DBGDIOCDrivCreateStream, + DBGDIOCDrivDestroyStream, + DBGDIOCDrivGetStream, + DBGDIOCDrivWriteString, + DBGDIOCDrivReadString, + DBGDIOCDrivWrite, + DBGDIOCDrivRead, + DBGDIOCDrivSetCaptureMode, + DBGDIOCDrivSetOutMode, + DBGDIOCDrivSetDebugLevel, + DBGDIOCDrivSetFrame, + DBGDIOCDrivGetFrame, + DBGDIOCDrivOverrideMode, + DBGDIOCDrivDefaultMode, + DBGDIOCDrivGetServiceTable, + DBGDIOCDrivWrite2, + DBGDIOCDrivWriteStringCM, + DBGDIOCDrivWriteCM, + DBGDIOCDrivSetMarker, + DBGDIOCDrivGetMarker, + DBGDIOCDrivIsCaptureFrame, + DBGDIOCDrivWriteLF, + DBGDIOCDrivReadLF, + DBGDIOCDrivWaitForEvent +}; + +#define MAX_DBGVXD_W32_API (sizeof(g_DBGDrivProc)/sizeof(IMG_UINT32)) + +#endif + diff --git a/tools/intern/debug/dbgdriv/linux/hostfunc.c b/tools/intern/debug/dbgdriv/linux/hostfunc.c new file mode 100644 index 0000000..dc2f035 --- /dev/null +++ b/tools/intern/debug/dbgdriv/linux/hostfunc.c @@ -0,0 +1,300 @@ +/********************************************************************** + * + * Copyright(c) 2008 Imagination Technologies Ltd. All rights reserved. + * + * This program is free software; you can redistribute it and/or modify it + * under the terms and conditions of the GNU General Public License, + * version 2, as published by the Free Software Foundation. + * + * This program is distributed in the hope it will be useful but, except + * as otherwise stated in writing, without any warranty; without even the + * implied warranty of merchantability or fitness for a particular purpose. + * See the GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License along with + * this program; if not, write to the Free Software Foundation, Inc., + * 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA. + * + * The full GNU General Public License is included in this distribution in + * the file called "COPYING". + * + * Contact Information: + * Imagination Technologies Ltd. + * Home Park Estate, Kings Langley, Herts, WD4 8LZ, UK + * + ******************************************************************************/ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,15)) +#include +#else +#include +#endif +#include + +#if defined(SUPPORT_DBGDRV_EVENT_OBJECTS) +#include +#include +#include +#include +#endif + +#include "img_types.h" +#include "pvr_debug.h" + +#include "dbgdrvif.h" +#include "hostfunc.h" + +IMG_UINT32 gPVRDebugLevel = DBGPRIV_WARNING; + +#define PVR_STRING_TERMINATOR '\0' +#define PVR_IS_FILE_SEPARATOR(character) ( ((character) == '\\') || ((character) == '/') ) + +void PVRSRVDebugPrintf ( + IMG_UINT32 ui32DebugLevel, + const IMG_CHAR* pszFileName, + IMG_UINT32 ui32Line, + const IMG_CHAR* pszFormat, + ... + ) +{ + IMG_BOOL bTrace, bDebug; +#if !defined(__sh__) + IMG_CHAR *pszLeafName; + + pszLeafName = (char *)strrchr (pszFileName, '\\'); + + if (pszLeafName) + { + pszFileName = pszLeafName; + } +#endif + + bTrace = gPVRDebugLevel & ui32DebugLevel & DBGPRIV_CALLTRACE; + bDebug = ((gPVRDebugLevel & DBGPRIV_ALLLEVELS) >= ui32DebugLevel); + + if (bTrace || bDebug) + { + va_list vaArgs; + static char szBuffer[256]; + + va_start (vaArgs, pszFormat); + + + if (bDebug) + { + switch(ui32DebugLevel) + { + case DBGPRIV_FATAL: + { + strcpy (szBuffer, "PVR_K:(Fatal): "); + break; + } + case DBGPRIV_ERROR: + { + strcpy (szBuffer, "PVR_K:(Error): "); + break; + } + case DBGPRIV_WARNING: + { + strcpy (szBuffer, "PVR_K:(Warning): "); + break; + } + case DBGPRIV_MESSAGE: + { + strcpy (szBuffer, "PVR_K:(Message): "); + break; + } + case DBGPRIV_VERBOSE: + { + strcpy (szBuffer, "PVR_K:(Verbose): "); + break; + } + default: + { + strcpy (szBuffer, "PVR_K:(Unknown message level)"); + break; + } + } + } + else + { + strcpy (szBuffer, "PVR_K: "); + } + + vsprintf (&szBuffer[strlen(szBuffer)], pszFormat, vaArgs); + + + + if (!bTrace) + { + sprintf (&szBuffer[strlen(szBuffer)], " [%d, %s]", (int)ui32Line, pszFileName); + } + + printk(KERN_INFO "%s\r\n", szBuffer); + + va_end (vaArgs); + } +} + +IMG_VOID HostMemSet(IMG_VOID *pvDest, IMG_UINT8 ui8Value, IMG_UINT32 ui32Size) +{ + memset(pvDest, (int) ui8Value, (size_t) ui32Size); +} + +IMG_VOID HostMemCopy(IMG_VOID *pvDst, IMG_VOID *pvSrc, IMG_UINT32 ui32Size) +{ +#if defined(USE_UNOPTIMISED_MEMCPY) + unsigned char *src,*dst; + int i; + + src=(unsigned char *)pvSrc; + dst=(unsigned char *)pvDst; + for(i=0;i +# Home Park Estate, Kings Langley, Herts, WD4 8LZ, UK +# +# +# + +include $(EURASIAROOT)/eurasiacon/build/linux/kbuild/Makefile.kbuild_subdir_common + +MODULE = dbgdrv + +INCLUDES = -I$(EURASIAROOT)/include4 \ + -I$(EURASIAROOT)/tools/intern/debug/dbgdriv/common \ + -I$(EURASIAROOT)/tools/intern/debug/dbgdriv/linux \ + -I$(EURASIAROOT)/tools/intern/debug/client + +SOURCES = ../main.c \ + ../../common/dbgdriv.c \ + ../../common/ioctl.c \ + ../hostfunc.c \ + ../../common/hotkey.c + + + diff --git a/tools/intern/debug/dbgdriv/linux/main.c b/tools/intern/debug/dbgdriv/linux/main.c new file mode 100644 index 0000000..09f9ab3 --- /dev/null +++ b/tools/intern/debug/dbgdriv/linux/main.c @@ -0,0 +1,218 @@ +/********************************************************************** + * + * Copyright(c) 2008 Imagination Technologies Ltd. All rights reserved. + * + * This program is free software; you can redistribute it and/or modify it + * under the terms and conditions of the GNU General Public License, + * version 2, as published by the Free Software Foundation. + * + * This program is distributed in the hope it will be useful but, except + * as otherwise stated in writing, without any warranty; without even the + * implied warranty of merchantability or fitness for a particular purpose. + * See the GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License along with + * this program; if not, write to the Free Software Foundation, Inc., + * 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA. + * + * The full GNU General Public License is included in this distribution in + * the file called "COPYING". + * + * Contact Information: + * Imagination Technologies Ltd. + * Home Park Estate, Kings Langley, Herts, WD4 8LZ, UK + * + ******************************************************************************/ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include "img_types.h" +#include "linuxsrv.h" +#include "ioctl.h" +#include "dbgdrvif.h" +#include "dbgdriv.h" +#include "hostfunc.h" +#include "pvr_debug.h" + + +#define DRVNAME "dbgdrv" + +MODULE_AUTHOR("Imagination Technologies Ltd. "); +MODULE_LICENSE("GPL"); +MODULE_SUPPORTED_DEVICE(DRVNAME); + +static int AssignedMajorNumber = 0; + +extern DBGKM_SERVICE_TABLE g_sDBGKMServices; + +long dbgdrv_ioctl(struct file *, unsigned int, unsigned long); + +static int dbgdrv_open(struct inode unref__ * pInode, struct file unref__ * pFile) +{ + return 0; +} + +static int dbgdrv_release(struct inode unref__ * pInode, struct file unref__ * pFile) +{ + return 0; +} + +static int dbgdrv_mmap(struct file* pFile, struct vm_area_struct* ps_vma) +{ + return 0; +} + +static struct file_operations dbgdrv_fops = { + owner:THIS_MODULE, + unlocked_ioctl:dbgdrv_ioctl, + open:dbgdrv_open, + release:dbgdrv_release, + mmap:dbgdrv_mmap, +}; + + +void DBGDrvGetServiceTable(void **fn_table) +{ + *fn_table = &g_sDBGKMServices; + +} + +void cleanup_module(void) +{ + if (AssignedMajorNumber > 0) + { + unregister_chrdev(AssignedMajorNumber, DRVNAME); + } + +#if defined(SUPPORT_DBGDRV_EVENT_OBJECTS) + HostDestroyEventObjects(); +#endif + + if (g_pvAPIMutex != IMG_NULL) + { + HostDestroyMutex(g_pvAPIMutex); + } + + return; +} + +int init_module(void) +{ + + if ((g_pvAPIMutex=HostCreateMutex()) == IMG_NULL) + { + cleanup_module(); + return -ENOMEM; + } + +#if defined(SUPPORT_DBGDRV_EVENT_OBJECTS) + + (void) HostCreateEventObjects(); +#endif + + AssignedMajorNumber = + register_chrdev(AssignedMajorNumber, DRVNAME, &dbgdrv_fops); + + if (AssignedMajorNumber <= 0) + { + PVR_DPF((PVR_DBG_ERROR," unable to get major\n")); + cleanup_module(); + return -EBUSY; + } + + return 0; +} + +long dbgdrv_ioctl(struct file *file, unsigned int cmd, unsigned long arg) +{ + IOCTL_PACKAGE *pIP = (IOCTL_PACKAGE *) arg; + + char *buffer, *in, *out; + + if((pIP->ui32InBufferSize > (PAGE_SIZE >> 1) ) || (pIP->ui32OutBufferSize > (PAGE_SIZE >> 1))) + { + PVR_DPF((PVR_DBG_ERROR,"Sizes of the buffers are too large, cannot do ioctl\n")); + return -1; + } + + buffer = (char *) HostPageablePageAlloc(1); + if(!buffer) + { + PVR_DPF((PVR_DBG_ERROR,"Failed to allocate buffer, cannot do ioctl\n")); + return -EFAULT; + } + + in = buffer; + out = buffer + (PAGE_SIZE >>1); + + if(copy_from_user(in, pIP->pInBuffer, pIP->ui32InBufferSize) != 0) + { + goto init_failed; + } + + cmd = ((pIP->ui32Cmd >> 2) & 0xFFF) - 0x801; + + if(pIP->ui32Cmd == DEBUG_SERVICE_READ) + { + IMG_CHAR *ui8Tmp; + IMG_UINT32 *pui32BytesCopied = (IMG_UINT32 *)out; + DBG_IN_READ *psReadInParams = (DBG_IN_READ *)in; + + ui8Tmp = vmalloc(psReadInParams->ui32OutBufferSize); + if(!ui8Tmp) + { + goto init_failed; + } + *pui32BytesCopied = ExtDBGDrivRead((DBG_STREAM *)psReadInParams->pvStream, + psReadInParams->bReadInitBuffer, + psReadInParams->ui32OutBufferSize, + ui8Tmp); + if(copy_to_user(psReadInParams->pui8OutBuffer, + ui8Tmp, + *pui32BytesCopied) != 0) + { + vfree(ui8Tmp); + goto init_failed; + } + vfree(ui8Tmp); + } + else + { + (g_DBGDrivProc[cmd])(in, out); + } + + if(copy_to_user(pIP->pOutBuffer, out, pIP->ui32OutBufferSize) != 0) + { + goto init_failed; + } + + HostPageablePageFree((IMG_VOID *)buffer); + return 0; + +init_failed: + HostPageablePageFree((IMG_VOID *)buffer); + return -EFAULT; +} + + +void RemoveHotKey(unsigned hHotKey) +{ + +} + +void DefineHotKey(unsigned ScanCode, unsigned ShiftState, void *pInfo) +{ + +} + +EXPORT_SYMBOL(DBGDrvGetServiceTable); +