4_00_00_01/1.4.14.2616 release
authorImagination Technologies/TI <imgtec>
Sat, 24 Mar 2012 23:36:31 +0000 (01:36 +0200)
committerGrazvydas Ignotas <notasas@gmail.com>
Sat, 24 Mar 2012 23:36:31 +0000 (01:36 +0200)
175 files changed:
COPYING [new file with mode: 0644]
INSTALL [new file with mode: 0644]
Kbuild [new file with mode: 0644]
Makefile [new file with mode: 0644]
README [new file with mode: 0644]
eurasiacon/build/linux/kbuild/Makefile.kbuild [new file with mode: 0644]
eurasiacon/build/linux/kbuild/Makefile.kbuild_subdir [new file with mode: 0644]
eurasiacon/build/linux/kbuild/Makefile.kbuild_subdir_common [new file with mode: 0644]
eurasiacon/build/linux/kbuild/Makefile.kbuild_subdir_rules [new file with mode: 0644]
eurasiacon/build/linux/makefile.shared_conf [new file with mode: 0755]
eurasiacon/build/linux/omap3430_linux/kbuild/Makefile [new file with mode: 0644]
eurasiacon/build/linux/omap3430_linux/kbuild/build_gfx_kernelmodules [new file with mode: 0755]
eurasiacon/build/linux/omap3430_linux/makefile.core [new file with mode: 0755]
eurasiacon/build/linux/omap3430_linux/makefile.shared_conf [new file with mode: 0755]
eurasiacon/build/linux/omap3630_linux/kbuild/Makefile [new file with mode: 0644]
eurasiacon/build/linux/omap3630_linux/kbuild/build_gfx_kernelmodules [new file with mode: 0755]
eurasiacon/build/linux/omap3630_linux/makefile.core [new file with mode: 0755]
eurasiacon/build/linux/omap3630_linux/makefile.shared_conf [new file with mode: 0755]
include4/dbgdrvif.h [new file with mode: 0644]
include4/img_defs.h [new file with mode: 0644]
include4/img_types.h [new file with mode: 0644]
include4/ioctldef.h [new file with mode: 0644]
include4/pdumpdefs.h [new file with mode: 0644]
include4/pvr_debug.h [new file with mode: 0644]
include4/pvrmodule.h [new file with mode: 0644]
include4/pvrversion.h [new file with mode: 0644]
include4/regpaths.h [new file with mode: 0644]
include4/services.h [new file with mode: 0644]
include4/servicesext.h [new file with mode: 0644]
include4/sgx_options.h [new file with mode: 0644]
include4/sgxapi_km.h [new file with mode: 0644]
include4/sgxscript.h [new file with mode: 0644]
services4/3rdparty/bufferclass_example/bufferclass_example.c [new file with mode: 0644]
services4/3rdparty/bufferclass_example/bufferclass_example.h [new file with mode: 0644]
services4/3rdparty/bufferclass_example/bufferclass_example_linux.c [new file with mode: 0644]
services4/3rdparty/bufferclass_example/bufferclass_example_linux.h [new file with mode: 0644]
services4/3rdparty/bufferclass_example/bufferclass_example_private.c [new file with mode: 0644]
services4/3rdparty/bufferclass_example/kbuild/Makefile [new file with mode: 0644]
services4/3rdparty/bufferclass_ti/Kbuild [new file with mode: 0755]
services4/3rdparty/bufferclass_ti/Makefile [new file with mode: 0644]
services4/3rdparty/bufferclass_ti/bc_cat.c [new file with mode: 0644]
services4/3rdparty/bufferclass_ti/bc_cat.h [new file with mode: 0644]
services4/3rdparty/bufferclass_ti/modules.order [new file with mode: 0644]
services4/3rdparty/dc_omap3430_linux/Kbuild [new file with mode: 0755]
services4/3rdparty/dc_omap3430_linux/kbuild/Makefile [new file with mode: 0644]
services4/3rdparty/dc_omap3430_linux/modules.order [new file with mode: 0644]
services4/3rdparty/dc_omap3430_linux/omaplfb.h [new file with mode: 0644]
services4/3rdparty/dc_omap3430_linux/omaplfb_displayclass.c [new file with mode: 0644]
services4/3rdparty/dc_omap3430_linux/omaplfb_linux.c [new file with mode: 0644]
services4/3rdparty/dc_ti8168_linux/Kbuild [new file with mode: 0755]
services4/3rdparty/dc_ti8168_linux/kbuild/Makefile [new file with mode: 0644]
services4/3rdparty/dc_ti8168_linux/modules.order [new file with mode: 0644]
services4/3rdparty/dc_ti8168_linux/omaplfb.h [new file with mode: 0644]
services4/3rdparty/dc_ti8168_linux/omaplfb_displayclass.c [new file with mode: 0644]
services4/3rdparty/dc_ti8168_linux/omaplfb_linux.c [new file with mode: 0644]
services4/include/kernelbuffer.h [new file with mode: 0644]
services4/include/kerneldisplay.h [new file with mode: 0644]
services4/include/pvr_bridge.h [new file with mode: 0644]
services4/include/pvr_bridge_km.h [new file with mode: 0644]
services4/include/pvrmmap.h [new file with mode: 0644]
services4/include/servicesint.h [new file with mode: 0644]
services4/include/sgx_bridge.h [new file with mode: 0644]
services4/include/sgxinfo.h [new file with mode: 0644]
services4/srvkm/bridged/bridged_pvr_bridge.c [new file with mode: 0644]
services4/srvkm/bridged/bridged_pvr_bridge.h [new file with mode: 0644]
services4/srvkm/bridged/bridged_support.c [new file with mode: 0644]
services4/srvkm/bridged/bridged_support.h [new file with mode: 0644]
services4/srvkm/bridged/sgx/bridged_sgx_bridge.c [new file with mode: 0644]
services4/srvkm/bridged/sgx/bridged_sgx_bridge.h [new file with mode: 0644]
services4/srvkm/common/buffer_manager.c [new file with mode: 0644]
services4/srvkm/common/deviceclass.c [new file with mode: 0644]
services4/srvkm/common/devicemem.c [new file with mode: 0644]
services4/srvkm/common/handle.c [new file with mode: 0644]
services4/srvkm/common/hash.c [new file with mode: 0644]
services4/srvkm/common/mem.c [new file with mode: 0644]
services4/srvkm/common/metrics.c [new file with mode: 0644]
services4/srvkm/common/pdump_common.c [new file with mode: 0644]
services4/srvkm/common/perproc.c [new file with mode: 0644]
services4/srvkm/common/power.c [new file with mode: 0644]
services4/srvkm/common/pvrsrv.c [new file with mode: 0644]
services4/srvkm/common/queue.c [new file with mode: 0644]
services4/srvkm/common/ra.c [new file with mode: 0644]
services4/srvkm/common/resman.c [new file with mode: 0644]
services4/srvkm/devices/sgx/mmu.c [new file with mode: 0644]
services4/srvkm/devices/sgx/mmu.h [new file with mode: 0644]
services4/srvkm/devices/sgx/pb.c [new file with mode: 0644]
services4/srvkm/devices/sgx/sgx_bridge_km.h [new file with mode: 0644]
services4/srvkm/devices/sgx/sgxconfig.h [new file with mode: 0644]
services4/srvkm/devices/sgx/sgxinfokm.h [new file with mode: 0644]
services4/srvkm/devices/sgx/sgxinit.c [new file with mode: 0644]
services4/srvkm/devices/sgx/sgxkick.c [new file with mode: 0644]
services4/srvkm/devices/sgx/sgxpower.c [new file with mode: 0644]
services4/srvkm/devices/sgx/sgxreset.c [new file with mode: 0644]
services4/srvkm/devices/sgx/sgxtransfer.c [new file with mode: 0644]
services4/srvkm/devices/sgx/sgxutils.c [new file with mode: 0644]
services4/srvkm/devices/sgx/sgxutils.h [new file with mode: 0644]
services4/srvkm/env/linux/env_data.h [new file with mode: 0644]
services4/srvkm/env/linux/env_perproc.h [new file with mode: 0644]
services4/srvkm/env/linux/event.c [new file with mode: 0644]
services4/srvkm/env/linux/event.h [new file with mode: 0644]
services4/srvkm/env/linux/kbuild/Makefile [new file with mode: 0644]
services4/srvkm/env/linux/linkage.h [new file with mode: 0644]
services4/srvkm/env/linux/lock.h [new file with mode: 0644]
services4/srvkm/env/linux/mm.c [new file with mode: 0644]
services4/srvkm/env/linux/mm.h [new file with mode: 0644]
services4/srvkm/env/linux/mmap.c [new file with mode: 0644]
services4/srvkm/env/linux/mmap.h [new file with mode: 0644]
services4/srvkm/env/linux/module.c [new file with mode: 0644]
services4/srvkm/env/linux/mutex.c [new file with mode: 0644]
services4/srvkm/env/linux/mutex.h [new file with mode: 0644]
services4/srvkm/env/linux/mutils.c [new file with mode: 0644]
services4/srvkm/env/linux/mutils.h [new file with mode: 0644]
services4/srvkm/env/linux/osfunc.c [new file with mode: 0644]
services4/srvkm/env/linux/osperproc.c [new file with mode: 0644]
services4/srvkm/env/linux/pdump.c [new file with mode: 0644]
services4/srvkm/env/linux/private_data.h [new file with mode: 0644]
services4/srvkm/env/linux/proc.c [new file with mode: 0644]
services4/srvkm/env/linux/proc.h [new file with mode: 0644]
services4/srvkm/env/linux/pvr_bridge_k.c [new file with mode: 0644]
services4/srvkm/env/linux/pvr_debug.c [new file with mode: 0644]
services4/srvkm/hwdefs/sgx530defs.h [new file with mode: 0644]
services4/srvkm/hwdefs/sgx540defs.h [new file with mode: 0644]
services4/srvkm/hwdefs/sgxcoretypes.h [new file with mode: 0644]
services4/srvkm/hwdefs/sgxdefs.h [new file with mode: 0644]
services4/srvkm/hwdefs/sgxerrata.h [new file with mode: 0644]
services4/srvkm/hwdefs/sgxfeaturedefs.h [new file with mode: 0644]
services4/srvkm/hwdefs/sgxmmu.h [new file with mode: 0644]
services4/srvkm/include/buffer_manager.h [new file with mode: 0644]
services4/srvkm/include/device.h [new file with mode: 0644]
services4/srvkm/include/handle.h [new file with mode: 0644]
services4/srvkm/include/hash.h [new file with mode: 0644]
services4/srvkm/include/metrics.h [new file with mode: 0644]
services4/srvkm/include/osfunc.h [new file with mode: 0644]
services4/srvkm/include/osperproc.h [new file with mode: 0644]
services4/srvkm/include/pdump_km.h [new file with mode: 0644]
services4/srvkm/include/perproc.h [new file with mode: 0644]
services4/srvkm/include/power.h [new file with mode: 0644]
services4/srvkm/include/queue.h [new file with mode: 0644]
services4/srvkm/include/ra.h [new file with mode: 0644]
services4/srvkm/include/resman.h [new file with mode: 0644]
services4/srvkm/include/services_headers.h [new file with mode: 0644]
services4/srvkm/include/srvkm.h [new file with mode: 0644]
services4/system/include/syscommon.h [new file with mode: 0644]
services4/system/omap3430/oemfuncs.h [new file with mode: 0644]
services4/system/omap3430/sysconfig.c [new file with mode: 0644]
services4/system/omap3430/sysconfig.h [new file with mode: 0644]
services4/system/omap3430/sysinfo.h [new file with mode: 0644]
services4/system/omap3430/syslocal.h [new file with mode: 0644]
services4/system/omap3430/sysutils.c [new file with mode: 0644]
services4/system/omap3430/sysutils_linux.c [new file with mode: 0644]
services4/system/omap3630/oemfuncs.h [new file with mode: 0644]
services4/system/omap3630/sysconfig.c [new file with mode: 0644]
services4/system/omap3630/sysconfig.h [new file with mode: 0644]
services4/system/omap3630/sysinfo.h [new file with mode: 0644]
services4/system/omap3630/syslocal.h [new file with mode: 0644]
services4/system/omap3630/sysutils.c [new file with mode: 0644]
services4/system/omap3630/sysutils_linux.c [new file with mode: 0644]
services4/system/ti8168/oemfuncs.h [new file with mode: 0644]
services4/system/ti8168/sysconfig.c [new file with mode: 0644]
services4/system/ti8168/sysconfig.h [new file with mode: 0644]
services4/system/ti8168/sysinfo.h [new file with mode: 0644]
services4/system/ti8168/syslocal.h [new file with mode: 0644]
services4/system/ti8168/sysutils.c [new file with mode: 0644]
services4/system/ti8168/sysutils_linux.c [new file with mode: 0644]
tools/intern/debug/client/linuxsrv.h [new file with mode: 0644]
tools/intern/debug/dbgdriv/common/dbgdriv.c [new file with mode: 0644]
tools/intern/debug/dbgdriv/common/dbgdriv.h [new file with mode: 0644]
tools/intern/debug/dbgdriv/common/hostfunc.h [new file with mode: 0644]
tools/intern/debug/dbgdriv/common/hotkey.c [new file with mode: 0644]
tools/intern/debug/dbgdriv/common/hotkey.h [new file with mode: 0644]
tools/intern/debug/dbgdriv/common/ioctl.c [new file with mode: 0644]
tools/intern/debug/dbgdriv/common/ioctl.h [new file with mode: 0644]
tools/intern/debug/dbgdriv/linux/hostfunc.c [new file with mode: 0644]
tools/intern/debug/dbgdriv/linux/kbuild/Makefile [new file with mode: 0644]
tools/intern/debug/dbgdriv/linux/main.c [new file with mode: 0644]

diff --git a/COPYING b/COPYING
new file mode 100644 (file)
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.
+
+    <one line to give the program's name and a brief idea of what it does.>
+    Copyright (C) 19yy  <name of author>
+
+    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.
+
+  <signature of Ty Coon>, 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 (file)
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 (file)
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 (file)
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 (file)
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. <gpl-support@imgtec.com>
+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 (file)
index 0000000..dd92077
--- /dev/null
@@ -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. <gpl-support@imgtec.com>
+# 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 (file)
index 0000000..c18bbe3
--- /dev/null
@@ -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. <gpl-support@imgtec.com>
+# 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 (file)
index 0000000..92d3034
--- /dev/null
@@ -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. <gpl-support@imgtec.com>
+# 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 (file)
index 0000000..a2af203
--- /dev/null
@@ -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. <gpl-support@imgtec.com>
+# 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 (executable)
index 0000000..14dcac0
--- /dev/null
@@ -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. <gpl-support@imgtec.com>
+# 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 (file)
index 0000000..5747505
--- /dev/null
@@ -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. <gpl-support@imgtec.com>
+# 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 (executable)
index 0000000..04f32f1
--- /dev/null
@@ -0,0 +1,23 @@
+#!/bin/sh
+
+#set home path
+#HOME=/home/<user>
+
+#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 (executable)
index 0000000..b16d3ef
--- /dev/null
@@ -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. <gpl-support@imgtec.com>
+# 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 (executable)
index 0000000..9eb7f17
--- /dev/null
@@ -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. <gpl-support@imgtec.com>
+# 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 (file)
index 0000000..5747505
--- /dev/null
@@ -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. <gpl-support@imgtec.com>
+# 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 (executable)
index 0000000..04f32f1
--- /dev/null
@@ -0,0 +1,23 @@
+#!/bin/sh
+
+#set home path
+#HOME=/home/<user>
+
+#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 (executable)
index 0000000..b16d3ef
--- /dev/null
@@ -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. <gpl-support@imgtec.com>
+# 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 (executable)
index 0000000..fed61f1
--- /dev/null
@@ -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. <gpl-support@imgtec.com>
+# 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 (file)
index 0000000..e10db38
--- /dev/null
@@ -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. <gpl-support@imgtec.com>
+ * 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 (file)
index 0000000..bf3f16e
--- /dev/null
@@ -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. <gpl-support@imgtec.com>
+ * 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 (file)
index 0000000..b1e0af4
--- /dev/null
@@ -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. <gpl-support@imgtec.com>
+ * 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 (file)
index 0000000..4b23ad4
--- /dev/null
@@ -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. <gpl-support@imgtec.com>
+ * 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 (file)
index 0000000..ca599ce
--- /dev/null
@@ -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. <gpl-support@imgtec.com>
+ * 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 (file)
index 0000000..72379c7
--- /dev/null
@@ -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. <gpl-support@imgtec.com>
+ * 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 (file)
index 0000000..30cb2c3
--- /dev/null
@@ -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. <gpl-support@imgtec.com>
+ * Home Park Estate, Kings Langley, Herts, WD4 8LZ, UK 
+ *
+ ******************************************************************************/
+
+#ifndef        _PVRMODULE_H_
+#define        _PVRMODULE_H_
+MODULE_AUTHOR("Imagination Technologies Ltd. <gpl-support@imgtec.com>");
+MODULE_LICENSE("GPL");
+#endif 
diff --git a/include4/pvrversion.h b/include4/pvrversion.h
new file mode 100644 (file)
index 0000000..dce1ccd
--- /dev/null
@@ -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. <gpl-support@imgtec.com>
+ * 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 (file)
index 0000000..a551eff
--- /dev/null
@@ -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. <gpl-support@imgtec.com>
+ * 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 (file)
index 0000000..f81ef27
--- /dev/null
@@ -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. <gpl-support@imgtec.com>
+ * 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 (file)
index 0000000..947f354
--- /dev/null
@@ -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. <gpl-support@imgtec.com>
+ * 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 (file)
index 0000000..dfafbd7
--- /dev/null
@@ -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. <gpl-support@imgtec.com>
+ * 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 (file)
index 0000000..ab0e411
--- /dev/null
@@ -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. <gpl-support@imgtec.com>
+ * 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 <asm/unistd.h>
+       #else
+               #include <unistd.h>
+       #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 (file)
index 0000000..47c9e48
--- /dev/null
@@ -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. <gpl-support@imgtec.com>
+ * 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 (file)
index 0000000..c32bf3c
--- /dev/null
@@ -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. <gpl-support@imgtec.com>
+ * 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 (file)
index 0000000..1791dd0
--- /dev/null
@@ -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. <gpl-support@imgtec.com>
+ * 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 (file)
index 0000000..e88764d
--- /dev/null
@@ -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. <gpl-support@imgtec.com>
+ * Home Park Estate, Kings Langley, Herts, WD4 8LZ, UK 
+ *
+ ******************************************************************************/
+
+#include <linux/version.h>
+#include <linux/kernel.h>
+#include <linux/module.h>
+#include <linux/fs.h>
+#include <asm/uaccess.h>
+#include <asm/io.h>
+
+#if defined(LMA)
+#include <linux/pci.h>
+#else
+#include <linux/dma-mapping.h>
+#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 <asm/cacheflush.h>
+#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 (file)
index 0000000..745072b
--- /dev/null
@@ -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. <gpl-support@imgtec.com>
+ * Home Park Estate, Kings Langley, Herts, WD4 8LZ, UK 
+ *
+ ******************************************************************************/
+
+#ifndef __BC_EXAMPLE_LINUX_H__
+#define __BC_EXAMPLE_LINUX_H__
+
+#include <linux/ioctl.h>
+
+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 (file)
index 0000000..721b825
--- /dev/null
@@ -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. <gpl-support@imgtec.com>
+ * 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<height;j++)
+       {
+               for(i=0;i<width;i++)
+               {
+                       y = (((i+iPhase)>>6)%(2)==0)? 0x7f:0x00;
+
+                       pui8y[count++] = y;
+               }
+       }
+
+       pui16uv = (unsigned short *)((unsigned char *)pvDest + (width * height));
+       count = 0;
+
+       for(j=0;j<height;j+=2)
+       {
+               for(i=0;i<width;i+=2)
+               {
+                       u = (j<(height/2))? ((i<(width/2))? 0xFF:0x33) : ((i<(width/2))? 0x33:0xAA);
+                       v = (j<(height/2))? ((i<(width/2))? 0xAC:0x0) : ((i<(width/2))? 0x03:0xEE);
+
+                       
+                       pui16uv[count++] = (v << 8) | u;
+
+               }
+       }
+
+       iPhase++;
+}
+
+void FillYUV422Image(void *pvDest, int width, int height, int bytestride)
+{
+       static int iPhase = 0;
+       int           x, y;
+       unsigned char u,v,y0,y1;
+       unsigned long *pui32yuv = (unsigned long *)pvDest;
+       unsigned int  count = 0;
+
+       for(y=0;y<height;y++)
+       {
+               for(x=0;x<width;x+=2)
+               {
+                       u = (y<(height/2))? ((x<(width/2))? 0xFF:0x33) : ((x<(width/2))? 0x33:0xAA);
+                       v = (y<(height/2))? ((x<(width/2))? 0xAA:0x0) : ((x<(width/2))? 0x03:0xEE);
+
+                       y0 = y1 = (((x+iPhase)>>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<Count; i++)
+       {
+               pui32Addr[i] = Colour32;
+       }
+
+       Count =  height;
+
+       pui16Addr = (unsigned short *)((unsigned char *)pvDest + (2 * Colour8));
+
+       for(i=0; i<Count; i++)
+       {
+               *pui16Addr = 0xF800U;
+
+               pui16Addr = (unsigned short *)((unsigned char *)pui16Addr + bytestride);
+       }
+       Count = bytestride >> 2;
+       
+       pui32Addr = (unsigned long *)((unsigned char *)pvDest + (bytestride * (MIN(height - 1, 0xFF) - Colour8)));
+
+       for(i=0; i<Count; i++)
+       {
+               pui32Addr[i] = 0x001F001FUL;
+       }
+
+       
+       Colour8 = (Colour8 + 1) % MIN(height - 1, 0xFFU);
+}
+
+
+int FillBuffer(unsigned int uiBufferIndex)
+{
+       BC_EXAMPLE_DEVINFO  *psDevInfo = GetAnchorPtr();
+       BC_EXAMPLE_BUFFER   *psBuffer;
+       BUFFER_INFO         *psBufferInfo;
+       PVRSRV_SYNC_DATA    *psSyncData;
+
+       
+       if(psDevInfo == NULL)
+       {
+               return -1;
+       }
+
+       psBuffer = &psDevInfo->psSystemBuffer[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 (file)
index 0000000..d0cbc45
--- /dev/null
@@ -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. <gpl-support@imgtec.com>
+# 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 (executable)
index 0000000..3dcf003
--- /dev/null
@@ -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 (file)
index 0000000..f261a6b
--- /dev/null
@@ -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 (file)
index 0000000..0b9f6e0
--- /dev/null
@@ -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. <gpl-support@imgtec.com>
+ * Home Park Estate, Kings Langley, Herts, WD4 8LZ, UK 
+ *
+ ******************************************************************************/
+
+#include <linux/kernel.h>
+#include <linux/module.h>
+#include <linux/fs.h>
+#include <asm/uaccess.h>
+#include <asm/io.h>
+#include <img_defs.h>
+#include <servicesext.h>
+#include <kernelbuffer.h>
+#include "bc_cat.h"
+
+#include <linux/slab.h>
+
+#include <linux/dma-mapping.h>
+
+#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 (file)
index 0000000..3ca0b69
--- /dev/null
@@ -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. <gpl-support@imgtec.com>
+ * Home Park Estate, Kings Langley, Herts, WD4 8LZ, UK 
+ *
+ ******************************************************************************/
+
+#ifndef __BC_CAT_H__
+#define __BC_CAT_H__
+
+#include <linux/ioctl.h>
+
+#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 (file)
index 0000000..cc7b6f2
--- /dev/null
@@ -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 (executable)
index 0000000..eca3626
--- /dev/null
@@ -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 (file)
index 0000000..54139af
--- /dev/null
@@ -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. <gpl-support@imgtec.com>
+# 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 (file)
index 0000000..104b655
--- /dev/null
@@ -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 (file)
index 0000000..da63959
--- /dev/null
@@ -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. <gpl-support@imgtec.com>
+ * 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 (file)
index 0000000..349beb5
--- /dev/null
@@ -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. <gpl-support@imgtec.com>
+ * Home Park Estate, Kings Langley, Herts, WD4 8LZ, UK 
+ *
+ ******************************************************************************/
+
+#include <linux/version.h>
+#include <linux/kernel.h>
+#include <linux/console.h>
+#include <linux/fb.h>
+#include <linux/module.h>
+#include <linux/string.h>
+#include <linux/notifier.h>
+#include <linux/spinlock.h>
+
+#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 <linux/workqueue.h>
+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; i<ui32BufferCount-1; i++)
+       {
+               psBuffer[i].psNext = &psBuffer[i+1];
+       }
+       
+       psBuffer[i].psNext = &psBuffer[0];
+
+       
+       for(i=0; i<ui32BufferCount; i++)
+       {
+               IMG_UINT32 ui32SwapBuffer = i + ui32BuffersToSkip;
+               IMG_UINT32 ui32BufferOffset = ui32SwapBuffer * (IMG_UINT32)psDevInfo->sFBInfo.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; i<ui32BufferCount; i++)
+       {
+               psVSyncFlips[i].bValid = OMAP_FALSE;
+               psVSyncFlips[i].bFlipped = OMAP_FALSE;
+               psVSyncFlips[i].bCmdCompleted = OMAP_FALSE;
+       }
+#if defined (SUPPORT_TI_DSS_FW)
+
+       OMAPLFBEnableDisplayRegisterAccess();
+
+       
+       psSwapChain->pvRegs = 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; i<psSwapChain->ulBufferCount; 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 (file)
index 0000000..9690796
--- /dev/null
@@ -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. <gpl-support@imgtec.com>
+ * Home Park Estate, Kings Langley, Herts, WD4 8LZ, UK 
+ *
+ ******************************************************************************/
+
+#ifndef AUTOCONF_INCLUDED
+#include <linux/config.h>
+#endif
+
+#include <linux/version.h>
+#include <linux/module.h>
+
+#include <linux/pci.h>
+#include <asm/uaccess.h>
+#include <linux/slab.h>
+#include <linux/errno.h>
+#include <linux/interrupt.h>
+
+#if defined(LDM_PLATFORM)
+#include <linux/platform_device.h>
+#endif 
+
+#if defined (SUPPORT_TI_DSS_FW)
+#include <asm/io.h>
+
+#if (LINUX_VERSION_CODE > KERNEL_VERSION(2,6,26))
+#include <plat/display.h>
+#else 
+#include <asm/arch-omap/display.h>
+#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 <plat/display.h>
+#include <linux/console.h>
+#include <linux/fb.h>
+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 (executable)
index 0000000..aba88c9
--- /dev/null
@@ -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 (file)
index 0000000..54139af
--- /dev/null
@@ -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. <gpl-support@imgtec.com>
+# 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 (file)
index 0000000..f1f4a73
--- /dev/null
@@ -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 (file)
index 0000000..66ff328
--- /dev/null
@@ -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. <gpl-support@imgtec.com>
+ * 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 (file)
index 0000000..8282c0b
--- /dev/null
@@ -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. <gpl-support@imgtec.com>
+ * Home Park Estate, Kings Langley, Herts, WD4 8LZ, UK 
+ *
+ ******************************************************************************/
+
+#include <linux/version.h>
+#include <linux/kernel.h>
+#include <linux/console.h>
+#include <linux/fb.h>
+#include <linux/module.h>
+#include <linux/string.h>
+#include <linux/notifier.h>
+#include <linux/spinlock.h>
+
+#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 <linux/workqueue.h>
+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; i<ui32BufferCount-1; i++)
+       {
+               psBuffer[i].psNext = &psBuffer[i+1];
+       }
+       
+       psBuffer[i].psNext = &psBuffer[0];
+
+       
+       for(i=0; i<ui32BufferCount; i++)
+       {
+               IMG_UINT32 ui32SwapBuffer = i + ui32BuffersToSkip;
+               IMG_UINT32 ui32BufferOffset = ui32SwapBuffer * (IMG_UINT32)psDevInfo->sFBInfo.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; i<ui32BufferCount; i++)
+       {
+               psVSyncFlips[i].bValid = OMAP_FALSE;
+               psVSyncFlips[i].bFlipped = OMAP_FALSE;
+               psVSyncFlips[i].bCmdCompleted = OMAP_FALSE;
+       }
+#if defined (SUPPORT_TI_DSS_FW)
+
+       OMAPLFBEnableDisplayRegisterAccess();
+
+       
+       psSwapChain->pvRegs = 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; i<psSwapChain->ulBufferCount; 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 (file)
index 0000000..9002cba
--- /dev/null
@@ -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. <gpl-support@imgtec.com>
+ * Home Park Estate, Kings Langley, Herts, WD4 8LZ, UK 
+ *
+ ******************************************************************************/
+
+#ifndef AUTOCONF_INCLUDED
+#include <linux/config.h>
+#endif
+
+#include <linux/version.h>
+#include <linux/module.h>
+
+#include <linux/pci.h>
+#include <asm/uaccess.h>
+#include <linux/slab.h>
+#include <linux/errno.h>
+#include <linux/interrupt.h>
+
+
+#include "img_defs.h"
+#include "servicesext.h"
+#include "kerneldisplay.h"
+#include "omaplfb.h"
+#include "pvrmodule.h"
+
+#include <plat/ti81xx-vpss.h>
+
+#if defined(LDM_PLATFORM)
+#include <linux/platform_device.h>
+#endif 
+
+#if defined (SUPPORT_TI_DSS_FW)
+#include <asm/io.h>
+
+#if (LINUX_VERSION_CODE > KERNEL_VERSION(2,6,26))
+#include <plat/display.h>
+#else 
+#include <asm/arch-omap/display.h>
+#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 <plat/display.h>
+#include <linux/console.h>
+#include <linux/fb.h>
+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 (file)
index 0000000..58f4e8c
--- /dev/null
@@ -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. <gpl-support@imgtec.com>
+ * 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 (file)
index 0000000..266814d
--- /dev/null
@@ -0,0 +1,155 @@
+/**********************************************************************\r
+ *\r
+ * Copyright(c) 2008 Imagination Technologies Ltd. All rights reserved.\r
+ * \r
+ * This program is free software; you can redistribute it and/or modify it\r
+ * under the terms and conditions of the GNU General Public License,\r
+ * version 2, as published by the Free Software Foundation.\r
+ * \r
+ * This program is distributed in the hope it will be useful but, except \r
+ * as otherwise stated in writing, without any warranty; without even the \r
+ * implied warranty of merchantability or fitness for a particular purpose. \r
+ * See the GNU General Public License for more details.\r
+ * \r
+ * You should have received a copy of the GNU General Public License along with\r
+ * this program; if not, write to the Free Software Foundation, Inc.,\r
+ * 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA.\r
+ * \r
+ * The full GNU General Public License is included in this distribution in\r
+ * the file called "COPYING".\r
+ *\r
+ * Contact Information:\r
+ * Imagination Technologies Ltd. <gpl-support@imgtec.com>\r
+ * Home Park Estate, Kings Langley, Herts, WD4 8LZ, UK \r
+ *\r
+ ******************************************************************************/\r
+\r
+#if !defined (__KERNELDISPLAY_H__)\r
+#define __KERNELDISPLAY_H__\r
+\r
+typedef PVRSRV_ERROR (*PFN_OPEN_DC_DEVICE)(IMG_UINT32, IMG_HANDLE*, PVRSRV_SYNC_DATA*);\r
+typedef PVRSRV_ERROR (*PFN_CLOSE_DC_DEVICE)(IMG_HANDLE);\r
+typedef PVRSRV_ERROR (*PFN_ENUM_DC_FORMATS)(IMG_HANDLE, IMG_UINT32*, DISPLAY_FORMAT*);\r
+typedef PVRSRV_ERROR (*PFN_ENUM_DC_DIMS)(IMG_HANDLE,\r
+                                                                                DISPLAY_FORMAT*,\r
+                                                                                IMG_UINT32*,\r
+                                                                                DISPLAY_DIMS*);\r
+typedef PVRSRV_ERROR (*PFN_GET_DC_SYSTEMBUFFER)(IMG_HANDLE, IMG_HANDLE*);\r
+typedef PVRSRV_ERROR (*PFN_GET_DC_INFO)(IMG_HANDLE, DISPLAY_INFO*);\r
+typedef PVRSRV_ERROR (*PFN_CREATE_DC_SWAPCHAIN)(IMG_HANDLE,\r
+                                                                                               IMG_UINT32, \r
+                                                                                               DISPLAY_SURF_ATTRIBUTES*, \r
+                                                                                               DISPLAY_SURF_ATTRIBUTES*,\r
+                                                                                               IMG_UINT32, \r
+                                                                                               PVRSRV_SYNC_DATA**,\r
+                                                                                               IMG_UINT32,\r
+                                                                                               IMG_HANDLE*, \r
+                                                                                               IMG_UINT32*);\r
+typedef PVRSRV_ERROR (*PFN_DESTROY_DC_SWAPCHAIN)(IMG_HANDLE, \r
+                                                                                                IMG_HANDLE);\r
+typedef PVRSRV_ERROR (*PFN_SET_DC_DSTRECT)(IMG_HANDLE, IMG_HANDLE, IMG_RECT*);\r
+typedef PVRSRV_ERROR (*PFN_SET_DC_SRCRECT)(IMG_HANDLE, IMG_HANDLE, IMG_RECT*);\r
+typedef PVRSRV_ERROR (*PFN_SET_DC_DSTCK)(IMG_HANDLE, IMG_HANDLE, IMG_UINT32);\r
+typedef PVRSRV_ERROR (*PFN_SET_DC_SRCCK)(IMG_HANDLE, IMG_HANDLE, IMG_UINT32);\r
+typedef PVRSRV_ERROR (*PFN_GET_DC_BUFFERS)(IMG_HANDLE,\r
+                                                                                  IMG_HANDLE,\r
+                                                                                  IMG_UINT32*,\r
+                                                                                  IMG_HANDLE*);\r
+typedef PVRSRV_ERROR (*PFN_SWAP_TO_DC_BUFFER)(IMG_HANDLE,\r
+                                                                                         IMG_HANDLE,\r
+                                                                                         IMG_UINT32,\r
+                                                                                         IMG_HANDLE,\r
+                                                                                         IMG_UINT32,\r
+                                                                                         IMG_RECT*);\r
+typedef PVRSRV_ERROR (*PFN_SWAP_TO_DC_SYSTEM)(IMG_HANDLE, IMG_HANDLE);\r
+typedef IMG_VOID (*PFN_SET_DC_STATE)(IMG_HANDLE, IMG_UINT32);\r
+\r
+typedef struct PVRSRV_DC_SRV2DISP_KMJTABLE_TAG\r
+{\r
+       IMG_UINT32                                              ui32TableSize;\r
+       PFN_OPEN_DC_DEVICE                              pfnOpenDCDevice;\r
+       PFN_CLOSE_DC_DEVICE                             pfnCloseDCDevice;\r
+       PFN_ENUM_DC_FORMATS                             pfnEnumDCFormats;\r
+       PFN_ENUM_DC_DIMS                                pfnEnumDCDims;\r
+       PFN_GET_DC_SYSTEMBUFFER                 pfnGetDCSystemBuffer;\r
+       PFN_GET_DC_INFO                                 pfnGetDCInfo;\r
+       PFN_GET_BUFFER_ADDR                             pfnGetBufferAddr;\r
+       PFN_CREATE_DC_SWAPCHAIN                 pfnCreateDCSwapChain;\r
+       PFN_DESTROY_DC_SWAPCHAIN                pfnDestroyDCSwapChain;\r
+       PFN_SET_DC_DSTRECT                              pfnSetDCDstRect;\r
+       PFN_SET_DC_SRCRECT                              pfnSetDCSrcRect;\r
+       PFN_SET_DC_DSTCK                                pfnSetDCDstColourKey;\r
+       PFN_SET_DC_SRCCK                                pfnSetDCSrcColourKey;\r
+       PFN_GET_DC_BUFFERS                              pfnGetDCBuffers;\r
+       PFN_SWAP_TO_DC_BUFFER                   pfnSwapToDCBuffer;\r
+       PFN_SWAP_TO_DC_SYSTEM                   pfnSwapToDCSystem;\r
+       PFN_SET_DC_STATE                                pfnSetDCState;\r
+\r
+} PVRSRV_DC_SRV2DISP_KMJTABLE;\r
+\r
+typedef IMG_BOOL (*PFN_ISR_HANDLER)(IMG_VOID*);\r
+\r
+typedef PVRSRV_ERROR (*PFN_DC_REGISTER_DISPLAY_DEV)(PVRSRV_DC_SRV2DISP_KMJTABLE*, IMG_UINT32*);\r
+typedef PVRSRV_ERROR (*PFN_DC_REMOVE_DISPLAY_DEV)(IMG_UINT32);\r
+typedef PVRSRV_ERROR (*PFN_DC_OEM_FUNCTION)(IMG_UINT32, IMG_VOID*, IMG_UINT32, IMG_VOID*, IMG_UINT32);\r
+typedef PVRSRV_ERROR (*PFN_DC_REGISTER_COMMANDPROCLIST)(IMG_UINT32, PPFN_CMD_PROC,IMG_UINT32[][2], IMG_UINT32);\r
+typedef PVRSRV_ERROR (*PFN_DC_REMOVE_COMMANDPROCLIST)(IMG_UINT32, IMG_UINT32);\r
+typedef IMG_VOID (*PFN_DC_CMD_COMPLETE)(IMG_HANDLE, IMG_BOOL);\r
+typedef PVRSRV_ERROR (*PFN_DC_REGISTER_SYS_ISR)(PFN_ISR_HANDLER, IMG_VOID*, IMG_UINT32, IMG_UINT32);\r
+typedef PVRSRV_ERROR (*PFN_DC_REGISTER_POWER)(IMG_UINT32, PFN_PRE_POWER, PFN_POST_POWER,\r
+                                                                                         PFN_PRE_CLOCKSPEED_CHANGE, PFN_POST_CLOCKSPEED_CHANGE,\r
+                                                                                         IMG_HANDLE, PVR_POWER_STATE, PVR_POWER_STATE);\r
+\r
+typedef struct PVRSRV_DC_DISP2SRV_KMJTABLE_TAG\r
+{\r
+       IMG_UINT32                                              ui32TableSize;\r
+       PFN_DC_REGISTER_DISPLAY_DEV             pfnPVRSRVRegisterDCDevice;\r
+       PFN_DC_REMOVE_DISPLAY_DEV               pfnPVRSRVRemoveDCDevice;\r
+       PFN_DC_OEM_FUNCTION                             pfnPVRSRVOEMFunction;\r
+       PFN_DC_REGISTER_COMMANDPROCLIST pfnPVRSRVRegisterCmdProcList;\r
+       PFN_DC_REMOVE_COMMANDPROCLIST   pfnPVRSRVRemoveCmdProcList;\r
+       PFN_DC_CMD_COMPLETE                             pfnPVRSRVCmdComplete;\r
+       PFN_DC_REGISTER_SYS_ISR                 pfnPVRSRVRegisterSystemISRHandler;\r
+       PFN_DC_REGISTER_POWER                   pfnPVRSRVRegisterPowerDevice;\r
+} PVRSRV_DC_DISP2SRV_KMJTABLE, *PPVRSRV_DC_DISP2SRV_KMJTABLE;\r
+\r
+\r
+typedef struct DISPLAYCLASS_FLIP_COMMAND_TAG\r
+{\r
+       \r
+       IMG_HANDLE hExtDevice;\r
+\r
+       \r
+       IMG_HANDLE hExtSwapChain;\r
+\r
+       \r
+       IMG_HANDLE hExtBuffer;\r
+\r
+       \r
+       IMG_HANDLE hPrivateTag;\r
+\r
+       \r
+       IMG_UINT32 ui32ClipRectCount;\r
+\r
+       \r
+       IMG_RECT *psClipRect;\r
+\r
+       \r
+       IMG_UINT32      ui32SwapInterval;\r
+\r
+} DISPLAYCLASS_FLIP_COMMAND;\r
+\r
+#define DC_FLIP_COMMAND                0\r
+\r
+#define DC_STATE_NO_FLUSH_COMMANDS             0\r
+#define DC_STATE_FLUSH_COMMANDS                        1\r
+#define DC_STATE_SUSPEND_COMMANDS              2\r
+#define DC_STATE_RESUME_COMMANDS               3\r
+\r
+\r
+typedef IMG_BOOL (*PFN_DC_GET_PVRJTABLE)(PPVRSRV_DC_DISP2SRV_KMJTABLE);\r
+\r
+\r
+\r
+#endif\r
+\r
diff --git a/services4/include/pvr_bridge.h b/services4/include/pvr_bridge.h
new file mode 100644 (file)
index 0000000..1ef24dc
--- /dev/null
@@ -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. <gpl-support@imgtec.com>
+ * 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 <linux/ioctl.h>
+    
+    #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 (file)
index 0000000..b171b7f
--- /dev/null
@@ -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. <gpl-support@imgtec.com>
+ * 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 (file)
index 0000000..4404d88
--- /dev/null
@@ -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. <gpl-support@imgtec.com>
+ * 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 (file)
index 0000000..7b74f8e
--- /dev/null
@@ -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. <gpl-support@imgtec.com>
+ * 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 (file)
index 0000000..c9b67cb
--- /dev/null
@@ -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. <gpl-support@imgtec.com>
+ * 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 (file)
index 0000000..0c7d690
--- /dev/null
@@ -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. <gpl-support@imgtec.com>
+ * 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 (file)
index 0000000..0a92f26
--- /dev/null
@@ -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. <gpl-support@imgtec.com>
+ * Home Park Estate, Kings Langley, Herts, WD4 8LZ, UK 
+ *
+ ******************************************************************************/
+
+
+
+#include <stddef.h>
+
+#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;i<BRIDGE_DISPATCH_TABLE_ENTRY_COUNT;i++)
+       {
+               if(!g_BridgeDispatchTable[i].pfFunction)
+               {
+                       g_BridgeDispatchTable[i].pfFunction = DummyBW;
+#if defined(DEBUG_BRIDGE_KM)
+                       g_BridgeDispatchTable[i].pszIOCName = "_PVRSRV_BRIDGE_DUMMY";
+                       g_BridgeDispatchTable[i].pszFunctionName = "DummyBW";
+                       g_BridgeDispatchTable[i].ui32CallCount = 0;
+                       g_BridgeDispatchTable[i].ui32CopyFromUserTotalBytes = 0;
+                       g_BridgeDispatchTable[i].ui32CopyToUserTotalBytes = 0;
+#endif
+               }
+       }
+
+       return PVRSRV_OK;
+}
+
+
+IMG_INT BridgedDispatchKM(PVRSRV_PER_PROCESS_DATA * psPerProc,
+                                         PVRSRV_BRIDGE_PACKAGE   * psBridgePackageKM)
+{
+
+       IMG_VOID   * psBridgeIn;
+       IMG_VOID   * psBridgeOut;
+       BridgeWrapperFunction pfBridgeHandler;
+       IMG_UINT32   ui32BridgeID = psBridgePackageKM->ui32BridgeID;
+       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 (file)
index 0000000..cb71f25
--- /dev/null
@@ -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. <gpl-support@imgtec.com>
+ * 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 (file)
index 0000000..d8a9eee
--- /dev/null
@@ -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. <gpl-support@imgtec.com>
+ * 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 (file)
index 0000000..371715d
--- /dev/null
@@ -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. <gpl-support@imgtec.com>
+ * 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 (file)
index 0000000..ff78232
--- /dev/null
@@ -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. <gpl-support@imgtec.com>
+ * Home Park Estate, Kings Langley, Herts, WD4 8LZ, UK 
+ *
+ ******************************************************************************/
+
+
+
+#include <stddef.h>
+
+#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; i<psDoKickIN->sCCBKick.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; i<ui32SharedPBDescSubKernelMemInfosCount; i++)
+       {
+               PVRSRV_BRIDGE_OUT_SGXFINDSHAREDPBDESC *psSGXFindSharedPBDescOut =
+                       psSGXFindSharedPBDescOUT;
+
+                       PVRSRVAllocSubHandleNR(psPerProc->psHandleBase,
+                                                         &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; i<ui32KernelMemInfoHandlesCount; i++)
+       {
+               eError = PVRSRVLookupHandle(psPerProc->psHandleBase,
+                                                                       (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; i<ui32KernelMemInfoHandlesCount; i++)
+       {
+               eError = PVRSRVReleaseHandle(psPerProc->psHandleBase,
+                                                                       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; i<ui32BufferArrayLength; i++)
+       {
+               PSGX_KICKTA_DUMP_BUFFER psBuffer;
+               PVRSRV_KERNEL_MEM_INFO  *psCtrlMemInfoKM;
+               IMG_CHAR * pszName;
+               IMG_HANDLE hUniqueTag;
+               IMG_UINT32      ui32Offset;
+
+               psBuffer = &psBufferArray[i];
+               pszName = psBuffer->pszName;
+               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 (file)
index 0000000..de6cfd1
--- /dev/null
@@ -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. <gpl-support@imgtec.com>
+ * 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 (file)
index 0000000..0ac347a
--- /dev/null
@@ -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. <gpl-support@imgtec.com>
+ * 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 (file)
index 0000000..4ba18b7
--- /dev/null
@@ -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. <gpl-support@imgtec.com>
+ * 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; i<psSwapChain->ui32BufferCount; 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; i<ui32BufferCount; i++)
+       {
+               eError = PVRSRVAllocSyncInfoKM(IMG_NULL,
+                                                                               psDCInfo->hDevMemContext,
+                                                                               &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; i<ui32BufferCount; i++)
+       {
+               if(psSwapChain->asBuffer[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; i<ui32ClipRectCount; i++)
+       {
+               psFlipCmd->psClipRect[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; i<psBCInfo->ui32BufferCount; 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; i<psBCInfo->ui32BufferCount; 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; i<psBCInfo->ui32BufferCount; 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 (file)
index 0000000..fa50292
--- /dev/null
@@ -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. <gpl-support@imgtec.com>
+ * Home Park Estate, Kings Langley, Herts, WD4 8LZ, UK 
+ *
+ ******************************************************************************/
+
+#include <stddef.h>
+
+#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; i<ui32HeapCount; i++)
+       {
+               
+               psHeapInfo[i].ui32HeapID = psDeviceMemoryHeap[i].ui32HeapID;
+               psHeapInfo[i].hDevMemHeap = psDeviceMemoryHeap[i].hDevMemHeap;
+               psHeapInfo[i].sDevVAddrBase = psDeviceMemoryHeap[i].sDevVAddrBase;
+               psHeapInfo[i].ui32HeapByteSize = psDeviceMemoryHeap[i].ui32HeapSize;
+               psHeapInfo[i].ui32Attribs = psDeviceMemoryHeap[i].ui32Attribs;
+       }
+
+       for(; i < PVRSRV_MAX_CLIENT_HEAPS; i++)
+       {
+               OSMemSet(psHeapInfo + i, 0, sizeof(*psHeapInfo));
+               psHeapInfo[i].ui32HeapID = (IMG_UINT32)PVRSRV_UNDEFINED_HEAP_ID;
+       }
+
+       return PVRSRV_OK;
+}
+
+IMG_EXPORT
+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)
+{
+       PVRSRV_DEVICE_NODE *psDeviceNode;
+       IMG_UINT32 ui32HeapCount, ui32ClientHeapCount=0;
+       DEVICE_MEMORY_HEAP_INFO *psDeviceMemoryHeap;
+       IMG_HANDLE hDevMemContext;
+       IMG_HANDLE hDevMemHeap;
+       IMG_DEV_PHYADDR sPDDevPAddr;
+       IMG_UINT32 i;
+
+#if !defined(PVR_SECURE_HANDLES)
+       PVR_UNREFERENCED_PARAMETER(pbShared);
+#endif
+
+       if (hDevCookie == IMG_NULL)
+       {
+               PVR_DPF((PVR_DBG_ERROR, "PVRSRVCreateDeviceMemContextKM: 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);
+
+       
+
+       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; i<ui32HeapCount; i++)
+       {
+               switch(psDeviceMemoryHeap[i].DevMemHeapType)
+               {
+                       case DEVICE_MEMORY_HEAP_SHARED_EXPORTED:
+                       {
+                               
+                               psHeapInfo[ui32ClientHeapCount].ui32HeapID = psDeviceMemoryHeap[i].ui32HeapID;
+                               psHeapInfo[ui32ClientHeapCount].hDevMemHeap = psDeviceMemoryHeap[i].hDevMemHeap;
+                               psHeapInfo[ui32ClientHeapCount].sDevVAddrBase = psDeviceMemoryHeap[i].sDevVAddrBase;
+                               psHeapInfo[ui32ClientHeapCount].ui32HeapByteSize = psDeviceMemoryHeap[i].ui32HeapSize;
+                               psHeapInfo[ui32ClientHeapCount].ui32Attribs = psDeviceMemoryHeap[i].ui32Attribs;
+#if defined(PVR_SECURE_HANDLES)
+                               pbShared[ui32ClientHeapCount] = IMG_TRUE;
+#endif
+                               ui32ClientHeapCount++;
+                               break;
+                       }
+                       case DEVICE_MEMORY_HEAP_PERCONTEXT:
+                       {
+                               hDevMemHeap = BM_CreateHeap(hDevMemContext,
+                                                                                       &psDeviceMemoryHeap[i]);
+
+                               
+                               psHeapInfo[ui32ClientHeapCount].ui32HeapID = psDeviceMemoryHeap[i].ui32HeapID;
+                               psHeapInfo[ui32ClientHeapCount].hDevMemHeap = hDevMemHeap;
+                               psHeapInfo[ui32ClientHeapCount].sDevVAddrBase = psDeviceMemoryHeap[i].sDevVAddrBase;
+                               psHeapInfo[ui32ClientHeapCount].ui32HeapByteSize = psDeviceMemoryHeap[i].ui32HeapSize;
+                               psHeapInfo[ui32ClientHeapCount].ui32Attribs = psDeviceMemoryHeap[i].ui32Attribs;
+#if defined(PVR_SECURE_HANDLES)
+                               pbShared[ui32ClientHeapCount] = IMG_FALSE;
+#endif
+
+                               ui32ClientHeapCount++;
+                               break;
+                       }
+               }
+       }
+
+       
+       *pui32ClientHeapCount = ui32ClientHeapCount;
+       *phDevMemContext = hDevMemContext;
+       
+       return PVRSRV_OK;
+}
+
+IMG_EXPORT
+PVRSRV_ERROR IMG_CALLCONV PVRSRVDestroyDeviceMemContextKM(IMG_HANDLE hDevCookie,
+                                                                                                                 IMG_HANDLE hDevMemContext,
+                                                                                                                 IMG_BOOL *pbDestroyed)
+{
+       PVR_UNREFERENCED_PARAMETER(hDevCookie);
+
+       return BM_DestroyContext(hDevMemContext, pbDestroyed);
+}
+
+
+
+
+IMG_EXPORT
+PVRSRV_ERROR IMG_CALLCONV PVRSRVGetDeviceMemHeapInfoKM(IMG_HANDLE                                      hDevCookie,
+                                                                                                                IMG_HANDLE                             hDevMemContext,
+                                                                                                                IMG_UINT32                             *pui32ClientHeapCount,
+                                                                                                                PVRSRV_HEAP_INFO                       *psHeapInfo,
+                                                                                                                IMG_BOOL                                       *pbShared)
+{
+       PVRSRV_DEVICE_NODE *psDeviceNode;
+       IMG_UINT32 ui32HeapCount, ui32ClientHeapCount=0;
+       DEVICE_MEMORY_HEAP_INFO *psDeviceMemoryHeap;
+       IMG_HANDLE hDevMemHeap;
+       IMG_UINT32 i;
+
+#if !defined(PVR_SECURE_HANDLES)
+       PVR_UNREFERENCED_PARAMETER(pbShared);
+#endif
+
+       if (hDevCookie == IMG_NULL)
+       {
+               PVR_DPF((PVR_DBG_ERROR, "PVRSRVGetDeviceMemHeapInfoKM: 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; i<ui32HeapCount; i++)
+       {
+               switch(psDeviceMemoryHeap[i].DevMemHeapType)
+               {
+                       case DEVICE_MEMORY_HEAP_SHARED_EXPORTED:
+                       {
+                               
+                               psHeapInfo[ui32ClientHeapCount].ui32HeapID = psDeviceMemoryHeap[i].ui32HeapID;
+                               psHeapInfo[ui32ClientHeapCount].hDevMemHeap = psDeviceMemoryHeap[i].hDevMemHeap;
+                               psHeapInfo[ui32ClientHeapCount].sDevVAddrBase = psDeviceMemoryHeap[i].sDevVAddrBase;
+                               psHeapInfo[ui32ClientHeapCount].ui32HeapByteSize = psDeviceMemoryHeap[i].ui32HeapSize;
+                               psHeapInfo[ui32ClientHeapCount].ui32Attribs = psDeviceMemoryHeap[i].ui32Attribs;
+#if defined(PVR_SECURE_HANDLES)
+                               pbShared[ui32ClientHeapCount] = IMG_TRUE;
+#endif
+                               ui32ClientHeapCount++;
+                               break;
+                       }
+                       case DEVICE_MEMORY_HEAP_PERCONTEXT:
+                       {
+                               hDevMemHeap = BM_CreateHeap(hDevMemContext,
+                                                                                       &psDeviceMemoryHeap[i]);
+
+                               
+                               psHeapInfo[ui32ClientHeapCount].ui32HeapID = psDeviceMemoryHeap[i].ui32HeapID;
+                               psHeapInfo[ui32ClientHeapCount].hDevMemHeap = hDevMemHeap;
+                               psHeapInfo[ui32ClientHeapCount].sDevVAddrBase = psDeviceMemoryHeap[i].sDevVAddrBase;
+                               psHeapInfo[ui32ClientHeapCount].ui32HeapByteSize = psDeviceMemoryHeap[i].ui32HeapSize;
+                               psHeapInfo[ui32ClientHeapCount].ui32Attribs = psDeviceMemoryHeap[i].ui32Attribs;
+#if defined(PVR_SECURE_HANDLES)
+                               pbShared[ui32ClientHeapCount] = IMG_FALSE;
+#endif
+
+                               ui32ClientHeapCount++;
+                               break;
+                       }
+               }
+       }
+
+       
+       *pui32ClientHeapCount = ui32ClientHeapCount;
+       
+       return PVRSRV_OK;
+}
+
+
+static PVRSRV_ERROR AllocDeviceMem(IMG_HANDLE          hDevCookie,
+                                                                       IMG_HANDLE              hDevMemHeap,
+                                                                       IMG_UINT32              ui32Flags,
+                                                                       IMG_UINT32              ui32Size,
+                                                                       IMG_UINT32              ui32Alignment,
+                                                                       PVRSRV_KERNEL_MEM_INFO  **ppsMemInfo)
+{
+       PVRSRV_KERNEL_MEM_INFO  *psMemInfo;
+       BM_HANDLE               hBuffer;
+       
+       PVRSRV_MEMBLK   *psMemBlock;
+       IMG_BOOL                bBMError;
+
+       PVR_UNREFERENCED_PARAMETER(hDevCookie);
+
+       *ppsMemInfo = IMG_NULL;
+
+       if(OSAllocMem(PVRSRV_PAGEABLE_SELECT,
+                                       sizeof(PVRSRV_KERNEL_MEM_INFO),
+                                       (IMG_VOID **)&psMemInfo, IMG_NULL) != PVRSRV_OK)
+       {
+               PVR_DPF((PVR_DBG_ERROR,"AllocDeviceMem: Failed to alloc memory for block"));
+               return (PVRSRV_ERROR_OUT_OF_MEMORY);
+       }
+
+       OSMemSet(psMemInfo, 0, sizeof(*psMemInfo));
+
+       psMemBlock = &(psMemInfo->sMemBlk);
+
+       
+       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; i<PVRSRV_MAX_CLIENT_HEAPS; i++)
+       {
+               if(HEAP_IDX(psDeviceMemoryHeap[i].ui32HeapID) == psDevMemoryInfo->ui32MappingHeapID)
+               {
+                       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; i<ui32PageCount; i++)
+       {
+               eError = BM_GetPhysPageAddr(psSrcMemInfo, sDevVAddr, &sDevPAddr);
+               if(eError != PVRSRV_OK)
+               {
+                       PVR_DPF((PVR_DBG_ERROR,"PVRSRVMapDeviceMemoryKM: Failed to retrieve page list from device"));
+                       goto ErrorExit;
+               }
+
+               
+               psSysPAddr[i] = SysDevPAddrToSysPAddr (psDeviceNode->sDevId.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; i<PVRSRV_MAX_CLIENT_HEAPS; i++)
+       {
+               if(HEAP_IDX(psDeviceMemoryHeap[i].ui32HeapID) == psDevMemoryInfo->ui32MappingHeapID)
+               {
+                       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 (file)
index 0000000..385747d
--- /dev/null
@@ -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. <gpl-support@imgtec.com>
+ * Home Park Estate, Kings Langley, Herts, WD4 8LZ, UK 
+ *
+ ******************************************************************************/
+
+#ifdef PVR_SECURE_HANDLES
+#include <stddef.h>
+
+#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 (file)
index 0000000..3f1f14c
--- /dev/null
@@ -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. <gpl-support@imgtec.com>
+ * 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; uIndex<uNewSize; uIndex++)
+            ppNewTable[uIndex] = IMG_NULL;
+
+        if (_Rehash (pHash, pHash->ppBucketTable, 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; uIndex<pHash->uSize; 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; uIndex<pHash->uSize; 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 (file)
index 0000000..a566518
--- /dev/null
@@ -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. <gpl-support@imgtec.com>
+ * 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 (file)
index 0000000..ee5cabd
--- /dev/null
@@ -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. <gpl-support@imgtec.com>
+ * 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 (file)
index 0000000..8dc3798
--- /dev/null
@@ -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. <gpl-support@imgtec.com>
+ * 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<MAX_PDUMP_MMU_CONTEXTS; i++)
+       {
+               if((gui16MMUContextUsage & (1UL << i)) == 0)
+               {
+                       
+                       gui16MMUContextUsage |= 1UL << i;
+                       *pui32MMUContextID = i;
+                       return PVRSRV_OK;
+               }
+       }
+       
+       PVR_DPF((PVR_DBG_ERROR, "_PdumpAllocMMUContext: no free MMU context ids"));
+       
+       return PVRSRV_ERROR_GENERIC;
+}
+
+
+static PVRSRV_ERROR _PdumpFreeMMUContext(IMG_UINT32 ui32MMUContextID)
+{
+       if(ui32MMUContextID < MAX_PDUMP_MMU_CONTEXTS)
+       {
+               
+               gui16MMUContextUsage &= ~(1UL << ui32MMUContextID);
+               return PVRSRV_OK;
+       }
+
+       PVR_DPF((PVR_DBG_ERROR, "_PdumpFreeMMUContext: MMU context ids invalid"));
+
+       return PVRSRV_ERROR_GENERIC;
+}
+
+
+PVRSRV_ERROR PDumpSetMMUContext(PVRSRV_DEVICE_TYPE eDeviceType,
+                                                               IMG_CHAR *pszMemSpace,
+                                                               IMG_UINT32 *pui32MMUContextID,
+                                                               IMG_UINT32 ui32MMUType,
+                                                               IMG_HANDLE hUniqueTag1,
+                                                               IMG_VOID *pvPDCPUAddr)
+{
+       IMG_UINT8 *pui8LinAddr = (IMG_UINT8 *)pvPDCPUAddr;
+       IMG_CPU_PHYADDR sCpuPAddr;
+       IMG_DEV_PHYADDR sDevPAddr;
+       IMG_UINT32 ui32MMUContextID;
+       PVRSRV_ERROR eError;
+
+       eError = _PdumpAllocMMUContext(&ui32MMUContextID);
+       if(eError != PVRSRV_OK)
+       {
+               PVR_DPF((PVR_DBG_ERROR, "PDumpSetMMUContext: _PdumpAllocMMUContext failed: %d", eError));               
+               return eError;
+       }
+
+       
+       sCpuPAddr = OSMapLinToCPUPhys(pui8LinAddr); 
+       sDevPAddr = SysCpuPAddrToDevPAddr(eDeviceType, sCpuPAddr);
+       
+       sDevPAddr.uiAddr &= ~PVRSRV_4K_PAGE_SIZE;
+       
+       PDumpComment("Set MMU Context\r\n");
+       
+       PDumpComment("MMU :%s:v%d %d :%s:PA_%8.8lX%8.8lX\r\n",
+                                               pszMemSpace,
+                                               ui32MMUContextID,
+                                               ui32MMUType,
+                                               pszMemSpace,
+                                               hUniqueTag1,
+                                               sDevPAddr.uiAddr);
+
+       
+       *pui32MMUContextID = ui32MMUContextID;
+
+       return PVRSRV_OK;
+}
+
+
+PVRSRV_ERROR PDumpClearMMUContext(PVRSRV_DEVICE_TYPE eDeviceType,
+                                                               IMG_CHAR *pszMemSpace,
+                                                               IMG_UINT32 ui32MMUContextID,
+                                                               IMG_UINT32 ui32MMUType)
+{
+       PVRSRV_ERROR eError;
+       
+       PVR_UNREFERENCED_PARAMETER(eDeviceType);
+
+       PDumpComment("Clear MMU Context\r\n");
+       
+       PDumpComment("MMU :%s:v%d %d\r\n",
+                                               pszMemSpace,
+                                               ui32MMUContextID,
+                                               ui32MMUType);
+
+       eError = _PdumpFreeMMUContext(ui32MMUContextID);
+       if(eError != PVRSRV_OK)
+       {
+               PVR_DPF((PVR_DBG_ERROR, "PDumpClearMMUContext: _PdumpFreeMMUContext failed: %d", eError));              
+               return eError;
+       }
+
+       return PVRSRV_OK;
+}
+
+#else  
+#endif 
diff --git a/services4/srvkm/common/perproc.c b/services4/srvkm/common/perproc.c
new file mode 100644 (file)
index 0000000..39974f3
--- /dev/null
@@ -0,0 +1,281 @@
+/**********************************************************************
+ *
+ * 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. <gpl-support@imgtec.com>
+ * 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 (file)
index 0000000..9bfa624
--- /dev/null
@@ -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. <gpl-support@imgtec.com>
+ * 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 (file)
index 0000000..768413f
--- /dev/null
@@ -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. <gpl-support@imgtec.com>
+ * 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; i<PVRSRV_MAX_DEVICES; i++)
+       {
+               psDevIdList[i].eDeviceType = PVRSRV_DEVICE_TYPE_UNKNOWN;
+       }
+       
+       
+       *pui32NumDevices = 0;
+       
+       
+
+
+
+       psDeviceNode = psSysData->psDeviceNodeList;
+       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 (file)
index 0000000..ffc2cdb
--- /dev/null
@@ -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. <gpl-support@imgtec.com>
+ * 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 <empty>\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; i<ui32DstSyncCount; i++)
+       {
+               psCommand->psDstSync[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; i<ui32SrcSyncCount; i++)
+       {
+               psCommand->psSrcSync[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; i<psCommand->ui32DstSyncCount; i++)
+       {
+               psCmdCompleteData->psDstSync[i] = psCommand->psDstSync[i];
+       }
+
+       
+       psCmdCompleteData->ui32SrcSyncCount = psCommand->ui32SrcSyncCount;
+       for (i=0; i<psCommand->ui32SrcSyncCount; 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; i<psCmdCompleteData->ui32DstSyncCount; i++)
+       {
+               psCmdCompleteData->psDstSync[i].psKernelSyncInfoKM->psSyncData->ui32WriteOpsComplete++;
+       }
+
+       
+       for (i=0; i<psCmdCompleteData->ui32SrcSyncCount; 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; i<ui32CmdCount; i++)
+       {
+               ppfnCmdProc[i] = ppfnCmdProcList[i];
+       }
+
+       
+       ui32AllocSize = ui32CmdCount * sizeof(COMMAND_COMPLETE_DATA*);
+       eError = OSAllocMem( PVRSRV_OS_NON_PAGEABLE_HEAP,
+                                        ui32AllocSize, 
+                                        (IMG_VOID **)&psSysData->ppsCmdCompleteData[ui32DevIndex], IMG_NULL);
+       if (eError != PVRSRV_OK)
+       {
+               PVR_DPF((PVR_DBG_ERROR,"PVRSRVRegisterCmdProcListKM: Failed to alloc CC data"));
+               goto ErrorExit;
+       }
+
+       for (i=0; i<ui32CmdCount; i++)
+       {
+               
+
+               ui32AllocSize = sizeof(COMMAND_COMPLETE_DATA) 
+                                         + ((ui32MaxSyncsPerCmd[i][0]
+                                         +     ui32MaxSyncsPerCmd[i][1])
+                                         * sizeof(PVRSRV_SYNC_OBJECT));         
+
+               eError = OSAllocMem(PVRSRV_OS_NON_PAGEABLE_HEAP,
+                                                       ui32AllocSize,
+                                                       (IMG_VOID **)&psSysData->ppsCmdCompleteData[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; i<ui32CmdCount; i++)
+               {
+                       if (psSysData->ppsCmdCompleteData[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; i<ui32CmdCount; i++)
+               {
+                       
+                       if(psSysData->ppsCmdCompleteData[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 (file)
index 0000000..8278abd
--- /dev/null
@@ -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. <gpl-support@imgtec.com>
+ * 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 <linux/kernel.h>
+#include "proc.h"
+#endif
+
+#ifdef USE_BM_FREESPACE_CHECK
+#include <stdio.h>
+#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<<uIndex < uSize)
+               uIndex++;
+#endif
+
+       while (uIndex < FREE_TABLE_LIMIT && pArena->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; i<FREE_TABLE_LIMIT; i++)
+               pArena->aHeadFree[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; uIndex<FREE_TABLE_LIMIT; uIndex++)
+               pArena->aHeadFree[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 (file)
index 0000000..d713c3c
--- /dev/null
@@ -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. <gpl-support@imgtec.com>
+ * Home Park Estate, Kings Langley, Herts, WD4 8LZ, UK 
+ *
+ ******************************************************************************/
+
+#include "services_headers.h"
+#include "resman.h"
+
+#ifdef __linux__
+#ifndef AUTOCONF_INCLUDED
+ #include <linux/config.h>
+#endif
+
+#include <linux/version.h>
+#include <linux/sched.h>
+#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,9)
+#include <linux/hardirq.h>
+#else
+#include <asm/hardirq.h>
+#endif
+
+#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,27)
+#include <linux/semaphore.h>
+#else
+#include <asm/semaphore.h>
+#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 (file)
index 0000000..cd35220
--- /dev/null
@@ -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. <gpl-support@imgtec.com>
+ * 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; (i<pMMUHeap->ui32PTEntryCount) && (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; i<pMMUHeap->ui32PTPageCount; 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_FEATURE_ADDRESS_SPACE_SIZE));
+#endif
+
+       
+       if (SysAcquireData(&psSysData) != PVRSRV_OK)
+       {
+               return IMG_FALSE;
+       }
+
+       
+       ui32PDIndex = DevVAddr.uiAddr >> (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; i<ui32PTPageCount; i++)
+       {
+               if(ppsPTInfoList[i] == IMG_NULL)
+               {
+                       OSAllocMem(PVRSRV_OS_PAGEABLE_HEAP,
+                                                sizeof (MMU_PT_INFO),
+                                                (IMG_VOID **)&ppsPTInfoList[i], IMG_NULL);
+                       if (ppsPTInfoList[i] == IMG_NULL)
+                       {
+                               PVR_DPF((PVR_DBG_ERROR, "_DeferredAllocPagetables: ERROR call to OSAllocMem failed"));
+                               return IMG_FALSE;
+                       }
+                       OSMemSet (ppsPTInfoList[i], 0, sizeof(MMU_PT_INFO));
+               }
+
+               if(ppsPTInfoList[i]->hPTPageOSMemHandle == 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; j<SGX_MMU_PT_SIZE; j++)
+                       {
+                               pui32Tmp[j] = pMMUHeap->psMMUContext->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; i<SGX_MMU_PD_SIZE; i++)
+       {
+               pui32Tmp[i] = psDevInfo->sDummyPTDevPAddr.uiAddr | SGX_MMU_PDE_VALID;
+       }
+
+       if(!psDevInfo->pvMMUContextList)
+       {
+               
+
+
+               pui32Tmp = (IMG_UINT32 *)psDevInfo->pvDummyPTPageCpuVAddr;
+               for(i=0; i<SGX_MMU_PT_SIZE; i++)
+               {
+                       pui32Tmp[i] = psDevInfo->sDummyDataDevPAddr.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; i<SGX_MMU_PD_SIZE; i++)
+       {
+               
+               pui32Tmp[i] = 0;
+       }
+#endif 
+
+       
+       PDUMPCOMMENT("Page directory contents");
+       PDUMPMEM2(PVRSRV_DEVICE_TYPE_SGX, pvPDCpuVAddr, SGX_MMU_PAGE_SIZE, 0, IMG_TRUE, PDUMP_PD_UNIQUETAG, PDUMP_PT_UNIQUETAG);
+
+       
+       psMMUContext->pvPDCpuVAddr = 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; i<SGX_MMU_PD_SIZE; i++)
+       {
+               
+               pui32Tmp[i] = 0;
+       }
+
+       
+
+
+
+       if(psMMUContext->psDeviceNode->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<ui32PageCount; i++)
+       {
+               MMU_PT_INFO **ppsPTInfoList;
+
+               
+               ui32PDIndex = sTmpDevVAddr.uiAddr >> (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; uCount<uSize; i++, uCount+=SGX_MMU_PAGE_SIZE)
+       {
+               IMG_SYS_PHYADDR sSysAddr;
+
+               sSysAddr = psSysAddr[i];
+
+
+               DevPAddr = SysSysPAddrToDevPAddr(PVRSRV_DEVICE_TYPE_SGX, sSysAddr);
+
+               MMU_MapPage (pMMUHeap, DevVAddr, DevPAddr, ui32MemFlags);
+               DevVAddr.uiAddr += SGX_MMU_PAGE_SIZE;
+
+               PVR_DPF ((PVR_DBG_MESSAGE, 
+                                "MMU_MapScatter: devVAddr=%08X, SysAddr=%08X, size=0x%x/0x%x",
+                                 DevVAddr.uiAddr, sSysAddr.uiAddr, uCount, uSize));
+       }
+
+#if defined(PDUMP)
+       MMU_PDumpPageTables (pMMUHeap, MapBaseDevVAddr, uSize, IMG_FALSE, hUniqueTag);
+#endif 
+}
+
+IMG_VOID
+MMU_MapPages (MMU_HEAP *pMMUHeap,
+                         IMG_DEV_VIRTADDR DevVAddr,
+                         IMG_SYS_PHYADDR SysPAddr,
+                         IMG_SIZE_T uSize,
+                         IMG_UINT32 ui32MemFlags,
+                         IMG_HANDLE hUniqueTag)
+{
+       IMG_DEV_PHYADDR DevPAddr;
+#if defined(PDUMP)
+       IMG_DEV_VIRTADDR MapBaseDevVAddr;
+#endif 
+       IMG_UINT32 uCount;
+       IMG_UINT32 ui32VAdvance = SGX_MMU_PAGE_SIZE;
+       IMG_UINT32 ui32PAdvance = SGX_MMU_PAGE_SIZE;
+
+       PVR_ASSERT (pMMUHeap != IMG_NULL);
+
+       PVR_DPF ((PVR_DBG_MESSAGE,
+                 "MMU_MapPages: mmu=%08X, devVAddr=%08X, SysPAddr=%08X, size=0x%x",
+                 pMMUHeap, DevVAddr.uiAddr, SysPAddr.uiAddr, uSize));
+
+#if defined(PDUMP)
+       MapBaseDevVAddr = DevVAddr;
+#else
+       PVR_UNREFERENCED_PARAMETER(hUniqueTag);
+#endif 
+
+       DevPAddr = SysSysPAddrToDevPAddr(PVRSRV_DEVICE_TYPE_SGX, SysPAddr);
+
+#if defined(FIX_HW_BRN_23281)
+       if(ui32MemFlags & PVRSRV_MEM_INTERLEAVED)
+       {
+               ui32VAdvance *= 2;
+       }
+#endif
+
+       
+
+
+       if(ui32MemFlags & PVRSRV_MEM_DUMMY)
+       {
+               ui32PAdvance = 0;
+       }
+
+       for (uCount=0; uCount<uSize; uCount+=ui32VAdvance)
+       {
+               MMU_MapPage (pMMUHeap, DevVAddr, DevPAddr, ui32MemFlags);
+               DevVAddr.uiAddr += ui32VAdvance;
+               DevPAddr.uiAddr += ui32PAdvance;
+       }
+
+#if defined(PDUMP)
+       MMU_PDumpPageTables (pMMUHeap, MapBaseDevVAddr, uSize, IMG_FALSE, hUniqueTag);
+#endif 
+}
+
+IMG_VOID
+MMU_MapShadow (MMU_HEAP          *pMMUHeap,
+                          IMG_DEV_VIRTADDR   MapBaseDevVAddr,
+                          IMG_SIZE_T         uByteSize,
+                          IMG_CPU_VIRTADDR   CpuVAddr,
+                          IMG_HANDLE         hOSMemHandle,
+                          IMG_DEV_VIRTADDR  *pDevVAddr,
+                          IMG_UINT32         ui32MemFlags,
+                          IMG_HANDLE         hUniqueTag)
+{
+       IMG_UINT32                      i;
+       IMG_UINT32                      uOffset = 0;
+       IMG_DEV_VIRTADDR        MapDevVAddr;
+       IMG_UINT32                      ui32VAdvance = SGX_MMU_PAGE_SIZE;
+       IMG_UINT32                      ui32PAdvance = SGX_MMU_PAGE_SIZE;
+
+#if !defined (PDUMP)
+       PVR_UNREFERENCED_PARAMETER(hUniqueTag);
+#endif
+
+       PVR_DPF ((PVR_DBG_MESSAGE,
+                       "MMU_MapShadow: %08X, 0x%x, %08X",
+                       MapBaseDevVAddr.uiAddr,
+                       uByteSize,
+                       CpuVAddr));
+
+       PVR_ASSERT(((IMG_UINT32)CpuVAddr & (SGX_MMU_PAGE_SIZE - 1)) == 0);
+       PVR_ASSERT(((IMG_UINT32)uByteSize & (SGX_MMU_PAGE_SIZE - 1)) == 0);
+       pDevVAddr->uiAddr = 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<uByteSize; i+=ui32VAdvance)
+       {
+               IMG_CPU_PHYADDR CpuPAddr;
+               IMG_DEV_PHYADDR DevPAddr;
+
+               if(CpuVAddr)
+               {
+                       CpuPAddr = OSMapLinToCPUPhys ((IMG_VOID *)((IMG_UINT32)CpuVAddr + uOffset));
+               }
+               else
+               {
+                       CpuPAddr = OSMemHandleToCpuPAddr(hOSMemHandle, uOffset);
+               }
+               DevPAddr = SysCpuPAddrToDevPAddr (PVRSRV_DEVICE_TYPE_SGX, CpuPAddr);
+
+               PVR_DPF ((PVR_DBG_MESSAGE,
+                               "0x%x: CpuVAddr=%08X, CpuPAddr=%08X, DevVAddr=%08X, DevPAddr=%08X",
+                               uOffset, 
+                               (IMG_UINTPTR_T)CpuVAddr + uOffset, 
+                               CpuPAddr.uiAddr, 
+                               MapDevVAddr.uiAddr, 
+                               DevPAddr.uiAddr));
+
+               MMU_MapPage (pMMUHeap, MapDevVAddr, DevPAddr, ui32MemFlags);
+
+               
+               MapDevVAddr.uiAddr += ui32VAdvance;
+               uOffset += ui32PAdvance;
+       }
+
+#if defined(PDUMP)
+       MMU_PDumpPageTables (pMMUHeap, MapBaseDevVAddr, uByteSize, IMG_FALSE, hUniqueTag);
+#endif 
+}
+
+
+IMG_VOID
+MMU_UnmapPages (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;
+
+#if !defined (PDUMP)
+       PVR_UNREFERENCED_PARAMETER(hUniqueTag);
+#endif
+
+       
+       sTmpDevVAddr = sDevVAddr;
+
+       for(i=0; i<ui32PageCount; i++)
+       {
+               MMU_PT_INFO **ppsPTInfoList;
+
+               
+               ui32PDIndex = sTmpDevVAddr.uiAddr >> (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 (file)
index 0000000..2319da8
--- /dev/null
@@ -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. <gpl-support@imgtec.com>
+ * 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 (file)
index 0000000..7b91abd
--- /dev/null
@@ -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. <gpl-support@imgtec.com>
+ * Home Park Estate, Kings Langley, Herts, WD4 8LZ, UK 
+ *
+ ******************************************************************************/
+
+#include <stddef.h>
+
+#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; i<psStubPBDesc->ui32SubKernelMemInfosCount; 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 ; i<psStubPBDesc->ui32SubKernelMemInfosCount; 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; i<ui32SharedPBDescSubKernelMemInfosCount; i++)
+       {
+               psStubPBDesc->ppsSubKernelMemInfos[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 (file)
index 0000000..c2c9647
--- /dev/null
@@ -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. <gpl-support@imgtec.com>
+ * 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 (file)
index 0000000..824192d
--- /dev/null
@@ -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. <gpl-support@imgtec.com>
+ * 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 (file)
index 0000000..fac1aee
--- /dev/null
@@ -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. <gpl-support@imgtec.com>
+ * 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 (file)
index 0000000..7b23933
--- /dev/null
@@ -0,0 +1,1707 @@
+/**********************************************************************\r
+ *\r
+ * Copyright(c) 2008 Imagination Technologies Ltd. All rights reserved.\r
+ * \r
+ * This program is free software; you can redistribute it and/or modify it\r
+ * under the terms and conditions of the GNU General Public License,\r
+ * version 2, as published by the Free Software Foundation.\r
+ * \r
+ * This program is distributed in the hope it will be useful but, except \r
+ * as otherwise stated in writing, without any warranty; without even the \r
+ * implied warranty of merchantability or fitness for a particular purpose. \r
+ * See the GNU General Public License for more details.\r
+ * \r
+ * You should have received a copy of the GNU General Public License along with\r
+ * this program; if not, write to the Free Software Foundation, Inc.,\r
+ * 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA.\r
+ * \r
+ * The full GNU General Public License is included in this distribution in\r
+ * the file called "COPYING".\r
+ *\r
+ * Contact Information:\r
+ * Imagination Technologies Ltd. <gpl-support@imgtec.com>\r
+ * Home Park Estate, Kings Langley, Herts, WD4 8LZ, UK \r
+ *\r
+ ******************************************************************************/\r
+\r
+#include <stddef.h>\r
+\r
+#include "sgxdefs.h"\r
+#include "sgxmmu.h"\r
+#include "services_headers.h"\r
+#include "buffer_manager.h"\r
+#include "sgxapi_km.h"\r
+#include "sgxinfo.h"\r
+#include "sgxinfokm.h"\r
+#include "sgxconfig.h"\r
+#include "sysconfig.h"\r
+#include "pvr_bridge_km.h"\r
+\r
+#include "pdump_km.h"\r
+#include "ra.h"\r
+#include "mmu.h"\r
+#include "handle.h"\r
+#include "perproc.h"\r
+\r
+#include "sgxutils.h"\r
+#include "pvrversion.h"\r
+#include "sgx_options.h"\r
+\r
+IMG_BOOL SGX_ISRHandler(IMG_VOID *pvData);\r
+\r
+IMG_UINT32 gui32EventStatusServicesByISR = 0;\r
+\r
+#if defined (PVRSRV_USSE_EDM_STATUS_RUNTIME)\r
+extern IMG_VOID RuntimeEDMEventStatusDebug(PPVRSRV_KERNEL_MEM_INFO psEDMStatusBufferMemInfo);\r
+#endif\r
+\r
+\r
+static\r
+PVRSRV_ERROR SGXGetBuildInfoKM(PVRSRV_SGXDEV_INFO      *psDevInfo,\r
+                                                         PVRSRV_DEVICE_NODE    *psDeviceNode);\r
+\r
+\r
+static IMG_VOID SGXCommandComplete(PVRSRV_DEVICE_NODE *psDeviceNode)\r
+{\r
+#if defined(OS_SUPPORTS_IN_LISR)\r
+       if (OSInLISR(psDeviceNode->psSysData))\r
+       {\r
+               \r
+               psDeviceNode->bReProcessDeviceCommandComplete = IMG_TRUE;\r
+       }\r
+       else\r
+       {\r
+               SGXScheduleProcessQueuesKM(psDeviceNode);\r
+       }\r
+#else\r
+       SGXScheduleProcessQueuesKM(psDeviceNode);\r
+#endif\r
+}\r
+\r
+static IMG_UINT32 DeinitDevInfo(PVRSRV_SGXDEV_INFO *psDevInfo)\r
+{\r
+       if (psDevInfo->psKernelCCBInfo != IMG_NULL)\r
+       {\r
+               \r
+\r
+               OSFreeMem(PVRSRV_OS_PAGEABLE_HEAP, sizeof(PVRSRV_SGX_CCB_INFO), psDevInfo->psKernelCCBInfo, IMG_NULL);\r
+       }\r
+\r
+       return PVRSRV_OK;\r
+}\r
+\r
+static PVRSRV_ERROR InitDevInfo(PVRSRV_PER_PROCESS_DATA *psPerProc,\r
+                                                               PVRSRV_DEVICE_NODE *psDeviceNode,\r
+                                                               SGX_BRIDGE_INIT_INFO *psInitInfo)\r
+{\r
+       PVRSRV_SGXDEV_INFO *psDevInfo = (PVRSRV_SGXDEV_INFO *)psDeviceNode->pvDevice;\r
+       PVRSRV_ERROR            eError;\r
+\r
+       PVRSRV_SGX_CCB_INFO     *psKernelCCBInfo = IMG_NULL;\r
+\r
+       PVR_UNREFERENCED_PARAMETER(psPerProc);\r
+       psDevInfo->sScripts = psInitInfo->sScripts;\r
+\r
+       psDevInfo->psKernelCCBMemInfo = (PVRSRV_KERNEL_MEM_INFO *)psInitInfo->hKernelCCBMemInfo;\r
+       psDevInfo->psKernelCCB = (PVRSRV_SGX_KERNEL_CCB *) psDevInfo->psKernelCCBMemInfo->pvLinAddrKM;\r
+\r
+       psDevInfo->psKernelCCBCtlMemInfo = (PVRSRV_KERNEL_MEM_INFO *)psInitInfo->hKernelCCBCtlMemInfo;\r
+       psDevInfo->psKernelCCBCtl = (PVRSRV_SGX_CCB_CTL *) psDevInfo->psKernelCCBCtlMemInfo->pvLinAddrKM;\r
+\r
+       psDevInfo->psKernelCCBEventKickerMemInfo = (PVRSRV_KERNEL_MEM_INFO *)psInitInfo->hKernelCCBEventKickerMemInfo;\r
+       psDevInfo->pui32KernelCCBEventKicker = (IMG_UINT32 *)psDevInfo->psKernelCCBEventKickerMemInfo->pvLinAddrKM;\r
+\r
+       psDevInfo->psKernelSGXHostCtlMemInfo = (PVRSRV_KERNEL_MEM_INFO *)psInitInfo->hKernelSGXHostCtlMemInfo;\r
+       psDevInfo->psSGXHostCtl = (SGXMKIF_HOST_CTL *)psDevInfo->psKernelSGXHostCtlMemInfo->pvLinAddrKM;\r
+\r
+       psDevInfo->psKernelSGXTA3DCtlMemInfo = (PVRSRV_KERNEL_MEM_INFO *)psInitInfo->hKernelSGXTA3DCtlMemInfo;\r
+\r
+       psDevInfo->psKernelSGXMiscMemInfo = (PVRSRV_KERNEL_MEM_INFO *)psInitInfo->hKernelSGXMiscMemInfo;\r
+\r
+#if defined(SGX_SUPPORT_HWPROFILING)\r
+       psDevInfo->psKernelHWProfilingMemInfo = (PVRSRV_KERNEL_MEM_INFO *)psInitInfo->hKernelHWProfilingMemInfo;\r
+#endif\r
+#if defined(SUPPORT_SGX_HWPERF)\r
+       psDevInfo->psKernelHWPerfCBMemInfo = (PVRSRV_KERNEL_MEM_INFO *)psInitInfo->hKernelHWPerfCBMemInfo;\r
+#endif\r
+#ifdef PVRSRV_USSE_EDM_STATUS_DEBUG\r
+       psDevInfo->psKernelEDMStatusBufferMemInfo = (PVRSRV_KERNEL_MEM_INFO *)psInitInfo->hKernelEDMStatusBufferMemInfo;\r
+#endif \r
+#if defined(SGX_FEATURE_OVERLAPPED_SPM)\r
+       psDevInfo->psKernelTmpRgnHeaderMemInfo = (PVRSRV_KERNEL_MEM_INFO *)psInitInfo->hKernelTmpRgnHeaderMemInfo;\r
+#endif\r
+#if defined(SGX_FEATURE_SPM_MODE_0)\r
+       psDevInfo->psKernelTmpDPMStateMemInfo = (PVRSRV_KERNEL_MEM_INFO *)psInitInfo->hKernelTmpDPMStateMemInfo;\r
+#endif\r
+       \r
+\r
+       eError = OSAllocMem(PVRSRV_OS_PAGEABLE_HEAP,\r
+                                               sizeof(PVRSRV_SGX_CCB_INFO),\r
+                                               (IMG_VOID **)&psKernelCCBInfo, 0);\r
+       if (eError != PVRSRV_OK)\r
+       {\r
+               PVR_DPF((PVR_DBG_ERROR,"InitDevInfo: Failed to alloc memory"));\r
+               goto failed_allockernelccb;\r
+       }\r
+\r
+\r
+       OSMemSet(psKernelCCBInfo, 0, sizeof(PVRSRV_SGX_CCB_INFO));\r
+       psKernelCCBInfo->psCCBMemInfo           = psDevInfo->psKernelCCBMemInfo;\r
+       psKernelCCBInfo->psCCBCtlMemInfo        = psDevInfo->psKernelCCBCtlMemInfo;\r
+       psKernelCCBInfo->psCommands                     = psDevInfo->psKernelCCB->asCommands;\r
+       psKernelCCBInfo->pui32WriteOffset       = &psDevInfo->psKernelCCBCtl->ui32WriteOffset;\r
+       psKernelCCBInfo->pui32ReadOffset        = &psDevInfo->psKernelCCBCtl->ui32ReadOffset;\r
+       psDevInfo->psKernelCCBInfo = psKernelCCBInfo;\r
+\r
+       \r
+\r
+       psDevInfo->ui32HostKickAddress = psInitInfo->ui32HostKickAddress;\r
+\r
+       \r
+       psDevInfo->ui32GetMiscInfoAddress = psInitInfo->ui32GetMiscInfoAddress;\r
+\r
+       psDevInfo->bForcePTOff = IMG_FALSE;\r
+\r
+       psDevInfo->ui32CacheControl = psInitInfo->ui32CacheControl;\r
+\r
+       psDevInfo->ui32EDMTaskReg0 = psInitInfo->ui32EDMTaskReg0;\r
+       psDevInfo->ui32EDMTaskReg1 = psInitInfo->ui32EDMTaskReg1;\r
+       psDevInfo->ui32ClkGateStatusReg = psInitInfo->ui32ClkGateStatusReg;\r
+       psDevInfo->ui32ClkGateStatusMask = psInitInfo->ui32ClkGateStatusMask;\r
+#if defined(SGX_FEATURE_MP)\r
+       psDevInfo->ui32MasterClkGateStatusReg = psInitInfo->ui32MasterClkGateStatusReg;\r
+       psDevInfo->ui32MasterClkGateStatusMask = psInitInfo->ui32MasterClkGateStatusMask;\r
+#endif \r
+\r
+\r
+       \r
+       OSMemCopy(&psDevInfo->asSGXDevData,  &psInitInfo->asInitDevData, sizeof(psDevInfo->asSGXDevData));\r
+\r
+       return PVRSRV_OK;\r
+\r
+failed_allockernelccb:\r
+       DeinitDevInfo(psDevInfo);\r
+\r
+       return eError;\r
+}\r
+\r
+\r
+\r
+\r
+static PVRSRV_ERROR SGXRunScript(PVRSRV_SGXDEV_INFO *psDevInfo, SGX_INIT_COMMAND *psScript, IMG_UINT32 ui32NumInitCommands)\r
+{\r
+       IMG_UINT32 ui32PC;\r
+       SGX_INIT_COMMAND *psComm;\r
+\r
+       for (ui32PC = 0, psComm = psScript;\r
+               ui32PC < ui32NumInitCommands;\r
+               ui32PC++, psComm++)\r
+       {\r
+               switch (psComm->eOp)\r
+               {\r
+                       case SGX_INIT_OP_WRITE_HW_REG:\r
+                       {\r
+                               OSWriteHWReg(psDevInfo->pvRegsBaseKM, psComm->sWriteHWReg.ui32Offset, psComm->sWriteHWReg.ui32Value);\r
+                               PDUMPREG(psComm->sWriteHWReg.ui32Offset, psComm->sWriteHWReg.ui32Value);\r
+                               break;\r
+                       }\r
+#if defined(PDUMP)\r
+                       case SGX_INIT_OP_PDUMP_HW_REG:\r
+                       {\r
+                               PDUMPREG(psComm->sPDumpHWReg.ui32Offset, psComm->sPDumpHWReg.ui32Value);\r
+                               break;\r
+                       }\r
+#endif\r
+                       case SGX_INIT_OP_HALT:\r
+                       {\r
+                               return PVRSRV_OK;\r
+                       }\r
+                       case SGX_INIT_OP_ILLEGAL:\r
+                       \r
+                       default:\r
+                       {\r
+                               PVR_DPF((PVR_DBG_ERROR,"SGXRunScript: PC %d: Illegal command: %d", ui32PC, psComm->eOp));\r
+                               return PVRSRV_ERROR_GENERIC;\r
+                       }\r
+               }\r
+\r
+       }\r
+\r
+       return PVRSRV_ERROR_GENERIC;\r
+}\r
+\r
+PVRSRV_ERROR SGXInitialise(PVRSRV_SGXDEV_INFO  *psDevInfo,\r
+                                                  IMG_BOOL                             bHardwareRecovery)\r
+{\r
+       PVRSRV_ERROR            eError;\r
+\r
+       \r
+\r
+       PDUMPCOMMENTWITHFLAGS(PDUMP_FLAGS_CONTINUOUS, "SGX initialisation script part 1\n");\r
+       eError = SGXRunScript(psDevInfo, psDevInfo->sScripts.asInitCommandsPart1, SGX_MAX_INIT_COMMANDS);\r
+       if (eError != PVRSRV_OK)\r
+       {\r
+               PVR_DPF((PVR_DBG_ERROR,"SGXInitialise: SGXRunScript (part 1) failed (%d)", eError));\r
+               return (PVRSRV_ERROR_GENERIC);\r
+       }\r
+       PDUMPCOMMENTWITHFLAGS(PDUMP_FLAGS_CONTINUOUS, "End of SGX initialisation script part 1\n");\r
+\r
+       \r
+       SGXReset(psDevInfo, PDUMP_FLAGS_CONTINUOUS);\r
+\r
+#if defined(EUR_CR_POWER)\r
+#if defined(SGX531)\r
+       \r
+\r
+\r
+\r
+\r
+       OSWriteHWReg(psDevInfo->pvRegsBaseKM, EUR_CR_POWER, 1);\r
+       PDUMPREG(EUR_CR_POWER, 1);\r
+#else\r
+       \r
+       OSWriteHWReg(psDevInfo->pvRegsBaseKM, EUR_CR_POWER, 0);\r
+       PDUMPREG(EUR_CR_POWER, 0);\r
+#endif\r
+#endif\r
+\r
+       \r
+       *psDevInfo->pui32KernelCCBEventKicker = 0;\r
+#if defined(PDUMP)\r
+       PDUMPMEM(IMG_NULL, psDevInfo->psKernelCCBEventKickerMemInfo, 0,\r
+                        sizeof(*psDevInfo->pui32KernelCCBEventKicker), PDUMP_FLAGS_CONTINUOUS,\r
+                        MAKEUNIQUETAG(psDevInfo->psKernelCCBEventKickerMemInfo));\r
+#endif \r
+\r
+       \r
+\r
+       PDUMPCOMMENTWITHFLAGS(PDUMP_FLAGS_CONTINUOUS, "SGX initialisation script part 2\n");\r
+       eError = SGXRunScript(psDevInfo, psDevInfo->sScripts.asInitCommandsPart2, SGX_MAX_INIT_COMMANDS);\r
+       if (eError != PVRSRV_OK)\r
+       {\r
+               PVR_DPF((PVR_DBG_ERROR,"SGXInitialise: SGXRunScript (part 2) failed (%d)", eError));\r
+               return (PVRSRV_ERROR_GENERIC);\r
+       }\r
+       PDUMPCOMMENTWITHFLAGS(PDUMP_FLAGS_CONTINUOUS, "End of SGX initialisation script part 2\n");\r
+\r
+#ifdef PLAT_TI8168\r
+        OSWriteHWReg(psDevInfo->pvRegsBaseKM, 0xFF08, 0x80000000);//OCP Bypass mode\r
+#else\r
+       if(cpu_is_omap3630())\r
+               OSWriteHWReg(psDevInfo->pvRegsBaseKM, 0xFF08, 0x80000000);//OCP Bypass mode\r
+#endif\r
+\r
+       SGXStartTimer(psDevInfo, (IMG_BOOL)!bHardwareRecovery);\r
+\r
+       if (bHardwareRecovery)\r
+       {\r
+               SGXMKIF_HOST_CTL        *psSGXHostCtl = (SGXMKIF_HOST_CTL *)psDevInfo->psSGXHostCtl;\r
+\r
+               \r
+               if (PollForValueKM((volatile IMG_UINT32 *)(&psSGXHostCtl->ui32InterruptClearFlags),\r
+                                                  0,\r
+                                                  PVRSRV_USSE_EDM_INTERRUPT_HWR,\r
+                                                  MAX_HW_TIME_US/WAIT_TRY_COUNT,\r
+                                                  1000) != PVRSRV_OK)\r
+               {\r
+                       PVR_DPF((PVR_DBG_ERROR, "SGXInitialise: Wait for uKernel HW Recovery failed"));\r
+                       PVR_DBG_BREAK;\r
+                       return PVRSRV_ERROR_RETRY;\r
+               }\r
+       }\r
+\r
+#if defined(FIX_HW_BRN_22997) && defined(FIX_HW_BRN_23030) && defined(SGX_FEATURE_HOST_PORT)\r
+       \r
+\r
+\r
+       WorkaroundBRN22997ReadHostPort(psDevInfo);\r
+#endif \r
+\r
+       PVR_ASSERT(psDevInfo->psKernelCCBCtl->ui32ReadOffset == psDevInfo->psKernelCCBCtl->ui32WriteOffset);\r
+\r
+       return PVRSRV_OK;\r
+}\r
+\r
+PVRSRV_ERROR SGXDeinitialise(IMG_HANDLE hDevCookie)\r
+\r
+{\r
+       PVRSRV_SGXDEV_INFO      *psDevInfo = (PVRSRV_SGXDEV_INFO *) hDevCookie;\r
+       PVRSRV_ERROR            eError;\r
+\r
+       \r
+       if (psDevInfo->pvRegsBaseKM == IMG_NULL)\r
+       {\r
+               return PVRSRV_OK;\r
+       }\r
+\r
+       eError = SGXRunScript(psDevInfo, psDevInfo->sScripts.asDeinitCommands, SGX_MAX_DEINIT_COMMANDS);\r
+       if (eError != PVRSRV_OK)\r
+       {\r
+               PVR_DPF((PVR_DBG_ERROR,"SGXDeinitialise: SGXRunScript failed (%d)", eError));\r
+               return (PVRSRV_ERROR_GENERIC);\r
+       }\r
+\r
+       return PVRSRV_OK;\r
+}\r
+\r
+\r
+static PVRSRV_ERROR DevInitSGXPart1 (IMG_VOID *pvDeviceNode)\r
+{\r
+       PVRSRV_SGXDEV_INFO      *psDevInfo;\r
+       IMG_HANDLE              hKernelDevMemContext;\r
+       IMG_DEV_PHYADDR         sPDDevPAddr;\r
+       IMG_UINT32              i;\r
+       PVRSRV_DEVICE_NODE  *psDeviceNode = (PVRSRV_DEVICE_NODE *)pvDeviceNode;\r
+       DEVICE_MEMORY_HEAP_INFO *psDeviceMemoryHeap = psDeviceNode->sDevMemoryInfo.psDeviceMemoryHeap;\r
+       PVRSRV_ERROR            eError;\r
+\r
+       PDUMPCOMMENT("SGX Initialisation Part 1");\r
+\r
+       \r
+       PDUMPCOMMENT("SGX Core Version Information: %s", SGX_CORE_FRIENDLY_NAME);\r
+#ifdef SGX_CORE_REV\r
+       PDUMPCOMMENT("SGX Core Revision Information: %d", SGX_CORE_REV);\r
+#else\r
+       PDUMPCOMMENT("SGX Core Revision Information: head rtl");\r
+#endif\r
+\r
+       \r
+\r
+       if(OSAllocMem( PVRSRV_OS_NON_PAGEABLE_HEAP,\r
+                                        sizeof(PVRSRV_SGXDEV_INFO),\r
+                                        (IMG_VOID **)&psDevInfo, IMG_NULL) != PVRSRV_OK)\r
+       {\r
+               PVR_DPF((PVR_DBG_ERROR,"DevInitSGXPart1 : Failed to alloc memory for DevInfo"));\r
+               return (PVRSRV_ERROR_OUT_OF_MEMORY);\r
+       }\r
+       OSMemSet (psDevInfo, 0, sizeof(PVRSRV_SGXDEV_INFO));\r
+\r
+       \r
+       psDevInfo->eDeviceType          = DEV_DEVICE_TYPE;\r
+       psDevInfo->eDeviceClass         = DEV_DEVICE_CLASS;\r
+\r
+       \r
+       psDeviceNode->pvDevice = (IMG_PVOID)psDevInfo;\r
+\r
+       \r
+       psDevInfo->pvDeviceMemoryHeap = (IMG_VOID*)psDeviceMemoryHeap;\r
+\r
+       \r
+       hKernelDevMemContext = BM_CreateContext(psDeviceNode,\r
+                                                                                       &sPDDevPAddr,\r
+                                                                                       IMG_NULL,\r
+                                                                                       IMG_NULL);\r
+\r
+       psDevInfo->sKernelPDDevPAddr = sPDDevPAddr;\r
+\r
+\r
+       \r
+       for(i=0; i<psDeviceNode->sDevMemoryInfo.ui32HeapCount; i++)\r
+       {\r
+               IMG_HANDLE hDevMemHeap;\r
+\r
+               switch(psDeviceMemoryHeap[i].DevMemHeapType)\r
+               {\r
+                       case DEVICE_MEMORY_HEAP_KERNEL:\r
+                       case DEVICE_MEMORY_HEAP_SHARED:\r
+                       case DEVICE_MEMORY_HEAP_SHARED_EXPORTED:\r
+                       {\r
+                               hDevMemHeap = BM_CreateHeap (hKernelDevMemContext,\r
+                                                                                               &psDeviceMemoryHeap[i]);\r
+                               \r
+\r
+\r
+                               psDeviceMemoryHeap[i].hDevMemHeap = hDevMemHeap;\r
+                               break;\r
+                       }\r
+               }\r
+       }\r
+\r
+       eError = MMU_BIFResetPDAlloc(psDevInfo);\r
+       if (eError != PVRSRV_OK)\r
+       {\r
+               PVR_DPF((PVR_DBG_ERROR,"DevInitSGX : Failed to alloc memory for BIF reset"));\r
+               return PVRSRV_ERROR_GENERIC;\r
+       }\r
+\r
+       return PVRSRV_OK;\r
+}\r
+\r
+IMG_EXPORT\r
+PVRSRV_ERROR SGXGetInfoForSrvinitKM(IMG_HANDLE hDevHandle, SGX_BRIDGE_INFO_FOR_SRVINIT *psInitInfo)\r
+{\r
+       PVRSRV_DEVICE_NODE      *psDeviceNode;\r
+       PVRSRV_SGXDEV_INFO      *psDevInfo;\r
+       PVRSRV_ERROR            eError;\r
+\r
+       PDUMPCOMMENT("SGXGetInfoForSrvinit");\r
+\r
+       psDeviceNode = (PVRSRV_DEVICE_NODE *)hDevHandle;\r
+       psDevInfo = (PVRSRV_SGXDEV_INFO *)psDeviceNode->pvDevice;\r
+\r
+       psInitInfo->sPDDevPAddr = psDevInfo->sKernelPDDevPAddr;\r
+\r
+       eError = PVRSRVGetDeviceMemHeapsKM(hDevHandle, &psInitInfo->asHeapInfo[0]);\r
+       if (eError != PVRSRV_OK)\r
+       {\r
+               PVR_DPF((PVR_DBG_ERROR,"SGXGetInfoForSrvinit: PVRSRVGetDeviceMemHeapsKM failed (%d)", eError));\r
+               return PVRSRV_ERROR_GENERIC;\r
+       }\r
+\r
+       return eError;\r
+}\r
+\r
+IMG_EXPORT\r
+PVRSRV_ERROR DevInitSGXPart2KM (PVRSRV_PER_PROCESS_DATA *psPerProc,\r
+                                IMG_HANDLE hDevHandle,\r
+                                SGX_BRIDGE_INIT_INFO *psInitInfo)\r
+{\r
+       PVRSRV_DEVICE_NODE      *psDeviceNode;\r
+       PVRSRV_SGXDEV_INFO      *psDevInfo;\r
+       PVRSRV_ERROR            eError;\r
+       SGX_DEVICE_MAP          *psSGXDeviceMap;\r
+       PVR_POWER_STATE         eDefaultPowerState;\r
+\r
+       PDUMPCOMMENT("SGX Initialisation Part 2");\r
+\r
+       psDeviceNode = (PVRSRV_DEVICE_NODE *)hDevHandle;\r
+       psDevInfo = (PVRSRV_SGXDEV_INFO *)psDeviceNode->pvDevice;\r
+\r
+       \r
+\r
+       eError = InitDevInfo(psPerProc, psDeviceNode, psInitInfo);\r
+       if (eError != PVRSRV_OK)\r
+       {\r
+               PVR_DPF((PVR_DBG_ERROR,"DevInitSGXPart2KM: Failed to load EDM program"));\r
+               goto failed_init_dev_info;\r
+       }\r
+\r
+\r
+       eError = SysGetDeviceMemoryMap(PVRSRV_DEVICE_TYPE_SGX,\r
+                                                                       (IMG_VOID**)&psSGXDeviceMap);\r
+       if (eError != PVRSRV_OK)\r
+       {\r
+               PVR_DPF((PVR_DBG_ERROR,"DevInitSGXPart2KM: Failed to get device memory map!"));\r
+               return PVRSRV_ERROR_INIT_FAILURE;\r
+       }\r
+\r
+       \r
+       if (psSGXDeviceMap->pvRegsCpuVBase)\r
+       {\r
+               psDevInfo->pvRegsBaseKM = psSGXDeviceMap->pvRegsCpuVBase;\r
+       }\r
+       else\r
+       {\r
+               \r
+               psDevInfo->pvRegsBaseKM = OSMapPhysToLin(psSGXDeviceMap->sRegsCpuPBase,\r
+                                                                                          psSGXDeviceMap->ui32RegsSize,\r
+                                                                                          PVRSRV_HAP_KERNEL_ONLY|PVRSRV_HAP_UNCACHED,\r
+                                                                                          IMG_NULL);\r
+               if (!psDevInfo->pvRegsBaseKM)\r
+               {\r
+                       PVR_DPF((PVR_DBG_ERROR,"DevInitSGXPart2KM: Failed to map in regs\n"));\r
+                       return PVRSRV_ERROR_BAD_MAPPING;\r
+               }\r
+       }\r
+       psDevInfo->ui32RegSize = psSGXDeviceMap->ui32RegsSize;\r
+       psDevInfo->sRegsPhysBase = psSGXDeviceMap->sRegsSysPBase;\r
+\r
+\r
+#if defined(SGX_FEATURE_HOST_PORT)\r
+       if (psSGXDeviceMap->ui32Flags & SGX_HOSTPORT_PRESENT)\r
+       {\r
+               \r
+               psDevInfo->pvHostPortBaseKM = OSMapPhysToLin(psSGXDeviceMap->sHPCpuPBase,\r
+                                                                                          psSGXDeviceMap->ui32HPSize,\r
+                                                                                          PVRSRV_HAP_KERNEL_ONLY|PVRSRV_HAP_UNCACHED,\r
+                                                                                          IMG_NULL);\r
+               if (!psDevInfo->pvHostPortBaseKM)\r
+               {\r
+                       PVR_DPF((PVR_DBG_ERROR,"DevInitSGXPart2KM: Failed to map in host port\n"));\r
+                       return PVRSRV_ERROR_BAD_MAPPING;\r
+               }\r
+               psDevInfo->ui32HPSize = psSGXDeviceMap->ui32HPSize;\r
+               psDevInfo->sHPSysPAddr = psSGXDeviceMap->sHPSysPBase;\r
+       }\r
+#endif\r
+\r
+#if defined (SYS_USING_INTERRUPTS)\r
+\r
+       \r
+       psDeviceNode->pvISRData = psDeviceNode;\r
+       \r
+       PVR_ASSERT(psDeviceNode->pfnDeviceISR == SGX_ISRHandler);\r
+\r
+#endif \r
+\r
+       \r
+#if defined(SUPPORT_ACTIVE_POWER_MANAGEMENT)\r
+       \r
+       psDevInfo->psSGXHostCtl->ui32PowerStatus |= PVRSRV_USSE_EDM_POWMAN_NO_WORK;\r
+       eDefaultPowerState = PVRSRV_POWER_STATE_D3;\r
+#else\r
+       eDefaultPowerState = PVRSRV_POWER_STATE_D0;\r
+#endif \r
+       eError = PVRSRVRegisterPowerDevice (psDeviceNode->sDevId.ui32DeviceIndex,\r
+                                                                               SGXPrePowerStateExt, SGXPostPowerStateExt,\r
+                                                                               SGXPreClockSpeedChange, SGXPostClockSpeedChange,\r
+                                                                               (IMG_HANDLE)psDeviceNode,\r
+                                                                               PVRSRV_POWER_STATE_D3,\r
+                                                                               eDefaultPowerState);\r
+       if (eError != PVRSRV_OK)\r
+       {\r
+               PVR_DPF((PVR_DBG_ERROR,"DevInitSGXPart2KM: failed to register device with power manager"));\r
+               return eError;\r
+       }\r
+\r
+#if defined(FIX_HW_BRN_22997) && defined(FIX_HW_BRN_23030) && defined(SGX_FEATURE_HOST_PORT)\r
+       eError = WorkaroundBRN22997Alloc(psDevInfo);\r
+       if (eError != PVRSRV_OK)\r
+       {\r
+               PVR_DPF((PVR_DBG_ERROR,"SGXInitialise : Failed to alloc memory for BRN22997 workaround"));\r
+               return eError;\r
+       }\r
+#endif \r
+\r
+#if defined(SUPPORT_EXTERNAL_SYSTEM_CACHE)\r
+       \r
+       psDevInfo->ui32ExtSysCacheRegsSize = psSGXDeviceMap->ui32ExtSysCacheRegsSize;\r
+       psDevInfo->sExtSysCacheRegsDevPBase = psSGXDeviceMap->sExtSysCacheRegsDevPBase;\r
+       eError = MMU_MapExtSystemCacheRegs(psDeviceNode);\r
+       if (eError != PVRSRV_OK)\r
+       {\r
+               PVR_DPF((PVR_DBG_ERROR,"SGXInitialise : Failed to map external system cache registers"));\r
+               return eError;\r
+       }       \r
+#endif \r
+\r
+       \r
+\r
+       OSMemSet(psDevInfo->psKernelCCB, 0, sizeof(PVRSRV_SGX_KERNEL_CCB));\r
+       OSMemSet(psDevInfo->psKernelCCBCtl, 0, sizeof(PVRSRV_SGX_CCB_CTL));\r
+       OSMemSet(psDevInfo->pui32KernelCCBEventKicker, 0, sizeof(*psDevInfo->pui32KernelCCBEventKicker));\r
+       PDUMPCOMMENT("Initialise Kernel CCB");\r
+       PDUMPMEM(IMG_NULL, psDevInfo->psKernelCCBMemInfo, 0, sizeof(PVRSRV_SGX_KERNEL_CCB), PDUMP_FLAGS_CONTINUOUS, MAKEUNIQUETAG(psDevInfo->psKernelCCBMemInfo));\r
+       PDUMPCOMMENT("Initialise Kernel CCB Control");\r
+       PDUMPMEM(IMG_NULL, psDevInfo->psKernelCCBCtlMemInfo, 0, sizeof(PVRSRV_SGX_CCB_CTL), PDUMP_FLAGS_CONTINUOUS, MAKEUNIQUETAG(psDevInfo->psKernelCCBCtlMemInfo));\r
+       PDUMPCOMMENT("Initialise Kernel CCB Event Kicker");\r
+       PDUMPMEM(IMG_NULL, psDevInfo->psKernelCCBEventKickerMemInfo, 0, sizeof(*psDevInfo->pui32KernelCCBEventKicker), PDUMP_FLAGS_CONTINUOUS, MAKEUNIQUETAG(psDevInfo->psKernelCCBEventKickerMemInfo));\r
+\r
+       return PVRSRV_OK;\r
+\r
+failed_init_dev_info:\r
+       return eError;\r
+}\r
+\r
+static PVRSRV_ERROR DevDeInitSGX (IMG_VOID *pvDeviceNode)\r
+{\r
+       PVRSRV_DEVICE_NODE                      *psDeviceNode = (PVRSRV_DEVICE_NODE *)pvDeviceNode;\r
+       PVRSRV_SGXDEV_INFO                      *psDevInfo = (PVRSRV_SGXDEV_INFO*)psDeviceNode->pvDevice;\r
+       PVRSRV_ERROR                            eError;\r
+       IMG_UINT32                                      ui32Heap;\r
+       DEVICE_MEMORY_HEAP_INFO         *psDeviceMemoryHeap;\r
+       SGX_DEVICE_MAP                          *psSGXDeviceMap;\r
+\r
+       if (!psDevInfo)\r
+       {\r
+               \r
+               PVR_DPF((PVR_DBG_ERROR,"DevDeInitSGX: Null DevInfo"));\r
+               return PVRSRV_OK;\r
+       }\r
+\r
+#if defined(SUPPORT_HW_RECOVERY)\r
+       if (psDevInfo->hTimer)\r
+       {\r
+               eError = OSRemoveTimer(psDevInfo->hTimer);\r
+               if (eError != PVRSRV_OK)\r
+               {\r
+                       PVR_DPF((PVR_DBG_ERROR,"DevDeInitSGX: Failed to remove timer"));\r
+                       return  eError;\r
+               }\r
+               psDevInfo->hTimer = IMG_NULL;\r
+       }\r
+#endif \r
+\r
+#if defined(SUPPORT_EXTERNAL_SYSTEM_CACHE)\r
+       \r
+       eError = MMU_UnmapExtSystemCacheRegs(psDeviceNode);\r
+       if (eError != PVRSRV_OK)\r
+       {\r
+               PVR_DPF((PVR_DBG_ERROR,"DevDeInitSGX: Failed to unmap ext system cache registers"));\r
+               return eError;\r
+       }       \r
+#endif \r
+\r
+#if defined(FIX_HW_BRN_22997) && defined(FIX_HW_BRN_23030) && defined(SGX_FEATURE_HOST_PORT)\r
+       WorkaroundBRN22997Free(psDevInfo);\r
+#endif \r
+\r
+       MMU_BIFResetPDFree(psDevInfo);\r
+\r
+\r
+       \r
+\r
+       DeinitDevInfo(psDevInfo);\r
+\r
+       \r
+       psDeviceMemoryHeap = (DEVICE_MEMORY_HEAP_INFO *)psDevInfo->pvDeviceMemoryHeap;\r
+       for(ui32Heap=0; ui32Heap<psDeviceNode->sDevMemoryInfo.ui32HeapCount; ui32Heap++)\r
+       {\r
+               switch(psDeviceMemoryHeap[ui32Heap].DevMemHeapType)\r
+               {\r
+                       case DEVICE_MEMORY_HEAP_KERNEL:\r
+                       case DEVICE_MEMORY_HEAP_SHARED:\r
+                       case DEVICE_MEMORY_HEAP_SHARED_EXPORTED:\r
+                       {\r
+                               if (psDeviceMemoryHeap[ui32Heap].hDevMemHeap != IMG_NULL)\r
+                               {\r
+                                       BM_DestroyHeap(psDeviceMemoryHeap[ui32Heap].hDevMemHeap);\r
+                               }\r
+                               break;\r
+                       }\r
+               }\r
+       }\r
+\r
+       \r
+       eError = BM_DestroyContext(psDeviceNode->sDevMemoryInfo.pBMKernelContext, IMG_NULL);\r
+       if (eError != PVRSRV_OK)\r
+       {\r
+               PVR_DPF((PVR_DBG_ERROR,"DevDeInitSGX : Failed to destroy kernel context"));\r
+               return eError;\r
+       }\r
+\r
+       \r
+       eError = PVRSRVRemovePowerDevice (((PVRSRV_DEVICE_NODE*)pvDeviceNode)->sDevId.ui32DeviceIndex);\r
+       if (eError != PVRSRV_OK)\r
+       {\r
+               return eError;\r
+       }\r
+\r
+       eError = SysGetDeviceMemoryMap(PVRSRV_DEVICE_TYPE_SGX,\r
+                                                                       (IMG_VOID**)&psSGXDeviceMap);\r
+       if (eError != PVRSRV_OK)\r
+       {\r
+               PVR_DPF((PVR_DBG_ERROR,"DevDeInitSGX: Failed to get device memory map!"));\r
+               return eError;\r
+       }\r
+\r
+       \r
+       if (!psSGXDeviceMap->pvRegsCpuVBase)\r
+       {\r
+               \r
+               if (psDevInfo->pvRegsBaseKM != IMG_NULL)\r
+               {\r
+                       OSUnMapPhysToLin(psDevInfo->pvRegsBaseKM,\r
+                                                        psDevInfo->ui32RegSize,\r
+                                                        PVRSRV_HAP_KERNEL_ONLY|PVRSRV_HAP_UNCACHED,\r
+                                                        IMG_NULL);\r
+               }\r
+       }\r
+\r
+#if defined(SGX_FEATURE_HOST_PORT)\r
+       if (psSGXDeviceMap->ui32Flags & SGX_HOSTPORT_PRESENT)\r
+       {\r
+               \r
+               if (psDevInfo->pvHostPortBaseKM != IMG_NULL)\r
+               {\r
+                       OSUnMapPhysToLin(psDevInfo->pvHostPortBaseKM,\r
+                                                  psDevInfo->ui32HPSize,\r
+                                                  PVRSRV_HAP_KERNEL_ONLY|PVRSRV_HAP_UNCACHED,\r
+                                                  IMG_NULL);\r
+               }\r
+       }\r
+#endif \r
+\r
+\r
+       \r
+       OSFreeMem(PVRSRV_OS_NON_PAGEABLE_HEAP,\r
+                               sizeof(PVRSRV_SGXDEV_INFO),\r
+                               psDevInfo,\r
+                               0);\r
+\r
+       psDeviceNode->pvDevice = IMG_NULL;\r
+\r
+       if (psDeviceMemoryHeap != IMG_NULL)\r
+       {\r
+       \r
+               OSFreeMem(PVRSRV_OS_NON_PAGEABLE_HEAP,\r
+                               sizeof(DEVICE_MEMORY_HEAP_INFO) * psDeviceNode->sDevMemoryInfo.ui32HeapCount,\r
+                               psDeviceMemoryHeap,\r
+                               0);\r
+       }\r
+\r
+       return PVRSRV_OK;\r
+}\r
+\r
+\r
+\r
+\r
+#if defined(SYS_USING_INTERRUPTS) || defined(SUPPORT_HW_RECOVERY)\r
+static\r
+IMG_VOID HWRecoveryResetSGX (PVRSRV_DEVICE_NODE *psDeviceNode,\r
+                                                                       IMG_UINT32                      ui32Component,\r
+                                                                       IMG_UINT32                      ui32CallerID)\r
+{\r
+       PVRSRV_ERROR            eError;\r
+       PVRSRV_SGXDEV_INFO      *psDevInfo = (PVRSRV_SGXDEV_INFO*)psDeviceNode->pvDevice;\r
+       SGXMKIF_HOST_CTL        *psSGXHostCtl = (SGXMKIF_HOST_CTL *)psDevInfo->psSGXHostCtl;\r
+\r
+       PVR_UNREFERENCED_PARAMETER(ui32Component);\r
+\r
+       \r
+\r
+       eError = PVRSRVPowerLock(ui32CallerID, IMG_FALSE);\r
+       if(eError != PVRSRV_OK)\r
+       {\r
+               \r
+\r
+\r
+               PVR_DPF((PVR_DBG_WARNING,"HWRecoveryResetSGX: Power transition in progress"));\r
+               return;\r
+       }\r
+\r
+       psSGXHostCtl->ui32InterruptClearFlags |= PVRSRV_USSE_EDM_INTERRUPT_HWR;\r
+\r
+       PVR_DPF((PVR_DBG_ERROR, "HWRecoveryResetSGX: SGX Hardware Recovery triggered"));\r
+\r
+\r
+       \r
+       PDUMPSUSPEND();\r
+\r
+       \r
+       do\r
+       {\r
+               eError = SGXInitialise(psDevInfo, IMG_TRUE);\r
+       }\r
+       while (eError == PVRSRV_ERROR_RETRY);\r
+       if (eError != PVRSRV_OK)\r
+       {\r
+               PVR_DPF((PVR_DBG_ERROR,"HWRecoveryResetSGX: SGXInitialise failed (%d)", eError));\r
+       }\r
+\r
+       \r
+       PDUMPRESUME();\r
+\r
+       PVRSRVPowerUnlock(ui32CallerID);\r
+\r
+       \r
+       SGXScheduleProcessQueuesKM(psDeviceNode);\r
+\r
+       \r
+       \r
+       PVRSRVProcessQueues(ui32CallerID, IMG_TRUE);\r
+}\r
+#endif \r
+\r
+\r
+#if defined(SUPPORT_HW_RECOVERY)\r
+IMG_VOID SGXOSTimer(IMG_VOID *pvData)\r
+{\r
+       PVRSRV_DEVICE_NODE *psDeviceNode = pvData;\r
+       PVRSRV_SGXDEV_INFO *psDevInfo = psDeviceNode->pvDevice;\r
+       static IMG_UINT32       ui32EDMTasks = 0;\r
+       static IMG_UINT32       ui32LockupCounter = 0; \r
+       static IMG_UINT32       ui32NumResets = 0;\r
+       IMG_UINT32              ui32CurrentEDMTasks;\r
+       IMG_BOOL                bLockup = IMG_FALSE;\r
+       IMG_BOOL                bPoweredDown;\r
+\r
+       \r
+       psDevInfo->ui32TimeStamp++;\r
+\r
+#if defined(NO_HARDWARE)\r
+       bPoweredDown = IMG_TRUE;\r
+#else\r
+       bPoweredDown = (IMG_BOOL)!SGXIsDevicePowered(psDeviceNode);\r
+#endif \r
+\r
+       \r
+       \r
+       if (bPoweredDown)\r
+       {\r
+               ui32LockupCounter = 0;\r
+       }\r
+       else\r
+       {\r
+               \r
+               ui32CurrentEDMTasks = OSReadHWReg(psDevInfo->pvRegsBaseKM, psDevInfo->ui32EDMTaskReg0);\r
+               if (psDevInfo->ui32EDMTaskReg1 != 0)\r
+               {\r
+                       ui32CurrentEDMTasks ^= OSReadHWReg(psDevInfo->pvRegsBaseKM, psDevInfo->ui32EDMTaskReg1);\r
+               }\r
+               if ((ui32CurrentEDMTasks == ui32EDMTasks) &&\r
+                       (psDevInfo->ui32NumResets == ui32NumResets))\r
+               {\r
+                       ui32LockupCounter++;\r
+                       if (ui32LockupCounter == 3)\r
+                       {\r
+                               ui32LockupCounter = 0;\r
+                               PVR_DPF((PVR_DBG_ERROR, "SGXOSTimer() detected SGX lockup (0x%x tasks)", ui32EDMTasks));\r
+\r
+                               bLockup = IMG_TRUE;\r
+                       }\r
+               }\r
+               else\r
+               {\r
+                       ui32LockupCounter = 0;\r
+                       ui32EDMTasks = ui32CurrentEDMTasks;\r
+                       ui32NumResets = psDevInfo->ui32NumResets;\r
+               }\r
+       }\r
+\r
+       if (bLockup)\r
+       {\r
+               SGXMKIF_HOST_CTL        *psSGXHostCtl = (SGXMKIF_HOST_CTL *)psDevInfo->psSGXHostCtl;\r
+\r
+               \r
+               psSGXHostCtl->ui32HostDetectedLockups ++;\r
+\r
+               \r
+               HWRecoveryResetSGX(psDeviceNode, 0, KERNEL_ID);\r
+       }\r
+}\r
+#endif \r
+\r
+\r
+#if defined(SYS_USING_INTERRUPTS)\r
+\r
+\r
+IMG_BOOL SGX_ISRHandler (IMG_VOID *pvData)\r
+{\r
+       IMG_BOOL bInterruptProcessed = IMG_FALSE;\r
+\r
+       \r
+       {\r
+               IMG_UINT32 ui32EventStatus, ui32EventEnable;\r
+               IMG_UINT32 ui32EventClear = 0;\r
+               PVRSRV_DEVICE_NODE *psDeviceNode;\r
+               PVRSRV_SGXDEV_INFO *psDevInfo;\r
+\r
+               \r
+               if(pvData == IMG_NULL)\r
+               {\r
+                       PVR_DPF((PVR_DBG_ERROR, "SGX_ISRHandler: Invalid params\n"));\r
+                       return bInterruptProcessed;\r
+               }\r
+\r
+               psDeviceNode = (PVRSRV_DEVICE_NODE *)pvData;\r
+               psDevInfo = (PVRSRV_SGXDEV_INFO *)psDeviceNode->pvDevice;\r
+\r
+               ui32EventStatus = OSReadHWReg(psDevInfo->pvRegsBaseKM, EUR_CR_EVENT_STATUS);\r
+               ui32EventEnable = OSReadHWReg(psDevInfo->pvRegsBaseKM, EUR_CR_EVENT_HOST_ENABLE);\r
+\r
+               \r
+\r
+               gui32EventStatusServicesByISR = ui32EventStatus;\r
+\r
+               \r
+               ui32EventStatus &= ui32EventEnable;\r
+\r
+               if (ui32EventStatus & EUR_CR_EVENT_STATUS_SW_EVENT_MASK)\r
+               {\r
+                       ui32EventClear |= EUR_CR_EVENT_HOST_CLEAR_SW_EVENT_MASK;\r
+               }\r
+\r
+               if (ui32EventClear)\r
+               {\r
+                       bInterruptProcessed = IMG_TRUE;\r
+\r
+                       \r
+                       ui32EventClear |= EUR_CR_EVENT_HOST_CLEAR_MASTER_INTERRUPT_MASK;\r
+\r
+                       \r
+                       OSWriteHWReg(psDevInfo->pvRegsBaseKM, EUR_CR_EVENT_HOST_CLEAR, ui32EventClear);\r
+               }\r
+       }\r
+\r
+       return bInterruptProcessed;\r
+}\r
+\r
+\r
+IMG_VOID SGX_MISRHandler (IMG_VOID *pvData)\r
+{\r
+       PVRSRV_DEVICE_NODE      *psDeviceNode = (PVRSRV_DEVICE_NODE *)pvData;\r
+       PVRSRV_SGXDEV_INFO      *psDevInfo = (PVRSRV_SGXDEV_INFO*)psDeviceNode->pvDevice;\r
+       SGXMKIF_HOST_CTL        *psSGXHostCtl = (SGXMKIF_HOST_CTL *)psDevInfo->psSGXHostCtl;\r
+\r
+       if (((psSGXHostCtl->ui32InterruptFlags & PVRSRV_USSE_EDM_INTERRUPT_HWR) != 0UL) &&\r
+               ((psSGXHostCtl->ui32InterruptClearFlags & PVRSRV_USSE_EDM_INTERRUPT_HWR) == 0UL))\r
+       {\r
+               HWRecoveryResetSGX(psDeviceNode, 0, ISR_ID);\r
+       }\r
+\r
+#if defined(OS_SUPPORTS_IN_LISR)\r
+       if (psDeviceNode->bReProcessDeviceCommandComplete)\r
+       {\r
+               SGXScheduleProcessQueuesKM(psDeviceNode);\r
+       }\r
+#endif\r
+\r
+#if defined(SUPPORT_ACTIVE_POWER_MANAGEMENT)\r
+       SGXTestActivePowerEvent(psDeviceNode, ISR_ID);\r
+#endif \r
+}\r
+#endif \r
+\r
+\r
+PVRSRV_ERROR SGXRegisterDevice (PVRSRV_DEVICE_NODE *psDeviceNode)\r
+{\r
+       DEVICE_MEMORY_INFO *psDevMemoryInfo;\r
+       DEVICE_MEMORY_HEAP_INFO *psDeviceMemoryHeap;\r
+\r
+       \r
+       psDeviceNode->sDevId.eDeviceType        = DEV_DEVICE_TYPE;\r
+       psDeviceNode->sDevId.eDeviceClass       = DEV_DEVICE_CLASS;\r
+\r
+       psDeviceNode->pfnInitDevice             = DevInitSGXPart1;\r
+       psDeviceNode->pfnDeInitDevice           = DevDeInitSGX;\r
+\r
+       psDeviceNode->pfnInitDeviceCompatCheck  = SGXDevInitCompatCheck;\r
+\r
+       \r
+\r
+       psDeviceNode->pfnMMUInitialise = MMU_Initialise;\r
+       psDeviceNode->pfnMMUFinalise = MMU_Finalise;\r
+       psDeviceNode->pfnMMUInsertHeap = MMU_InsertHeap;\r
+       psDeviceNode->pfnMMUCreate = MMU_Create;\r
+       psDeviceNode->pfnMMUDelete = MMU_Delete;\r
+       psDeviceNode->pfnMMUAlloc = MMU_Alloc;\r
+       psDeviceNode->pfnMMUFree = MMU_Free;\r
+       psDeviceNode->pfnMMUMapPages = MMU_MapPages;\r
+       psDeviceNode->pfnMMUMapShadow = MMU_MapShadow;\r
+       psDeviceNode->pfnMMUUnmapPages = MMU_UnmapPages;\r
+       psDeviceNode->pfnMMUMapScatter = MMU_MapScatter;\r
+       psDeviceNode->pfnMMUGetPhysPageAddr = MMU_GetPhysPageAddr;\r
+       psDeviceNode->pfnMMUGetPDDevPAddr = MMU_GetPDDevPAddr;\r
+\r
+#if defined (SYS_USING_INTERRUPTS)\r
+       \r
+\r
+       psDeviceNode->pfnDeviceISR = SGX_ISRHandler;\r
+       psDeviceNode->pfnDeviceMISR = SGX_MISRHandler;\r
+#endif\r
+\r
+       \r
+\r
+       psDeviceNode->pfnDeviceCommandComplete = SGXCommandComplete;\r
+\r
+       \r
+\r
+       psDevMemoryInfo = &psDeviceNode->sDevMemoryInfo;\r
+       \r
+       psDevMemoryInfo->ui32AddressSpaceSizeLog2 = SGX_FEATURE_ADDRESS_SPACE_SIZE;\r
+\r
+       \r
+       psDevMemoryInfo->ui32Flags = 0;\r
+\r
+       \r
+       psDevMemoryInfo->ui32HeapCount = SGX_MAX_HEAP_ID;\r
+\r
+       \r
+       psDevMemoryInfo->ui32SyncHeapID = SGX_SYNCINFO_HEAP_ID;\r
+\r
+       \r
+#if defined(SUPPORT_SGX_GENERAL_MAPPING_HEAP)\r
+       psDevMemoryInfo->ui32MappingHeapID = SGX_GENERAL_MAPPING_HEAP_ID;\r
+#else\r
+       psDevMemoryInfo->ui32MappingHeapID = SGX_GENERAL_HEAP_ID;\r
+#endif\r
+\r
+       \r
+       if(OSAllocMem( PVRSRV_OS_PAGEABLE_HEAP,\r
+                                        sizeof(DEVICE_MEMORY_HEAP_INFO) * psDevMemoryInfo->ui32HeapCount,\r
+                                        (IMG_VOID **)&psDevMemoryInfo->psDeviceMemoryHeap, 0) != PVRSRV_OK)\r
+       {\r
+               PVR_DPF((PVR_DBG_ERROR,"SGXRegisterDevice : Failed to alloc memory for DEVICE_MEMORY_HEAP_INFO"));\r
+               return (PVRSRV_ERROR_OUT_OF_MEMORY);\r
+       }\r
+       OSMemSet(psDevMemoryInfo->psDeviceMemoryHeap, 0, sizeof(DEVICE_MEMORY_HEAP_INFO) * psDevMemoryInfo->ui32HeapCount);\r
+\r
+       psDeviceMemoryHeap = psDevMemoryInfo->psDeviceMemoryHeap;\r
+\r
+       \r
+\r
+\r
+       \r
+       psDeviceMemoryHeap[SGX_GENERAL_HEAP_ID].ui32HeapID = HEAP_ID( PVRSRV_DEVICE_TYPE_SGX , SGX_GENERAL_HEAP_ID);\r
+       psDeviceMemoryHeap[SGX_GENERAL_HEAP_ID].sDevVAddrBase.uiAddr = SGX_GENERAL_HEAP_BASE;\r
+       psDeviceMemoryHeap[SGX_GENERAL_HEAP_ID].ui32HeapSize = SGX_GENERAL_HEAP_SIZE;\r
+       psDeviceMemoryHeap[SGX_GENERAL_HEAP_ID].ui32Attribs = PVRSRV_HAP_WRITECOMBINE\r
+                                                                                                               | PVRSRV_MEM_RAM_BACKED_ALLOCATION\r
+                                                                                                               | PVRSRV_HAP_SINGLE_PROCESS;\r
+       psDeviceMemoryHeap[SGX_GENERAL_HEAP_ID].pszName = "General";\r
+       psDeviceMemoryHeap[SGX_GENERAL_HEAP_ID].pszBSName = "General BS";\r
+       psDeviceMemoryHeap[SGX_GENERAL_HEAP_ID].DevMemHeapType = DEVICE_MEMORY_HEAP_PERCONTEXT;\r
+       \r
+       psDeviceMemoryHeap[SGX_GENERAL_HEAP_ID].ui32DataPageSize = SGX_MMU_PAGE_SIZE;\r
+\r
+       \r
+       psDeviceMemoryHeap[SGX_TADATA_HEAP_ID].ui32HeapID = HEAP_ID( PVRSRV_DEVICE_TYPE_SGX , SGX_TADATA_HEAP_ID);\r
+       psDeviceMemoryHeap[SGX_TADATA_HEAP_ID].sDevVAddrBase.uiAddr = SGX_TADATA_HEAP_BASE;\r
+       psDeviceMemoryHeap[SGX_TADATA_HEAP_ID].ui32HeapSize = SGX_TADATA_HEAP_SIZE;\r
+       psDeviceMemoryHeap[SGX_TADATA_HEAP_ID].ui32Attribs = PVRSRV_HAP_WRITECOMBINE\r
+                                                                                                               | PVRSRV_MEM_RAM_BACKED_ALLOCATION\r
+                                                                                                               | PVRSRV_HAP_MULTI_PROCESS;\r
+       psDeviceMemoryHeap[SGX_TADATA_HEAP_ID].pszName = "TA Data";\r
+       psDeviceMemoryHeap[SGX_TADATA_HEAP_ID].pszBSName = "TA Data BS";\r
+       psDeviceMemoryHeap[SGX_TADATA_HEAP_ID].DevMemHeapType = DEVICE_MEMORY_HEAP_PERCONTEXT;\r
+       \r
+       psDeviceMemoryHeap[SGX_TADATA_HEAP_ID].ui32DataPageSize = SGX_MMU_PAGE_SIZE;\r
+\r
+       \r
+       psDeviceMemoryHeap[SGX_KERNEL_CODE_HEAP_ID].ui32HeapID = HEAP_ID( PVRSRV_DEVICE_TYPE_SGX ,SGX_KERNEL_CODE_HEAP_ID);\r
+       psDeviceMemoryHeap[SGX_KERNEL_CODE_HEAP_ID].sDevVAddrBase.uiAddr = SGX_KERNEL_CODE_HEAP_BASE;\r
+       psDeviceMemoryHeap[SGX_KERNEL_CODE_HEAP_ID].ui32HeapSize = SGX_KERNEL_CODE_HEAP_SIZE;\r
+       psDeviceMemoryHeap[SGX_KERNEL_CODE_HEAP_ID].ui32Attribs = PVRSRV_HAP_WRITECOMBINE\r
+                                                                                                                       | PVRSRV_MEM_RAM_BACKED_ALLOCATION\r
+                                                                                                                       | PVRSRV_HAP_MULTI_PROCESS;\r
+       psDeviceMemoryHeap[SGX_KERNEL_CODE_HEAP_ID].pszName = "Kernel Code";\r
+       psDeviceMemoryHeap[SGX_KERNEL_CODE_HEAP_ID].pszBSName = "Kernel Code BS";\r
+       psDeviceMemoryHeap[SGX_KERNEL_CODE_HEAP_ID].DevMemHeapType = DEVICE_MEMORY_HEAP_SHARED_EXPORTED;\r
+       \r
+       psDeviceMemoryHeap[SGX_KERNEL_CODE_HEAP_ID].ui32DataPageSize = SGX_MMU_PAGE_SIZE;\r
+\r
+       \r
+       psDeviceMemoryHeap[SGX_KERNEL_DATA_HEAP_ID].ui32HeapID = HEAP_ID( PVRSRV_DEVICE_TYPE_SGX ,SGX_KERNEL_DATA_HEAP_ID);\r
+       psDeviceMemoryHeap[SGX_KERNEL_DATA_HEAP_ID].sDevVAddrBase.uiAddr = SGX_KERNEL_DATA_HEAP_BASE;\r
+       psDeviceMemoryHeap[SGX_KERNEL_DATA_HEAP_ID].ui32HeapSize = SGX_KERNEL_DATA_HEAP_SIZE;\r
+       psDeviceMemoryHeap[SGX_KERNEL_DATA_HEAP_ID].ui32Attribs = PVRSRV_HAP_WRITECOMBINE\r
+                                                                                                                               | PVRSRV_MEM_RAM_BACKED_ALLOCATION\r
+                                                                                                                               | PVRSRV_HAP_MULTI_PROCESS;\r
+       psDeviceMemoryHeap[SGX_KERNEL_DATA_HEAP_ID].pszName = "KernelData";\r
+       psDeviceMemoryHeap[SGX_KERNEL_DATA_HEAP_ID].pszBSName = "KernelData BS";\r
+       psDeviceMemoryHeap[SGX_KERNEL_DATA_HEAP_ID].DevMemHeapType = DEVICE_MEMORY_HEAP_SHARED_EXPORTED;\r
+       \r
+       psDeviceMemoryHeap[SGX_KERNEL_DATA_HEAP_ID].ui32DataPageSize = SGX_MMU_PAGE_SIZE;\r
+\r
+       \r
+       psDeviceMemoryHeap[SGX_PIXELSHADER_HEAP_ID].ui32HeapID = HEAP_ID( PVRSRV_DEVICE_TYPE_SGX ,SGX_PIXELSHADER_HEAP_ID);\r
+       psDeviceMemoryHeap[SGX_PIXELSHADER_HEAP_ID].sDevVAddrBase.uiAddr = SGX_PIXELSHADER_HEAP_BASE;\r
+       psDeviceMemoryHeap[SGX_PIXELSHADER_HEAP_ID].ui32HeapSize = SGX_PIXELSHADER_HEAP_SIZE;\r
+       psDeviceMemoryHeap[SGX_PIXELSHADER_HEAP_ID].ui32Attribs = PVRSRV_HAP_WRITECOMBINE\r
+                                                                                                                               | PVRSRV_MEM_RAM_BACKED_ALLOCATION\r
+                                                                                                                               | PVRSRV_HAP_SINGLE_PROCESS;\r
+       psDeviceMemoryHeap[SGX_PIXELSHADER_HEAP_ID].pszName = "PixelShaderUSSE";\r
+       psDeviceMemoryHeap[SGX_PIXELSHADER_HEAP_ID].pszBSName = "PixelShaderUSSE BS";\r
+       psDeviceMemoryHeap[SGX_PIXELSHADER_HEAP_ID].DevMemHeapType = DEVICE_MEMORY_HEAP_PERCONTEXT;\r
+       \r
+       psDeviceMemoryHeap[SGX_PIXELSHADER_HEAP_ID].ui32DataPageSize = SGX_MMU_PAGE_SIZE;\r
+\r
+       \r
+       psDeviceMemoryHeap[SGX_VERTEXSHADER_HEAP_ID].ui32HeapID = HEAP_ID( PVRSRV_DEVICE_TYPE_SGX ,SGX_VERTEXSHADER_HEAP_ID);\r
+       psDeviceMemoryHeap[SGX_VERTEXSHADER_HEAP_ID].sDevVAddrBase.uiAddr = SGX_VERTEXSHADER_HEAP_BASE;\r
+       psDeviceMemoryHeap[SGX_VERTEXSHADER_HEAP_ID].ui32HeapSize = SGX_VERTEXSHADER_HEAP_SIZE;\r
+       psDeviceMemoryHeap[SGX_VERTEXSHADER_HEAP_ID].ui32Attribs = PVRSRV_HAP_WRITECOMBINE\r
+                                                                                                                               | PVRSRV_MEM_RAM_BACKED_ALLOCATION\r
+                                                                                                                               | PVRSRV_HAP_SINGLE_PROCESS;\r
+       psDeviceMemoryHeap[SGX_VERTEXSHADER_HEAP_ID].pszName = "VertexShaderUSSE";\r
+       psDeviceMemoryHeap[SGX_VERTEXSHADER_HEAP_ID].pszBSName = "VertexShaderUSSE BS";\r
+       psDeviceMemoryHeap[SGX_VERTEXSHADER_HEAP_ID].DevMemHeapType = DEVICE_MEMORY_HEAP_PERCONTEXT;\r
+       \r
+       psDeviceMemoryHeap[SGX_VERTEXSHADER_HEAP_ID].ui32DataPageSize = SGX_MMU_PAGE_SIZE;\r
+\r
+       \r
+       psDeviceMemoryHeap[SGX_PDSPIXEL_CODEDATA_HEAP_ID].ui32HeapID = HEAP_ID( PVRSRV_DEVICE_TYPE_SGX ,SGX_PDSPIXEL_CODEDATA_HEAP_ID);\r
+       psDeviceMemoryHeap[SGX_PDSPIXEL_CODEDATA_HEAP_ID].sDevVAddrBase.uiAddr = SGX_PDSPIXEL_CODEDATA_HEAP_BASE;\r
+       psDeviceMemoryHeap[SGX_PDSPIXEL_CODEDATA_HEAP_ID].ui32HeapSize = SGX_PDSPIXEL_CODEDATA_HEAP_SIZE;\r
+       psDeviceMemoryHeap[SGX_PDSPIXEL_CODEDATA_HEAP_ID].ui32Attribs = PVRSRV_HAP_WRITECOMBINE\r
+                                                                                                                               | PVRSRV_MEM_RAM_BACKED_ALLOCATION\r
+                                                                                                                               | PVRSRV_HAP_SINGLE_PROCESS;\r
+       psDeviceMemoryHeap[SGX_PDSPIXEL_CODEDATA_HEAP_ID].pszName = "PDSPixelCodeData";\r
+       psDeviceMemoryHeap[SGX_PDSPIXEL_CODEDATA_HEAP_ID].pszBSName = "PDSPixelCodeData BS";\r
+       psDeviceMemoryHeap[SGX_PDSPIXEL_CODEDATA_HEAP_ID].DevMemHeapType = DEVICE_MEMORY_HEAP_PERCONTEXT;\r
+       \r
+       psDeviceMemoryHeap[SGX_PDSPIXEL_CODEDATA_HEAP_ID].ui32DataPageSize = SGX_MMU_PAGE_SIZE;\r
+\r
+       \r
+       psDeviceMemoryHeap[SGX_PDSVERTEX_CODEDATA_HEAP_ID].ui32HeapID = HEAP_ID( PVRSRV_DEVICE_TYPE_SGX ,SGX_PDSVERTEX_CODEDATA_HEAP_ID);\r
+       psDeviceMemoryHeap[SGX_PDSVERTEX_CODEDATA_HEAP_ID].sDevVAddrBase.uiAddr = SGX_PDSVERTEX_CODEDATA_HEAP_BASE;\r
+       psDeviceMemoryHeap[SGX_PDSVERTEX_CODEDATA_HEAP_ID].ui32HeapSize = SGX_PDSVERTEX_CODEDATA_HEAP_SIZE;\r
+       psDeviceMemoryHeap[SGX_PDSVERTEX_CODEDATA_HEAP_ID].ui32Attribs = PVRSRV_HAP_WRITECOMBINE\r
+                                                                                                                               | PVRSRV_MEM_RAM_BACKED_ALLOCATION\r
+                                                                                                                               | PVRSRV_HAP_SINGLE_PROCESS;\r
+       psDeviceMemoryHeap[SGX_PDSVERTEX_CODEDATA_HEAP_ID].pszName = "PDSVertexCodeData";\r
+       psDeviceMemoryHeap[SGX_PDSVERTEX_CODEDATA_HEAP_ID].pszBSName = "PDSVertexCodeData BS";\r
+       psDeviceMemoryHeap[SGX_PDSVERTEX_CODEDATA_HEAP_ID].DevMemHeapType = DEVICE_MEMORY_HEAP_PERCONTEXT;\r
+       \r
+       psDeviceMemoryHeap[SGX_PDSVERTEX_CODEDATA_HEAP_ID].ui32DataPageSize = SGX_MMU_PAGE_SIZE;\r
+\r
+       \r
+       psDeviceMemoryHeap[SGX_SYNCINFO_HEAP_ID].ui32HeapID = HEAP_ID( PVRSRV_DEVICE_TYPE_SGX ,SGX_SYNCINFO_HEAP_ID);\r
+       psDeviceMemoryHeap[SGX_SYNCINFO_HEAP_ID].sDevVAddrBase.uiAddr = SGX_SYNCINFO_HEAP_BASE;\r
+       psDeviceMemoryHeap[SGX_SYNCINFO_HEAP_ID].ui32HeapSize = SGX_SYNCINFO_HEAP_SIZE;\r
+       psDeviceMemoryHeap[SGX_SYNCINFO_HEAP_ID].ui32Attribs = PVRSRV_HAP_WRITECOMBINE\r
+                                                                                                               | PVRSRV_MEM_RAM_BACKED_ALLOCATION\r
+                                                                                                               | PVRSRV_HAP_MULTI_PROCESS;\r
+       psDeviceMemoryHeap[SGX_SYNCINFO_HEAP_ID].pszName = "CacheCoherent";\r
+       psDeviceMemoryHeap[SGX_SYNCINFO_HEAP_ID].pszBSName = "CacheCoherent BS";\r
+       \r
+       psDeviceMemoryHeap[SGX_SYNCINFO_HEAP_ID].DevMemHeapType = DEVICE_MEMORY_HEAP_SHARED_EXPORTED;\r
+       \r
+       psDeviceMemoryHeap[SGX_SYNCINFO_HEAP_ID].ui32DataPageSize = SGX_MMU_PAGE_SIZE;\r
+\r
+       \r
+       psDeviceMemoryHeap[SGX_3DPARAMETERS_HEAP_ID].ui32HeapID = HEAP_ID(PVRSRV_DEVICE_TYPE_SGX, SGX_3DPARAMETERS_HEAP_ID);\r
+       psDeviceMemoryHeap[SGX_3DPARAMETERS_HEAP_ID].sDevVAddrBase.uiAddr = SGX_3DPARAMETERS_HEAP_BASE;\r
+       psDeviceMemoryHeap[SGX_3DPARAMETERS_HEAP_ID].ui32HeapSize = SGX_3DPARAMETERS_HEAP_SIZE;\r
+       psDeviceMemoryHeap[SGX_3DPARAMETERS_HEAP_ID].pszName = "3DParameters";\r
+       psDeviceMemoryHeap[SGX_3DPARAMETERS_HEAP_ID].pszBSName = "3DParameters BS";\r
+#if defined(SUPPORT_PERCONTEXT_PB)\r
+       psDeviceMemoryHeap[SGX_3DPARAMETERS_HEAP_ID].ui32Attribs = PVRSRV_HAP_WRITECOMBINE\r
+                                                                                                                       | PVRSRV_MEM_RAM_BACKED_ALLOCATION\r
+                                                                                                                       | PVRSRV_HAP_SINGLE_PROCESS;\r
+       psDeviceMemoryHeap[SGX_3DPARAMETERS_HEAP_ID].DevMemHeapType = DEVICE_MEMORY_HEAP_PERCONTEXT;\r
+#else\r
+       psDeviceMemoryHeap[SGX_3DPARAMETERS_HEAP_ID].ui32Attribs = PVRSRV_HAP_WRITECOMBINE\r
+                                                                                                       | PVRSRV_MEM_RAM_BACKED_ALLOCATION\r
+                                                                                                       | PVRSRV_HAP_MULTI_PROCESS;\r
+       psDeviceMemoryHeap[SGX_3DPARAMETERS_HEAP_ID].DevMemHeapType = DEVICE_MEMORY_HEAP_SHARED_EXPORTED;\r
+#endif\r
+       \r
+       psDeviceMemoryHeap[SGX_3DPARAMETERS_HEAP_ID].ui32DataPageSize = SGX_MMU_PAGE_SIZE;\r
+\r
+#if defined(SUPPORT_SGX_GENERAL_MAPPING_HEAP)\r
+       \r
+       psDeviceMemoryHeap[SGX_GENERAL_MAPPING_HEAP_ID].ui32HeapID = HEAP_ID( PVRSRV_DEVICE_TYPE_SGX , SGX_GENERAL_MAPPING_HEAP_ID);\r
+       psDeviceMemoryHeap[SGX_GENERAL_MAPPING_HEAP_ID].sDevVAddrBase.uiAddr = SGX_GENERAL_MAPPING_HEAP_BASE;\r
+       psDeviceMemoryHeap[SGX_GENERAL_MAPPING_HEAP_ID].ui32HeapSize = SGX_GENERAL_MAPPING_HEAP_SIZE;\r
+       psDeviceMemoryHeap[SGX_GENERAL_MAPPING_HEAP_ID].ui32Attribs = PVRSRV_HAP_WRITECOMBINE | PVRSRV_HAP_MULTI_PROCESS;\r
+       psDeviceMemoryHeap[SGX_GENERAL_MAPPING_HEAP_ID].pszName = "GeneralMapping";\r
+       psDeviceMemoryHeap[SGX_GENERAL_MAPPING_HEAP_ID].pszBSName = "GeneralMapping BS";\r
+#if defined(SGX_FEATURE_2D_HARDWARE) && defined(SGX_FEATURE_MULTIPLE_MEM_CONTEXTS) && defined(FIX_HW_BRN_23410)\r
+       \r
+\r
+\r
+\r
+\r
+\r
+\r
+       psDeviceMemoryHeap[SGX_GENERAL_MAPPING_HEAP_ID].DevMemHeapType = DEVICE_MEMORY_HEAP_SHARED_EXPORTED;\r
+#else\r
+       psDeviceMemoryHeap[SGX_GENERAL_MAPPING_HEAP_ID].DevMemHeapType = DEVICE_MEMORY_HEAP_PERCONTEXT;\r
+#endif\r
+       \r
+       psDeviceMemoryHeap[SGX_GENERAL_MAPPING_HEAP_ID].ui32DataPageSize = SGX_MMU_PAGE_SIZE;\r
+#endif \r
+\r
+#if defined(SGX_FEATURE_2D_HARDWARE)\r
+\r
+       \r
+       psDeviceMemoryHeap[SGX_2D_HEAP_ID].ui32HeapID = HEAP_ID( PVRSRV_DEVICE_TYPE_SGX ,SGX_2D_HEAP_ID);\r
+       psDeviceMemoryHeap[SGX_2D_HEAP_ID].sDevVAddrBase.uiAddr = SGX_2D_HEAP_BASE;\r
+       psDeviceMemoryHeap[SGX_2D_HEAP_ID].ui32HeapSize = SGX_2D_HEAP_SIZE;\r
+       psDeviceMemoryHeap[SGX_2D_HEAP_ID].ui32Attribs = PVRSRV_HAP_WRITECOMBINE\r
+                                                                                                               | PVRSRV_MEM_RAM_BACKED_ALLOCATION\r
+                                                                                                               | PVRSRV_HAP_SINGLE_PROCESS;\r
+       psDeviceMemoryHeap[SGX_2D_HEAP_ID].pszName = "2D";\r
+       psDeviceMemoryHeap[SGX_2D_HEAP_ID].pszBSName = "2D BS";\r
+       \r
+       psDeviceMemoryHeap[SGX_2D_HEAP_ID].DevMemHeapType = DEVICE_MEMORY_HEAP_SHARED_EXPORTED;\r
+       \r
+       psDeviceMemoryHeap[SGX_2D_HEAP_ID].ui32DataPageSize = SGX_MMU_PAGE_SIZE;\r
+#endif \r
+\r
+\r
+       return PVRSRV_OK;\r
+}\r
+\r
+IMG_EXPORT\r
+PVRSRV_ERROR SGXGetClientInfoKM(IMG_HANDLE                                     hDevCookie,\r
+                                                               SGX_CLIENT_INFO*                psClientInfo)\r
+{\r
+       PVRSRV_SGXDEV_INFO *psDevInfo = (PVRSRV_SGXDEV_INFO *)((PVRSRV_DEVICE_NODE *)hDevCookie)->pvDevice;\r
+\r
+       \r
+\r
+       psDevInfo->ui32ClientRefCount++;\r
+#ifdef PDUMP\r
+\r
+       \r
+       if(psDevInfo->ui32ClientRefCount == 1)\r
+       {\r
+               psDevInfo->psKernelCCBInfo->ui32CCBDumpWOff = 0;\r
+       }\r
+\r
+#endif\r
+       \r
+\r
+       psClientInfo->ui32ProcessID = OSGetCurrentProcessIDKM();\r
+\r
+       \r
+\r
+       OSMemCopy(&psClientInfo->asDevData, &psDevInfo->asSGXDevData, sizeof(psClientInfo->asDevData));\r
+\r
+       \r
+       return PVRSRV_OK;\r
+}\r
+\r
+PVRSRV_ERROR SGXDevInitCompatCheck(PVRSRV_DEVICE_NODE *psDeviceNode)\r
+{\r
+       PVRSRV_SGXDEV_INFO                              *psDevInfo;\r
+       PPVRSRV_KERNEL_MEM_INFO                 psMemInfo;\r
+       PVRSRV_ERROR    eError;\r
+#if !defined(NO_HARDWARE)\r
+       IMG_UINT32                      ui32BuildOptions, ui32BuildOptionsMismatch;\r
+       PVRSRV_SGX_MISCINFO_FEATURES    *psSGXFeatures;\r
+#endif\r
+\r
+       \r
+       if(psDeviceNode->sDevId.eDeviceType != PVRSRV_DEVICE_TYPE_SGX)\r
+       {\r
+               PVR_DPF((PVR_DBG_ERROR, "SGXDevInitCompatCheck: Device not of type SGX"));\r
+               eError = PVRSRV_ERROR_INVALID_PARAMS;\r
+               goto exit;\r
+       }\r
+       psDevInfo = psDeviceNode->pvDevice;\r
+       psMemInfo = psDevInfo->psKernelSGXMiscMemInfo;\r
+\r
+#if !defined (NO_HARDWARE)\r
+       \r
+       eError = SGXGetBuildInfoKM(psDevInfo, psDeviceNode);\r
+       if(eError != PVRSRV_OK)\r
+       {\r
+               PVR_DPF((PVR_DBG_ERROR, "SGXDevInitCompatCheck: Unable to validate device DDK version"));\r
+               goto exit;\r
+       }\r
+       psSGXFeatures = &((PVRSRV_SGX_MISCINFO_INFO*)(psMemInfo->pvLinAddrKM))->sSGXFeatures;\r
+       if( (psSGXFeatures->ui32DDKVersion !=\r
+               ((PVRVERSION_MAJ << 16) |\r
+                (PVRVERSION_MIN << 8) |\r
+                 PVRVERSION_BRANCH) ) ||\r
+               (psSGXFeatures->ui32DDKBuild != PVRVERSION_BUILD) )\r
+       {\r
+               PVR_DPF((PVR_DBG_ERROR, "SGXDevInitCompatCheck: Incompatible driver DDK revision (%ld)/device DDK revision (%ld).",\r
+                               PVRVERSION_BUILD, psSGXFeatures->ui32DDKBuild));\r
+               eError = PVRSRV_ERROR_DDK_VERSION_MISMATCH;\r
+               goto exit;\r
+       }\r
+       else\r
+       {\r
+               PVR_DPF((PVR_DBG_WARNING, "(Success) SGXInit: driver DDK (%ld) and device DDK (%ld) match",\r
+                               PVRVERSION_BUILD, psSGXFeatures->ui32DDKBuild));\r
+       }\r
+\r
+\r
+       \r
+       ui32BuildOptions = psSGXFeatures->ui32BuildOptions;\r
+       if (ui32BuildOptions != (SGX_BUILD_OPTIONS))\r
+       {\r
+               ui32BuildOptionsMismatch = ui32BuildOptions ^ (SGX_BUILD_OPTIONS);\r
+               if ( ((SGX_BUILD_OPTIONS) & ui32BuildOptionsMismatch) != 0)\r
+               {\r
+                       PVR_DPF((PVR_DBG_ERROR, "SGXInit: Mismatch in driver and microkernel build options; "\r
+                               "extra options present in driver: (0x%lx)",\r
+                               (SGX_BUILD_OPTIONS) & ui32BuildOptionsMismatch ));\r
+               }\r
+\r
+               if ( (ui32BuildOptions & ui32BuildOptionsMismatch) != 0)\r
+               {\r
+                       PVR_DPF((PVR_DBG_ERROR, "SGXInit: Mismatch in driver and microkernel build options; "\r
+                               "extra options present in microkernel: (0x%lx)",\r
+                               ui32BuildOptions & ui32BuildOptionsMismatch ));\r
+               }\r
+               eError = PVRSRV_ERROR_BUILD_MISMATCH;\r
+               goto exit;\r
+       }\r
+       else\r
+       {\r
+               PVR_DPF((PVR_DBG_WARNING, "(Success) SGXInit: Driver and microkernel build options match."));\r
+       }\r
+\r
+#endif\r
+       eError = PVRSRV_OK;\r
+exit:\r
+#if defined(IGNORE_SGX_INIT_COMPATIBILITY_CHECK)\r
+       return PVRSRV_OK;\r
+#else\r
+       return eError;\r
+#endif\r
+}\r
+\r
+static\r
+PVRSRV_ERROR SGXGetBuildInfoKM(PVRSRV_SGXDEV_INFO      *psDevInfo,\r
+                                                         PVRSRV_DEVICE_NODE    *psDeviceNode)\r
+{\r
+       PVRSRV_ERROR            eError;\r
+       SGXMKIF_COMMAND         sCommandData;  \r
+       PVRSRV_SGX_MISCINFO_INFO                        *psSGXMiscInfoInt;      \r
+       PVRSRV_SGX_MISCINFO_FEATURES            *psSGXFeatures;         \r
+\r
+       PPVRSRV_KERNEL_MEM_INFO psMemInfo = psDevInfo->psKernelSGXMiscMemInfo;\r
+\r
+       if (! psMemInfo->pvLinAddrKM)\r
+       {\r
+               PVR_DPF((PVR_DBG_ERROR, "SGXGetMiscInfoKM: Invalid address."));\r
+               return PVRSRV_ERROR_INVALID_PARAMS;\r
+       }\r
+       psSGXMiscInfoInt = psMemInfo->pvLinAddrKM;\r
+       psSGXMiscInfoInt->ui32MiscInfoFlags &= ~PVRSRV_USSE_MISCINFO_READY;\r
+       psSGXFeatures = &psSGXMiscInfoInt->sSGXFeatures;\r
+\r
+       \r
+       OSMemSet(psMemInfo->pvLinAddrKM, 0,\r
+                       sizeof(PVRSRV_SGX_MISCINFO_INFO));\r
+\r
+       \r
+       sCommandData.ui32Data[1] = psMemInfo->sDevVAddr.uiAddr; \r
+\r
+       eError = SGXScheduleCCBCommandKM(psDeviceNode,\r
+                       SGXMKIF_COMMAND_REQUEST_SGXMISCINFO,\r
+                       &sCommandData,\r
+                       KERNEL_ID,\r
+                       0);\r
+\r
+       if (eError != PVRSRV_OK)\r
+       {\r
+               PVR_DPF((PVR_DBG_ERROR, "SGXGetMiscInfoKM: SGXScheduleCCBCommandKM failed."));\r
+               return eError;\r
+       }\r
+\r
+       \r
+#if !defined(NO_HARDWARE)\r
+       {\r
+               IMG_BOOL bTimeout = IMG_TRUE;\r
+\r
+               LOOP_UNTIL_TIMEOUT(MAX_HW_TIME_US)\r
+               {\r
+                       if ((psSGXMiscInfoInt->ui32MiscInfoFlags & PVRSRV_USSE_MISCINFO_READY) != 0)\r
+                       {\r
+                               bTimeout = IMG_FALSE;\r
+                               break;\r
+                       }\r
+               } END_LOOP_UNTIL_TIMEOUT();\r
+               \r
+               if(bTimeout)\r
+               {\r
+                       return PVRSRV_ERROR_TIMEOUT;\r
+               }\r
+       }\r
+#endif \r
+\r
+       return PVRSRV_OK;\r
+}\r
+\r
+IMG_EXPORT\r
+PVRSRV_ERROR SGXGetMiscInfoKM(PVRSRV_SGXDEV_INFO       *psDevInfo,\r
+                                                         SGX_MISC_INFO                 *psMiscInfo,\r
+                                                         PVRSRV_DEVICE_NODE    *psDeviceNode)\r
+{\r
+       switch(psMiscInfo->eRequest)\r
+       {\r
+               case SGX_MISC_INFO_REQUEST_CLOCKSPEED:\r
+               {\r
+                       psMiscInfo->uData.ui32SGXClockSpeed = psDevInfo->ui32CoreClockSpeed;\r
+                       return PVRSRV_OK;\r
+               }\r
+\r
+               case SGX_MISC_INFO_REQUEST_SGXREV:\r
+               {\r
+                       PVRSRV_SGX_MISCINFO_FEATURES            *psSGXFeatures;\r
+                       PPVRSRV_KERNEL_MEM_INFO psMemInfo = psDevInfo->psKernelSGXMiscMemInfo;\r
+\r
+                       SGXGetBuildInfoKM(psDevInfo, psDeviceNode);\r
+                       psSGXFeatures = &((PVRSRV_SGX_MISCINFO_INFO*)(psMemInfo->pvLinAddrKM))->sSGXFeatures;\r
+\r
+                       \r
+                       psMiscInfo->uData.sSGXFeatures = *psSGXFeatures;\r
+\r
+                       \r
+                       PVR_DPF((PVR_DBG_MESSAGE, "SGXGetMiscInfoKM: Core 0x%lx, sw ID 0x%lx, sw Rev 0x%lx\n",\r
+                                       psSGXFeatures->ui32CoreRev,\r
+                                       psSGXFeatures->ui32CoreIdSW,\r
+                                       psSGXFeatures->ui32CoreRevSW));\r
+                       PVR_DPF((PVR_DBG_MESSAGE, "SGXGetMiscInfoKM: DDK version 0x%lx, DDK build 0x%lx\n",\r
+                                       psSGXFeatures->ui32DDKVersion,\r
+                                       psSGXFeatures->ui32DDKBuild));\r
+\r
+                       \r
+                       return PVRSRV_OK;\r
+               }\r
+\r
+               case SGX_MISC_INFO_REQUEST_DRIVER_SGXREV:\r
+               {\r
+                       PPVRSRV_KERNEL_MEM_INFO psMemInfo = psDevInfo->psKernelSGXMiscMemInfo;\r
+                       PVRSRV_SGX_MISCINFO_FEATURES            *psSGXFeatures;\r
+\r
+                       psSGXFeatures = &((PVRSRV_SGX_MISCINFO_INFO*)(psMemInfo->pvLinAddrKM))->sSGXFeatures;\r
+\r
+                       \r
+                       OSMemSet(psMemInfo->pvLinAddrKM, 0,\r
+                                       sizeof(PVRSRV_SGX_MISCINFO_INFO));\r
+\r
+                       psSGXFeatures->ui32DDKVersion =\r
+                               (PVRVERSION_MAJ << 16) |\r
+                               (PVRVERSION_MIN << 8) |\r
+                               PVRVERSION_BRANCH;\r
+                       psSGXFeatures->ui32DDKBuild = PVRVERSION_BUILD;\r
+\r
+                       \r
+                       psMiscInfo->uData.sSGXFeatures = *psSGXFeatures;\r
+                       return PVRSRV_OK;\r
+               }\r
+\r
+#ifdef SUPPORT_SGX_HWPERF\r
+               case SGX_MISC_INFO_REQUEST_SET_HWPERF_STATUS:\r
+               {\r
+                       SGXMKIF_HWPERF_CB *psHWPerfCB = psDevInfo->psKernelHWPerfCBMemInfo->pvLinAddrKM;\r
+                       IMG_UINT ui32MatchingFlags;\r
+\r
+                       \r
+                       if ((psMiscInfo->uData.ui32NewHWPerfStatus & ~(PVRSRV_SGX_HWPERF_GRAPHICS_ON | PVRSRV_SGX_HWPERF_MK_EXECUTION_ON)) != 0)\r
+                       {\r
+                               return PVRSRV_ERROR_INVALID_PARAMS;\r
+                       }\r
+\r
+                       \r
+                       ui32MatchingFlags = psMiscInfo->uData.ui32NewHWPerfStatus & psDevInfo->psSGXHostCtl->ui32HWPerfFlags;\r
+                       if((ui32MatchingFlags & PVRSRV_SGX_HWPERF_GRAPHICS_ON) == 0UL)\r
+                       {\r
+                               psHWPerfCB->ui32OrdinalGRAPHICS = 0xffffffff;\r
+                       }\r
+                       if((ui32MatchingFlags & PVRSRV_SGX_HWPERF_MK_EXECUTION_ON) == 0UL)\r
+                       {\r
+                               psHWPerfCB->ui32OrdinalMK_EXECUTION = 0xffffffffUL;\r
+                       }\r
+\r
+                       \r
+                       psDevInfo->psSGXHostCtl->ui32HWPerfFlags = psMiscInfo->uData.ui32NewHWPerfStatus;\r
+                       #if defined(PDUMP)\r
+                       PDUMPCOMMENTWITHFLAGS(PDUMP_FLAGS_CONTINUOUS, "SGX ukernel HWPerf status %lu\n",\r
+                                                                 psDevInfo->psSGXHostCtl->ui32HWPerfFlags);\r
+                       PDUMPMEM(IMG_NULL, psDevInfo->psKernelSGXHostCtlMemInfo,\r
+                                        offsetof(SGXMKIF_HOST_CTL, ui32HWPerfFlags),\r
+                                        sizeof(psDevInfo->psSGXHostCtl->ui32HWPerfFlags), PDUMP_FLAGS_CONTINUOUS,\r
+                                        MAKEUNIQUETAG(psDevInfo->psKernelSGXHostCtlMemInfo));\r
+                       #endif \r
+\r
+                       return PVRSRV_OK;\r
+               }\r
+               case SGX_MISC_INFO_REQUEST_HWPERF_CB_ON:\r
+               {\r
+                       \r
+                       SGXMKIF_HWPERF_CB *psHWPerfCB = psDevInfo->psKernelHWPerfCBMemInfo->pvLinAddrKM;\r
+                       psHWPerfCB->ui32OrdinalGRAPHICS = 0xffffffffUL;\r
+                       \r
+                       psDevInfo->psSGXHostCtl->ui32HWPerfFlags |= PVRSRV_SGX_HWPERF_GRAPHICS_ON;\r
+                       return PVRSRV_OK;\r
+               }\r
+               case SGX_MISC_INFO_REQUEST_HWPERF_CB_OFF:\r
+               {\r
+                       \r
+                       psDevInfo->psSGXHostCtl->ui32HWPerfFlags = 0;\r
+                       return PVRSRV_OK;\r
+               }\r
+               case SGX_MISC_INFO_REQUEST_HWPERF_RETRIEVE_CB:\r
+               {\r
+                       \r
+                       SGX_MISC_INFO_HWPERF_RETRIEVE_CB *psRetrieve = &psMiscInfo->uData.sRetrieveCB;\r
+                       SGXMKIF_HWPERF_CB *psHWPerfCB = psDevInfo->psKernelHWPerfCBMemInfo->pvLinAddrKM;\r
+                       IMG_UINT i;\r
+\r
+                       for (i = 0; psHWPerfCB->ui32Woff != psHWPerfCB->ui32Roff && i < psRetrieve->ui32ArraySize; i++)\r
+                       {\r
+                               SGXMKIF_HWPERF_CB_ENTRY *psData = &psHWPerfCB->psHWPerfCBData[psHWPerfCB->ui32Roff];\r
+                               \r
+\r
+\r
+                               psRetrieve->psHWPerfData[i].ui32FrameNo = psData->ui32FrameNo;\r
+                               psRetrieve->psHWPerfData[i].ui32Type = (psData->ui32Type & PVRSRV_SGX_HWPERF_TYPE_OP_MASK);\r
+                               psRetrieve->psHWPerfData[i].ui32StartTime = psData->ui32Time;\r
+                               psRetrieve->psHWPerfData[i].ui32StartTimeWraps = psData->ui32TimeWraps;\r
+                               psRetrieve->psHWPerfData[i].ui32EndTime = psData->ui32Time;\r
+                               psRetrieve->psHWPerfData[i].ui32EndTimeWraps = psData->ui32TimeWraps;\r
+                               psRetrieve->psHWPerfData[i].ui32ClockSpeed = psDevInfo->ui32CoreClockSpeed;\r
+                               psRetrieve->psHWPerfData[i].ui32TimeMax = psDevInfo->ui32uKernelTimerClock;\r
+                               psHWPerfCB->ui32Roff = (psHWPerfCB->ui32Roff + 1) & (SGXMKIF_HWPERF_CB_SIZE - 1);\r
+                       }\r
+                       psRetrieve->ui32DataCount = i;\r
+                       psRetrieve->ui32Time = OSClockus();\r
+                       return PVRSRV_OK;\r
+               }\r
+#endif \r
+               default:\r
+               {\r
+                       \r
+                       return PVRSRV_ERROR_INVALID_PARAMS;\r
+               }\r
+       }\r
+}\r
+\r
+#if defined(SUPPORT_SGX_HWPERF)\r
+IMG_EXPORT\r
+PVRSRV_ERROR SGXReadDiffCountersKM(IMG_HANDLE                                  hDevHandle,\r
+                                                                        IMG_UINT32                                     ui32Reg,\r
+                                                                        IMG_UINT32                                     *pui32Old,\r
+                                                                        IMG_BOOL                                       bNew,\r
+                                                                        IMG_UINT32                                     ui32New,\r
+                                                                        IMG_UINT32                                     ui32NewReset,\r
+                                                                        IMG_UINT32                                     ui32CountersReg,\r
+                                                                        IMG_UINT32                                     *pui32Time,\r
+                                                                        IMG_BOOL                                       *pbActive,\r
+                                                                        PVRSRV_SGXDEV_DIFF_INFO        *psDiffs)\r
+{\r
+       PVRSRV_ERROR            eError;\r
+       SYS_DATA                        *psSysData;\r
+       PVRSRV_POWER_DEV        *psPowerDevice;\r
+       IMG_BOOL                        bPowered = IMG_FALSE;\r
+       PVRSRV_DEVICE_NODE      *psDeviceNode = hDevHandle;\r
+       PVRSRV_SGXDEV_INFO      *psDevInfo = psDeviceNode->pvDevice;\r
+\r
+       \r
+       if(bNew)\r
+       {\r
+               psDevInfo->ui32HWGroupRequested = ui32New;\r
+       }\r
+       psDevInfo->ui32HWReset |= ui32NewReset;\r
+\r
+       \r
+       eError = PVRSRVPowerLock(KERNEL_ID, IMG_FALSE);\r
+       if (eError != PVRSRV_OK)\r
+       {\r
+               return eError;\r
+       }\r
+\r
+       SysAcquireData(&psSysData);\r
+\r
+       \r
+       psPowerDevice = psSysData->psPowerDeviceList;\r
+       while (psPowerDevice)\r
+       {\r
+               if (psPowerDevice->ui32DeviceIndex == psDeviceNode->sDevId.ui32DeviceIndex)\r
+               {\r
+                       bPowered = (IMG_BOOL)(psPowerDevice->eCurrentPowerState == PVRSRV_POWER_STATE_D0);\r
+                       break;\r
+               }\r
+\r
+               psPowerDevice = psPowerDevice->psNext;\r
+       }\r
+\r
+       \r
+       *pbActive = bPowered;\r
+\r
+       \r
+\r
+       {\r
+               PVRSRV_SGXDEV_DIFF_INFO sNew, *psPrev = &psDevInfo->sDiffInfo;\r
+               IMG_UINT32                                      i;\r
+\r
+               sNew.ui32Time[0] = OSClockus();\r
+\r
+               \r
+               *pui32Time = sNew.ui32Time[0];\r
+\r
+               \r
+               if(sNew.ui32Time[0] != psPrev->ui32Time[0] && bPowered)\r
+               {\r
+                       \r
+                       *pui32Old = OSReadHWReg(psDevInfo->pvRegsBaseKM, ui32Reg);\r
+\r
+                       for (i = 0; i < PVRSRV_SGX_DIFF_NUM_COUNTERS; ++i)\r
+                       {\r
+                               sNew.aui32Counters[i] = OSReadHWReg(psDevInfo->pvRegsBaseKM, ui32CountersReg + (i * 4));\r
+                       }\r
+\r
+                       \r
+\r
+                       if (psDevInfo->ui32HWGroupRequested != *pui32Old)\r
+                       {\r
+                               \r
+                               if(psDevInfo->ui32HWReset != 0)\r
+                               {\r
+                                       OSWriteHWReg(psDevInfo->pvRegsBaseKM, ui32Reg, psDevInfo->ui32HWGroupRequested | psDevInfo->ui32HWReset);\r
+                                       psDevInfo->ui32HWReset = 0;\r
+                               }\r
+\r
+                               OSWriteHWReg(psDevInfo->pvRegsBaseKM, ui32Reg, psDevInfo->ui32HWGroupRequested);\r
+                       }\r
+\r
+                       sNew.ui32Marker[0] = psDevInfo->ui32KickTACounter;\r
+                       sNew.ui32Marker[1] = psDevInfo->ui32KickTARenderCounter;\r
+\r
+                       sNew.ui32Time[1] = psDevInfo->psSGXHostCtl->ui32TimeWraps;\r
+\r
+                       \r
+                       for (i = 0; i < PVRSRV_SGX_DIFF_NUM_COUNTERS; ++i)\r
+                       {\r
+                               psDiffs->aui32Counters[i] = sNew.aui32Counters[i] - psPrev->aui32Counters[i];\r
+                       }\r
+\r
+                       psDiffs->ui32Marker[0]                  = sNew.ui32Marker[0] - psPrev->ui32Marker[0];\r
+                       psDiffs->ui32Marker[1]                  = sNew.ui32Marker[1] - psPrev->ui32Marker[1];\r
+\r
+                       psDiffs->ui32Time[0]                    = sNew.ui32Time[0] - psPrev->ui32Time[0];\r
+                       psDiffs->ui32Time[1]                    = sNew.ui32Time[1] - psPrev->ui32Time[1];\r
+\r
+                       \r
+                       *psPrev = sNew;\r
+               }\r
+               else\r
+               {\r
+                       \r
+                       for (i = 0; i < PVRSRV_SGX_DIFF_NUM_COUNTERS; ++i)\r
+                       {\r
+                               psDiffs->aui32Counters[i] = 0;\r
+                       }\r
+\r
+                       psDiffs->ui32Marker[0] = 0;\r
+                       psDiffs->ui32Marker[1] = 0;\r
+\r
+                       psDiffs->ui32Time[0] = 0;\r
+                       psDiffs->ui32Time[1] = 0;\r
+               }\r
+       }\r
+\r
+       \r
+       PVRSRVPowerUnlock(KERNEL_ID);\r
+\r
+#if defined(SUPPORT_ACTIVE_POWER_MANAGEMENT)\r
+       SGXTestActivePowerEvent(psDeviceNode, KERNEL_ID);\r
+#endif \r
+\r
+       return eError;\r
+}\r
+\r
+\r
+IMG_EXPORT\r
+PVRSRV_ERROR SGXReadHWPerfCBKM(IMG_HANDLE                                      hDevHandle,\r
+                                                          IMG_UINT32                                   ui32ArraySize,\r
+                                                          PVRSRV_SGX_HWPERF_CB_ENTRY   *psClientHWPerfEntry,\r
+                                                          IMG_UINT32                                   *pui32DataCount,\r
+                                                          IMG_UINT32                                   *pui32ClockSpeed,\r
+                                                          IMG_UINT32                                   *pui32HostTimeStamp)\r
+{\r
+       PVRSRV_ERROR            eError = PVRSRV_OK;\r
+       PVRSRV_DEVICE_NODE      *psDeviceNode = hDevHandle;\r
+       PVRSRV_SGXDEV_INFO      *psDevInfo = psDeviceNode->pvDevice;\r
+       SGXMKIF_HWPERF_CB       *psHWPerfCB = psDevInfo->psKernelHWPerfCBMemInfo->pvLinAddrKM;\r
+       IMG_UINT                        i;\r
+\r
+       for (i = 0;\r
+                psHWPerfCB->ui32Woff != psHWPerfCB->ui32Roff && i < ui32ArraySize;\r
+                i++)\r
+       {\r
+               SGXMKIF_HWPERF_CB_ENTRY *psMKPerfEntry = &psHWPerfCB->psHWPerfCBData[psHWPerfCB->ui32Roff];\r
+\r
+               psClientHWPerfEntry[i].ui32FrameNo = psMKPerfEntry->ui32FrameNo;\r
+               psClientHWPerfEntry[i].ui32Type = psMKPerfEntry->ui32Type;\r
+               psClientHWPerfEntry[i].ui32Ordinal      = psMKPerfEntry->ui32Ordinal;\r
+               psClientHWPerfEntry[i].ui32Clocksx16 = SGXConvertTimeStamp(psDevInfo,\r
+                                                                                                       psMKPerfEntry->ui32TimeWraps,\r
+                                                                                                       psMKPerfEntry->ui32Time);\r
+               OSMemCopy(&psClientHWPerfEntry[i].ui32Counters[0],\r
+                                 &psMKPerfEntry->ui32Counters[0],\r
+                                 sizeof(psMKPerfEntry->ui32Counters));\r
+\r
+               psHWPerfCB->ui32Roff = (psHWPerfCB->ui32Roff + 1) & (SGXMKIF_HWPERF_CB_SIZE - 1);\r
+       }\r
+\r
+       *pui32DataCount = i;\r
+       *pui32ClockSpeed = psDevInfo->ui32CoreClockSpeed;\r
+       *pui32HostTimeStamp = OSClockus();\r
+\r
+       return eError;\r
+}\r
+#else\r
+#endif \r
+\r
+\r
diff --git a/services4/srvkm/devices/sgx/sgxkick.c b/services4/srvkm/devices/sgx/sgxkick.c
new file mode 100644 (file)
index 0000000..0d5cf4f
--- /dev/null
@@ -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. <gpl-support@imgtec.com>
+ * Home Park Estate, Kings Langley, Herts, WD4 8LZ, UK 
+ *
+ ******************************************************************************/
+
+#include <stddef.h> 
+#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; i<psCCBKick->ui32NumSrcSyncs; 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; i<ui32NumDstSyncs; 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;
+                       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; i<psCCBKick->ui32NumSrcSyncs; 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; i<psCCBKick->ui32NumSrcSyncs; 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; i<psCCBKick->ui32NumSrcSyncs; 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; i<psCCBKick->ui32NumDstSyncObjects; 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 (file)
index 0000000..69c0a8f
--- /dev/null
@@ -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. <gpl-support@imgtec.com>
+ * Home Park Estate, Kings Langley, Herts, WD4 8LZ, UK 
+ *
+ ******************************************************************************/
+
+#include <stddef.h>
+
+#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 (file)
index 0000000..b630552
--- /dev/null
@@ -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. <gpl-support@imgtec.com>
+ * 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 (file)
index 0000000..b6f9ab2
--- /dev/null
@@ -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. <gpl-support@imgtec.com>
+ * Home Park Estate, Kings Langley, Herts, WD4 8LZ, UK 
+ *
+ ******************************************************************************/
+
+#if defined(TRANSFER_QUEUE)
+
+#include <stddef.h>
+
+#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 (file)
index 0000000..c09cf44
--- /dev/null
@@ -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. <gpl-support@imgtec.com>
+ * Home Park Estate, Kings Langley, Herts, WD4 8LZ, UK 
+ *
+ ******************************************************************************/
+
+#include <stddef.h>
+
+#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 <linux/tty.h>                 
+#else
+#include <stdio.h>
+#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 (file)
index 0000000..9fa69bd
--- /dev/null
@@ -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. <gpl-support@imgtec.com>
+ * 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 (file)
index 0000000..2d7d30b
--- /dev/null
@@ -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. <gpl-support@imgtec.com>
+ * Home Park Estate, Kings Langley, Herts, WD4 8LZ, UK 
+ *
+ ******************************************************************************/
+
+#ifndef _ENV_DATA_
+#define _ENV_DATA_
+
+#include <linux/interrupt.h>
+#include <linux/pci.h>
+
+#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 (file)
index 0000000..40404f5
--- /dev/null
@@ -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. <gpl-support@imgtec.com>
+ * 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 (file)
index 0000000..a10f874
--- /dev/null
@@ -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. <gpl-support@imgtec.com>
+ * Home Park Estate, Kings Langley, Herts, WD4 8LZ, UK 
+ *
+ ******************************************************************************/
+
+#ifndef AUTOCONF_INCLUDED
+ #include <linux/config.h>
+#endif
+
+#include <linux/version.h>
+#include <asm/io.h>
+#include <asm/page.h>
+#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,22))
+#include <asm/system.h>
+#endif
+#include <linux/mm.h>
+#include <linux/slab.h>
+#include <linux/vmalloc.h>
+#include <linux/delay.h>
+#include <linux/pci.h>
+
+#include <linux/string.h>
+#include <linux/sched.h>
+#include <linux/interrupt.h>
+#include <asm/hardirq.h>
+#include <linux/timer.h>
+#include <linux/capability.h>
+#include <linux/sched.h>
+#include <asm/uaccess.h>
+
+#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 (file)
index 0000000..d07bc97
--- /dev/null
@@ -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. <gpl-support@imgtec.com>
+ * 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 (file)
index 0000000..7001d9e
--- /dev/null
@@ -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. <gpl-support@imgtec.com>
+# 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 (file)
index 0000000..5c0bb0e
--- /dev/null
@@ -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. <gpl-support@imgtec.com>
+ * 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 (file)
index 0000000..e0bf5ee
--- /dev/null
@@ -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. <gpl-support@imgtec.com>
+ * 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 (file)
index 0000000..179dd48
--- /dev/null
@@ -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. <gpl-support@imgtec.com>
+ * Home Park Estate, Kings Langley, Herts, WD4 8LZ, UK 
+ *
+ ******************************************************************************/
+
+#ifndef AUTOCONF_INCLUDED
+ #include <linux/config.h>
+#endif
+
+#include <linux/version.h>
+#include <linux/mm.h>
+#include <linux/vmalloc.h>
+#include <asm/io.h>
+#if (LINUX_VERSION_CODE < KERNEL_VERSION(2,6,0))
+#include <linux/wrapper.h>
+#endif
+#include <linux/slab.h>
+#include <linux/highmem.h>
+#include <linux/sched.h>
+
+#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<ui32PageCount; i++)
+    {
+        pvPageList[i] = alloc_pages(GFP_KERNEL | __GFP_HIGHMEM, 0);
+        if(!pvPageList[i])
+        {
+            goto failed_alloc_pages;
+        }
+#if (LINUX_VERSION_CODE < KERNEL_VERSION(2,6,15))
+       
+#if (LINUX_VERSION_CODE > 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<ui32PageCount;i++)
+    {
+#if (LINUX_VERSION_CODE < KERNEL_VERSION(2,6,15))              
+#if (LINUX_VERSION_CODE > 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,
+                          "<mem_areas_header>\n"
+                          "\t<count>%lu</count>\n"
+                          "\t<watermark key=\"mar0\" description=\"current\" bytes=\"%lu\"/>\n" 
+                          "\t<watermark key=\"mar1\" description=\"high\" bytes=\"%lu\"/>\n" 
+                          "</mem_areas_header>\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
+                       "<linux_mem_area>\n"
+                       "\t<pointer>%8p</pointer>\n"
+                       "\t<type>%s</type>\n"
+                       "\t<cpu_virtual>%8p</cpu_virtual>\n"
+                       "\t<cpu_physical>%08lx</cpu_physical>\n"
+                       "\t<bytes>%ld</bytes>\n"
+                       "\t<pid>%u</pid>\n"
+                       "\t<flags>%08lx</flags>\n"
+                       "\t<flags_string>%s</flags_string>\n"
+                       "</linux_mem_area>\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, "<meminfo>\n<meminfo_header>\n");
+        Ret =  printAppend(buffer, count, Ret,
+                           "<watermark key=\"mr0\" description=\"kmalloc_current\" bytes=\"%ld\"/>\n",
+                           g_WaterMarkData[DEBUG_MEM_ALLOC_TYPE_KMALLOC]);
+        Ret =  printAppend(buffer, count, Ret,
+                           "<watermark key=\"mr1\" description=\"kmalloc_high\" bytes=\"%ld\"/>\n",
+                           g_HighWaterMarkData[DEBUG_MEM_ALLOC_TYPE_KMALLOC]);
+        Ret =  printAppend(buffer, count, Ret,
+                           "<watermark key=\"mr2\" description=\"vmalloc_current\" bytes=\"%ld\"/>\n",
+                           g_WaterMarkData[DEBUG_MEM_ALLOC_TYPE_VMALLOC]);
+        Ret =  printAppend(buffer, count, Ret,
+                           "<watermark key=\"mr3\" description=\"vmalloc_high\" bytes=\"%ld\"/>\n",
+                           g_HighWaterMarkData[DEBUG_MEM_ALLOC_TYPE_VMALLOC]);
+        Ret =  printAppend(buffer, count, Ret,
+                           "<watermark key=\"mr4\" description=\"alloc_pages_current\" bytes=\"%ld\"/>\n",
+                           g_WaterMarkData[DEBUG_MEM_ALLOC_TYPE_ALLOC_PAGES]);
+        Ret =  printAppend(buffer, count, Ret,
+                           "<watermark key=\"mr5\" description=\"alloc_pages_high\" bytes=\"%ld\"/>\n",
+                           g_HighWaterMarkData[DEBUG_MEM_ALLOC_TYPE_ALLOC_PAGES]);
+        Ret =  printAppend(buffer, count, Ret,
+                           "<watermark key=\"mr6\" description=\"ioremap_current\" bytes=\"%ld\"/>\n",
+                           g_WaterMarkData[DEBUG_MEM_ALLOC_TYPE_IOREMAP]);
+        Ret =  printAppend(buffer, count, Ret,
+                           "<watermark key=\"mr7\" description=\"ioremap_high\" bytes=\"%ld\"/>\n",
+                           g_HighWaterMarkData[DEBUG_MEM_ALLOC_TYPE_IOREMAP]);
+        Ret =  printAppend(buffer, count, Ret,
+                           "<watermark key=\"mr8\" description=\"io_current\" bytes=\"%ld\"/>\n",
+                           g_WaterMarkData[DEBUG_MEM_ALLOC_TYPE_IO]);
+        Ret =  printAppend(buffer, count, Ret,
+                           "<watermark key=\"mr9\" description=\"io_high\" bytes=\"%ld\"/>\n",
+                           g_HighWaterMarkData[DEBUG_MEM_ALLOC_TYPE_IO]);
+        Ret =  printAppend(buffer, count, Ret,
+                           "<watermark key=\"mr10\" description=\"kmem_cache_current\" bytes=\"%ld\"/>\n",
+                           g_WaterMarkData[DEBUG_MEM_ALLOC_TYPE_KMEM_CACHE]);
+        Ret =  printAppend(buffer, count, Ret,
+                           "<watermark key=\"mr11\" description=\"kmem_cache_high\" bytes=\"%ld\"/>\n",
+                           g_HighWaterMarkData[DEBUG_MEM_ALLOC_TYPE_KMEM_CACHE]);
+        Ret =  printAppend(buffer, count, Ret, "\n");
+
+        Ret =  printAppend(buffer, count, Ret,
+                           "<watermark key=\"mr14\" description=\"system_ram_current\" bytes=\"%ld\"/>\n",
+                           g_SysRAMWaterMark);
+        Ret =  printAppend(buffer, count, Ret,
+                           "<watermark key=\"mr15\" description=\"system_ram_high\" bytes=\"%ld\"/>\n",
+                           g_SysRAMHighWaterMark);
+        Ret =  printAppend(buffer, count, Ret,
+                           "<watermark key=\"mr16\" description=\"system_io_current\" bytes=\"%ld\"/>\n",
+                           g_IOMemWaterMark);
+        Ret =  printAppend(buffer, count, Ret,
+                           "<watermark key=\"mr17\" description=\"system_io_high\" bytes=\"%ld\"/>\n",
+                           g_IOMemHighWaterMark);
+
+        Ret =  printAppend(buffer, count, Ret, "</meminfo_header>\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, "</meminfo>\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
+                           "<allocation>\n"
+                           "\t<type>%s</type>\n"
+                           "\t<cpu_virtual>%-8p</cpu_virtual>\n"
+                           "\t<cpu_physical>%08lx</cpu_physical>\n"
+                           "\t<bytes>%ld</bytes>\n"
+                           "\t<pid>%d</pid>\n"
+                           "\t<private>%s</private>\n"
+                           "\t<filename>%s</filename>\n"
+                           "\t<line>%ld</line>\n"
+                           "</allocation>\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
+                           "<allocation>\n"
+                           "\t<type>%s</type>\n"
+                           "\t<cpu_virtual>%-8p</cpu_virtual>\n"
+                           "\t<cpu_physical>%08lx</cpu_physical>\n"
+                           "\t<bytes>%ld</bytes>\n"
+                           "\t<pid>%d</pid>\n"
+                           "\t<private>%s</private>\n"
+                           "\t<filename>%s</filename>\n"
+                           "\t<line>%ld</line>\n"
+                           "</allocation>\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 (file)
index 0000000..7d2da4e
--- /dev/null
@@ -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. <gpl-support@imgtec.com>
+ * Home Park Estate, Kings Langley, Herts, WD4 8LZ, UK 
+ *
+ ******************************************************************************/
+
+#ifndef __IMG_LINUX_MM_H__
+#define __IMG_LINUX_MM_H__
+
+#ifndef AUTOCONF_INCLUDED
+ #include <linux/config.h>
+#endif
+
+#include <linux/version.h>
+#include <linux/slab.h>
+#include <linux/mm.h>
+#include <linux/list.h>
+
+#include <asm/io.h>
+
+#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 (file)
index 0000000..774d5ea
--- /dev/null
@@ -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. <gpl-support@imgtec.com>
+ * Home Park Estate, Kings Langley, Herts, WD4 8LZ, UK 
+ *
+ ******************************************************************************/
+
+#ifndef AUTOCONF_INCLUDED
+ #include <linux/config.h>
+#endif
+
+#include <linux/version.h>
+#include <linux/mm.h>
+#include <linux/module.h>
+#include <linux/vmalloc.h>
+#if (LINUX_VERSION_CODE < KERNEL_VERSION(2,6,0))
+#include <linux/wrapper.h>
+#endif
+#include <linux/slab.h>
+#include <asm/io.h>
+#include <asm/page.h>
+#include <asm/shmparam.h>
+#include <asm/pgtable.h>
+#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,22))
+#include <linux/sched.h>
+#include <asm/current.h>
+#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
+                          "<mmap_header>\n"
+                          "\t<count>%lu</count>\n"
+                          "\t<bytes>%lu</bytes>\n"
+                          "</mmap_header>\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
+                        "<mmap_record>\n"
+                                               "\t<pointer>%-8p</pointer>\n"
+                        "\t<user_virtual>%-8lx</user_virtual>\n"
+                        "\t<kernel_virtual>%-8p</kernel_virtual>\n"
+                        "\t<cpu_physical>%08lx</cpu_physical>\n"
+                        "\t<mmap_offset>%08lx</mmap_offset>\n"
+                        "\t<bytes>%-8ld</bytes>\n"
+                        "\t<linux_mem_area_type>%-24s</linux_mem_area_type>\n"
+                        "\t<pid>%-5lu</pid>\n"
+                        "\t<name>%-8s</name>\n"
+                        "\t<flags>%08lx</flags>\n"
+                        "\t<flags_string>%s</flags_string>\n"
+                        "</mmap_record>\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 (file)
index 0000000..5c9f2b2
--- /dev/null
@@ -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. <gpl-support@imgtec.com>
+ * Home Park Estate, Kings Langley, Herts, WD4 8LZ, UK 
+ *
+ ******************************************************************************/
+
+#if !defined(__MMAP_H__)
+#define __MMAP_H__
+
+#include <linux/mm.h>
+#include <linux/list.h>
+
+#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 (file)
index 0000000..b7ddda3
--- /dev/null
@@ -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. <gpl-support@imgtec.com>
+ * Home Park Estate, Kings Langley, Herts, WD4 8LZ, UK 
+ *
+ ******************************************************************************/
+
+#ifndef AUTOCONF_INCLUDED
+ #include <linux/config.h>
+#endif
+
+#include <linux/init.h>
+#include <linux/kernel.h>
+#include <linux/module.h>
+#include <linux/version.h>
+#include <linux/fs.h>
+#include <linux/proc_fs.h>
+
+#if defined(LDM_PLATFORM)
+#include <linux/platform_device.h>
+#endif 
+
+#if defined(LDM_PCI)
+#include <linux/pci.h>
+#endif 
+
+#if defined(DEBUG) && defined(PVR_MANUAL_POWER_CONTROL)
+#include <asm/uaccess.h>
+#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 <linux/moduleparam.h>
+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 (file)
index 0000000..1ff98b8
--- /dev/null
@@ -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. <gpl-support@imgtec.com>
+ * Home Park Estate, Kings Langley, Herts, WD4 8LZ, UK 
+ *
+ ******************************************************************************/
+
+#include <linux/version.h>
+#include <linux/errno.h>
+#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,15))
+#include <linux/mutex.h>
+#else
+#include <asm/semaphore.h>
+#endif
+#include <linux/module.h>
+
+#include <img_defs.h>
+#include <services.h>
+
+#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 (file)
index 0000000..b24a599
--- /dev/null
@@ -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. <gpl-support@imgtec.com>
+ * Home Park Estate, Kings Langley, Herts, WD4 8LZ, UK 
+ *
+ ******************************************************************************/
+
+#ifndef __INCLUDED_LINUX_MUTEX_H_
+#define __INCLUDED_LINUX_MUTEX_H_
+
+#include <linux/version.h>
+
+#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,15))
+#include <linux/mutex.h>
+#else
+#include <asm/semaphore.h>
+#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 (file)
index 0000000..9abff78
--- /dev/null
@@ -0,0 +1,132 @@
+/**********************************************************************\r
+ *\r
+ * Copyright(c) 2008 Imagination Technologies Ltd. All rights reserved.\r
+ * \r
+ * This program is free software; you can redistribute it and/or modify it\r
+ * under the terms and conditions of the GNU General Public License,\r
+ * version 2, as published by the Free Software Foundation.\r
+ * \r
+ * This program is distributed in the hope it will be useful but, except \r
+ * as otherwise stated in writing, without any warranty; without even the \r
+ * implied warranty of merchantability or fitness for a particular purpose. \r
+ * See the GNU General Public License for more details.\r
+ * \r
+ * You should have received a copy of the GNU General Public License along with\r
+ * this program; if not, write to the Free Software Foundation, Inc.,\r
+ * 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA.\r
+ * \r
+ * The full GNU General Public License is included in this distribution in\r
+ * the file called "COPYING".\r
+ *\r
+ * Contact Information:\r
+ * Imagination Technologies Ltd. <gpl-support@imgtec.com>\r
+ * Home Park Estate, Kings Langley, Herts, WD4 8LZ, UK \r
+ *\r
+ ******************************************************************************/\r
+\r
+#ifndef AUTOCONF_INCLUDED\r
+#include <linux/config.h>\r
+#endif\r
+#include <linux/version.h>\r
+\r
+#include <linux/spinlock.h>\r
+#include <asm/page.h>\r
+/* Compilation Error */\r
+/*#include <asm/pgtable.h> */\r
+\r
+#include "img_defs.h"\r
+#include "pvr_debug.h"\r
+#include "mutils.h"\r
+\r
+#if defined(SUPPORT_LINUX_X86_PAT)\r
+#define        PAT_LINUX_X86_WC        1\r
+\r
+#define        PAT_X86_ENTRY_BITS      8\r
+\r
+#define        PAT_X86_BIT_PWT         1\r
+#define        PAT_X86_BIT_PCD         2\r
+#define        PAT_X86_BIT_PAT         4\r
+#define        PAT_X86_BIT_MASK        (PAT_X86_BIT_PAT | PAT_X86_BIT_PCD | PAT_X86_BIT_PWT)\r
+\r
+static IMG_BOOL g_write_combining_available = IMG_FALSE;\r
+\r
+#define        PROT_TO_PAT_INDEX(v, B) ((v & _PAGE_ ## B) ? PAT_X86_BIT_ ## B : 0)\r
+\r
+static inline IMG_UINT\r
+pvr_pat_index(pgprotval_t prot_val)\r
+{\r
+       IMG_UINT ret = 0;\r
+       pgprotval_t val = prot_val & _PAGE_CACHE_MASK;\r
+\r
+       ret |= PROT_TO_PAT_INDEX(val, PAT);\r
+       ret |= PROT_TO_PAT_INDEX(val, PCD);\r
+       ret |= PROT_TO_PAT_INDEX(val, PWT);\r
+\r
+       return ret;\r
+}\r
+\r
+static inline IMG_UINT\r
+pvr_pat_entry(u64 pat, IMG_UINT index)\r
+{\r
+       return (pat >> (index * PAT_X86_ENTRY_BITS)) & PAT_X86_BIT_MASK;\r
+}\r
+\r
+static IMG_VOID\r
+PVRLinuxX86PATProbe(IMG_VOID)\r
+{\r
+       \r
+       if (cpu_has_pat)\r
+       {\r
+               u64 pat;\r
+               IMG_UINT pat_index;\r
+               IMG_UINT pat_entry;\r
+\r
+               PVR_TRACE(("%s: PAT available", __FUNCTION__));\r
+               \r
+               rdmsrl(MSR_IA32_CR_PAT, pat);\r
+               PVR_TRACE(("%s: Top 32 bits of PAT: 0x%.8x", __FUNCTION__, (IMG_UINT)(pat >> 32)));\r
+               PVR_TRACE(("%s: Bottom 32 bits of PAT: 0x%.8x", __FUNCTION__, (IMG_UINT)(pat)));\r
+\r
+               pat_index = pvr_pat_index(_PAGE_CACHE_WC);\r
+               PVR_TRACE(("%s: PAT index for write combining: %u", __FUNCTION__, pat_index));\r
+\r
+               pat_entry = pvr_pat_entry(pat, pat_index);\r
+               PVR_TRACE(("%s: PAT entry for write combining: 0x%.2x (should be 0x%.2x)", __FUNCTION__, pat_entry, PAT_LINUX_X86_WC));\r
+\r
+#if defined(SUPPORT_LINUX_X86_WRITECOMBINE)\r
+               g_write_combining_available = (IMG_BOOL)(pat_entry == PAT_LINUX_X86_WC);\r
+#endif\r
+       }\r
+#if defined(DEBUG)\r
+#if defined(SUPPORT_LINUX_X86_WRITECOMBINE)\r
+       if (g_write_combining_available)\r
+       {\r
+               PVR_TRACE(("%s: Write combining available via PAT", __FUNCTION__));\r
+       }\r
+       else\r
+       {\r
+               PVR_TRACE(("%s: Write combining not available", __FUNCTION__));\r
+       }\r
+#else  \r
+       PVR_TRACE(("%s: Write combining disabled in driver build", __FUNCTION__));\r
+#endif \r
+#endif \r
+}\r
+\r
+pgprot_t\r
+pvr_pgprot_writecombine(pgprot_t prot)\r
+{\r
+    \r
+       return (g_write_combining_available) ?\r
+               __pgprot((pgprot_val(prot) & ~_PAGE_CACHE_MASK) | _PAGE_CACHE_WC) : pgprot_noncached(prot);\r
+}\r
+#endif \r
+\r
+IMG_VOID\r
+PVRLinuxMUtilsInit(IMG_VOID)\r
+{\r
+#if defined(SUPPORT_LINUX_X86_PAT)\r
+       PVRLinuxX86PATProbe();\r
+#endif\r
+}\r
+\r
diff --git a/services4/srvkm/env/linux/mutils.h b/services4/srvkm/env/linux/mutils.h
new file mode 100644 (file)
index 0000000..943c2bd
--- /dev/null
@@ -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. <gpl-support@imgtec.com>
+ * Home Park Estate, Kings Langley, Herts, WD4 8LZ, UK 
+ *
+ ******************************************************************************/
+
+#ifndef __IMG_LINUX_MUTILS_H__
+#define __IMG_LINUX_MUTILS_H__
+
+#ifndef AUTOCONF_INCLUDED
+#include <linux/config.h>
+#endif
+
+#include <linux/version.h>
+
+#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 (file)
index 0000000..17e5d97
--- /dev/null
@@ -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. <gpl-support@imgtec.com>
+ * Home Park Estate, Kings Langley, Herts, WD4 8LZ, UK 
+ *
+ ******************************************************************************/
+
+#ifndef AUTOCONF_INCLUDED
+ #include <linux/config.h>
+#endif
+
+#include <linux/version.h>
+#include <asm/io.h>
+#include <asm/page.h>
+#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,22))
+#include <asm/system.h>
+#endif
+#include <linux/mm.h>
+#include <linux/pagemap.h>
+#include <linux/hugetlb.h> 
+#include <linux/slab.h>
+#include <linux/vmalloc.h>
+#include <linux/delay.h>
+#include <linux/pci.h>
+
+#include <linux/string.h>
+#include <linux/sched.h>
+#include <linux/interrupt.h>
+#include <asm/hardirq.h>
+#include <linux/timer.h>
+#include <linux/capability.h>
+#include <asm/uaccess.h>
+#include <linux/spinlock.h>
+
+#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;i<ui32Size;i++)
+    {
+        Dst[i]=Src[i];
+    }
+#else
+       memcpy(pvDst, pvSrc, ui32Size);
+#endif
+}
+
+
+IMG_VOID OSMemSet(IMG_VOID *pvDest, IMG_UINT8 ui8Value, IMG_UINT32 ui32Size)
+{
+#if defined(USE_UNOPTIMISED_MEMSET)
+    IMG_UINT8 *Buff;
+    IMG_INT i;
+
+    Buff=(IMG_UINT8 *)pvDest;
+    for(i=0;i<ui32Size;i++)
+    {
+        Buff[i]=ui8Value;
+    }
+#else
+       memset(pvDest, (IMG_INT) ui8Value, (size_t) ui32Size);
+#endif
+}
+
+
+IMG_CHAR *OSStringCopy(IMG_CHAR *pszDest, const IMG_CHAR *pszSrc)
+{
+       return (strcpy(pszDest, pszSrc));
+}
+
+IMG_INT32 OSSNPrintf(IMG_CHAR *pStr, IMG_UINT32 ui32Size, const IMG_CHAR *pszFormat, ...)
+{
+    va_list argList;
+    IMG_INT32 iCount;
+
+    va_start(argList, pszFormat);
+    iCount = vsnprintf(pStr, (size_t)ui32Size, pszFormat, argList);
+    va_end(argList);
+
+    return iCount;
+}
+
+IMG_VOID OSBreakResourceLock (PVRSRV_RESOURCE *psResource, IMG_UINT32 ui32ID)
+{
+       volatile IMG_UINT32 *pui32Access = (volatile IMG_UINT32 *)&psResource->ui32Lock;
+
+       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(&current->mm->mmap_sem);
+       iNumPagesMapped = get_user_pages(current, current->mm, ulStartAddr, psInfo->iNumPages, 1, 0, psInfo->ppsPages, NULL);
+       up_read(&current->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(&current->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(&current->mm->mmap_sem);
+
+exit_check:
+       CheckPagesContiguous(psInfo);
+
+
+       
+       *phOSWrapMem = (IMG_HANDLE)psInfo;
+
+       return PVRSRV_OK;
+
+error_release_mmap_sem:
+       up_read(&current->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 (file)
index 0000000..0793875
--- /dev/null
@@ -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. <gpl-support@imgtec.com>
+ * 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 (file)
index 0000000..b7f948a
--- /dev/null
@@ -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. <gpl-support@imgtec.com>
+ * Home Park Estate, Kings Langley, Herts, WD4 8LZ, UK 
+ *
+ ******************************************************************************/
+
+#if defined (SUPPORT_SGX)
+#if defined (PDUMP)
+#include <asm/atomic.h>
+#include <stdarg.h>
+#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 <linux/tty.h>                 
+
+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) && (ui32Count<SZ_MSG_SIZE_MAX) )
+       {
+               ui32Count++;
+       }
+       
+       
+       if ( (pszMsg[ui32Count-1] != '\n') && (ui32Count<SZ_MSG_SIZE_MAX))
+       {
+               pszMsg[ui32Count] = '\n';
+               ui32Count++;
+               pszMsg[ui32Count] = '\0';
+       }
+       if ( (pszMsg[ui32Count-2] != '\r') && (ui32Count<SZ_MSG_SIZE_MAX) )
+       {
+               pszMsg[ui32Count-1] = '\r';
+               pszMsg[ui32Count] = '\n';
+               ui32Count++;
+               pszMsg[ui32Count] = '\0';
+       }
+
+       PDumpWriteString2(pszMsg, ui32Flags);
+
+       return PVRSRV_OK;
+}
+
+PVRSRV_ERROR PDumpDriverInfoKM(IMG_CHAR *pszString, IMG_UINT32 ui32Flags)
+{
+       IMG_UINT32 ui32Count = 0;
+       __PDBG_PDUMP_STATE_GET_MSG_STRING(PVRSRV_ERROR_GENERIC);
+
+       
+       snprintf(pszMsg, SZ_MSG_SIZE_MAX, "%s", pszString);
+
+       
+       while ((pszMsg[ui32Count]!=0) && (ui32Count<SZ_MSG_SIZE_MAX) )
+       {
+               ui32Count++;
+       }
+       
+       
+       if ( (pszMsg[ui32Count-1] != '\n') && (ui32Count<SZ_MSG_SIZE_MAX))
+       {
+               pszMsg[ui32Count] = '\n';
+               ui32Count++;
+               pszMsg[ui32Count] = '\0';
+       }
+       if ( (pszMsg[ui32Count-2] != '\r') && (ui32Count<SZ_MSG_SIZE_MAX) )
+       {
+               pszMsg[ui32Count-1] = '\r';
+               pszMsg[ui32Count] = '\n';
+               ui32Count++;
+               pszMsg[ui32Count] = '\0';
+       }
+
+       if      (!PDumpWriteILock(gsDBGPdumpState.
+                                                 psStream[PDUMP_STREAM_DRIVERINFO],
+                                                 (IMG_UINT8 *)pszMsg,
+                                                 ui32Count,
+                                                 ui32Flags))
+       {
+               if      (ui32Flags & PDUMP_FLAGS_CONTINUOUS)
+               {
+                       return PVRSRV_ERROR_GENERIC;
+               }
+               else
+               {
+                       return PVRSRV_ERROR_CMD_NOT_PROCESSED;
+               }
+       }
+
+       return PVRSRV_OK;
+}
+
+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)
+{
+       __PDBG_PDUMP_STATE_GET_SCRIPT_STRING(PVRSRV_ERROR_GENERIC);
+       PDUMPCOMMENTWITHFLAGS(ui32PDumpFlags, "\r\n-- Dump bitmap of render\r\n");
+
+#if defined(SGX_FEATURE_MULTIPLE_MEM_CONTEXTS)
+       
+       snprintf(pszScript,
+                               SZ_SCRIPT_SIZE_MAX,
+                               "SII %s %s.bin :SGXMEM:v%x:0x%08lX 0x%08lX 0x%08lX 0x%08X 0x%08lX 0x%08lX 0x%08lX 0x%08X\r\n",
+                               pszFileName,
+                               pszFileName,
+                               PDUMP_DATAMASTER_PIXEL,
+                               sDevBaseAddr.uiAddr,
+                               ui32Size,
+                               ui32FileOffset,
+                               ePixelFormat,
+                               ui32Width,
+                               ui32Height,
+                               ui32StrideInBytes,
+                               eMemFormat);
+#else
+       snprintf(pszScript,
+                               SZ_SCRIPT_SIZE_MAX,
+                               "SII %s %s.bin :SGXMEM:v:0x%08lX 0x%08lX 0x%08lX 0x%08X 0x%08lX 0x%08lX 0x%08lX 0x%08X\r\n",
+                               pszFileName,
+                               pszFileName,
+                               sDevBaseAddr.uiAddr,
+                               ui32Size,
+                               ui32FileOffset,
+                               ePixelFormat,
+                               ui32Width,
+                               ui32Height,
+                               ui32StrideInBytes,
+                               eMemFormat);
+#endif
+
+       PDumpWriteString2( pszScript, ui32PDumpFlags);
+       return PVRSRV_OK;
+}
+
+PVRSRV_ERROR PDumpReadRegKM            (       IMG_CHAR *pszFileName,
+                                                                       IMG_UINT32 ui32FileOffset,
+                                                                       IMG_UINT32 ui32Address,
+                                                                       IMG_UINT32 ui32Size,
+                                                                       IMG_UINT32 ui32PDumpFlags)
+{
+       __PDBG_PDUMP_STATE_GET_SCRIPT_STRING(PVRSRV_ERROR_GENERIC);
+
+       snprintf(pszScript,
+                       SZ_SCRIPT_SIZE_MAX,
+                       "SAB :SGXREG:0x%08lX 0x%08lX %s\r\n",
+                       ui32Address,
+                       ui32FileOffset,
+                       pszFileName);
+
+       PDumpWriteString2( pszScript, ui32PDumpFlags);
+
+       return PVRSRV_OK;
+}
+
+
+static IMG_BOOL PDumpWriteString2(IMG_CHAR * pszString, IMG_UINT32 ui32Flags)
+{
+       return PDumpWriteILock(gsDBGPdumpState.psStream[PDUMP_STREAM_SCRIPT2], (IMG_UINT8 *) pszString, strlen(pszString), ui32Flags);
+}
+
+
+static IMG_BOOL PDumpWriteILock(PDBG_STREAM psStream, IMG_UINT8 *pui8Data, IMG_UINT32 ui32Count, IMG_UINT32 ui32Flags)
+{
+       IMG_UINT32 ui32Written = 0;
+       IMG_UINT32 ui32Off = 0;
+
+       if (!psStream || PDumpSuspended() || (ui32Flags & PDUMP_FLAGS_NEVER))
+       {
+               return IMG_TRUE;
+       }
+       
+
+       
+
+       if (psStream == gsDBGPdumpState.psStream[PDUMP_STREAM_PARAM2])
+       {
+               IMG_UINT32 ui32ParamOutPos = gpfnDbgDrv->pfnGetStreamOffset(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 (file)
index 0000000..9629a63
--- /dev/null
@@ -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. <gpl-support@imgtec.com>
+ * 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 (file)
index 0000000..bc8fd00
--- /dev/null
@@ -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. <gpl-support@imgtec.com>
+ * Home Park Estate, Kings Langley, Herts, WD4 8LZ, UK 
+ *
+ ******************************************************************************/
+
+#ifndef AUTOCONF_INCLUDED
+ #include <linux/config.h>
+#endif
+
+#include <linux/init.h>
+#include <linux/module.h>
+#include <linux/version.h>
+#include <linux/fs.h>
+#include <linux/proc_fs.h>
+
+#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 (file)
index 0000000..dbb5a7a
--- /dev/null
@@ -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. <gpl-support@imgtec.com>
+ * Home Park Estate, Kings Langley, Herts, WD4 8LZ, UK 
+ *
+ ******************************************************************************/
+
+#ifndef __SERVICES_PROC_H__
+#define __SERVICES_PROC_H__
+
+#include <asm/system.h>                
+#include <linux/proc_fs.h>     
+
+#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 (file)
index 0000000..c211023
--- /dev/null
@@ -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. <gpl-support@imgtec.com>
+ * 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 (file)
index 0000000..bdee215
--- /dev/null
@@ -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. <gpl-support@imgtec.com>
+ * Home Park Estate, Kings Langley, Herts, WD4 8LZ, UK 
+ *
+ ******************************************************************************/
+
+  
+#ifndef AUTOCONF_INCLUDED
+ #include <linux/config.h>
+#endif
+
+#include <asm/io.h>
+#include <asm/uaccess.h>
+#include <linux/kernel.h>
+#include <linux/hardirq.h>
+#include <linux/module.h>
+#include <linux/spinlock.h>
+#include <linux/tty.h>                 
+#include <stdarg.h>
+#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 (file)
index 0000000..830600d
--- /dev/null
@@ -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. <gpl-support@imgtec.com>
+ * 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 (file)
index 0000000..b755374
--- /dev/null
@@ -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. <gpl-support@imgtec.com>
+ * 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<<EUR_CR_MNE_CR_CTRL_INVAL_PREQ_SHIFT+2)
+#define EUR_CR_MNE_CR_CTRL_INVAL_PREQ_USEC_MASK (1<<EUR_CR_MNE_CR_CTRL_INVAL_PREQ_SHIFT+1)
+#define EUR_CR_MNE_CR_CTRL_INVAL_PREQ_CACHE_MASK (1<<EUR_CR_MNE_CR_CTRL_INVAL_PREQ_SHIFT)
+#define EUR_CR_MNE_CR_CTRL_INVAL_MASK                  0x00000001
+#define EUR_CR_MNE_CR_CTRL_INVAL_SHIFT                 0
+#define EUR_CR_MNE_CR_USE_INVAL                                        0x0D04
+#define EUR_CR_MNE_CR_USE_INVAL_ADDR_MASK              0xFFFFFFFF
+#define EUR_CR_MNE_CR_USE_INVAL_ADDR_SHIFT             0
+#define EUR_CR_MNE_CR_STAT                                     0x0D08
+#define EUR_CR_MNE_CR_STAT_PAUSED_MASK         0x00000400
+#define EUR_CR_MNE_CR_STAT_PAUSED_SHIFT                10
+#define EUR_CR_MNE_CR_STAT_READS_MASK          0x000003FF
+#define EUR_CR_MNE_CR_STAT_READS_SHIFT         0
+#define EUR_CR_MNE_CR_STAT_STATS                       0x0D0C
+#define EUR_CR_MNE_CR_STAT_STATS_RST_MASK      0x000FFFF0
+#define EUR_CR_MNE_CR_STAT_STATS_RST_SHIFT     4
+#define EUR_CR_MNE_CR_STAT_STATS_SEL_MASK      0x0000000F
+#define EUR_CR_MNE_CR_STAT_STATS_SEL_SHIFT     0
+#define EUR_CR_MNE_CR_STAT_STATS_OUT                           0x0D10
+#define EUR_CR_MNE_CR_STAT_STATS_OUT_VALUE_MASK                0xFFFFFFFF
+#define EUR_CR_MNE_CR_STAT_STATS_OUT_VALUE_SHIFT       0
+#define EUR_CR_MNE_CR_EVENT_STATUS                             0x0D14
+#define EUR_CR_MNE_CR_EVENT_STATUS_INVAL_MASK  0x00000001
+#define EUR_CR_MNE_CR_EVENT_STATUS_INVAL_SHIFT 0
+#define EUR_CR_MNE_CR_EVENT_CLEAR                              0x0D18
+#define EUR_CR_MNE_CR_EVENT_CLEAR_INVAL_MASK   0x00000001
+#define EUR_CR_MNE_CR_EVENT_CLEAR_INVAL_SHIFT  0
+
+#endif 
+
diff --git a/services4/srvkm/hwdefs/sgxcoretypes.h b/services4/srvkm/hwdefs/sgxcoretypes.h
new file mode 100644 (file)
index 0000000..6dc26ef
--- /dev/null
@@ -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. <gpl-support@imgtec.com>
+ * 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 (file)
index 0000000..0f92a31
--- /dev/null
@@ -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. <gpl-support@imgtec.com>
+ * 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 (file)
index 0000000..ba4b9c3
--- /dev/null
@@ -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. <gpl-support@imgtec.com>
+ * 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 (file)
index 0000000..a161658
--- /dev/null
@@ -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. <gpl-support@imgtec.com>
+ * 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 (file)
index 0000000..2100788
--- /dev/null
@@ -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. <gpl-support@imgtec.com>
+ * 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<<SGX_MMU_PAGE_SHIFT)
+#define SGX_MMU_PAGE_MASK                              (SGX_MMU_PAGE_SIZE - 1UL)
+
+#define SGX_MMU_PD_SHIFT                               (10)
+#define SGX_MMU_PD_SIZE                                        (1UL<<SGX_MMU_PD_SHIFT)
+#define SGX_MMU_PD_MASK                                        (0xFFC00000UL)
+
+#define SGX_MMU_PDE_ADDR_MASK                  (0xFFFFF000UL)
+#define SGX_MMU_PDE_VALID                              (0x00000001UL)
+#define SGX_MMU_PDE_PAGE_SIZE_4K               (0x00000000UL)
+#if defined(SGX_FEATURE_VARIABLE_MMU_PAGE_SIZE)
+#define SGX_MMU_PDE_PAGE_SIZE_16K              (0x00000002UL)
+#define SGX_MMU_PDE_PAGE_SIZE_64K              (0x00000004UL)
+#define SGX_MMU_PDE_PAGE_SIZE_256K             (0x00000006UL)
+#define SGX_MMU_PDE_PAGE_SIZE_1M               (0x00000008UL)
+#define SGX_MMU_PDE_PAGE_SIZE_4M               (0x0000000AUL)
+#else
+#define SGX_MMU_PDE_WRITEONLY                  (0x00000002UL)
+#define SGX_MMU_PDE_READONLY                   (0x00000004UL)
+#define SGX_MMU_PDE_CACHECONSISTENT            (0x00000008UL)
+#define SGX_MMU_PDE_EDMPROTECT                 (0x00000010UL)
+#endif
+
+#define SGX_MMU_PT_SHIFT                               (10)
+#define SGX_MMU_PT_SIZE                                        (1UL<<SGX_MMU_PT_SHIFT)
+#define SGX_MMU_PT_MASK                                        (0x003FF000UL)
+
+#define SGX_MMU_PTE_ADDR_MASK                  (0xFFFFF000UL)
+#define SGX_MMU_PTE_VALID                              (0x00000001UL)
+#define SGX_MMU_PTE_WRITEONLY                  (0x00000002UL)
+#define SGX_MMU_PTE_READONLY                   (0x00000004UL)
+#define SGX_MMU_PTE_CACHECONSISTENT            (0x00000008UL)
+#define SGX_MMU_PTE_EDMPROTECT                 (0x00000010UL)
+
+#endif 
+
diff --git a/services4/srvkm/include/buffer_manager.h b/services4/srvkm/include/buffer_manager.h
new file mode 100644 (file)
index 0000000..1651b60
--- /dev/null
@@ -0,0 +1,211 @@
+/**********************************************************************
+ *
+ * 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. <gpl-support@imgtec.com>
+ * 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 (file)
index 0000000..31ee11e
--- /dev/null
@@ -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. <gpl-support@imgtec.com>
+ * 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 (file)
index 0000000..fda74f1
--- /dev/null
@@ -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. <gpl-support@imgtec.com>
+ * 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 (file)
index 0000000..d45f4a9
--- /dev/null
@@ -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. <gpl-support@imgtec.com>
+ * 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 (file)
index 0000000..2632f8d
--- /dev/null
@@ -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. <gpl-support@imgtec.com>
+ * 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 (file)
index 0000000..da48598
--- /dev/null
@@ -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. <gpl-support@imgtec.com>
+ * 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 <linux/hardirq.h>
+#include <linux/string.h>
+#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 (file)
index 0000000..80a912f
--- /dev/null
@@ -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. <gpl-support@imgtec.com>
+ * 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 (file)
index 0000000..106fd4e
--- /dev/null
@@ -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. <gpl-support@imgtec.com>
+ * 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 (file)
index 0000000..233bb59
--- /dev/null
@@ -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. <gpl-support@imgtec.com>
+ * 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 (file)
index 0000000..5d0f0c3
--- /dev/null
@@ -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. <gpl-support@imgtec.com>
+ * 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 (file)
index 0000000..7926f05
--- /dev/null
@@ -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. <gpl-support@imgtec.com>
+ * 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 <linux/types.h>
+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 (file)
index 0000000..593f17f
--- /dev/null
@@ -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. <gpl-support@imgtec.com>
+ * 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 (file)
index 0000000..37d5e3e
--- /dev/null
@@ -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. <gpl-support@imgtec.com>
+ * 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 (file)
index 0000000..eb00dbb
--- /dev/null
@@ -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. <gpl-support@imgtec.com>
+ * 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 (file)
index 0000000..0bb1116
--- /dev/null
@@ -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. <gpl-support@imgtec.com>
+ * 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 (file)
index 0000000..a3675a7
--- /dev/null
@@ -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. <gpl-support@imgtec.com>
+ * 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 <asm/io.h>
+#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 (file)
index 0000000..206f7fa
--- /dev/null
@@ -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. <gpl-support@imgtec.com>
+ * 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 (file)
index 0000000..142ba41
--- /dev/null
@@ -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. <gpl-support@imgtec.com>
+ * 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; i<SYS_DEVICE_COUNT; i++)
+       {
+               gpsSysData->sDeviceID[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; i<psDevMemoryInfo->ui32HeapCount; 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 (file)
index 0000000..d818f77
--- /dev/null
@@ -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. <gpl-support@imgtec.com>
+ * 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 (file)
index 0000000..89622fe
--- /dev/null
@@ -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. <gpl-support@imgtec.com>
+ * 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 (file)
index 0000000..b97c0e2
--- /dev/null
@@ -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. <gpl-support@imgtec.com>
+ * Home Park Estate, Kings Langley, Herts, WD4 8LZ, UK 
+ *
+ ******************************************************************************/
+
+#if !defined(__SYSLOCAL_H__)
+#define __SYSLOCAL_H__
+
+#if defined(__linux__)
+
+#include <linux/version.h>
+#include <linux/clk.h>
+#include <linux/spinlock.h>
+#include <asm/atomic.h>
+
+#if (LINUX_VERSION_CODE > KERNEL_VERSION(2,6,26))
+#include <linux/semaphore.h>
+#include <linux/resource.h>
+#else 
+#include <asm/semaphore.h>
+#if (LINUX_VERSION_CODE > KERNEL_VERSION(2,6,22))
+#include <asm/arch/resource.h>
+#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 (file)
index 0000000..3d3def0
--- /dev/null
@@ -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. <gpl-support@imgtec.com>
+ * 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 (file)
index 0000000..6c3063e
--- /dev/null
@@ -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. <gpl-support@imgtec.com>
+ * Home Park Estate, Kings Langley, Herts, WD4 8LZ, UK 
+ *
+ ******************************************************************************/
+
+#include <linux/version.h>
+#include <linux/clk.h>
+#include <linux/err.h>
+#include <linux/hardirq.h>
+#include <linux/spinlock.h>
+#include <asm/bug.h>
+
+#if (LINUX_VERSION_CODE > KERNEL_VERSION(2,6,31))
+#include <linux/semaphore.h>
+#include <plat/resource.h>
+#include <plat/omap-pm.h>
+#else
+
+#if (LINUX_VERSION_CODE > KERNEL_VERSION(2,6,26))
+#include <linux/semaphore.h>
+#include <mach/resource.h>
+#include <mach/omap-pm.h>
+#else
+#include <asm/semaphore.h>
+#if (LINUX_VERSION_CODE > KERNEL_VERSION(2,6,22))
+#include <asm/arch/resource.h>
+#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 (file)
index 0000000..1131534
--- /dev/null
@@ -0,0 +1,56 @@
+/**********************************************************************\r
+ *\r
+ * Copyright(c) 2008 Imagination Technologies Ltd. All rights reserved.\r
+ * \r
+ * This program is free software; you can redistribute it and/or modify it\r
+ * under the terms and conditions of the GNU General Public License,\r
+ * version 2, as published by the Free Software Foundation.\r
+ * \r
+ * This program is distributed in the hope it will be useful but, except \r
+ * as otherwise stated in writing, without any warranty; without even the \r
+ * implied warranty of merchantability or fitness for a particular purpose. \r
+ * See the GNU General Public License for more details.\r
+ * \r
+ * You should have received a copy of the GNU General Public License along with\r
+ * this program; if not, write to the Free Software Foundation, Inc.,\r
+ * 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA.\r
+ * \r
+ * The full GNU General Public License is included in this distribution in\r
+ * the file called "COPYING".\r
+ *\r
+ * Contact Information:\r
+ * Imagination Technologies Ltd. <gpl-support@imgtec.com>\r
+ * Home Park Estate, Kings Langley, Herts, WD4 8LZ, UK \r
+ *\r
+ ******************************************************************************/\r
+\r
+#if !defined(__OEMFUNCS_H__)\r
+#define __OEMFUNCS_H__\r
+\r
+#if defined (__cplusplus)\r
+extern "C" {\r
+#endif\r
+\r
+typedef IMG_UINT32   (*PFN_SRV_BRIDGEDISPATCH)( IMG_UINT32  Ioctl,\r
+                                                                                               IMG_BYTE   *pInBuf,\r
+                                                                                               IMG_UINT32  InBufLen, \r
+                                                                                           IMG_BYTE   *pOutBuf,\r
+                                                                                               IMG_UINT32  OutBufLen,\r
+                                                                                               IMG_UINT32 *pdwBytesTransferred);\r
+typedef struct PVRSRV_DC_OEM_JTABLE_TAG\r
+{\r
+       PFN_SRV_BRIDGEDISPATCH                  pfnOEMBridgeDispatch;\r
+       IMG_PVOID                                               pvDummy1;\r
+       IMG_PVOID                                               pvDummy2;\r
+       IMG_PVOID                                               pvDummy3;\r
+\r
+} PVRSRV_DC_OEM_JTABLE;\r
+\r
+#define OEM_GET_EXT_FUNCS                      (1<<1)\r
+\r
+#if defined(__cplusplus)\r
+}\r
+#endif\r
+\r
+#endif \r
+\r
diff --git a/services4/system/omap3630/sysconfig.c b/services4/system/omap3630/sysconfig.c
new file mode 100644 (file)
index 0000000..38f3e4b
--- /dev/null
@@ -0,0 +1,807 @@
+/**********************************************************************\r
+ *\r
+ * Copyright(c) 2008 Imagination Technologies Ltd. All rights reserved.\r
+ * \r
+ * This program is free software; you can redistribute it and/or modify it\r
+ * under the terms and conditions of the GNU General Public License,\r
+ * version 2, as published by the Free Software Foundation.\r
+ * \r
+ * This program is distributed in the hope it will be useful but, except \r
+ * as otherwise stated in writing, without any warranty; without even the \r
+ * implied warranty of merchantability or fitness for a particular purpose. \r
+ * See the GNU General Public License for more details.\r
+ * \r
+ * You should have received a copy of the GNU General Public License along with\r
+ * this program; if not, write to the Free Software Foundation, Inc.,\r
+ * 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA.\r
+ * \r
+ * The full GNU General Public License is included in this distribution in\r
+ * the file called "COPYING".\r
+ *\r
+ * Contact Information:\r
+ * Imagination Technologies Ltd. <gpl-support@imgtec.com>\r
+ * Home Park Estate, Kings Langley, Herts, WD4 8LZ, UK \r
+ *\r
+ ******************************************************************************/\r
+\r
+#include "services_headers.h"\r
+#include "kerneldisplay.h"\r
+#include "oemfuncs.h"\r
+#include "sgxinfo.h"\r
+#include "pdump_km.h"\r
+#include "sgxinfokm.h"\r
+#include "syslocal.h"\r
+#include "sysconfig.h"\r
+\r
+SYS_DATA* gpsSysData = (SYS_DATA*)IMG_NULL;\r
+SYS_DATA  gsSysData;\r
+\r
+static SYS_SPECIFIC_DATA gsSysSpecificData;\r
+SYS_SPECIFIC_DATA *gpsSysSpecificData;\r
+\r
+static IMG_UINT32      gui32SGXDeviceID;\r
+static SGX_DEVICE_MAP  gsSGXDeviceMap;\r
+static PVRSRV_DEVICE_NODE *gpsSGXDevNode;\r
+\r
+#define DEVICE_SGX_INTERRUPT (1 << 0)\r
+\r
+#if defined(NO_HARDWARE)\r
+static IMG_CPU_VIRTADDR gsSGXRegsCPUVAddr;\r
+#endif\r
+\r
+IMG_UINT32 PVRSRV_BridgeDispatchKM(IMG_UINT32  Ioctl,\r
+                                                                  IMG_BYTE             *pInBuf,\r
+                                                                  IMG_UINT32   InBufLen,\r
+                                                                  IMG_BYTE             *pOutBuf,\r
+                                                                  IMG_UINT32   OutBufLen,\r
+                                                                  IMG_UINT32   *pdwBytesTransferred);\r
+\r
+static PVRSRV_ERROR SysLocateDevices(SYS_DATA *psSysData)\r
+{\r
+#if defined(NO_HARDWARE)\r
+       PVRSRV_ERROR eError;\r
+       IMG_CPU_PHYADDR sCpuPAddr;\r
+#endif\r
+\r
+       PVR_UNREFERENCED_PARAMETER(psSysData);\r
+\r
+       \r
+       gsSGXDeviceMap.ui32Flags = 0x0;\r
+       \r
+#if defined(NO_HARDWARE)\r
+       \r
+       \r
+       eError = OSBaseAllocContigMemory(SYS_OMAP3430_SGX_REGS_SIZE, \r
+                                                                        &gsSGXRegsCPUVAddr,\r
+                                                                        &sCpuPAddr);\r
+       if(eError != PVRSRV_OK)\r
+       {\r
+               return eError;\r
+       }\r
+       gsSGXDeviceMap.sRegsCpuPBase = sCpuPAddr;\r
+       gsSGXDeviceMap.sRegsSysPBase = SysCpuPAddrToSysPAddr(gsSGXDeviceMap.sRegsCpuPBase);\r
+       gsSGXDeviceMap.ui32RegsSize = SYS_OMAP3430_SGX_REGS_SIZE;\r
+#if defined(__linux__)\r
+       \r
+       gsSGXDeviceMap.pvRegsCpuVBase = gsSGXRegsCPUVAddr;\r
+#else\r
+       \r
+       gsSGXDeviceMap.pvRegsCpuVBase = IMG_NULL;\r
+#endif\r
+\r
+       OSMemSet(gsSGXRegsCPUVAddr, 0, SYS_OMAP3430_SGX_REGS_SIZE);\r
+\r
+       \r
+\r
+\r
+       gsSGXDeviceMap.ui32IRQ = 0;\r
+\r
+#else \r
+\r
+       gsSGXDeviceMap.sRegsSysPBase.uiAddr = SYS_OMAP3430_SGX_REGS_SYS_PHYS_BASE;\r
+       gsSGXDeviceMap.sRegsCpuPBase = SysSysPAddrToCpuPAddr(gsSGXDeviceMap.sRegsSysPBase);\r
+       gsSGXDeviceMap.ui32RegsSize = SYS_OMAP3430_SGX_REGS_SIZE;\r
+\r
+       gsSGXDeviceMap.ui32IRQ = SYS_OMAP3430_SGX_IRQ;\r
+\r
+#endif \r
+\r
+\r
+       \r
+\r
+\r
+       return PVRSRV_OK;\r
+}\r
+\r
+\r
+IMG_CHAR *SysCreateVersionString(IMG_CPU_PHYADDR sRegRegion)\r
+{\r
+       static IMG_CHAR aszVersionString[100];\r
+       SYS_DATA        *psSysData;\r
+       IMG_UINT32      ui32SGXRevision;\r
+       IMG_INT32       i32Count;\r
+#if !defined(NO_HARDWARE)\r
+       IMG_VOID        *pvRegsLinAddr;\r
+\r
+       pvRegsLinAddr = OSMapPhysToLin(sRegRegion,\r
+                                                                  SYS_OMAP3430_SGX_REGS_SIZE,\r
+                                                                  PVRSRV_HAP_UNCACHED|PVRSRV_HAP_KERNEL_ONLY,\r
+                                                                  IMG_NULL);\r
+       if(!pvRegsLinAddr)\r
+       {\r
+               return IMG_NULL;\r
+       }\r
+\r
+       ui32SGXRevision = OSReadHWReg((IMG_PVOID)((IMG_PBYTE)pvRegsLinAddr),\r
+                                                                 EUR_CR_CORE_REVISION);\r
+#else\r
+       ui32SGXRevision = 0;\r
+#endif\r
+\r
+       if (SysAcquireData(&psSysData) != PVRSRV_OK)\r
+       {\r
+               return IMG_NULL;\r
+       }\r
+\r
+       i32Count = OSSNPrintf(aszVersionString, 100,\r
+                                                 "SGX revision = %u.%u.%u",\r
+                                                 (IMG_UINT)((ui32SGXRevision & EUR_CR_CORE_REVISION_MAJOR_MASK)\r
+                                                       >> EUR_CR_CORE_REVISION_MAJOR_SHIFT),\r
+                                                 (IMG_UINT)((ui32SGXRevision & EUR_CR_CORE_REVISION_MINOR_MASK)\r
+                                                       >> EUR_CR_CORE_REVISION_MINOR_SHIFT),\r
+                                                 (IMG_UINT)((ui32SGXRevision & EUR_CR_CORE_REVISION_MAINTENANCE_MASK)\r
+                                                       >> EUR_CR_CORE_REVISION_MAINTENANCE_SHIFT)\r
+                                                );\r
+\r
+#if !defined(NO_HARDWARE)\r
+       OSUnMapPhysToLin(pvRegsLinAddr,\r
+                                        SYS_OMAP3430_SGX_REGS_SIZE,\r
+                                        PVRSRV_HAP_UNCACHED|PVRSRV_HAP_KERNEL_ONLY,\r
+                                        IMG_NULL);\r
+#endif\r
+\r
+       if(i32Count == -1)\r
+       {\r
+               return IMG_NULL;\r
+       }\r
+\r
+       return aszVersionString;\r
+}\r
+\r
+\r
+PVRSRV_ERROR SysInitialise(IMG_VOID)\r
+{\r
+       IMG_UINT32                      i;\r
+       PVRSRV_ERROR            eError;\r
+       PVRSRV_DEVICE_NODE      *psDeviceNode;\r
+       IMG_CPU_PHYADDR         TimerRegPhysBase;\r
+\r
+#if defined(DEBUG)\r
+       PVR_DPF((PVR_DBG_WARNING,"SysInitialise: Entering..."));\r
+#endif\r
+\r
+#if !defined(SGX_DYNAMIC_TIMING_INFO)\r
+       SGX_TIMING_INFORMATION* psTimingInfo;\r
+#endif\r
+       gpsSysData = &gsSysData;\r
+       OSMemSet(gpsSysData, 0, sizeof(SYS_DATA));\r
+\r
+       gpsSysSpecificData =  &gsSysSpecificData;\r
+       OSMemSet(gpsSysSpecificData, 0, sizeof(SYS_SPECIFIC_DATA));\r
+\r
+       gpsSysData->pvSysSpecificData = gpsSysSpecificData;\r
+\r
+       eError = OSInitEnvData(&gpsSysData->pvEnvSpecificData);\r
+       if (eError != PVRSRV_OK)\r
+       {\r
+               PVR_DPF((PVR_DBG_ERROR,"SysInitialise: Failed to setup env structure"));\r
+               SysDeinitialise(gpsSysData);\r
+               gpsSysData = IMG_NULL;\r
+               return eError;\r
+       }\r
+       SYS_SPECIFIC_DATA_SET(&gsSysSpecificData, SYS_SPECIFIC_DATA_ENABLE_ENVDATA);\r
+\r
+       gpsSysData->ui32NumDevices = SYS_DEVICE_COUNT;\r
+\r
+       \r
+       for(i=0; i<SYS_DEVICE_COUNT; i++)\r
+       {\r
+               gpsSysData->sDeviceID[i].uiID = i;\r
+               gpsSysData->sDeviceID[i].bInUse = IMG_FALSE;\r
+       }\r
+\r
+       gpsSysData->psDeviceNodeList = IMG_NULL;\r
+       gpsSysData->psQueueList = IMG_NULL;\r
+\r
+       eError = SysInitialiseCommon(gpsSysData);\r
+       if (eError != PVRSRV_OK)\r
+       {\r
+               PVR_DPF((PVR_DBG_ERROR,"SysInitialise: Failed in SysInitialiseCommon"));\r
+               SysDeinitialise(gpsSysData);\r
+               gpsSysData = IMG_NULL;\r
+               return eError;\r
+       }\r
+\r
+       TimerRegPhysBase.uiAddr = SYS_OMAP3430_GP11TIMER_REGS_SYS_PHYS_BASE;\r
+       gpsSysData->pvSOCTimerRegisterKM = IMG_NULL;\r
+       gpsSysData->hSOCTimerRegisterOSMemHandle = 0;\r
+       OSReservePhys(TimerRegPhysBase,\r
+                                 4,\r
+                                 PVRSRV_HAP_MULTI_PROCESS|PVRSRV_HAP_UNCACHED,\r
+                                 (IMG_VOID **)&gpsSysData->pvSOCTimerRegisterKM,\r
+                                 &gpsSysData->hSOCTimerRegisterOSMemHandle);\r
+\r
+#if !defined(SGX_DYNAMIC_TIMING_INFO)\r
+       \r
+       psTimingInfo = &gsSGXDeviceMap.sTimingInfo;\r
+       psTimingInfo->ui32CoreClockSpeed = SYS_SGX_CLOCK_SPEED;\r
+       psTimingInfo->ui32HWRecoveryFreq = SYS_SGX_HWRECOVERY_TIMEOUT_FREQ; \r
+       psTimingInfo->ui32ActivePowManLatencyms = SYS_SGX_ACTIVE_POWER_LATENCY_MS; \r
+       psTimingInfo->ui32uKernelFreq = SYS_SGX_PDS_TIMER_FREQ; \r
+#endif\r
+\r
+       \r
+\r
+       gpsSysSpecificData->ui32SrcClockDiv = 3;\r
+\r
+       \r
+\r
+\r
+\r
+       eError = SysLocateDevices(gpsSysData);\r
+       if (eError != PVRSRV_OK)\r
+       {\r
+               PVR_DPF((PVR_DBG_ERROR,"SysInitialise: Failed to locate devices"));\r
+               SysDeinitialise(gpsSysData);\r
+               gpsSysData = IMG_NULL;\r
+               return eError;\r
+       }\r
+       SYS_SPECIFIC_DATA_SET(&gsSysSpecificData, SYS_SPECIFIC_DATA_ENABLE_LOCATEDEV);\r
+\r
+       \r
+\r
+\r
+       eError = PVRSRVRegisterDevice(gpsSysData, SGXRegisterDevice,\r
+                                                                 DEVICE_SGX_INTERRUPT, &gui32SGXDeviceID);\r
+       if (eError != PVRSRV_OK)\r
+       {\r
+               PVR_DPF((PVR_DBG_ERROR,"SysInitialise: Failed to register device!"));\r
+               SysDeinitialise(gpsSysData);\r
+               gpsSysData = IMG_NULL;\r
+               return eError;\r
+       }\r
+       SYS_SPECIFIC_DATA_SET(&gsSysSpecificData, SYS_SPECIFIC_DATA_ENABLE_REGDEV);\r
+\r
+       \r
+\r
+\r
+       \r
+       psDeviceNode = gpsSysData->psDeviceNodeList;\r
+       while(psDeviceNode)\r
+       {\r
+               \r
+               switch(psDeviceNode->sDevId.eDeviceType)\r
+               {\r
+                       case PVRSRV_DEVICE_TYPE_SGX:\r
+                       {\r
+                               DEVICE_MEMORY_INFO *psDevMemoryInfo;\r
+                               DEVICE_MEMORY_HEAP_INFO *psDeviceMemoryHeap;\r
+\r
+                               \r
+\r
+\r
+                               psDeviceNode->psLocalDevMemArena = IMG_NULL;\r
+\r
+                               \r
+                               psDevMemoryInfo = &psDeviceNode->sDevMemoryInfo;\r
+                               psDeviceMemoryHeap = psDevMemoryInfo->psDeviceMemoryHeap;\r
+\r
+                               \r
+                               for(i=0; i<psDevMemoryInfo->ui32HeapCount; i++)\r
+                               {\r
+                                       psDeviceMemoryHeap[i].ui32Attribs |= PVRSRV_BACKINGSTORE_SYSMEM_NONCONTIG;\r
+                               }\r
+\r
+                               gpsSGXDevNode = psDeviceNode;\r
+                               gsSysSpecificData.psSGXDevNode = psDeviceNode;\r
+\r
+                               break;\r
+                       }\r
+                       default:\r
+                               PVR_DPF((PVR_DBG_ERROR,"SysInitialise: Failed to find SGX device node!"));\r
+                               return PVRSRV_ERROR_INIT_FAILURE;\r
+               }\r
+\r
+               \r
+               psDeviceNode = psDeviceNode->psNext;\r
+       }\r
+\r
+       PDUMPINIT();\r
+       SYS_SPECIFIC_DATA_SET(&gsSysSpecificData, SYS_SPECIFIC_DATA_ENABLE_PDUMPINIT);\r
+\r
+       eError = EnableSystemClocks(gpsSysData);\r
+       if (eError != PVRSRV_OK)\r
+       {\r
+               PVR_DPF((PVR_DBG_ERROR,"SysInitialise: Failed to Enable system clocks (%d)", eError));\r
+               SysDeinitialise(gpsSysData);\r
+               gpsSysData = IMG_NULL;\r
+               return eError;\r
+       }\r
+       SYS_SPECIFIC_DATA_SET(&gsSysSpecificData, SYS_SPECIFIC_DATA_ENABLE_SYSCLOCKS);\r
+\r
+#if defined(SUPPORT_ACTIVE_POWER_MANAGEMENT)\r
+       eError = EnableSGXClocks(gpsSysData);\r
+       if (eError != PVRSRV_OK)\r
+       {\r
+               PVR_DPF((PVR_DBG_ERROR,"SysInitialise: Failed to Enable SGX clocks (%d)", eError));\r
+               SysDeinitialise(gpsSysData);\r
+               gpsSysData = IMG_NULL;\r
+               return eError;\r
+       }\r
+#endif \r
+\r
+       eError = PVRSRVInitialiseDevice(gui32SGXDeviceID);\r
+       if (eError != PVRSRV_OK)\r
+       {\r
+               PVR_DPF((PVR_DBG_ERROR,"SysInitialise: Failed to initialise device!"));\r
+               SysDeinitialise(gpsSysData);\r
+               gpsSysData = IMG_NULL;\r
+               return eError;\r
+       }\r
+       SYS_SPECIFIC_DATA_SET(&gsSysSpecificData, SYS_SPECIFIC_DATA_ENABLE_INITDEV);\r
+\r
+#if defined(SUPPORT_ACTIVE_POWER_MANAGEMENT)\r
+       \r
+       DisableSGXClocks(gpsSysData);\r
+#endif \r
+\r
+       return PVRSRV_OK;\r
+}\r
+\r
+\r
+PVRSRV_ERROR SysFinalise(IMG_VOID)\r
+{\r
+       PVRSRV_ERROR eError = PVRSRV_OK;\r
+       \r
+#if defined(SUPPORT_ACTIVE_POWER_MANAGEMENT)\r
+       eError = EnableSGXClocks(gpsSysData);\r
+       if (eError != PVRSRV_OK)\r
+       {\r
+               PVR_DPF((PVR_DBG_ERROR,"SysInitialise: Failed to Enable SGX clocks (%d)", eError));\r
+               SysDeinitialise(gpsSysData);\r
+               gpsSysData = IMG_NULL;\r
+               return eError;\r
+       }\r
+#endif \r
+\r
+#if defined(SYS_USING_INTERRUPTS)\r
+\r
+       eError = OSInstallMISR(gpsSysData);\r
+       if (eError != PVRSRV_OK)\r
+       {\r
+               PVR_DPF((PVR_DBG_ERROR,"SysFinalise: Failed to install MISR"));\r
+               SysDeinitialise(gpsSysData);\r
+               gpsSysData = IMG_NULL;\r
+               return eError;\r
+       }\r
+       SYS_SPECIFIC_DATA_SET(&gsSysSpecificData, SYS_SPECIFIC_DATA_ENABLE_MISR);\r
+\r
+       \r
+       eError = OSInstallDeviceLISR(gpsSysData, gsSGXDeviceMap.ui32IRQ, "SGX ISR", gpsSGXDevNode);\r
+       if (eError != PVRSRV_OK)\r
+       {\r
+               PVR_DPF((PVR_DBG_ERROR,"SysFinalise: Failed to install ISR"));\r
+               SysDeinitialise(gpsSysData);\r
+               gpsSysData = IMG_NULL;\r
+               return eError;\r
+       }\r
+       SYS_SPECIFIC_DATA_SET(&gsSysSpecificData, SYS_SPECIFIC_DATA_ENABLE_LISR);\r
+#endif \r
+\r
+       \r
+       gpsSysData->pszVersionString = SysCreateVersionString(gsSGXDeviceMap.sRegsCpuPBase);\r
+       if (!gpsSysData->pszVersionString)\r
+       {\r
+               PVR_DPF((PVR_DBG_ERROR,"SysFinalise: Failed to create a system version string"));\r
+       }\r
+       else\r
+       {\r
+               PVR_DPF((PVR_DBG_WARNING, "SysFinalise: Version string: %s", gpsSysData->pszVersionString));\r
+       }\r
+\r
+#if defined(SUPPORT_ACTIVE_POWER_MANAGEMENT)\r
+       \r
+       DisableSGXClocks(gpsSysData);\r
+#endif \r
+\r
+       gpsSysSpecificData->bSGXInitComplete = IMG_TRUE;\r
+\r
+       return eError;\r
+}\r
+\r
+\r
+PVRSRV_ERROR SysDeinitialise (SYS_DATA *psSysData)\r
+{\r
+       PVRSRV_ERROR eError;\r
+       \r
+#if defined(SYS_USING_INTERRUPTS)\r
+       if (SYS_SPECIFIC_DATA_TEST(gpsSysSpecificData, SYS_SPECIFIC_DATA_ENABLE_LISR))\r
+       {\r
+               eError = OSUninstallDeviceLISR(psSysData);\r
+               if (eError != PVRSRV_OK)\r
+               {\r
+                       PVR_DPF((PVR_DBG_ERROR,"SysDeinitialise: OSUninstallDeviceLISR failed"));\r
+                       return eError;\r
+               }\r
+       }\r
+\r
+       if (SYS_SPECIFIC_DATA_TEST(gpsSysSpecificData, SYS_SPECIFIC_DATA_ENABLE_MISR))\r
+       {\r
+               eError = OSUninstallMISR(psSysData);\r
+               if (eError != PVRSRV_OK)\r
+               {\r
+                       PVR_DPF((PVR_DBG_ERROR,"SysDeinitialise: OSUninstallMISR failed"));\r
+                       return eError;\r
+               }\r
+       }\r
+#else\r
+       PVR_UNREFERENCED_PARAMETER(psSysData);\r
+#endif \r
+\r
+       if (SYS_SPECIFIC_DATA_TEST(gpsSysSpecificData, SYS_SPECIFIC_DATA_ENABLE_INITDEV))\r
+       {\r
+#if defined(SUPPORT_ACTIVE_POWER_MANAGEMENT)\r
+               PVR_ASSERT(SYS_SPECIFIC_DATA_TEST(gpsSysSpecificData, SYS_SPECIFIC_DATA_ENABLE_SYSCLOCKS));\r
+               \r
+               eError = EnableSGXClocks(gpsSysData);\r
+               if (eError != PVRSRV_OK)\r
+               {\r
+                       PVR_DPF((PVR_DBG_ERROR,"SysDeinitialise: EnableSGXClocks failed"));\r
+                       return eError;\r
+               }\r
+#endif \r
+\r
+               \r
+               eError = PVRSRVDeinitialiseDevice (gui32SGXDeviceID);\r
+               if (eError != PVRSRV_OK)\r
+               {\r
+                       PVR_DPF((PVR_DBG_ERROR,"SysDeinitialise: failed to de-init the device"));\r
+                       return eError;\r
+               }\r
+       }\r
+       \r
+       \r
+\r
+       if (SYS_SPECIFIC_DATA_TEST(gpsSysSpecificData, SYS_SPECIFIC_DATA_ENABLE_SYSCLOCKS))\r
+       {\r
+               DisableSystemClocks(gpsSysData);\r
+       }\r
+\r
+       if (SYS_SPECIFIC_DATA_TEST(gpsSysSpecificData, SYS_SPECIFIC_DATA_ENABLE_ENVDATA))\r
+       {       \r
+               eError = OSDeInitEnvData(gpsSysData->pvEnvSpecificData);\r
+               if (eError != PVRSRV_OK)\r
+               {\r
+                       PVR_DPF((PVR_DBG_ERROR,"SysDeinitialise: failed to de-init env structure"));\r
+                       return eError;\r
+               }\r
+       }\r
+\r
+       if(gpsSysData->pvSOCTimerRegisterKM)\r
+       {\r
+               OSUnReservePhys(gpsSysData->pvSOCTimerRegisterKM,\r
+                                               4,\r
+                                               PVRSRV_HAP_MULTI_PROCESS|PVRSRV_HAP_UNCACHED,\r
+                                               gpsSysData->hSOCTimerRegisterOSMemHandle);\r
+       }\r
+\r
+       SysDeinitialiseCommon(gpsSysData);\r
+\r
+#if defined(NO_HARDWARE)\r
+       if(SYS_SPECIFIC_DATA_TEST(gpsSysSpecificData, SYS_SPECIFIC_DATA_ENABLE_LOCATEDEV))\r
+       {\r
+               \r
+               OSBaseFreeContigMemory(SYS_OMAP3430_SGX_REGS_SIZE, gsSGXRegsCPUVAddr, gsSGXDeviceMap.sRegsCpuPBase);\r
+       }\r
+#endif\r
+\r
+       \r
+       if(SYS_SPECIFIC_DATA_TEST(gpsSysSpecificData, SYS_SPECIFIC_DATA_ENABLE_PDUMPINIT))\r
+       {\r
+               PDUMPDEINIT();\r
+       }\r
+\r
+       gpsSysSpecificData->ui32SysSpecificData = 0;\r
+       gpsSysSpecificData->bSGXInitComplete = IMG_FALSE;\r
+\r
+       gpsSysData = IMG_NULL;\r
+\r
+       return PVRSRV_OK;\r
+}\r
+\r
+\r
+PVRSRV_ERROR SysGetDeviceMemoryMap(PVRSRV_DEVICE_TYPE  eDeviceType,\r
+                                                                  IMG_VOID                             **ppvDeviceMap)\r
+{\r
+\r
+       switch(eDeviceType)\r
+       {\r
+               case PVRSRV_DEVICE_TYPE_SGX:\r
+               {\r
+                       \r
+                       *ppvDeviceMap = (IMG_VOID*)&gsSGXDeviceMap;\r
+\r
+                       break;\r
+               }\r
+               default:\r
+               {\r
+                       PVR_DPF((PVR_DBG_ERROR,"SysGetDeviceMemoryMap: unsupported device type"));\r
+               }\r
+       }\r
+       return PVRSRV_OK;\r
+}\r
+\r
+\r
+IMG_DEV_PHYADDR SysCpuPAddrToDevPAddr(PVRSRV_DEVICE_TYPE       eDeviceType,\r
+                                                                         IMG_CPU_PHYADDR               CpuPAddr)\r
+{\r
+       IMG_DEV_PHYADDR DevPAddr;\r
+\r
+       PVR_UNREFERENCED_PARAMETER(eDeviceType);\r
+\r
+       \r
+       DevPAddr.uiAddr = CpuPAddr.uiAddr;\r
+       \r
+       return DevPAddr;\r
+}\r
+\r
+IMG_CPU_PHYADDR SysSysPAddrToCpuPAddr (IMG_SYS_PHYADDR sys_paddr)\r
+{\r
+       IMG_CPU_PHYADDR cpu_paddr;\r
+\r
+       \r
+       cpu_paddr.uiAddr = sys_paddr.uiAddr;\r
+       return cpu_paddr;\r
+}\r
+\r
+IMG_SYS_PHYADDR SysCpuPAddrToSysPAddr (IMG_CPU_PHYADDR cpu_paddr)\r
+{\r
+       IMG_SYS_PHYADDR sys_paddr;\r
+\r
+       \r
+       sys_paddr.uiAddr = cpu_paddr.uiAddr;\r
+       return sys_paddr;\r
+}\r
+\r
+\r
+IMG_DEV_PHYADDR SysSysPAddrToDevPAddr(PVRSRV_DEVICE_TYPE eDeviceType, IMG_SYS_PHYADDR SysPAddr)\r
+{\r
+       IMG_DEV_PHYADDR DevPAddr;\r
+\r
+       PVR_UNREFERENCED_PARAMETER(eDeviceType);\r
+\r
+       \r
+       DevPAddr.uiAddr = SysPAddr.uiAddr;\r
+\r
+       return DevPAddr;\r
+}\r
+\r
+\r
+IMG_SYS_PHYADDR SysDevPAddrToSysPAddr(PVRSRV_DEVICE_TYPE eDeviceType, IMG_DEV_PHYADDR DevPAddr)\r
+{\r
+       IMG_SYS_PHYADDR SysPAddr;\r
+\r
+       PVR_UNREFERENCED_PARAMETER(eDeviceType);\r
+\r
+       \r
+       SysPAddr.uiAddr = DevPAddr.uiAddr;\r
+\r
+       return SysPAddr;\r
+}\r
+\r
+\r
+IMG_VOID SysRegisterExternalDevice(PVRSRV_DEVICE_NODE *psDeviceNode)\r
+{\r
+       PVR_UNREFERENCED_PARAMETER(psDeviceNode);\r
+}\r
+\r
+\r
+IMG_VOID SysRemoveExternalDevice(PVRSRV_DEVICE_NODE *psDeviceNode)\r
+{\r
+       PVR_UNREFERENCED_PARAMETER(psDeviceNode);\r
+}\r
+\r
+\r
+IMG_UINT32 SysGetInterruptSource(SYS_DATA                      *psSysData,\r
+                                                                PVRSRV_DEVICE_NODE     *psDeviceNode)\r
+{\r
+       PVR_UNREFERENCED_PARAMETER(psSysData);\r
+#if defined(NO_HARDWARE)\r
+       \r
+       return 0xFFFFFFFF;\r
+#else\r
+       \r
+       return psDeviceNode->ui32SOCInterruptBit;\r
+#endif\r
+}\r
+\r
+\r
+IMG_VOID SysClearInterrupts(SYS_DATA* psSysData, IMG_UINT32 ui32ClearBits)\r
+{\r
+       PVR_UNREFERENCED_PARAMETER(psSysData);\r
+       PVR_UNREFERENCED_PARAMETER(ui32ClearBits);\r
+\r
+       \r
+       OSReadHWReg(((PVRSRV_SGXDEV_INFO *)gpsSGXDevNode->pvDevice)->pvRegsBaseKM,\r
+                                                                               EUR_CR_EVENT_HOST_CLEAR);\r
+}\r
+\r
+\r
+PVRSRV_ERROR SysSystemPrePowerState(PVR_POWER_STATE eNewPowerState)\r
+{\r
+       PVRSRV_ERROR eError = PVRSRV_OK;\r
+\r
+       if (eNewPowerState == PVRSRV_POWER_STATE_D3)\r
+       {\r
+               PVR_TRACE(("SysSystemPrePowerState: Entering state D3"));\r
+\r
+#if defined(SYS_USING_INTERRUPTS)\r
+               if (SYS_SPECIFIC_DATA_TEST(&gsSysSpecificData, SYS_SPECIFIC_DATA_ENABLE_LISR))\r
+               {\r
+#if defined(SYS_CUSTOM_POWERLOCK_WRAP)\r
+                       IMG_BOOL bWrapped = WrapSystemPowerChange(&gsSysSpecificData);\r
+#endif\r
+                       eError = OSUninstallDeviceLISR(gpsSysData);\r
+#if defined(SYS_CUSTOM_POWERLOCK_WRAP)\r
+                       if (bWrapped)\r
+                       {\r
+                               UnwrapSystemPowerChange(&gsSysSpecificData);\r
+                       }\r
+#endif\r
+                       if (eError != PVRSRV_OK)\r
+                       {\r
+                               PVR_DPF((PVR_DBG_ERROR,"SysSystemPrePowerState: OSUninstallDeviceLISR failed (%d)", eError));\r
+                               return eError;\r
+                       }\r
+                       SYS_SPECIFIC_DATA_SET(&gsSysSpecificData, SYS_SPECIFIC_DATA_PM_UNINSTALL_LISR);\r
+                       SYS_SPECIFIC_DATA_CLEAR(&gsSysSpecificData, SYS_SPECIFIC_DATA_ENABLE_LISR);\r
+               }\r
+#endif\r
+\r
+               if (SYS_SPECIFIC_DATA_TEST(&gsSysSpecificData, SYS_SPECIFIC_DATA_ENABLE_SYSCLOCKS))\r
+               {\r
+                       DisableSystemClocks(gpsSysData);\r
+\r
+                       SYS_SPECIFIC_DATA_SET(&gsSysSpecificData, SYS_SPECIFIC_DATA_PM_DISABLE_SYSCLOCKS);\r
+                       SYS_SPECIFIC_DATA_CLEAR(&gsSysSpecificData, SYS_SPECIFIC_DATA_ENABLE_SYSCLOCKS);\r
+               }\r
+       }\r
+\r
+       return eError;\r
+}\r
+\r
+\r
+PVRSRV_ERROR SysSystemPostPowerState(PVR_POWER_STATE eNewPowerState)\r
+{\r
+       PVRSRV_ERROR eError = PVRSRV_OK;\r
+\r
+       if (eNewPowerState == PVRSRV_POWER_STATE_D0)\r
+       {\r
+               PVR_TRACE(("SysSystemPostPowerState: Entering state D0"));\r
+\r
+               if (SYS_SPECIFIC_DATA_TEST(&gsSysSpecificData, SYS_SPECIFIC_DATA_PM_DISABLE_SYSCLOCKS))\r
+               {\r
+                       eError = EnableSystemClocks(gpsSysData);\r
+                       if (eError != PVRSRV_OK)\r
+                       {\r
+                               PVR_DPF((PVR_DBG_ERROR,"SysSystemPostPowerState: EnableSystemClocks failed (%d)", eError));\r
+                               return eError;\r
+                       }\r
+                       SYS_SPECIFIC_DATA_SET(&gsSysSpecificData, SYS_SPECIFIC_DATA_ENABLE_SYSCLOCKS);\r
+                       SYS_SPECIFIC_DATA_CLEAR(&gsSysSpecificData, SYS_SPECIFIC_DATA_PM_DISABLE_SYSCLOCKS);\r
+               }\r
+\r
+#if defined(SYS_USING_INTERRUPTS)\r
+               if (SYS_SPECIFIC_DATA_TEST(&gsSysSpecificData, SYS_SPECIFIC_DATA_PM_UNINSTALL_LISR))\r
+               {\r
+#if defined(SYS_CUSTOM_POWERLOCK_WRAP)\r
+                       IMG_BOOL bWrapped = WrapSystemPowerChange(&gsSysSpecificData);\r
+#endif\r
+\r
+                       eError = OSInstallDeviceLISR(gpsSysData, gsSGXDeviceMap.ui32IRQ, "SGX ISR", gpsSGXDevNode);\r
+#if defined(SYS_CUSTOM_POWERLOCK_WRAP)\r
+                       if (bWrapped)\r
+                       {\r
+                               UnwrapSystemPowerChange(&gsSysSpecificData);\r
+                       }\r
+#endif\r
+                       if (eError != PVRSRV_OK)\r
+                       {\r
+                               PVR_DPF((PVR_DBG_ERROR,"SysSystemPostPowerState: OSInstallDeviceLISR failed to install ISR (%d)", eError));\r
+                               return eError;\r
+                       }\r
+                       SYS_SPECIFIC_DATA_SET(&gsSysSpecificData, SYS_SPECIFIC_DATA_ENABLE_LISR);\r
+                       SYS_SPECIFIC_DATA_CLEAR(&gsSysSpecificData, SYS_SPECIFIC_DATA_PM_UNINSTALL_LISR);\r
+               }\r
+#endif\r
+       }\r
+       return eError;\r
+}\r
+\r
+\r
+PVRSRV_ERROR SysDevicePrePowerState(IMG_UINT32                 ui32DeviceIndex,\r
+                                                                       PVR_POWER_STATE         eNewPowerState,\r
+                                                                       PVR_POWER_STATE         eCurrentPowerState)\r
+{\r
+       PVR_UNREFERENCED_PARAMETER(eCurrentPowerState);\r
+\r
+       if (ui32DeviceIndex != gui32SGXDeviceID)\r
+       {\r
+               return PVRSRV_OK;\r
+       }\r
+\r
+#if defined(SUPPORT_ACTIVE_POWER_MANAGEMENT)\r
+       if (eNewPowerState == PVRSRV_POWER_STATE_D3)\r
+       {\r
+               PVR_DPF((PVR_DBG_MESSAGE, "SysDevicePrePowerState: SGX Entering state D3"));\r
+               DisableSGXClocks(gpsSysData);\r
+               PVRSRVSetDCState(DC_STATE_SUSPEND_COMMANDS);\r
+       }\r
+#else  \r
+       PVR_UNREFERENCED_PARAMETER(eNewPowerState );\r
+#endif \r
+       return PVRSRV_OK;\r
+}\r
+\r
+\r
+PVRSRV_ERROR SysDevicePostPowerState(IMG_UINT32                        ui32DeviceIndex,\r
+                                                                        PVR_POWER_STATE        eNewPowerState,\r
+                                                                        PVR_POWER_STATE        eCurrentPowerState)\r
+{\r
+       PVRSRV_ERROR eError = PVRSRV_OK;\r
+\r
+       PVR_UNREFERENCED_PARAMETER(eNewPowerState);\r
+\r
+       if (ui32DeviceIndex != gui32SGXDeviceID)\r
+       {\r
+               return eError;\r
+       }\r
+\r
+#if defined(SUPPORT_ACTIVE_POWER_MANAGEMENT)\r
+       if (eCurrentPowerState == PVRSRV_POWER_STATE_D3)\r
+       {\r
+               PVR_DPF((PVR_DBG_MESSAGE, "SysDevicePostPowerState: SGX Leaving state D3"));\r
+               PVRSRVSetDCState(DC_STATE_RESUME_COMMANDS);\r
+               eError = EnableSGXClocks(gpsSysData);\r
+       }\r
+#else  \r
+       PVR_UNREFERENCED_PARAMETER(eCurrentPowerState);\r
+#endif \r
+\r
+       return eError;\r
+}\r
+\r
+\r
+PVRSRV_ERROR SysOEMFunction (  IMG_UINT32      ui32ID,\r
+                                                               IMG_VOID        *pvIn,\r
+                                                               IMG_UINT32      ulInSize,\r
+                                                               IMG_VOID        *pvOut,\r
+                                                               IMG_UINT32      ulOutSize)\r
+{\r
+       PVR_UNREFERENCED_PARAMETER(ui32ID);\r
+       PVR_UNREFERENCED_PARAMETER(pvIn);\r
+       PVR_UNREFERENCED_PARAMETER(ulInSize);\r
+       PVR_UNREFERENCED_PARAMETER(pvOut);\r
+       PVR_UNREFERENCED_PARAMETER(ulOutSize);\r
+\r
+       if ((ui32ID == OEM_GET_EXT_FUNCS) &&\r
+               (ulOutSize == sizeof(PVRSRV_DC_OEM_JTABLE)))\r
+       {\r
+               \r
+               PVRSRV_DC_OEM_JTABLE *psOEMJTable = (PVRSRV_DC_OEM_JTABLE*) pvOut;\r
+               psOEMJTable->pfnOEMBridgeDispatch = &PVRSRV_BridgeDispatchKM;\r
+               return PVRSRV_OK;\r
+       }\r
+\r
+       return PVRSRV_ERROR_INVALID_PARAMS;\r
+}\r
diff --git a/services4/system/omap3630/sysconfig.h b/services4/system/omap3630/sysconfig.h
new file mode 100644 (file)
index 0000000..22852f5
--- /dev/null
@@ -0,0 +1,53 @@
+/**********************************************************************\r
+ *\r
+ * Copyright(c) 2008 Imagination Technologies Ltd. All rights reserved.\r
+ * \r
+ * This program is free software; you can redistribute it and/or modify it\r
+ * under the terms and conditions of the GNU General Public License,\r
+ * version 2, as published by the Free Software Foundation.\r
+ * \r
+ * This program is distributed in the hope it will be useful but, except \r
+ * as otherwise stated in writing, without any warranty; without even the \r
+ * implied warranty of merchantability or fitness for a particular purpose. \r
+ * See the GNU General Public License for more details.\r
+ * \r
+ * You should have received a copy of the GNU General Public License along with\r
+ * this program; if not, write to the Free Software Foundation, Inc.,\r
+ * 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA.\r
+ * \r
+ * The full GNU General Public License is included in this distribution in\r
+ * the file called "COPYING".\r
+ *\r
+ * Contact Information:\r
+ * Imagination Technologies Ltd. <gpl-support@imgtec.com>\r
+ * Home Park Estate, Kings Langley, Herts, WD4 8LZ, UK \r
+ *\r
+ ******************************************************************************/\r
+\r
+#if !defined(__SOCCONFIG_H__)\r
+#define __SOCCONFIG_H__\r
+\r
+#include "syscommon.h"\r
+\r
+#define VS_PRODUCT_NAME        "OMAP3630"\r
+\r
+#define SYS_SGX_CLOCK_SPEED    200000000\r
+#define SYS_SGX_HWRECOVERY_TIMEOUT_FREQ                (100)   \r
+#define SYS_SGX_PDS_TIMER_FREQ                 (1000)  \r
+#define SYS_SGX_ACTIVE_POWER_LATENCY_MS                (1)\r
+\r
+\r
+#define        SYS_OMAP3430_VDD2_OPP3_SGX_CLOCK_SPEED SYS_SGX_CLOCK_SPEED\r
+#define SYS_OMAP3430_VDD2_OPP2_SGX_CLOCK_SPEED (SYS_SGX_CLOCK_SPEED / 2)\r
+\r
+#define SYS_OMAP3430_SGX_REGS_SYS_PHYS_BASE  0x50000000\r
+#define SYS_OMAP3430_SGX_REGS_SIZE           0x10000\r
+\r
+#define SYS_OMAP3430_SGX_IRQ                            21\r
+\r
+#define SYS_OMAP3430_GP11TIMER_ENABLE_SYS_PHYS_BASE  0x48088024\r
+#define SYS_OMAP3430_GP11TIMER_REGS_SYS_PHYS_BASE       0x48088028\r
+#define SYS_OMAP3430_GP11TIMER_TSICR_SYS_PHYS_BASE      0x48088040\r
+\r
\r
+#endif \r
diff --git a/services4/system/omap3630/sysinfo.h b/services4/system/omap3630/sysinfo.h
new file mode 100644 (file)
index 0000000..88e3096
--- /dev/null
@@ -0,0 +1,98 @@
+/**********************************************************************\r
+ *\r
+ * Copyright(c) 2008 Imagination Technologies Ltd. All rights reserved.\r
+ * \r
+ * This program is free software; you can redistribute it and/or modify it\r
+ * under the terms and conditions of the GNU General Public License,\r
+ * version 2, as published by the Free Software Foundation.\r
+ * \r
+ * This program is distributed in the hope it will be useful but, except \r
+ * as otherwise stated in writing, without any warranty; without even the \r
+ * implied warranty of merchantability or fitness for a particular purpose. \r
+ * See the GNU General Public License for more details.\r
+ * \r
+ * You should have received a copy of the GNU General Public License along with\r
+ * this program; if not, write to the Free Software Foundation, Inc.,\r
+ * 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA.\r
+ * \r
+ * The full GNU General Public License is included in this distribution in\r
+ * the file called "COPYING".\r
+ *\r
+ * Contact Information:\r
+ * Imagination Technologies Ltd. <gpl-support@imgtec.com>\r
+ * Home Park Estate, Kings Langley, Herts, WD4 8LZ, UK \r
+ *\r
+ ******************************************************************************/\r
+\r
+#if !defined(__SYSINFO_H__)\r
+#define __SYSINFO_H__\r
+\r
+#define MAX_HW_TIME_US                         (500000)\r
+#define WAIT_TRY_COUNT                         (10000)\r
+\r
+typedef enum _SYS_DEVICE_TYPE_\r
+{\r
+       SYS_DEVICE_SGX                                          = 0,\r
+\r
+       SYS_DEVICE_FORCE_I16                            = 0x7fff\r
+\r
+} SYS_DEVICE_TYPE;\r
+\r
+#define SYS_DEVICE_COUNT 3 \r
+\r
+#define PRM_REG32(offset)        (offset)\r
+#define CM_REG32(offset)         (offset)\r
+\r
+#define CM_FCLKEN_SGX          CM_REG32(0xB00)\r
+#define                CM_FCLKEN_SGX_EN_3D                                     0x00000002\r
+\r
+#define CM_ICLKEN_SGX          CM_REG32(0xB10)\r
+#define                CM_ICLKEN_SGX_EN_SGX                            0x00000001\r
+\r
+#define CM_IDLEST_SGX          CM_REG32(0xB20)\r
+#define                CM_IDLEST_SGX_ST_SGX                            0x00000001\r
+\r
+#define CM_CLKSEL_SGX          CM_REG32(0xB40)\r
+#define                CM_CLKSEL_SGX_MASK                                      0x0000000f\r
+#define                CM_CLKSEL_SGX_L3DIV3                            0x00000000\r
+#define                CM_CLKSEL_SGX_L3DIV4                            0x00000001\r
+#define                CM_CLKSEL_SGX_L3DIV6                            0x00000002\r
+#define                CM_CLKSEL_SGX_96M                                       0x00000003\r
+\r
+#define CM_SLEEPDEP_SGX                CM_REG32(0xB44)\r
+#define CM_CLKSTCTRL_SGX       CM_REG32(0xB48)\r
+#define        CM_CLKSTCTRL_SGX_AUTOSTATE                      0x00008001\r
+\r
+#define CM_CLKSTST_SGX         CM_REG32(0xB4C)\r
+#define        CM_CLKSTST_SGX_STATUS_VALID                     0x00000001\r
+\r
+#define RM_RSTST_SGX           PRM_REG32(0xB58)\r
+#define        RM_RSTST_SGX_RST_MASK                           0x0000000F\r
+#define        RM_RSTST_SGX_COREDOMAINWKUP_RST         0x00000008\r
+#define        RM_RSTST_SGX_DOMAINWKUP_RST                     0x00000004\r
+#define        RM_RSTST_SGX_GLOBALWARM_RST                     0x00000002\r
+#define        RM_RSTST_SGX_GLOBALCOLD_RST                     0x00000001\r
+\r
+#define PM_WKDEP_SGX           PRM_REG32(0xBC8)\r
+#define        PM_WKDEP_SGX_EN_WAKEUP                          0x00000010\r
+#define        PM_WKDEP_SGX_EN_MPU                                     0x00000002\r
+#define        PM_WKDEP_SGX_EN_CORE                            0x00000001\r
+\r
+#define PM_PWSTCTRL_SGX                PRM_REG32(0xBE0)\r
+#define                PM_PWSTCTRL_SGX_POWERSTATE_MASK         0x00000003\r
+#define                        PM_PWSTCTRL_SGX_OFF                             0x00000000\r
+#define                        PM_PWSTCTRL_SGX_RETENTION               0x00000001\r
+#define                        PM_PWSTCTRL_SGX_ON                              0x00000003\r
+\r
+#define PM_PWSTST_SGX          PRM_REG32(0xBE4)\r
+#define                PM_PWSTST_SGX_INTRANSITION                      0x00100000\r
+#define                PM_PWSTST_SGX_CLKACTIVITY                       0x00080000\r
+#define                PM_PWSTST_SGX_POWERSTATE_MASK           0x00000003\r
+#define                        PM_PWSTST_SGX_OFF                               0x00000003\r
+#define                        PM_PWSTST_SGX_RETENTION                 0x00000001\r
+#define                        PM_PWSTST_SGX_ON                                0x00000000\r
+\r
+#define PM_PREPWSTST_SGX       PRM_REG32(0xBE8)\r
+\r
+\r
+#endif \r
diff --git a/services4/system/omap3630/syslocal.h b/services4/system/omap3630/syslocal.h
new file mode 100644 (file)
index 0000000..74de28f
--- /dev/null
@@ -0,0 +1,128 @@
+/**********************************************************************\r
+ *\r
+ * Copyright(c) 2008 Imagination Technologies Ltd. All rights reserved.\r
+ * \r
+ * This program is free software; you can redistribute it and/or modify it\r
+ * under the terms and conditions of the GNU General Public License,\r
+ * version 2, as published by the Free Software Foundation.\r
+ * \r
+ * This program is distributed in the hope it will be useful but, except \r
+ * as otherwise stated in writing, without any warranty; without even the \r
+ * implied warranty of merchantability or fitness for a particular purpose. \r
+ * See the GNU General Public License for more details.\r
+ * \r
+ * You should have received a copy of the GNU General Public License along with\r
+ * this program; if not, write to the Free Software Foundation, Inc.,\r
+ * 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA.\r
+ * \r
+ * The full GNU General Public License is included in this distribution in\r
+ * the file called "COPYING".\r
+ *\r
+ * Contact Information:\r
+ * Imagination Technologies Ltd. <gpl-support@imgtec.com>\r
+ * Home Park Estate, Kings Langley, Herts, WD4 8LZ, UK \r
+ *\r
+ ******************************************************************************/\r
+\r
+#if !defined(__SYSLOCAL_H__)\r
+#define __SYSLOCAL_H__\r
+\r
+#if defined(__linux__)\r
+\r
+#include <linux/version.h>\r
+#include <linux/clk.h>\r
+#include <linux/spinlock.h>\r
+#include <asm/atomic.h>\r
+\r
+#if (LINUX_VERSION_CODE > KERNEL_VERSION(2,6,26))\r
+#include <linux/semaphore.h>\r
+#include <linux/resource.h>\r
+#else \r
+#include <asm/semaphore.h>\r
+#if (LINUX_VERSION_CODE > KERNEL_VERSION(2,6,22))\r
+#include <asm/arch/resource.h>\r
+#endif \r
+#endif \r
+\r
+#endif \r
+\r
+#if defined (__cplusplus)\r
+extern "C" {\r
+#endif\r
+\r
\r
\r
+IMG_CHAR *SysCreateVersionString(IMG_CPU_PHYADDR sRegRegion);\r
+\r
+IMG_VOID DisableSystemClocks(SYS_DATA *psSysData);\r
+PVRSRV_ERROR EnableSystemClocks(SYS_DATA *psSysData);\r
+\r
+IMG_VOID DisableSGXClocks(SYS_DATA *psSysData);\r
+PVRSRV_ERROR EnableSGXClocks(SYS_DATA *psSysData);\r
+\r
+#define SYS_SPECIFIC_DATA_ENABLE_SYSCLOCKS     0x00000001\r
+#define SYS_SPECIFIC_DATA_ENABLE_LISR          0x00000002\r
+#define SYS_SPECIFIC_DATA_ENABLE_MISR          0x00000004\r
+#define SYS_SPECIFIC_DATA_ENABLE_ENVDATA       0x00000008\r
+#define SYS_SPECIFIC_DATA_ENABLE_LOCDEV                0x00000010\r
+#define SYS_SPECIFIC_DATA_ENABLE_REGDEV                0x00000020\r
+#define SYS_SPECIFIC_DATA_ENABLE_PDUMPINIT     0x00000040\r
+#define SYS_SPECIFIC_DATA_ENABLE_INITDEV       0x00000080\r
+#define SYS_SPECIFIC_DATA_ENABLE_LOCATEDEV     0x00000100\r
+\r
+#define        SYS_SPECIFIC_DATA_PM_UNINSTALL_LISR     0x00000200\r
+#define        SYS_SPECIFIC_DATA_PM_DISABLE_SYSCLOCKS  0x00000400\r
+\r
+#define        SYS_SPECIFIC_DATA_SET(psSysSpecData, flag) ((IMG_VOID)((psSysSpecData)->ui32SysSpecificData |= (flag)))\r
+\r
+#define        SYS_SPECIFIC_DATA_CLEAR(psSysSpecData, flag) ((IMG_VOID)((psSysSpecData)->ui32SysSpecificData &= ~(flag)))\r
+\r
+#define        SYS_SPECIFIC_DATA_TEST(psSysSpecData, flag) (((psSysSpecData)->ui32SysSpecificData & (flag)) != 0)\r
\r
+typedef struct _SYS_SPECIFIC_DATA_TAG_\r
+{\r
+       IMG_UINT32      ui32SysSpecificData;\r
+       PVRSRV_DEVICE_NODE *psSGXDevNode;\r
+       IMG_BOOL        bSGXInitComplete;\r
+#if !defined(__linux__)\r
+       IMG_BOOL        bSGXClocksEnabled;\r
+#endif\r
+       IMG_UINT32      ui32SrcClockDiv;\r
+#if defined(__linux__)\r
+       IMG_BOOL        bSysClocksOneTimeInit;\r
+       IMG_BOOL        bConstraintNotificationsEnabled;\r
+       atomic_t        sSGXClocksEnabled;\r
+       spinlock_t      sPowerLock;\r
+       atomic_t        sPowerLockCPU;\r
+       spinlock_t      sNotifyLock;\r
+       atomic_t        sNotifyLockCPU;\r
+       IMG_BOOL        bCallVDD2PostFunc;\r
+\r
+       struct clk      *psCORE_CK;\r
+       struct clk      *psSGX_FCK;\r
+       struct clk      *psSGX_ICK;\r
+       struct clk      *psMPU_CK;\r
+#if defined(DEBUG) || defined(TIMING)\r
+       struct clk      *psGPT11_FCK;\r
+       struct clk      *psGPT11_ICK;\r
+#endif\r
+#if (LINUX_VERSION_CODE > KERNEL_VERSION(2,6,22))              \r
+       struct constraint_handle *pVdd2Handle;\r
+#endif \r
+#endif \r
+} SYS_SPECIFIC_DATA;\r
+\r
+extern SYS_SPECIFIC_DATA *gpsSysSpecificData;\r
+\r
+#if defined(SYS_CUSTOM_POWERLOCK_WRAP)\r
+IMG_BOOL WrapSystemPowerChange(SYS_SPECIFIC_DATA *psSysSpecData);\r
+IMG_VOID UnwrapSystemPowerChange(SYS_SPECIFIC_DATA *psSysSpecData);\r
+#endif\r
+\r
+#if defined(__cplusplus)\r
+}\r
+#endif\r
+\r
+#endif \r
+\r
+\r
diff --git a/services4/system/omap3630/sysutils.c b/services4/system/omap3630/sysutils.c
new file mode 100644 (file)
index 0000000..cb3cee7
--- /dev/null
@@ -0,0 +1,30 @@
+/**********************************************************************\r
+ *\r
+ * Copyright(c) 2008 Imagination Technologies Ltd. All rights reserved.\r
+ * \r
+ * This program is free software; you can redistribute it and/or modify it\r
+ * under the terms and conditions of the GNU General Public License,\r
+ * version 2, as published by the Free Software Foundation.\r
+ * \r
+ * This program is distributed in the hope it will be useful but, except \r
+ * as otherwise stated in writing, without any warranty; without even the \r
+ * implied warranty of merchantability or fitness for a particular purpose. \r
+ * See the GNU General Public License for more details.\r
+ * \r
+ * You should have received a copy of the GNU General Public License along with\r
+ * this program; if not, write to the Free Software Foundation, Inc.,\r
+ * 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA.\r
+ * \r
+ * The full GNU General Public License is included in this distribution in\r
+ * the file called "COPYING".\r
+ *\r
+ * Contact Information:\r
+ * Imagination Technologies Ltd. <gpl-support@imgtec.com>\r
+ * Home Park Estate, Kings Langley, Herts, WD4 8LZ, UK \r
+ *\r
+ ******************************************************************************/\r
+\r
+#if defined(__linux__)\r
+#include "sysutils_linux.c"\r
+#endif\r
+\r
diff --git a/services4/system/omap3630/sysutils_linux.c b/services4/system/omap3630/sysutils_linux.c
new file mode 100644 (file)
index 0000000..159b4da
--- /dev/null
@@ -0,0 +1,810 @@
+/**********************************************************************\r
+ *\r
+ * Copyright(c) 2008 Imagination Technologies Ltd. All rights reserved.\r
+ *\r
+ * This program is free software; you can redistribute it and/or modify it\r
+ * under the terms and conditions of the GNU General Public License,\r
+ * version 2, as published by the Free Software Foundation.\r
+ *\r
+ * This program is distributed in the hope it will be useful but, except\r
+ * as otherwise stated in writing, without any warranty; without even the\r
+ * implied warranty of merchantability or fitness for a particular purpose.\r
+ * See the GNU General Public License for more details.\r
+ *\r
+ * You should have received a copy of the GNU General Public License along with\r
+ * this program; if not, write to the Free Software Foundation, Inc.,\r
+ * 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA.\r
+ *\r
+ * The full GNU General Public License is included in this distribution in\r
+ * the file called "COPYING".\r
+ *\r
+ * Contact Information:\r
+ * Imagination Technologies Ltd. <gpl-support@imgtec.com>\r
+ * Home Park Estate, Kings Langley, Herts, WD4 8LZ, UK\r
+ *\r
+ ******************************************************************************/\r
+\r
+#include <linux/version.h>\r
+#include <linux/clk.h>\r
+#include <linux/err.h>\r
+#include <linux/hardirq.h>\r
+#include <linux/spinlock.h>\r
+#include <asm/bug.h>\r
+#include <linux/platform_device.h>\r
+\r
+#if (LINUX_VERSION_CODE > KERNEL_VERSION(2,6,31))\r
+#include <linux/semaphore.h>\r
+#include <plat/resource.h>\r
+#include <plat/omap-pm.h>\r
+#else\r
+\r
+#if (LINUX_VERSION_CODE > KERNEL_VERSION(2,6,26))\r
+#include <linux/semaphore.h>\r
+#include <mach/resource.h>\r
+#include <mach/omap-pm.h>\r
+#else\r
+#include <asm/semaphore.h>\r
+#if (LINUX_VERSION_CODE > KERNEL_VERSION(2,6,22))\r
+#include <asm/arch/resource.h>\r
+#endif\r
+#endif\r
+#endif\r
+\r
+#if    (LINUX_VERSION_CODE >  KERNEL_VERSION(2,6,27)) && \\r
+       (LINUX_VERSION_CODE <= KERNEL_VERSION(2,6,29))\r
+#define CONSTRAINT_NOTIFICATIONS\r
+#endif\r
+#include "sgxdefs.h"\r
+#include "services_headers.h"\r
+#include "sysinfo.h"\r
+#include "sgxapi_km.h"\r
+#include "sysconfig.h"\r
+#include "sgxinfokm.h"\r
+#include "syslocal.h"\r
+void set_vdd2_constraint(void);\r
+void remove_vdd2_constraint(void);\r
+#define        ONE_MHZ 1000000\r
+#define        HZ_TO_MHZ(m) ((m) / ONE_MHZ)\r
+\r
+#if defined(SUPPORT_OMAP3630_SGXFCLK_96M)\r
+#define SGX_PARENT_CLOCK "cm_96m_fck"\r
+#elif defined(SUPPORT_OMAP3630_SGXFCLK_192M)\r
+#define SGX_PARENT_CLOCK "omap_192m_alwon_ck"\r
+#elif defined(SUPPORT_OMAP3630_SGXFCLK_corex2)\r
+#define SGX_PARENT_CLOCK "corex2_fck"\r
+#else\r
+#define SGX_PARENT_CLOCK "core_ck"\r
+#endif\r
+\r
+#if !defined(PDUMP) && !defined(NO_HARDWARE)\r
+struct sgx_platform_data {\r
+          void(*set_min_bus_tput)(struct device *dev, u8 agent_id, unsigned long r);\r
+};\r
+\r
+static struct sgx_platform_data pdata = {\r
+\r
+       //.set_min_bus_tput = &omap_pm_set_min_bus_tput,\r
+          .set_min_bus_tput = NULL,\r
+};\r
+\r
+static struct platform_device sgx_dev = {\r
+         .name = "sgx_dev",\r
+         .id = 1,\r
+         .dev.platform_data = &pdata,\r
+};\r
+void set_vdd2_constraint(void)\r
+{\r
+       if(pdata.set_min_bus_tput){\r
+               pdata.set_min_bus_tput(&(sgx_dev.dev), OCP_INITIATOR_AGENT,800000);\r
+       }\r
+}\r
+\r
+void remove_vdd2_constraint(void)\r
+{\r
+       if(pdata.set_min_bus_tput)\r
+               pdata.set_min_bus_tput(&(sgx_dev.dev), OCP_INITIATOR_AGENT, 0);\r
+\r
+}\r
+#endif\r
+#if !defined(PDUMP) && !defined(NO_HARDWARE)\r
+static IMG_BOOL PowerLockWrappedOnCPU(SYS_SPECIFIC_DATA *psSysSpecData)\r
+{\r
+       IMG_INT iCPU;\r
+       IMG_BOOL bLocked = IMG_FALSE;\r
+\r
+       if (!in_interrupt())\r
+       {\r
+               iCPU = get_cpu();\r
+               bLocked = (iCPU == atomic_read(&psSysSpecData->sPowerLockCPU));\r
+\r
+               put_cpu();\r
+       }\r
+\r
+       return bLocked;\r
+}\r
+\r
+static IMG_VOID PowerLockWrap(SYS_SPECIFIC_DATA *psSysSpecData)\r
+{\r
+       IMG_INT iCPU;\r
+\r
+       if (!in_interrupt())\r
+       {\r
+\r
+               iCPU = get_cpu();\r
+\r
+\r
+               PVR_ASSERT(iCPU != -1);\r
+\r
+               PVR_ASSERT(!PowerLockWrappedOnCPU(psSysSpecData));\r
+\r
+               spin_lock(&psSysSpecData->sPowerLock);\r
+\r
+               atomic_set(&psSysSpecData->sPowerLockCPU, iCPU);\r
+       }\r
+}\r
+\r
+static IMG_VOID PowerLockUnwrap(SYS_SPECIFIC_DATA *psSysSpecData)\r
+{\r
+       if (!in_interrupt())\r
+       {\r
+               PVR_ASSERT(PowerLockWrappedOnCPU(psSysSpecData));\r
+\r
+               atomic_set(&psSysSpecData->sPowerLockCPU, -1);\r
+\r
+               spin_unlock(&psSysSpecData->sPowerLock);\r
+\r
+               put_cpu();\r
+       }\r
+}\r
+\r
+PVRSRV_ERROR SysPowerLockWrap(SYS_DATA *psSysData)\r
+{\r
+       SYS_SPECIFIC_DATA *psSysSpecData = (SYS_SPECIFIC_DATA *) psSysData->pvSysSpecificData;\r
+\r
+       PowerLockWrap(psSysSpecData);\r
+\r
+       return PVRSRV_OK;\r
+}\r
+\r
+IMG_VOID SysPowerLockUnwrap(SYS_DATA *psSysData)\r
+{\r
+       SYS_SPECIFIC_DATA *psSysSpecData = (SYS_SPECIFIC_DATA *) psSysData->pvSysSpecificData;\r
+\r
+       PowerLockUnwrap(psSysSpecData);\r
+}\r
+#else\r
+static IMG_BOOL PowerLockWrappedOnCPU(SYS_SPECIFIC_DATA unref__ *psSysSpecData)\r
+{\r
+       return IMG_FALSE;\r
+}\r
+\r
+static IMG_VOID PowerLockWrap(SYS_SPECIFIC_DATA unref__ *psSysSpecData)\r
+{\r
+}\r
+\r
+static IMG_VOID PowerLockUnwrap(SYS_SPECIFIC_DATA unref__ *psSysSpecData)\r
+{\r
+}\r
+\r
+PVRSRV_ERROR SysPowerLockWrap(SYS_DATA unref__ *psSysData)\r
+{\r
+       return PVRSRV_OK;\r
+}\r
+\r
+IMG_VOID SysPowerLockUnwrap(SYS_DATA unref__ *psSysData)\r
+{\r
+}\r
+#endif\r
+\r
+IMG_BOOL WrapSystemPowerChange(SYS_SPECIFIC_DATA *psSysSpecData)\r
+{\r
+       IMG_BOOL bPowerLock = PowerLockWrappedOnCPU(psSysSpecData);\r
+\r
+       if (bPowerLock)\r
+       {\r
+               PowerLockUnwrap(psSysSpecData);\r
+       }\r
+\r
+       return bPowerLock;\r
+}\r
+\r
+IMG_VOID UnwrapSystemPowerChange(SYS_SPECIFIC_DATA *psSysSpecData)\r
+{\r
+       PowerLockWrap(psSysSpecData);\r
+}\r
+\r
+static inline IMG_UINT32 scale_by_rate(IMG_UINT32 val, IMG_UINT32 rate1, IMG_UINT32 rate2)\r
+{\r
+       if (rate1 >= rate2)\r
+       {\r
+               return val * (rate1 / rate2);\r
+       }\r
+\r
+       return val / (rate2 / rate1);\r
+}\r
+\r
+static inline IMG_UINT32 scale_prop_to_SGX_clock(IMG_UINT32 val, IMG_UINT32 rate)\r
+{\r
+       return scale_by_rate(val, rate, SYS_SGX_CLOCK_SPEED);\r
+}\r
+\r
+static inline IMG_UINT32 scale_inv_prop_to_SGX_clock(IMG_UINT32 val, IMG_UINT32 rate)\r
+{\r
+       return scale_by_rate(val, SYS_SGX_CLOCK_SPEED, rate);\r
+}\r
+\r
+IMG_VOID SysGetSGXTimingInformation(SGX_TIMING_INFORMATION *psTimingInfo)\r
+{\r
+       IMG_UINT32 rate;\r
+\r
+#if defined(NO_HARDWARE)\r
+       rate = SYS_SGX_CLOCK_SPEED;\r
+#else\r
+       PVR_ASSERT(atomic_read(&gpsSysSpecificData->sSGXClocksEnabled) != 0);\r
+\r
+       rate = clk_get_rate(gpsSysSpecificData->psSGX_FCK);\r
+       PVR_ASSERT(rate != 0);\r
+#endif\r
+       psTimingInfo->ui32CoreClockSpeed = rate;\r
+       psTimingInfo->ui32HWRecoveryFreq = scale_prop_to_SGX_clock(SYS_SGX_HWRECOVERY_TIMEOUT_FREQ, rate);\r
+       psTimingInfo->ui32uKernelFreq = scale_prop_to_SGX_clock(SYS_SGX_PDS_TIMER_FREQ, rate);\r
+       psTimingInfo->ui32ActivePowManLatencyms = SYS_SGX_ACTIVE_POWER_LATENCY_MS;\r
+}\r
+\r
+#if defined(CONSTRAINT_NOTIFICATIONS)\r
+#if !defined(SGX_DYNAMIC_TIMING_INFO)\r
+#error "SGX_DYNAMIC_TIMING_INFO must be defined for this platform"\r
+#endif\r
+\r
+#if !defined(PDUMP) && !defined(NO_HARDWARE)\r
+static inline IMG_BOOL ConstraintNotificationsEnabled(SYS_SPECIFIC_DATA *psSysSpecData)\r
+{\r
+       return (atomic_read(&psSysSpecData->sSGXClocksEnabled) != 0) && psSysSpecData->bSGXInitComplete && psSysSpecData->bConstraintNotificationsEnabled;\r
+\r
+}\r
+\r
+static IMG_BOOL NotifyLockedOnCPU(SYS_SPECIFIC_DATA *psSysSpecData)\r
+{\r
+       IMG_INT iCPU = get_cpu();\r
+       IMG_BOOL bLocked = (iCPU == atomic_read(&psSysSpecData->sNotifyLockCPU));\r
+\r
+       put_cpu();\r
+\r
+       return bLocked;\r
+}\r
+\r
+static IMG_VOID NotifyLock(SYS_SPECIFIC_DATA *psSysSpecData)\r
+{\r
+       IMG_INT iCPU;\r
+\r
+       BUG_ON(in_interrupt());\r
+\r
+\r
+       iCPU = get_cpu();\r
+\r
+\r
+       PVR_ASSERT(iCPU != -1);\r
+\r
+       PVR_ASSERT(!NotifyLockedOnCPU(psSysSpecData));\r
+\r
+       spin_lock(&psSysSpecData->sNotifyLock);\r
+\r
+       atomic_set(&psSysSpecData->sNotifyLockCPU, iCPU);\r
+\r
+}\r
+\r
+static IMG_VOID NotifyUnlock(SYS_SPECIFIC_DATA *psSysSpecData)\r
+{\r
+       PVR_ASSERT(NotifyLockedOnCPU(psSysSpecData));\r
+\r
+       atomic_set(&psSysSpecData->sNotifyLockCPU, -1);\r
+\r
+       spin_unlock(&psSysSpecData->sNotifyLock);\r
+\r
+       put_cpu();\r
+}\r
+\r
+static IMG_INT VDD2PostFunc(struct notifier_block *n, IMG_UINT32 event, IMG_VOID *ptr)\r
+{\r
+       PVR_UNREFERENCED_PARAMETER(n);\r
+       PVR_UNREFERENCED_PARAMETER(event);\r
+       PVR_UNREFERENCED_PARAMETER(ptr);\r
+\r
+       if (in_interrupt())\r
+       {\r
+               PVR_DPF((PVR_DBG_ERROR, "%s Called in interrupt context.  Ignoring.", __FUNCTION__));\r
+               return 0;\r
+       }\r
+\r
+\r
+       if (!NotifyLockedOnCPU(gpsSysSpecificData))\r
+       {\r
+               return 0;\r
+       }\r
+\r
+#if defined(DEBUG)\r
+       if (ConstraintNotificationsEnabled(gpsSysSpecificData))\r
+       {\r
+               IMG_UINT32 rate;\r
+\r
+               rate = clk_get_rate(gpsSysSpecificData->psSGX_FCK);\r
+\r
+               PVR_ASSERT(rate != 0);\r
+\r
+               PVR_DPF((PVR_DBG_MESSAGE, "%s: SGX clock rate: %dMHz", __FUNCTION__, HZ_TO_MHZ(rate)));\r
+       }\r
+#endif\r
+       if (gpsSysSpecificData->bCallVDD2PostFunc)\r
+       {\r
+               PVRSRVDevicePostClockSpeedChange(gpsSysSpecificData->psSGXDevNode->sDevId.ui32DeviceIndex, IMG_TRUE, IMG_NULL);\r
+\r
+               gpsSysSpecificData->bCallVDD2PostFunc = IMG_FALSE;\r
+       }\r
+       else\r
+       {\r
+               if (ConstraintNotificationsEnabled(gpsSysSpecificData))\r
+               {\r
+                       PVR_TRACE(("%s: Not calling PVR clock speed notification functions", __FUNCTION__));\r
+               }\r
+       }\r
+\r
+       NotifyUnlock(gpsSysSpecificData);\r
+\r
+       return 0;\r
+}\r
+\r
+static IMG_INT VDD2PreFunc(struct notifier_block *n, IMG_UINT32 event, IMG_VOID *ptr)\r
+{\r
+       PVR_UNREFERENCED_PARAMETER(n);\r
+       PVR_UNREFERENCED_PARAMETER(event);\r
+       PVR_UNREFERENCED_PARAMETER(ptr);\r
+\r
+       if (in_interrupt())\r
+       {\r
+               PVR_DPF((PVR_DBG_WARNING, "%s Called in interrupt context.  Ignoring.", __FUNCTION__));\r
+               return 0;\r
+       }\r
+\r
+       if (PowerLockWrappedOnCPU(gpsSysSpecificData))\r
+       {\r
+               PVR_DPF((PVR_DBG_WARNING, "%s Called from within a power transition.  Ignoring.", __FUNCTION__));\r
+               return 0;\r
+       }\r
+\r
+       NotifyLock(gpsSysSpecificData);\r
+\r
+       PVR_ASSERT(!gpsSysSpecificData->bCallVDD2PostFunc);\r
+\r
+       if (ConstraintNotificationsEnabled(gpsSysSpecificData))\r
+       {\r
+               PVRSRV_ERROR eError;\r
+\r
+               eError = PVRSRVDevicePreClockSpeedChange(gpsSysSpecificData->psSGXDevNode->sDevId.ui32DeviceIndex, IMG_TRUE, IMG_NULL);\r
+\r
+               gpsSysSpecificData->bCallVDD2PostFunc = (eError == PVRSRV_OK);\r
+\r
+       }\r
+\r
+       return 0;\r
+}\r
+static IMG_VOID RegisterConstraintNotifications(IMG_VOID)\r
+{\r
+       PVR_TRACE(("Registering constraint notifications"));\r
+\r
+       PVR_ASSERT(!gpsSysSpecificData->bConstraintNotificationsEnabled);\r
+\r
+\r
+       NotifyLock(gpsSysSpecificData);\r
+       gpsSysSpecificData->bConstraintNotificationsEnabled = IMG_TRUE;\r
+       NotifyUnlock(gpsSysSpecificData);\r
+\r
+       PVR_TRACE(("VDD2 constraint notifications registered"));\r
+}\r
+\r
+static IMG_VOID UnRegisterConstraintNotifications(IMG_VOID)\r
+{\r
+       PVR_TRACE(("Unregistering constraint notifications"));\r
+\r
+\r
+       NotifyLock(gpsSysSpecificData);\r
+       gpsSysSpecificData->bConstraintNotificationsEnabled = IMG_FALSE;\r
+       NotifyUnlock(gpsSysSpecificData);\r
+\r
+}\r
+#else\r
+static IMG_VOID RegisterConstraintNotifications(IMG_VOID)\r
+{\r
+}\r
+\r
+static IMG_VOID UnRegisterConstraintNotifications(IMG_VOID)\r
+{\r
+}\r
+#endif\r
+#endif\r
+\r
+PVRSRV_ERROR EnableSGXClocks(SYS_DATA *psSysData)\r
+{\r
+#if !defined(NO_HARDWARE)\r
+       SYS_SPECIFIC_DATA *psSysSpecData = (SYS_SPECIFIC_DATA *) psSysData->pvSysSpecificData;\r
+       long lNewRate;\r
+       IMG_INT res;\r
+\r
+\r
+       if (atomic_read(&psSysSpecData->sSGXClocksEnabled) != 0)\r
+       {\r
+               return PVRSRV_OK;\r
+       }\r
+\r
+       PVR_DPF((PVR_DBG_MESSAGE, "EnableSGXClocks: Enabling SGX Clocks"));\r
+\r
+#if defined(DEBUG)\r
+       {\r
+\r
+               IMG_UINT32 rate = clk_get_rate(psSysSpecData->psMPU_CK);\r
+               PVR_DPF((PVR_DBG_MESSAGE, "EnableSGXClocks: CPU Clock is %dMhz", HZ_TO_MHZ(rate)));\r
+       }\r
+#endif\r
+\r
+       res = clk_enable(psSysSpecData->psSGX_FCK);\r
+       if (res < 0)\r
+       {\r
+               PVR_DPF((PVR_DBG_ERROR, "EnableSGXClocks: Couldn't enable SGX functional clock (%d)", res));\r
+               return PVRSRV_ERROR_GENERIC;\r
+       }\r
+\r
+       res = clk_enable(psSysSpecData->psSGX_ICK);\r
+       if (res < 0)\r
+       {\r
+               PVR_DPF((PVR_DBG_ERROR, "EnableSGXClocks: Couldn't enable SGX interface clock (%d)", res));\r
+\r
+               clk_disable(psSysSpecData->psSGX_FCK);\r
+               return PVRSRV_ERROR_GENERIC;\r
+       }\r
+\r
+       lNewRate = clk_round_rate(psSysSpecData->psSGX_FCK, SYS_SGX_CLOCK_SPEED + ONE_MHZ);\r
+       //PVR_DPF((PVR_DBG_WARNING, "EnableSGXClocks: New SGX Func Clk = (%d)", lNewRate));\r
+       if (lNewRate <= 0)\r
+       {\r
+               PVR_DPF((PVR_DBG_ERROR, "EnableSGXClocks: Couldn't round SGX functional clock rate"));\r
+               return PVRSRV_ERROR_GENERIC;\r
+       }\r
+\r
+       res = clk_set_rate(psSysSpecData->psSGX_FCK, lNewRate);\r
+       if (res < 0)\r
+       {\r
+               PVR_DPF((PVR_DBG_ERROR, "EnableSGXClocks: Couldn't set SGX function clock rate (%d)", res));\r
+               return PVRSRV_ERROR_GENERIC;\r
+       }\r
+\r
+\r
+#if defined(DEBUG)\r
+       {\r
+\r
+               IMG_UINT32 rate = clk_get_rate(psSysSpecData->psSGX_FCK);\r
+               PVR_DPF((PVR_DBG_MESSAGE, "EnableSGXClocks: SGX Functional Clock is %dMhz", HZ_TO_MHZ(rate)));\r
+       }\r
+#endif\r
+\r
+       set_vdd2_constraint();\r
+\r
+       lNewRate  = clk_get_rate(psSysSpecData->psSGX_FCK);\r
+       atomic_set(&psSysSpecData->sSGXClocksEnabled, 1);\r
+       //PVR_DPF((PVR_DBG_WARNING, "EnableSGXClocks: Final SGX Func Clk = (%d)", lNewRate));\r
+\r
+#else\r
+       PVR_UNREFERENCED_PARAMETER(psSysData);\r
+#endif\r
+       return PVRSRV_OK;\r
+}\r
+\r
+\r
+IMG_VOID DisableSGXClocks(SYS_DATA *psSysData)\r
+{\r
+#if !defined(NO_HARDWARE)\r
+       SYS_SPECIFIC_DATA *psSysSpecData = (SYS_SPECIFIC_DATA *) psSysData->pvSysSpecificData;\r
+\r
+       if (atomic_read(&psSysSpecData->sSGXClocksEnabled) == 0)\r
+       {\r
+               return;\r
+       }\r
+\r
+       PVR_DPF((PVR_DBG_MESSAGE, "DisableSGXClocks: Disabling SGX Clocks"));\r
+\r
+       if (psSysSpecData->psSGX_ICK)\r
+       {\r
+               clk_disable(psSysSpecData->psSGX_ICK);\r
+       }\r
+\r
+       if (psSysSpecData->psSGX_FCK)\r
+       {\r
+               clk_disable(psSysSpecData->psSGX_FCK);\r
+       }\r
+\r
+       remove_vdd2_constraint();\r
+\r
+       atomic_set(&psSysSpecData->sSGXClocksEnabled, 0);\r
+\r
+#else\r
+       PVR_UNREFERENCED_PARAMETER(psSysData);\r
+#endif\r
+}\r
+\r
+PVRSRV_ERROR EnableSystemClocks(SYS_DATA *psSysData)\r
+{\r
+       SYS_SPECIFIC_DATA *psSysSpecData = (SYS_SPECIFIC_DATA *) psSysData->pvSysSpecificData;\r
+       struct clk *psCLK;\r
+       IMG_INT res;\r
+       PVRSRV_ERROR eError;\r
+       IMG_BOOL bPowerLock;\r
+\r
+#if defined(DEBUG) || defined(TIMING)\r
+       IMG_INT rate;\r
+       struct clk *sys_ck;\r
+       IMG_CPU_PHYADDR     TimerRegPhysBase;\r
+       IMG_HANDLE hTimerEnable;\r
+       IMG_UINT32 *pui32TimerEnable;\r
+\r
+#endif\r
+\r
+       PVR_TRACE(("EnableSystemClocks: Enabling System Clocks"));\r
+\r
+       if (!psSysSpecData->bSysClocksOneTimeInit)\r
+       {\r
+               bPowerLock = IMG_FALSE;\r
+\r
+               spin_lock_init(&psSysSpecData->sPowerLock);\r
+               atomic_set(&psSysSpecData->sPowerLockCPU, -1);\r
+               spin_lock_init(&psSysSpecData->sNotifyLock);\r
+               atomic_set(&psSysSpecData->sNotifyLockCPU, -1);\r
+\r
+               atomic_set(&psSysSpecData->sSGXClocksEnabled, 0);\r
+\r
+               psCLK = clk_get(NULL, SGX_PARENT_CLOCK);\r
+               if (IS_ERR(psCLK))\r
+               {\r
+                       PVR_DPF((PVR_DBG_ERROR, "EnableSsystemClocks: Couldn't get Core Clock"));\r
+                       goto ExitError;\r
+               }\r
+               psSysSpecData->psCORE_CK = psCLK;\r
+\r
+               psCLK = clk_get(NULL, "sgx_fck");\r
+               if (IS_ERR(psCLK))\r
+               {\r
+                       PVR_DPF((PVR_DBG_ERROR, "EnableSsystemClocks: Couldn't get SGX Functional Clock"));\r
+                       goto ExitError;\r
+               }\r
+               psSysSpecData->psSGX_FCK = psCLK;\r
+\r
+               psCLK = clk_get(NULL, "sgx_ick");\r
+               if (IS_ERR(psCLK))\r
+               {\r
+                       PVR_DPF((PVR_DBG_ERROR, "EnableSystemClocks: Couldn't get SGX Interface Clock"));\r
+                       goto ExitError;\r
+               }\r
+               psSysSpecData->psSGX_ICK = psCLK;\r
+\r
+#if defined(DEBUG)\r
+               psCLK = clk_get(NULL, "mpu_ck");\r
+               if (IS_ERR(psCLK))\r
+               {\r
+                       PVR_DPF((PVR_DBG_ERROR, "EnableSystemClocks: Couldn't get MPU Clock"));\r
+                       goto ExitError;\r
+               }\r
+               psSysSpecData->psMPU_CK = psCLK;\r
+#endif\r
+               res = clk_set_parent(psSysSpecData->psSGX_FCK, psSysSpecData->psCORE_CK);\r
+               if (res < 0)\r
+               {\r
+                       PVR_DPF((PVR_DBG_ERROR, "EnableSystemClocks: Couldn't set SGX parent clock (%d)", res));\r
+                       goto ExitError;\r
+               }\r
+\r
+               psSysSpecData->bSysClocksOneTimeInit = IMG_TRUE;\r
+       }\r
+       else\r
+       {\r
+\r
+               bPowerLock = PowerLockWrappedOnCPU(psSysSpecData);\r
+               if (bPowerLock)\r
+               {\r
+                       PowerLockUnwrap(psSysSpecData);\r
+               }\r
+       }\r
+\r
+#if defined(CONSTRAINT_NOTIFICATIONS)\r
+\r
+       RegisterConstraintNotifications();\r
+#endif\r
+\r
+#if defined(DEBUG) || defined(TIMING)\r
+\r
+       psCLK = clk_get(NULL, "gpt11_fck");\r
+       if (IS_ERR(psCLK))\r
+       {\r
+               PVR_DPF((PVR_DBG_ERROR, "EnableSystemClocks: Couldn't get GPTIMER11 functional clock"));\r
+               goto ExitUnRegisterConstraintNotifications;\r
+       }\r
+       psSysSpecData->psGPT11_FCK = psCLK;\r
+\r
+       psCLK = clk_get(NULL, "gpt11_ick");\r
+       if (IS_ERR(psCLK))\r
+       {\r
+               PVR_DPF((PVR_DBG_ERROR, "EnableSystemClocks: Couldn't get GPTIMER11 interface clock"));\r
+               goto ExitUnRegisterConstraintNotifications;\r
+       }\r
+       psSysSpecData->psGPT11_ICK = psCLK;\r
+\r
+       sys_ck = clk_get(NULL, "sys_ck");\r
+       if (IS_ERR(sys_ck))\r
+       {\r
+               PVR_DPF((PVR_DBG_ERROR, "EnableSystemClocks: Couldn't get System clock"));\r
+               goto ExitUnRegisterConstraintNotifications;\r
+       }\r
+\r
+       if(clk_get_parent(psSysSpecData->psGPT11_FCK) != sys_ck)\r
+       {\r
+               PVR_TRACE(("Setting GPTIMER11 parent to System Clock"));\r
+               res = clk_set_parent(psSysSpecData->psGPT11_FCK, sys_ck);\r
+               if (res < 0)\r
+               {\r
+                       PVR_DPF((PVR_DBG_ERROR, "EnableSystemClocks: Couldn't set GPTIMER11 parent clock (%d)", res));\r
+               goto ExitUnRegisterConstraintNotifications;\r
+               }\r
+       }\r
+\r
+       rate = clk_get_rate(psSysSpecData->psGPT11_FCK);\r
+       PVR_TRACE(("GPTIMER11 clock is %dMHz", HZ_TO_MHZ(rate)));\r
+\r
+       res = clk_enable(psSysSpecData->psGPT11_FCK);\r
+       if (res < 0)\r
+       {\r
+               PVR_DPF((PVR_DBG_ERROR, "EnableSystemClocks: Couldn't enable GPTIMER11 functional clock (%d)", res));\r
+               goto ExitUnRegisterConstraintNotifications;\r
+       }\r
+\r
+       res = clk_enable(psSysSpecData->psGPT11_ICK);\r
+       if (res < 0)\r
+       {\r
+               PVR_DPF((PVR_DBG_ERROR, "EnableSystemClocks: Couldn't enable GPTIMER11 interface clock (%d)", res));\r
+               goto ExitDisableGPT11FCK;\r
+       }\r
+\r
+\r
+       TimerRegPhysBase.uiAddr = SYS_OMAP3430_GP11TIMER_TSICR_SYS_PHYS_BASE;\r
+       pui32TimerEnable = OSMapPhysToLin(TimerRegPhysBase,\r
+                  4,\r
+                  PVRSRV_HAP_KERNEL_ONLY|PVRSRV_HAP_UNCACHED,\r
+                  &hTimerEnable);\r
+\r
+       if (pui32TimerEnable == IMG_NULL)\r
+       {\r
+               PVR_DPF((PVR_DBG_ERROR, "EnableSystemClocks: OSMapPhysToLin failed"));\r
+               goto ExitDisableGPT11ICK;\r
+       }\r
+\r
+       rate = *pui32TimerEnable;\r
+       if(!(rate & 4))\r
+       {\r
+               PVR_TRACE(("Setting GPTIMER11 mode to posted (currently is non-posted)"));\r
+\r
+\r
+               *pui32TimerEnable = rate | 4;\r
+       }\r
+\r
+       OSUnMapPhysToLin(pui32TimerEnable,\r
+                   4,\r
+                   PVRSRV_HAP_KERNEL_ONLY|PVRSRV_HAP_UNCACHED,\r
+                   hTimerEnable);\r
+\r
+\r
+       TimerRegPhysBase.uiAddr = SYS_OMAP3430_GP11TIMER_ENABLE_SYS_PHYS_BASE;\r
+       pui32TimerEnable = OSMapPhysToLin(TimerRegPhysBase,\r
+                  4,\r
+                  PVRSRV_HAP_KERNEL_ONLY|PVRSRV_HAP_UNCACHED,\r
+                  &hTimerEnable);\r
+\r
+       if (pui32TimerEnable == IMG_NULL)\r
+       {\r
+               PVR_DPF((PVR_DBG_ERROR, "EnableSystemClocks: OSMapPhysToLin failed"));\r
+               goto ExitDisableGPT11ICK;\r
+       }\r
+\r
+\r
+       *pui32TimerEnable = 3;\r
+\r
+       OSUnMapPhysToLin(pui32TimerEnable,\r
+                   4,\r
+                   PVRSRV_HAP_KERNEL_ONLY|PVRSRV_HAP_UNCACHED,\r
+                   hTimerEnable);\r
+\r
+#endif\r
+\r
+       eError = PVRSRV_OK;\r
+       goto Exit;\r
+\r
+#if defined(DEBUG) || defined(TIMING)\r
+ExitDisableGPT11ICK:\r
+       clk_disable(psSysSpecData->psGPT11_ICK);\r
+ExitDisableGPT11FCK:\r
+       clk_disable(psSysSpecData->psGPT11_FCK);\r
+ExitUnRegisterConstraintNotifications:\r
+#endif\r
+#if defined(CONSTRAINT_NOTIFICATIONS)\r
+       UnRegisterConstraintNotifications();\r
+\r
+#endif\r
+ExitError:\r
+       eError = PVRSRV_ERROR_GENERIC;\r
+Exit:\r
+       if (bPowerLock)\r
+       {\r
+               PowerLockWrap(psSysSpecData);\r
+       }\r
+\r
+#if !defined(SUPPORT_ACTIVE_POWER_MANAGEMENT)\r
+       if (eError == PVRSRV_OK)\r
+       {\r
+\r
+               eError = EnableSGXClocks(psSysData);\r
+       }\r
+#endif\r
+       return eError;\r
+}\r
+\r
+IMG_VOID DisableSystemClocks(SYS_DATA *psSysData)\r
+{\r
+       SYS_SPECIFIC_DATA *psSysSpecData = (SYS_SPECIFIC_DATA *) psSysData->pvSysSpecificData;\r
+       IMG_BOOL bPowerLock;\r
+#if defined(DEBUG) || defined(TIMING)\r
+       IMG_CPU_PHYADDR TimerRegPhysBase;\r
+       IMG_HANDLE hTimerDisable;\r
+       IMG_UINT32 *pui32TimerDisable;\r
+#endif\r
+\r
+       PVR_TRACE(("DisableSystemClocks: Disabling System Clocks"));\r
+\r
+       DisableSGXClocks(psSysData);\r
+\r
+       bPowerLock = PowerLockWrappedOnCPU(psSysSpecData);\r
+       if (bPowerLock)\r
+       {\r
+\r
+               PowerLockUnwrap(psSysSpecData);\r
+       }\r
+\r
+#if defined(CONSTRAINT_NOTIFICATIONS)\r
+       UnRegisterConstraintNotifications();\r
+#endif\r
+\r
+#if defined(DEBUG) || defined(TIMING)\r
+\r
+       TimerRegPhysBase.uiAddr = SYS_OMAP3430_GP11TIMER_ENABLE_SYS_PHYS_BASE;\r
+       pui32TimerDisable = OSMapPhysToLin(TimerRegPhysBase,\r
+                               4,\r
+                               PVRSRV_HAP_KERNEL_ONLY|PVRSRV_HAP_UNCACHED,\r
+                               &hTimerDisable);\r
+\r
+       if (pui32TimerDisable == IMG_NULL)\r
+       {\r
+               PVR_DPF((PVR_DBG_ERROR, "DisableSystemClocks: OSMapPhysToLin failed"));\r
+       }\r
+       else\r
+       {\r
+               *pui32TimerDisable = 0;\r
+\r
+               OSUnMapPhysToLin(pui32TimerDisable,\r
+                               4,\r
+                               PVRSRV_HAP_KERNEL_ONLY|PVRSRV_HAP_UNCACHED,\r
+                               hTimerDisable);\r
+       }\r
+\r
+       clk_disable(psSysSpecData->psGPT11_ICK);\r
+\r
+       clk_disable(psSysSpecData->psGPT11_FCK);\r
+\r
+#endif\r
+       if (bPowerLock)\r
+       {\r
+               PowerLockWrap(psSysSpecData);\r
+       }\r
+}\r
diff --git a/services4/system/ti8168/oemfuncs.h b/services4/system/ti8168/oemfuncs.h
new file mode 100644 (file)
index 0000000..1131534
--- /dev/null
@@ -0,0 +1,56 @@
+/**********************************************************************\r
+ *\r
+ * Copyright(c) 2008 Imagination Technologies Ltd. All rights reserved.\r
+ * \r
+ * This program is free software; you can redistribute it and/or modify it\r
+ * under the terms and conditions of the GNU General Public License,\r
+ * version 2, as published by the Free Software Foundation.\r
+ * \r
+ * This program is distributed in the hope it will be useful but, except \r
+ * as otherwise stated in writing, without any warranty; without even the \r
+ * implied warranty of merchantability or fitness for a particular purpose. \r
+ * See the GNU General Public License for more details.\r
+ * \r
+ * You should have received a copy of the GNU General Public License along with\r
+ * this program; if not, write to the Free Software Foundation, Inc.,\r
+ * 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA.\r
+ * \r
+ * The full GNU General Public License is included in this distribution in\r
+ * the file called "COPYING".\r
+ *\r
+ * Contact Information:\r
+ * Imagination Technologies Ltd. <gpl-support@imgtec.com>\r
+ * Home Park Estate, Kings Langley, Herts, WD4 8LZ, UK \r
+ *\r
+ ******************************************************************************/\r
+\r
+#if !defined(__OEMFUNCS_H__)\r
+#define __OEMFUNCS_H__\r
+\r
+#if defined (__cplusplus)\r
+extern "C" {\r
+#endif\r
+\r
+typedef IMG_UINT32   (*PFN_SRV_BRIDGEDISPATCH)( IMG_UINT32  Ioctl,\r
+                                                                                               IMG_BYTE   *pInBuf,\r
+                                                                                               IMG_UINT32  InBufLen, \r
+                                                                                           IMG_BYTE   *pOutBuf,\r
+                                                                                               IMG_UINT32  OutBufLen,\r
+                                                                                               IMG_UINT32 *pdwBytesTransferred);\r
+typedef struct PVRSRV_DC_OEM_JTABLE_TAG\r
+{\r
+       PFN_SRV_BRIDGEDISPATCH                  pfnOEMBridgeDispatch;\r
+       IMG_PVOID                                               pvDummy1;\r
+       IMG_PVOID                                               pvDummy2;\r
+       IMG_PVOID                                               pvDummy3;\r
+\r
+} PVRSRV_DC_OEM_JTABLE;\r
+\r
+#define OEM_GET_EXT_FUNCS                      (1<<1)\r
+\r
+#if defined(__cplusplus)\r
+}\r
+#endif\r
+\r
+#endif \r
+\r
diff --git a/services4/system/ti8168/sysconfig.c b/services4/system/ti8168/sysconfig.c
new file mode 100644 (file)
index 0000000..38f3e4b
--- /dev/null
@@ -0,0 +1,807 @@
+/**********************************************************************\r
+ *\r
+ * Copyright(c) 2008 Imagination Technologies Ltd. All rights reserved.\r
+ * \r
+ * This program is free software; you can redistribute it and/or modify it\r
+ * under the terms and conditions of the GNU General Public License,\r
+ * version 2, as published by the Free Software Foundation.\r
+ * \r
+ * This program is distributed in the hope it will be useful but, except \r
+ * as otherwise stated in writing, without any warranty; without even the \r
+ * implied warranty of merchantability or fitness for a particular purpose. \r
+ * See the GNU General Public License for more details.\r
+ * \r
+ * You should have received a copy of the GNU General Public License along with\r
+ * this program; if not, write to the Free Software Foundation, Inc.,\r
+ * 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA.\r
+ * \r
+ * The full GNU General Public License is included in this distribution in\r
+ * the file called "COPYING".\r
+ *\r
+ * Contact Information:\r
+ * Imagination Technologies Ltd. <gpl-support@imgtec.com>\r
+ * Home Park Estate, Kings Langley, Herts, WD4 8LZ, UK \r
+ *\r
+ ******************************************************************************/\r
+\r
+#include "services_headers.h"\r
+#include "kerneldisplay.h"\r
+#include "oemfuncs.h"\r
+#include "sgxinfo.h"\r
+#include "pdump_km.h"\r
+#include "sgxinfokm.h"\r
+#include "syslocal.h"\r
+#include "sysconfig.h"\r
+\r
+SYS_DATA* gpsSysData = (SYS_DATA*)IMG_NULL;\r
+SYS_DATA  gsSysData;\r
+\r
+static SYS_SPECIFIC_DATA gsSysSpecificData;\r
+SYS_SPECIFIC_DATA *gpsSysSpecificData;\r
+\r
+static IMG_UINT32      gui32SGXDeviceID;\r
+static SGX_DEVICE_MAP  gsSGXDeviceMap;\r
+static PVRSRV_DEVICE_NODE *gpsSGXDevNode;\r
+\r
+#define DEVICE_SGX_INTERRUPT (1 << 0)\r
+\r
+#if defined(NO_HARDWARE)\r
+static IMG_CPU_VIRTADDR gsSGXRegsCPUVAddr;\r
+#endif\r
+\r
+IMG_UINT32 PVRSRV_BridgeDispatchKM(IMG_UINT32  Ioctl,\r
+                                                                  IMG_BYTE             *pInBuf,\r
+                                                                  IMG_UINT32   InBufLen,\r
+                                                                  IMG_BYTE             *pOutBuf,\r
+                                                                  IMG_UINT32   OutBufLen,\r
+                                                                  IMG_UINT32   *pdwBytesTransferred);\r
+\r
+static PVRSRV_ERROR SysLocateDevices(SYS_DATA *psSysData)\r
+{\r
+#if defined(NO_HARDWARE)\r
+       PVRSRV_ERROR eError;\r
+       IMG_CPU_PHYADDR sCpuPAddr;\r
+#endif\r
+\r
+       PVR_UNREFERENCED_PARAMETER(psSysData);\r
+\r
+       \r
+       gsSGXDeviceMap.ui32Flags = 0x0;\r
+       \r
+#if defined(NO_HARDWARE)\r
+       \r
+       \r
+       eError = OSBaseAllocContigMemory(SYS_OMAP3430_SGX_REGS_SIZE, \r
+                                                                        &gsSGXRegsCPUVAddr,\r
+                                                                        &sCpuPAddr);\r
+       if(eError != PVRSRV_OK)\r
+       {\r
+               return eError;\r
+       }\r
+       gsSGXDeviceMap.sRegsCpuPBase = sCpuPAddr;\r
+       gsSGXDeviceMap.sRegsSysPBase = SysCpuPAddrToSysPAddr(gsSGXDeviceMap.sRegsCpuPBase);\r
+       gsSGXDeviceMap.ui32RegsSize = SYS_OMAP3430_SGX_REGS_SIZE;\r
+#if defined(__linux__)\r
+       \r
+       gsSGXDeviceMap.pvRegsCpuVBase = gsSGXRegsCPUVAddr;\r
+#else\r
+       \r
+       gsSGXDeviceMap.pvRegsCpuVBase = IMG_NULL;\r
+#endif\r
+\r
+       OSMemSet(gsSGXRegsCPUVAddr, 0, SYS_OMAP3430_SGX_REGS_SIZE);\r
+\r
+       \r
+\r
+\r
+       gsSGXDeviceMap.ui32IRQ = 0;\r
+\r
+#else \r
+\r
+       gsSGXDeviceMap.sRegsSysPBase.uiAddr = SYS_OMAP3430_SGX_REGS_SYS_PHYS_BASE;\r
+       gsSGXDeviceMap.sRegsCpuPBase = SysSysPAddrToCpuPAddr(gsSGXDeviceMap.sRegsSysPBase);\r
+       gsSGXDeviceMap.ui32RegsSize = SYS_OMAP3430_SGX_REGS_SIZE;\r
+\r
+       gsSGXDeviceMap.ui32IRQ = SYS_OMAP3430_SGX_IRQ;\r
+\r
+#endif \r
+\r
+\r
+       \r
+\r
+\r
+       return PVRSRV_OK;\r
+}\r
+\r
+\r
+IMG_CHAR *SysCreateVersionString(IMG_CPU_PHYADDR sRegRegion)\r
+{\r
+       static IMG_CHAR aszVersionString[100];\r
+       SYS_DATA        *psSysData;\r
+       IMG_UINT32      ui32SGXRevision;\r
+       IMG_INT32       i32Count;\r
+#if !defined(NO_HARDWARE)\r
+       IMG_VOID        *pvRegsLinAddr;\r
+\r
+       pvRegsLinAddr = OSMapPhysToLin(sRegRegion,\r
+                                                                  SYS_OMAP3430_SGX_REGS_SIZE,\r
+                                                                  PVRSRV_HAP_UNCACHED|PVRSRV_HAP_KERNEL_ONLY,\r
+                                                                  IMG_NULL);\r
+       if(!pvRegsLinAddr)\r
+       {\r
+               return IMG_NULL;\r
+       }\r
+\r
+       ui32SGXRevision = OSReadHWReg((IMG_PVOID)((IMG_PBYTE)pvRegsLinAddr),\r
+                                                                 EUR_CR_CORE_REVISION);\r
+#else\r
+       ui32SGXRevision = 0;\r
+#endif\r
+\r
+       if (SysAcquireData(&psSysData) != PVRSRV_OK)\r
+       {\r
+               return IMG_NULL;\r
+       }\r
+\r
+       i32Count = OSSNPrintf(aszVersionString, 100,\r
+                                                 "SGX revision = %u.%u.%u",\r
+                                                 (IMG_UINT)((ui32SGXRevision & EUR_CR_CORE_REVISION_MAJOR_MASK)\r
+                                                       >> EUR_CR_CORE_REVISION_MAJOR_SHIFT),\r
+                                                 (IMG_UINT)((ui32SGXRevision & EUR_CR_CORE_REVISION_MINOR_MASK)\r
+                                                       >> EUR_CR_CORE_REVISION_MINOR_SHIFT),\r
+                                                 (IMG_UINT)((ui32SGXRevision & EUR_CR_CORE_REVISION_MAINTENANCE_MASK)\r
+                                                       >> EUR_CR_CORE_REVISION_MAINTENANCE_SHIFT)\r
+                                                );\r
+\r
+#if !defined(NO_HARDWARE)\r
+       OSUnMapPhysToLin(pvRegsLinAddr,\r
+                                        SYS_OMAP3430_SGX_REGS_SIZE,\r
+                                        PVRSRV_HAP_UNCACHED|PVRSRV_HAP_KERNEL_ONLY,\r
+                                        IMG_NULL);\r
+#endif\r
+\r
+       if(i32Count == -1)\r
+       {\r
+               return IMG_NULL;\r
+       }\r
+\r
+       return aszVersionString;\r
+}\r
+\r
+\r
+PVRSRV_ERROR SysInitialise(IMG_VOID)\r
+{\r
+       IMG_UINT32                      i;\r
+       PVRSRV_ERROR            eError;\r
+       PVRSRV_DEVICE_NODE      *psDeviceNode;\r
+       IMG_CPU_PHYADDR         TimerRegPhysBase;\r
+\r
+#if defined(DEBUG)\r
+       PVR_DPF((PVR_DBG_WARNING,"SysInitialise: Entering..."));\r
+#endif\r
+\r
+#if !defined(SGX_DYNAMIC_TIMING_INFO)\r
+       SGX_TIMING_INFORMATION* psTimingInfo;\r
+#endif\r
+       gpsSysData = &gsSysData;\r
+       OSMemSet(gpsSysData, 0, sizeof(SYS_DATA));\r
+\r
+       gpsSysSpecificData =  &gsSysSpecificData;\r
+       OSMemSet(gpsSysSpecificData, 0, sizeof(SYS_SPECIFIC_DATA));\r
+\r
+       gpsSysData->pvSysSpecificData = gpsSysSpecificData;\r
+\r
+       eError = OSInitEnvData(&gpsSysData->pvEnvSpecificData);\r
+       if (eError != PVRSRV_OK)\r
+       {\r
+               PVR_DPF((PVR_DBG_ERROR,"SysInitialise: Failed to setup env structure"));\r
+               SysDeinitialise(gpsSysData);\r
+               gpsSysData = IMG_NULL;\r
+               return eError;\r
+       }\r
+       SYS_SPECIFIC_DATA_SET(&gsSysSpecificData, SYS_SPECIFIC_DATA_ENABLE_ENVDATA);\r
+\r
+       gpsSysData->ui32NumDevices = SYS_DEVICE_COUNT;\r
+\r
+       \r
+       for(i=0; i<SYS_DEVICE_COUNT; i++)\r
+       {\r
+               gpsSysData->sDeviceID[i].uiID = i;\r
+               gpsSysData->sDeviceID[i].bInUse = IMG_FALSE;\r
+       }\r
+\r
+       gpsSysData->psDeviceNodeList = IMG_NULL;\r
+       gpsSysData->psQueueList = IMG_NULL;\r
+\r
+       eError = SysInitialiseCommon(gpsSysData);\r
+       if (eError != PVRSRV_OK)\r
+       {\r
+               PVR_DPF((PVR_DBG_ERROR,"SysInitialise: Failed in SysInitialiseCommon"));\r
+               SysDeinitialise(gpsSysData);\r
+               gpsSysData = IMG_NULL;\r
+               return eError;\r
+       }\r
+\r
+       TimerRegPhysBase.uiAddr = SYS_OMAP3430_GP11TIMER_REGS_SYS_PHYS_BASE;\r
+       gpsSysData->pvSOCTimerRegisterKM = IMG_NULL;\r
+       gpsSysData->hSOCTimerRegisterOSMemHandle = 0;\r
+       OSReservePhys(TimerRegPhysBase,\r
+                                 4,\r
+                                 PVRSRV_HAP_MULTI_PROCESS|PVRSRV_HAP_UNCACHED,\r
+                                 (IMG_VOID **)&gpsSysData->pvSOCTimerRegisterKM,\r
+                                 &gpsSysData->hSOCTimerRegisterOSMemHandle);\r
+\r
+#if !defined(SGX_DYNAMIC_TIMING_INFO)\r
+       \r
+       psTimingInfo = &gsSGXDeviceMap.sTimingInfo;\r
+       psTimingInfo->ui32CoreClockSpeed = SYS_SGX_CLOCK_SPEED;\r
+       psTimingInfo->ui32HWRecoveryFreq = SYS_SGX_HWRECOVERY_TIMEOUT_FREQ; \r
+       psTimingInfo->ui32ActivePowManLatencyms = SYS_SGX_ACTIVE_POWER_LATENCY_MS; \r
+       psTimingInfo->ui32uKernelFreq = SYS_SGX_PDS_TIMER_FREQ; \r
+#endif\r
+\r
+       \r
+\r
+       gpsSysSpecificData->ui32SrcClockDiv = 3;\r
+\r
+       \r
+\r
+\r
+\r
+       eError = SysLocateDevices(gpsSysData);\r
+       if (eError != PVRSRV_OK)\r
+       {\r
+               PVR_DPF((PVR_DBG_ERROR,"SysInitialise: Failed to locate devices"));\r
+               SysDeinitialise(gpsSysData);\r
+               gpsSysData = IMG_NULL;\r
+               return eError;\r
+       }\r
+       SYS_SPECIFIC_DATA_SET(&gsSysSpecificData, SYS_SPECIFIC_DATA_ENABLE_LOCATEDEV);\r
+\r
+       \r
+\r
+\r
+       eError = PVRSRVRegisterDevice(gpsSysData, SGXRegisterDevice,\r
+                                                                 DEVICE_SGX_INTERRUPT, &gui32SGXDeviceID);\r
+       if (eError != PVRSRV_OK)\r
+       {\r
+               PVR_DPF((PVR_DBG_ERROR,"SysInitialise: Failed to register device!"));\r
+               SysDeinitialise(gpsSysData);\r
+               gpsSysData = IMG_NULL;\r
+               return eError;\r
+       }\r
+       SYS_SPECIFIC_DATA_SET(&gsSysSpecificData, SYS_SPECIFIC_DATA_ENABLE_REGDEV);\r
+\r
+       \r
+\r
+\r
+       \r
+       psDeviceNode = gpsSysData->psDeviceNodeList;\r
+       while(psDeviceNode)\r
+       {\r
+               \r
+               switch(psDeviceNode->sDevId.eDeviceType)\r
+               {\r
+                       case PVRSRV_DEVICE_TYPE_SGX:\r
+                       {\r
+                               DEVICE_MEMORY_INFO *psDevMemoryInfo;\r
+                               DEVICE_MEMORY_HEAP_INFO *psDeviceMemoryHeap;\r
+\r
+                               \r
+\r
+\r
+                               psDeviceNode->psLocalDevMemArena = IMG_NULL;\r
+\r
+                               \r
+                               psDevMemoryInfo = &psDeviceNode->sDevMemoryInfo;\r
+                               psDeviceMemoryHeap = psDevMemoryInfo->psDeviceMemoryHeap;\r
+\r
+                               \r
+                               for(i=0; i<psDevMemoryInfo->ui32HeapCount; i++)\r
+                               {\r
+                                       psDeviceMemoryHeap[i].ui32Attribs |= PVRSRV_BACKINGSTORE_SYSMEM_NONCONTIG;\r
+                               }\r
+\r
+                               gpsSGXDevNode = psDeviceNode;\r
+                               gsSysSpecificData.psSGXDevNode = psDeviceNode;\r
+\r
+                               break;\r
+                       }\r
+                       default:\r
+                               PVR_DPF((PVR_DBG_ERROR,"SysInitialise: Failed to find SGX device node!"));\r
+                               return PVRSRV_ERROR_INIT_FAILURE;\r
+               }\r
+\r
+               \r
+               psDeviceNode = psDeviceNode->psNext;\r
+       }\r
+\r
+       PDUMPINIT();\r
+       SYS_SPECIFIC_DATA_SET(&gsSysSpecificData, SYS_SPECIFIC_DATA_ENABLE_PDUMPINIT);\r
+\r
+       eError = EnableSystemClocks(gpsSysData);\r
+       if (eError != PVRSRV_OK)\r
+       {\r
+               PVR_DPF((PVR_DBG_ERROR,"SysInitialise: Failed to Enable system clocks (%d)", eError));\r
+               SysDeinitialise(gpsSysData);\r
+               gpsSysData = IMG_NULL;\r
+               return eError;\r
+       }\r
+       SYS_SPECIFIC_DATA_SET(&gsSysSpecificData, SYS_SPECIFIC_DATA_ENABLE_SYSCLOCKS);\r
+\r
+#if defined(SUPPORT_ACTIVE_POWER_MANAGEMENT)\r
+       eError = EnableSGXClocks(gpsSysData);\r
+       if (eError != PVRSRV_OK)\r
+       {\r
+               PVR_DPF((PVR_DBG_ERROR,"SysInitialise: Failed to Enable SGX clocks (%d)", eError));\r
+               SysDeinitialise(gpsSysData);\r
+               gpsSysData = IMG_NULL;\r
+               return eError;\r
+       }\r
+#endif \r
+\r
+       eError = PVRSRVInitialiseDevice(gui32SGXDeviceID);\r
+       if (eError != PVRSRV_OK)\r
+       {\r
+               PVR_DPF((PVR_DBG_ERROR,"SysInitialise: Failed to initialise device!"));\r
+               SysDeinitialise(gpsSysData);\r
+               gpsSysData = IMG_NULL;\r
+               return eError;\r
+       }\r
+       SYS_SPECIFIC_DATA_SET(&gsSysSpecificData, SYS_SPECIFIC_DATA_ENABLE_INITDEV);\r
+\r
+#if defined(SUPPORT_ACTIVE_POWER_MANAGEMENT)\r
+       \r
+       DisableSGXClocks(gpsSysData);\r
+#endif \r
+\r
+       return PVRSRV_OK;\r
+}\r
+\r
+\r
+PVRSRV_ERROR SysFinalise(IMG_VOID)\r
+{\r
+       PVRSRV_ERROR eError = PVRSRV_OK;\r
+       \r
+#if defined(SUPPORT_ACTIVE_POWER_MANAGEMENT)\r
+       eError = EnableSGXClocks(gpsSysData);\r
+       if (eError != PVRSRV_OK)\r
+       {\r
+               PVR_DPF((PVR_DBG_ERROR,"SysInitialise: Failed to Enable SGX clocks (%d)", eError));\r
+               SysDeinitialise(gpsSysData);\r
+               gpsSysData = IMG_NULL;\r
+               return eError;\r
+       }\r
+#endif \r
+\r
+#if defined(SYS_USING_INTERRUPTS)\r
+\r
+       eError = OSInstallMISR(gpsSysData);\r
+       if (eError != PVRSRV_OK)\r
+       {\r
+               PVR_DPF((PVR_DBG_ERROR,"SysFinalise: Failed to install MISR"));\r
+               SysDeinitialise(gpsSysData);\r
+               gpsSysData = IMG_NULL;\r
+               return eError;\r
+       }\r
+       SYS_SPECIFIC_DATA_SET(&gsSysSpecificData, SYS_SPECIFIC_DATA_ENABLE_MISR);\r
+\r
+       \r
+       eError = OSInstallDeviceLISR(gpsSysData, gsSGXDeviceMap.ui32IRQ, "SGX ISR", gpsSGXDevNode);\r
+       if (eError != PVRSRV_OK)\r
+       {\r
+               PVR_DPF((PVR_DBG_ERROR,"SysFinalise: Failed to install ISR"));\r
+               SysDeinitialise(gpsSysData);\r
+               gpsSysData = IMG_NULL;\r
+               return eError;\r
+       }\r
+       SYS_SPECIFIC_DATA_SET(&gsSysSpecificData, SYS_SPECIFIC_DATA_ENABLE_LISR);\r
+#endif \r
+\r
+       \r
+       gpsSysData->pszVersionString = SysCreateVersionString(gsSGXDeviceMap.sRegsCpuPBase);\r
+       if (!gpsSysData->pszVersionString)\r
+       {\r
+               PVR_DPF((PVR_DBG_ERROR,"SysFinalise: Failed to create a system version string"));\r
+       }\r
+       else\r
+       {\r
+               PVR_DPF((PVR_DBG_WARNING, "SysFinalise: Version string: %s", gpsSysData->pszVersionString));\r
+       }\r
+\r
+#if defined(SUPPORT_ACTIVE_POWER_MANAGEMENT)\r
+       \r
+       DisableSGXClocks(gpsSysData);\r
+#endif \r
+\r
+       gpsSysSpecificData->bSGXInitComplete = IMG_TRUE;\r
+\r
+       return eError;\r
+}\r
+\r
+\r
+PVRSRV_ERROR SysDeinitialise (SYS_DATA *psSysData)\r
+{\r
+       PVRSRV_ERROR eError;\r
+       \r
+#if defined(SYS_USING_INTERRUPTS)\r
+       if (SYS_SPECIFIC_DATA_TEST(gpsSysSpecificData, SYS_SPECIFIC_DATA_ENABLE_LISR))\r
+       {\r
+               eError = OSUninstallDeviceLISR(psSysData);\r
+               if (eError != PVRSRV_OK)\r
+               {\r
+                       PVR_DPF((PVR_DBG_ERROR,"SysDeinitialise: OSUninstallDeviceLISR failed"));\r
+                       return eError;\r
+               }\r
+       }\r
+\r
+       if (SYS_SPECIFIC_DATA_TEST(gpsSysSpecificData, SYS_SPECIFIC_DATA_ENABLE_MISR))\r
+       {\r
+               eError = OSUninstallMISR(psSysData);\r
+               if (eError != PVRSRV_OK)\r
+               {\r
+                       PVR_DPF((PVR_DBG_ERROR,"SysDeinitialise: OSUninstallMISR failed"));\r
+                       return eError;\r
+               }\r
+       }\r
+#else\r
+       PVR_UNREFERENCED_PARAMETER(psSysData);\r
+#endif \r
+\r
+       if (SYS_SPECIFIC_DATA_TEST(gpsSysSpecificData, SYS_SPECIFIC_DATA_ENABLE_INITDEV))\r
+       {\r
+#if defined(SUPPORT_ACTIVE_POWER_MANAGEMENT)\r
+               PVR_ASSERT(SYS_SPECIFIC_DATA_TEST(gpsSysSpecificData, SYS_SPECIFIC_DATA_ENABLE_SYSCLOCKS));\r
+               \r
+               eError = EnableSGXClocks(gpsSysData);\r
+               if (eError != PVRSRV_OK)\r
+               {\r
+                       PVR_DPF((PVR_DBG_ERROR,"SysDeinitialise: EnableSGXClocks failed"));\r
+                       return eError;\r
+               }\r
+#endif \r
+\r
+               \r
+               eError = PVRSRVDeinitialiseDevice (gui32SGXDeviceID);\r
+               if (eError != PVRSRV_OK)\r
+               {\r
+                       PVR_DPF((PVR_DBG_ERROR,"SysDeinitialise: failed to de-init the device"));\r
+                       return eError;\r
+               }\r
+       }\r
+       \r
+       \r
+\r
+       if (SYS_SPECIFIC_DATA_TEST(gpsSysSpecificData, SYS_SPECIFIC_DATA_ENABLE_SYSCLOCKS))\r
+       {\r
+               DisableSystemClocks(gpsSysData);\r
+       }\r
+\r
+       if (SYS_SPECIFIC_DATA_TEST(gpsSysSpecificData, SYS_SPECIFIC_DATA_ENABLE_ENVDATA))\r
+       {       \r
+               eError = OSDeInitEnvData(gpsSysData->pvEnvSpecificData);\r
+               if (eError != PVRSRV_OK)\r
+               {\r
+                       PVR_DPF((PVR_DBG_ERROR,"SysDeinitialise: failed to de-init env structure"));\r
+                       return eError;\r
+               }\r
+       }\r
+\r
+       if(gpsSysData->pvSOCTimerRegisterKM)\r
+       {\r
+               OSUnReservePhys(gpsSysData->pvSOCTimerRegisterKM,\r
+                                               4,\r
+                                               PVRSRV_HAP_MULTI_PROCESS|PVRSRV_HAP_UNCACHED,\r
+                                               gpsSysData->hSOCTimerRegisterOSMemHandle);\r
+       }\r
+\r
+       SysDeinitialiseCommon(gpsSysData);\r
+\r
+#if defined(NO_HARDWARE)\r
+       if(SYS_SPECIFIC_DATA_TEST(gpsSysSpecificData, SYS_SPECIFIC_DATA_ENABLE_LOCATEDEV))\r
+       {\r
+               \r
+               OSBaseFreeContigMemory(SYS_OMAP3430_SGX_REGS_SIZE, gsSGXRegsCPUVAddr, gsSGXDeviceMap.sRegsCpuPBase);\r
+       }\r
+#endif\r
+\r
+       \r
+       if(SYS_SPECIFIC_DATA_TEST(gpsSysSpecificData, SYS_SPECIFIC_DATA_ENABLE_PDUMPINIT))\r
+       {\r
+               PDUMPDEINIT();\r
+       }\r
+\r
+       gpsSysSpecificData->ui32SysSpecificData = 0;\r
+       gpsSysSpecificData->bSGXInitComplete = IMG_FALSE;\r
+\r
+       gpsSysData = IMG_NULL;\r
+\r
+       return PVRSRV_OK;\r
+}\r
+\r
+\r
+PVRSRV_ERROR SysGetDeviceMemoryMap(PVRSRV_DEVICE_TYPE  eDeviceType,\r
+                                                                  IMG_VOID                             **ppvDeviceMap)\r
+{\r
+\r
+       switch(eDeviceType)\r
+       {\r
+               case PVRSRV_DEVICE_TYPE_SGX:\r
+               {\r
+                       \r
+                       *ppvDeviceMap = (IMG_VOID*)&gsSGXDeviceMap;\r
+\r
+                       break;\r
+               }\r
+               default:\r
+               {\r
+                       PVR_DPF((PVR_DBG_ERROR,"SysGetDeviceMemoryMap: unsupported device type"));\r
+               }\r
+       }\r
+       return PVRSRV_OK;\r
+}\r
+\r
+\r
+IMG_DEV_PHYADDR SysCpuPAddrToDevPAddr(PVRSRV_DEVICE_TYPE       eDeviceType,\r
+                                                                         IMG_CPU_PHYADDR               CpuPAddr)\r
+{\r
+       IMG_DEV_PHYADDR DevPAddr;\r
+\r
+       PVR_UNREFERENCED_PARAMETER(eDeviceType);\r
+\r
+       \r
+       DevPAddr.uiAddr = CpuPAddr.uiAddr;\r
+       \r
+       return DevPAddr;\r
+}\r
+\r
+IMG_CPU_PHYADDR SysSysPAddrToCpuPAddr (IMG_SYS_PHYADDR sys_paddr)\r
+{\r
+       IMG_CPU_PHYADDR cpu_paddr;\r
+\r
+       \r
+       cpu_paddr.uiAddr = sys_paddr.uiAddr;\r
+       return cpu_paddr;\r
+}\r
+\r
+IMG_SYS_PHYADDR SysCpuPAddrToSysPAddr (IMG_CPU_PHYADDR cpu_paddr)\r
+{\r
+       IMG_SYS_PHYADDR sys_paddr;\r
+\r
+       \r
+       sys_paddr.uiAddr = cpu_paddr.uiAddr;\r
+       return sys_paddr;\r
+}\r
+\r
+\r
+IMG_DEV_PHYADDR SysSysPAddrToDevPAddr(PVRSRV_DEVICE_TYPE eDeviceType, IMG_SYS_PHYADDR SysPAddr)\r
+{\r
+       IMG_DEV_PHYADDR DevPAddr;\r
+\r
+       PVR_UNREFERENCED_PARAMETER(eDeviceType);\r
+\r
+       \r
+       DevPAddr.uiAddr = SysPAddr.uiAddr;\r
+\r
+       return DevPAddr;\r
+}\r
+\r
+\r
+IMG_SYS_PHYADDR SysDevPAddrToSysPAddr(PVRSRV_DEVICE_TYPE eDeviceType, IMG_DEV_PHYADDR DevPAddr)\r
+{\r
+       IMG_SYS_PHYADDR SysPAddr;\r
+\r
+       PVR_UNREFERENCED_PARAMETER(eDeviceType);\r
+\r
+       \r
+       SysPAddr.uiAddr = DevPAddr.uiAddr;\r
+\r
+       return SysPAddr;\r
+}\r
+\r
+\r
+IMG_VOID SysRegisterExternalDevice(PVRSRV_DEVICE_NODE *psDeviceNode)\r
+{\r
+       PVR_UNREFERENCED_PARAMETER(psDeviceNode);\r
+}\r
+\r
+\r
+IMG_VOID SysRemoveExternalDevice(PVRSRV_DEVICE_NODE *psDeviceNode)\r
+{\r
+       PVR_UNREFERENCED_PARAMETER(psDeviceNode);\r
+}\r
+\r
+\r
+IMG_UINT32 SysGetInterruptSource(SYS_DATA                      *psSysData,\r
+                                                                PVRSRV_DEVICE_NODE     *psDeviceNode)\r
+{\r
+       PVR_UNREFERENCED_PARAMETER(psSysData);\r
+#if defined(NO_HARDWARE)\r
+       \r
+       return 0xFFFFFFFF;\r
+#else\r
+       \r
+       return psDeviceNode->ui32SOCInterruptBit;\r
+#endif\r
+}\r
+\r
+\r
+IMG_VOID SysClearInterrupts(SYS_DATA* psSysData, IMG_UINT32 ui32ClearBits)\r
+{\r
+       PVR_UNREFERENCED_PARAMETER(psSysData);\r
+       PVR_UNREFERENCED_PARAMETER(ui32ClearBits);\r
+\r
+       \r
+       OSReadHWReg(((PVRSRV_SGXDEV_INFO *)gpsSGXDevNode->pvDevice)->pvRegsBaseKM,\r
+                                                                               EUR_CR_EVENT_HOST_CLEAR);\r
+}\r
+\r
+\r
+PVRSRV_ERROR SysSystemPrePowerState(PVR_POWER_STATE eNewPowerState)\r
+{\r
+       PVRSRV_ERROR eError = PVRSRV_OK;\r
+\r
+       if (eNewPowerState == PVRSRV_POWER_STATE_D3)\r
+       {\r
+               PVR_TRACE(("SysSystemPrePowerState: Entering state D3"));\r
+\r
+#if defined(SYS_USING_INTERRUPTS)\r
+               if (SYS_SPECIFIC_DATA_TEST(&gsSysSpecificData, SYS_SPECIFIC_DATA_ENABLE_LISR))\r
+               {\r
+#if defined(SYS_CUSTOM_POWERLOCK_WRAP)\r
+                       IMG_BOOL bWrapped = WrapSystemPowerChange(&gsSysSpecificData);\r
+#endif\r
+                       eError = OSUninstallDeviceLISR(gpsSysData);\r
+#if defined(SYS_CUSTOM_POWERLOCK_WRAP)\r
+                       if (bWrapped)\r
+                       {\r
+                               UnwrapSystemPowerChange(&gsSysSpecificData);\r
+                       }\r
+#endif\r
+                       if (eError != PVRSRV_OK)\r
+                       {\r
+                               PVR_DPF((PVR_DBG_ERROR,"SysSystemPrePowerState: OSUninstallDeviceLISR failed (%d)", eError));\r
+                               return eError;\r
+                       }\r
+                       SYS_SPECIFIC_DATA_SET(&gsSysSpecificData, SYS_SPECIFIC_DATA_PM_UNINSTALL_LISR);\r
+                       SYS_SPECIFIC_DATA_CLEAR(&gsSysSpecificData, SYS_SPECIFIC_DATA_ENABLE_LISR);\r
+               }\r
+#endif\r
+\r
+               if (SYS_SPECIFIC_DATA_TEST(&gsSysSpecificData, SYS_SPECIFIC_DATA_ENABLE_SYSCLOCKS))\r
+               {\r
+                       DisableSystemClocks(gpsSysData);\r
+\r
+                       SYS_SPECIFIC_DATA_SET(&gsSysSpecificData, SYS_SPECIFIC_DATA_PM_DISABLE_SYSCLOCKS);\r
+                       SYS_SPECIFIC_DATA_CLEAR(&gsSysSpecificData, SYS_SPECIFIC_DATA_ENABLE_SYSCLOCKS);\r
+               }\r
+       }\r
+\r
+       return eError;\r
+}\r
+\r
+\r
+PVRSRV_ERROR SysSystemPostPowerState(PVR_POWER_STATE eNewPowerState)\r
+{\r
+       PVRSRV_ERROR eError = PVRSRV_OK;\r
+\r
+       if (eNewPowerState == PVRSRV_POWER_STATE_D0)\r
+       {\r
+               PVR_TRACE(("SysSystemPostPowerState: Entering state D0"));\r
+\r
+               if (SYS_SPECIFIC_DATA_TEST(&gsSysSpecificData, SYS_SPECIFIC_DATA_PM_DISABLE_SYSCLOCKS))\r
+               {\r
+                       eError = EnableSystemClocks(gpsSysData);\r
+                       if (eError != PVRSRV_OK)\r
+                       {\r
+                               PVR_DPF((PVR_DBG_ERROR,"SysSystemPostPowerState: EnableSystemClocks failed (%d)", eError));\r
+                               return eError;\r
+                       }\r
+                       SYS_SPECIFIC_DATA_SET(&gsSysSpecificData, SYS_SPECIFIC_DATA_ENABLE_SYSCLOCKS);\r
+                       SYS_SPECIFIC_DATA_CLEAR(&gsSysSpecificData, SYS_SPECIFIC_DATA_PM_DISABLE_SYSCLOCKS);\r
+               }\r
+\r
+#if defined(SYS_USING_INTERRUPTS)\r
+               if (SYS_SPECIFIC_DATA_TEST(&gsSysSpecificData, SYS_SPECIFIC_DATA_PM_UNINSTALL_LISR))\r
+               {\r
+#if defined(SYS_CUSTOM_POWERLOCK_WRAP)\r
+                       IMG_BOOL bWrapped = WrapSystemPowerChange(&gsSysSpecificData);\r
+#endif\r
+\r
+                       eError = OSInstallDeviceLISR(gpsSysData, gsSGXDeviceMap.ui32IRQ, "SGX ISR", gpsSGXDevNode);\r
+#if defined(SYS_CUSTOM_POWERLOCK_WRAP)\r
+                       if (bWrapped)\r
+                       {\r
+                               UnwrapSystemPowerChange(&gsSysSpecificData);\r
+                       }\r
+#endif\r
+                       if (eError != PVRSRV_OK)\r
+                       {\r
+                               PVR_DPF((PVR_DBG_ERROR,"SysSystemPostPowerState: OSInstallDeviceLISR failed to install ISR (%d)", eError));\r
+                               return eError;\r
+                       }\r
+                       SYS_SPECIFIC_DATA_SET(&gsSysSpecificData, SYS_SPECIFIC_DATA_ENABLE_LISR);\r
+                       SYS_SPECIFIC_DATA_CLEAR(&gsSysSpecificData, SYS_SPECIFIC_DATA_PM_UNINSTALL_LISR);\r
+               }\r
+#endif\r
+       }\r
+       return eError;\r
+}\r
+\r
+\r
+PVRSRV_ERROR SysDevicePrePowerState(IMG_UINT32                 ui32DeviceIndex,\r
+                                                                       PVR_POWER_STATE         eNewPowerState,\r
+                                                                       PVR_POWER_STATE         eCurrentPowerState)\r
+{\r
+       PVR_UNREFERENCED_PARAMETER(eCurrentPowerState);\r
+\r
+       if (ui32DeviceIndex != gui32SGXDeviceID)\r
+       {\r
+               return PVRSRV_OK;\r
+       }\r
+\r
+#if defined(SUPPORT_ACTIVE_POWER_MANAGEMENT)\r
+       if (eNewPowerState == PVRSRV_POWER_STATE_D3)\r
+       {\r
+               PVR_DPF((PVR_DBG_MESSAGE, "SysDevicePrePowerState: SGX Entering state D3"));\r
+               DisableSGXClocks(gpsSysData);\r
+               PVRSRVSetDCState(DC_STATE_SUSPEND_COMMANDS);\r
+       }\r
+#else  \r
+       PVR_UNREFERENCED_PARAMETER(eNewPowerState );\r
+#endif \r
+       return PVRSRV_OK;\r
+}\r
+\r
+\r
+PVRSRV_ERROR SysDevicePostPowerState(IMG_UINT32                        ui32DeviceIndex,\r
+                                                                        PVR_POWER_STATE        eNewPowerState,\r
+                                                                        PVR_POWER_STATE        eCurrentPowerState)\r
+{\r
+       PVRSRV_ERROR eError = PVRSRV_OK;\r
+\r
+       PVR_UNREFERENCED_PARAMETER(eNewPowerState);\r
+\r
+       if (ui32DeviceIndex != gui32SGXDeviceID)\r
+       {\r
+               return eError;\r
+       }\r
+\r
+#if defined(SUPPORT_ACTIVE_POWER_MANAGEMENT)\r
+       if (eCurrentPowerState == PVRSRV_POWER_STATE_D3)\r
+       {\r
+               PVR_DPF((PVR_DBG_MESSAGE, "SysDevicePostPowerState: SGX Leaving state D3"));\r
+               PVRSRVSetDCState(DC_STATE_RESUME_COMMANDS);\r
+               eError = EnableSGXClocks(gpsSysData);\r
+       }\r
+#else  \r
+       PVR_UNREFERENCED_PARAMETER(eCurrentPowerState);\r
+#endif \r
+\r
+       return eError;\r
+}\r
+\r
+\r
+PVRSRV_ERROR SysOEMFunction (  IMG_UINT32      ui32ID,\r
+                                                               IMG_VOID        *pvIn,\r
+                                                               IMG_UINT32      ulInSize,\r
+                                                               IMG_VOID        *pvOut,\r
+                                                               IMG_UINT32      ulOutSize)\r
+{\r
+       PVR_UNREFERENCED_PARAMETER(ui32ID);\r
+       PVR_UNREFERENCED_PARAMETER(pvIn);\r
+       PVR_UNREFERENCED_PARAMETER(ulInSize);\r
+       PVR_UNREFERENCED_PARAMETER(pvOut);\r
+       PVR_UNREFERENCED_PARAMETER(ulOutSize);\r
+\r
+       if ((ui32ID == OEM_GET_EXT_FUNCS) &&\r
+               (ulOutSize == sizeof(PVRSRV_DC_OEM_JTABLE)))\r
+       {\r
+               \r
+               PVRSRV_DC_OEM_JTABLE *psOEMJTable = (PVRSRV_DC_OEM_JTABLE*) pvOut;\r
+               psOEMJTable->pfnOEMBridgeDispatch = &PVRSRV_BridgeDispatchKM;\r
+               return PVRSRV_OK;\r
+       }\r
+\r
+       return PVRSRV_ERROR_INVALID_PARAMS;\r
+}\r
diff --git a/services4/system/ti8168/sysconfig.h b/services4/system/ti8168/sysconfig.h
new file mode 100644 (file)
index 0000000..516155e
--- /dev/null
@@ -0,0 +1,53 @@
+/**********************************************************************\r
+ *\r
+ * Copyright(c) 2008 Imagination Technologies Ltd. All rights reserved.\r
+ * \r
+ * This program is free software; you can redistribute it and/or modify it\r
+ * under the terms and conditions of the GNU General Public License,\r
+ * version 2, as published by the Free Software Foundation.\r
+ * \r
+ * This program is distributed in the hope it will be useful but, except \r
+ * as otherwise stated in writing, without any warranty; without even the \r
+ * implied warranty of merchantability or fitness for a particular purpose. \r
+ * See the GNU General Public License for more details.\r
+ * \r
+ * You should have received a copy of the GNU General Public License along with\r
+ * this program; if not, write to the Free Software Foundation, Inc.,\r
+ * 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA.\r
+ * \r
+ * The full GNU General Public License is included in this distribution in\r
+ * the file called "COPYING".\r
+ *\r
+ * Contact Information:\r
+ * Imagination Technologies Ltd. <gpl-support@imgtec.com>\r
+ * Home Park Estate, Kings Langley, Herts, WD4 8LZ, UK \r
+ *\r
+ ******************************************************************************/\r
+\r
+#if !defined(__SOCCONFIG_H__)\r
+#define __SOCCONFIG_H__\r
+\r
+#include "syscommon.h"\r
+\r
+#define VS_PRODUCT_NAME        "OMAP3630"\r
+\r
+#define SYS_SGX_CLOCK_SPEED    330000000\r
+#define SYS_SGX_HWRECOVERY_TIMEOUT_FREQ                (100)   \r
+#define SYS_SGX_PDS_TIMER_FREQ                 (1000)  \r
+#define SYS_SGX_ACTIVE_POWER_LATENCY_MS                (1)\r
+\r
+\r
+#define        SYS_OMAP3430_VDD2_OPP3_SGX_CLOCK_SPEED SYS_SGX_CLOCK_SPEED\r
+#define SYS_OMAP3430_VDD2_OPP2_SGX_CLOCK_SPEED (SYS_SGX_CLOCK_SPEED / 2)\r
+\r
+#define SYS_OMAP3430_SGX_REGS_SYS_PHYS_BASE  0x56000000\r
+#define SYS_OMAP3430_SGX_REGS_SIZE           0x10000\r
+\r
+#define SYS_OMAP3430_SGX_IRQ                           37 \r
+\r
+#define SYS_OMAP3430_GP11TIMER_ENABLE_SYS_PHYS_BASE      0x48048038\r
+#define SYS_OMAP3430_GP11TIMER_REGS_SYS_PHYS_BASE       0x4804803C\r
+#define SYS_OMAP3430_GP11TIMER_TSICR_SYS_PHYS_BASE      0x48048054\r
+\r
\r
+#endif \r
diff --git a/services4/system/ti8168/sysinfo.h b/services4/system/ti8168/sysinfo.h
new file mode 100644 (file)
index 0000000..88e3096
--- /dev/null
@@ -0,0 +1,98 @@
+/**********************************************************************\r
+ *\r
+ * Copyright(c) 2008 Imagination Technologies Ltd. All rights reserved.\r
+ * \r
+ * This program is free software; you can redistribute it and/or modify it\r
+ * under the terms and conditions of the GNU General Public License,\r
+ * version 2, as published by the Free Software Foundation.\r
+ * \r
+ * This program is distributed in the hope it will be useful but, except \r
+ * as otherwise stated in writing, without any warranty; without even the \r
+ * implied warranty of merchantability or fitness for a particular purpose. \r
+ * See the GNU General Public License for more details.\r
+ * \r
+ * You should have received a copy of the GNU General Public License along with\r
+ * this program; if not, write to the Free Software Foundation, Inc.,\r
+ * 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA.\r
+ * \r
+ * The full GNU General Public License is included in this distribution in\r
+ * the file called "COPYING".\r
+ *\r
+ * Contact Information:\r
+ * Imagination Technologies Ltd. <gpl-support@imgtec.com>\r
+ * Home Park Estate, Kings Langley, Herts, WD4 8LZ, UK \r
+ *\r
+ ******************************************************************************/\r
+\r
+#if !defined(__SYSINFO_H__)\r
+#define __SYSINFO_H__\r
+\r
+#define MAX_HW_TIME_US                         (500000)\r
+#define WAIT_TRY_COUNT                         (10000)\r
+\r
+typedef enum _SYS_DEVICE_TYPE_\r
+{\r
+       SYS_DEVICE_SGX                                          = 0,\r
+\r
+       SYS_DEVICE_FORCE_I16                            = 0x7fff\r
+\r
+} SYS_DEVICE_TYPE;\r
+\r
+#define SYS_DEVICE_COUNT 3 \r
+\r
+#define PRM_REG32(offset)        (offset)\r
+#define CM_REG32(offset)         (offset)\r
+\r
+#define CM_FCLKEN_SGX          CM_REG32(0xB00)\r
+#define                CM_FCLKEN_SGX_EN_3D                                     0x00000002\r
+\r
+#define CM_ICLKEN_SGX          CM_REG32(0xB10)\r
+#define                CM_ICLKEN_SGX_EN_SGX                            0x00000001\r
+\r
+#define CM_IDLEST_SGX          CM_REG32(0xB20)\r
+#define                CM_IDLEST_SGX_ST_SGX                            0x00000001\r
+\r
+#define CM_CLKSEL_SGX          CM_REG32(0xB40)\r
+#define                CM_CLKSEL_SGX_MASK                                      0x0000000f\r
+#define                CM_CLKSEL_SGX_L3DIV3                            0x00000000\r
+#define                CM_CLKSEL_SGX_L3DIV4                            0x00000001\r
+#define                CM_CLKSEL_SGX_L3DIV6                            0x00000002\r
+#define                CM_CLKSEL_SGX_96M                                       0x00000003\r
+\r
+#define CM_SLEEPDEP_SGX                CM_REG32(0xB44)\r
+#define CM_CLKSTCTRL_SGX       CM_REG32(0xB48)\r
+#define        CM_CLKSTCTRL_SGX_AUTOSTATE                      0x00008001\r
+\r
+#define CM_CLKSTST_SGX         CM_REG32(0xB4C)\r
+#define        CM_CLKSTST_SGX_STATUS_VALID                     0x00000001\r
+\r
+#define RM_RSTST_SGX           PRM_REG32(0xB58)\r
+#define        RM_RSTST_SGX_RST_MASK                           0x0000000F\r
+#define        RM_RSTST_SGX_COREDOMAINWKUP_RST         0x00000008\r
+#define        RM_RSTST_SGX_DOMAINWKUP_RST                     0x00000004\r
+#define        RM_RSTST_SGX_GLOBALWARM_RST                     0x00000002\r
+#define        RM_RSTST_SGX_GLOBALCOLD_RST                     0x00000001\r
+\r
+#define PM_WKDEP_SGX           PRM_REG32(0xBC8)\r
+#define        PM_WKDEP_SGX_EN_WAKEUP                          0x00000010\r
+#define        PM_WKDEP_SGX_EN_MPU                                     0x00000002\r
+#define        PM_WKDEP_SGX_EN_CORE                            0x00000001\r
+\r
+#define PM_PWSTCTRL_SGX                PRM_REG32(0xBE0)\r
+#define                PM_PWSTCTRL_SGX_POWERSTATE_MASK         0x00000003\r
+#define                        PM_PWSTCTRL_SGX_OFF                             0x00000000\r
+#define                        PM_PWSTCTRL_SGX_RETENTION               0x00000001\r
+#define                        PM_PWSTCTRL_SGX_ON                              0x00000003\r
+\r
+#define PM_PWSTST_SGX          PRM_REG32(0xBE4)\r
+#define                PM_PWSTST_SGX_INTRANSITION                      0x00100000\r
+#define                PM_PWSTST_SGX_CLKACTIVITY                       0x00080000\r
+#define                PM_PWSTST_SGX_POWERSTATE_MASK           0x00000003\r
+#define                        PM_PWSTST_SGX_OFF                               0x00000003\r
+#define                        PM_PWSTST_SGX_RETENTION                 0x00000001\r
+#define                        PM_PWSTST_SGX_ON                                0x00000000\r
+\r
+#define PM_PREPWSTST_SGX       PRM_REG32(0xBE8)\r
+\r
+\r
+#endif \r
diff --git a/services4/system/ti8168/syslocal.h b/services4/system/ti8168/syslocal.h
new file mode 100644 (file)
index 0000000..74de28f
--- /dev/null
@@ -0,0 +1,128 @@
+/**********************************************************************\r
+ *\r
+ * Copyright(c) 2008 Imagination Technologies Ltd. All rights reserved.\r
+ * \r
+ * This program is free software; you can redistribute it and/or modify it\r
+ * under the terms and conditions of the GNU General Public License,\r
+ * version 2, as published by the Free Software Foundation.\r
+ * \r
+ * This program is distributed in the hope it will be useful but, except \r
+ * as otherwise stated in writing, without any warranty; without even the \r
+ * implied warranty of merchantability or fitness for a particular purpose. \r
+ * See the GNU General Public License for more details.\r
+ * \r
+ * You should have received a copy of the GNU General Public License along with\r
+ * this program; if not, write to the Free Software Foundation, Inc.,\r
+ * 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA.\r
+ * \r
+ * The full GNU General Public License is included in this distribution in\r
+ * the file called "COPYING".\r
+ *\r
+ * Contact Information:\r
+ * Imagination Technologies Ltd. <gpl-support@imgtec.com>\r
+ * Home Park Estate, Kings Langley, Herts, WD4 8LZ, UK \r
+ *\r
+ ******************************************************************************/\r
+\r
+#if !defined(__SYSLOCAL_H__)\r
+#define __SYSLOCAL_H__\r
+\r
+#if defined(__linux__)\r
+\r
+#include <linux/version.h>\r
+#include <linux/clk.h>\r
+#include <linux/spinlock.h>\r
+#include <asm/atomic.h>\r
+\r
+#if (LINUX_VERSION_CODE > KERNEL_VERSION(2,6,26))\r
+#include <linux/semaphore.h>\r
+#include <linux/resource.h>\r
+#else \r
+#include <asm/semaphore.h>\r
+#if (LINUX_VERSION_CODE > KERNEL_VERSION(2,6,22))\r
+#include <asm/arch/resource.h>\r
+#endif \r
+#endif \r
+\r
+#endif \r
+\r
+#if defined (__cplusplus)\r
+extern "C" {\r
+#endif\r
+\r
\r
\r
+IMG_CHAR *SysCreateVersionString(IMG_CPU_PHYADDR sRegRegion);\r
+\r
+IMG_VOID DisableSystemClocks(SYS_DATA *psSysData);\r
+PVRSRV_ERROR EnableSystemClocks(SYS_DATA *psSysData);\r
+\r
+IMG_VOID DisableSGXClocks(SYS_DATA *psSysData);\r
+PVRSRV_ERROR EnableSGXClocks(SYS_DATA *psSysData);\r
+\r
+#define SYS_SPECIFIC_DATA_ENABLE_SYSCLOCKS     0x00000001\r
+#define SYS_SPECIFIC_DATA_ENABLE_LISR          0x00000002\r
+#define SYS_SPECIFIC_DATA_ENABLE_MISR          0x00000004\r
+#define SYS_SPECIFIC_DATA_ENABLE_ENVDATA       0x00000008\r
+#define SYS_SPECIFIC_DATA_ENABLE_LOCDEV                0x00000010\r
+#define SYS_SPECIFIC_DATA_ENABLE_REGDEV                0x00000020\r
+#define SYS_SPECIFIC_DATA_ENABLE_PDUMPINIT     0x00000040\r
+#define SYS_SPECIFIC_DATA_ENABLE_INITDEV       0x00000080\r
+#define SYS_SPECIFIC_DATA_ENABLE_LOCATEDEV     0x00000100\r
+\r
+#define        SYS_SPECIFIC_DATA_PM_UNINSTALL_LISR     0x00000200\r
+#define        SYS_SPECIFIC_DATA_PM_DISABLE_SYSCLOCKS  0x00000400\r
+\r
+#define        SYS_SPECIFIC_DATA_SET(psSysSpecData, flag) ((IMG_VOID)((psSysSpecData)->ui32SysSpecificData |= (flag)))\r
+\r
+#define        SYS_SPECIFIC_DATA_CLEAR(psSysSpecData, flag) ((IMG_VOID)((psSysSpecData)->ui32SysSpecificData &= ~(flag)))\r
+\r
+#define        SYS_SPECIFIC_DATA_TEST(psSysSpecData, flag) (((psSysSpecData)->ui32SysSpecificData & (flag)) != 0)\r
\r
+typedef struct _SYS_SPECIFIC_DATA_TAG_\r
+{\r
+       IMG_UINT32      ui32SysSpecificData;\r
+       PVRSRV_DEVICE_NODE *psSGXDevNode;\r
+       IMG_BOOL        bSGXInitComplete;\r
+#if !defined(__linux__)\r
+       IMG_BOOL        bSGXClocksEnabled;\r
+#endif\r
+       IMG_UINT32      ui32SrcClockDiv;\r
+#if defined(__linux__)\r
+       IMG_BOOL        bSysClocksOneTimeInit;\r
+       IMG_BOOL        bConstraintNotificationsEnabled;\r
+       atomic_t        sSGXClocksEnabled;\r
+       spinlock_t      sPowerLock;\r
+       atomic_t        sPowerLockCPU;\r
+       spinlock_t      sNotifyLock;\r
+       atomic_t        sNotifyLockCPU;\r
+       IMG_BOOL        bCallVDD2PostFunc;\r
+\r
+       struct clk      *psCORE_CK;\r
+       struct clk      *psSGX_FCK;\r
+       struct clk      *psSGX_ICK;\r
+       struct clk      *psMPU_CK;\r
+#if defined(DEBUG) || defined(TIMING)\r
+       struct clk      *psGPT11_FCK;\r
+       struct clk      *psGPT11_ICK;\r
+#endif\r
+#if (LINUX_VERSION_CODE > KERNEL_VERSION(2,6,22))              \r
+       struct constraint_handle *pVdd2Handle;\r
+#endif \r
+#endif \r
+} SYS_SPECIFIC_DATA;\r
+\r
+extern SYS_SPECIFIC_DATA *gpsSysSpecificData;\r
+\r
+#if defined(SYS_CUSTOM_POWERLOCK_WRAP)\r
+IMG_BOOL WrapSystemPowerChange(SYS_SPECIFIC_DATA *psSysSpecData);\r
+IMG_VOID UnwrapSystemPowerChange(SYS_SPECIFIC_DATA *psSysSpecData);\r
+#endif\r
+\r
+#if defined(__cplusplus)\r
+}\r
+#endif\r
+\r
+#endif \r
+\r
+\r
diff --git a/services4/system/ti8168/sysutils.c b/services4/system/ti8168/sysutils.c
new file mode 100644 (file)
index 0000000..cb3cee7
--- /dev/null
@@ -0,0 +1,30 @@
+/**********************************************************************\r
+ *\r
+ * Copyright(c) 2008 Imagination Technologies Ltd. All rights reserved.\r
+ * \r
+ * This program is free software; you can redistribute it and/or modify it\r
+ * under the terms and conditions of the GNU General Public License,\r
+ * version 2, as published by the Free Software Foundation.\r
+ * \r
+ * This program is distributed in the hope it will be useful but, except \r
+ * as otherwise stated in writing, without any warranty; without even the \r
+ * implied warranty of merchantability or fitness for a particular purpose. \r
+ * See the GNU General Public License for more details.\r
+ * \r
+ * You should have received a copy of the GNU General Public License along with\r
+ * this program; if not, write to the Free Software Foundation, Inc.,\r
+ * 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA.\r
+ * \r
+ * The full GNU General Public License is included in this distribution in\r
+ * the file called "COPYING".\r
+ *\r
+ * Contact Information:\r
+ * Imagination Technologies Ltd. <gpl-support@imgtec.com>\r
+ * Home Park Estate, Kings Langley, Herts, WD4 8LZ, UK \r
+ *\r
+ ******************************************************************************/\r
+\r
+#if defined(__linux__)\r
+#include "sysutils_linux.c"\r
+#endif\r
+\r
diff --git a/services4/system/ti8168/sysutils_linux.c b/services4/system/ti8168/sysutils_linux.c
new file mode 100644 (file)
index 0000000..17be8f3
--- /dev/null
@@ -0,0 +1,738 @@
+/**********************************************************************\r
+ *\r
+ * Copyright(c) 2008 Imagination Technologies Ltd. All rights reserved.\r
+ *\r
+ * This program is free software; you can redistribute it and/or modify it\r
+ * under the terms and conditions of the GNU General Public License,\r
+ * version 2, as published by the Free Software Foundation.\r
+ *\r
+ * This program is distributed in the hope it will be useful but, except\r
+ * as otherwise stated in writing, without any warranty; without even the\r
+ * implied warranty of merchantability or fitness for a particular purpose.\r
+ * See the GNU General Public License for more details.\r
+ *\r
+ * You should have received a copy of the GNU General Public License along with\r
+ * this program; if not, write to the Free Software Foundation, Inc.,\r
+ * 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA.\r
+ *\r
+ * The full GNU General Public License is included in this distribution in\r
+ * the file called "COPYING".\r
+ *\r
+ * Contact Information:\r
+ * Imagination Technologies Ltd. <gpl-support@imgtec.com>\r
+ * Home Park Estate, Kings Langley, Herts, WD4 8LZ, UK\r
+ *\r
+ ******************************************************************************/\r
+\r
+#include <linux/version.h>\r
+#include <linux/clk.h>\r
+#include <linux/err.h>\r
+#include <linux/hardirq.h>\r
+#include <linux/spinlock.h>\r
+#include <asm/bug.h>\r
+#include <linux/platform_device.h>\r
+\r
+#if (LINUX_VERSION_CODE > KERNEL_VERSION(2,6,31))\r
+#include <linux/semaphore.h>\r
+//#include <plat/resource.h>\r
+#include <plat/omap-pm.h>\r
+#else\r
+\r
+#if (LINUX_VERSION_CODE > KERNEL_VERSION(2,6,26))\r
+#include <linux/semaphore.h>\r
+#include <mach/resource.h>\r
+#include <mach/omap-pm.h>\r
+#else\r
+#include <asm/semaphore.h>\r
+#if (LINUX_VERSION_CODE > KERNEL_VERSION(2,6,22))\r
+#include <asm/arch/resource.h>\r
+#endif\r
+#endif\r
+#endif\r
+\r
+#if    (LINUX_VERSION_CODE >  KERNEL_VERSION(2,6,27)) && \\r
+       (LINUX_VERSION_CODE <= KERNEL_VERSION(2,6,29))\r
+#define CONSTRAINT_NOTIFICATIONS\r
+#endif\r
+#include "sgxdefs.h"\r
+#include "services_headers.h"\r
+#include "sysinfo.h"\r
+#include "sgxapi_km.h"\r
+#include "sysconfig.h"\r
+#include "sgxinfokm.h"\r
+#include "syslocal.h"\r
+void set_vdd2_constraint(void);\r
+void remove_vdd2_constraint(void);\r
+#define        ONE_MHZ 1000000\r
+#define        HZ_TO_MHZ(m) ((m) / ONE_MHZ)\r
+\r
+#if defined(SUPPORT_OMAP3630_SGXFCLK_96M)\r
+#define SGX_PARENT_CLOCK "cm_96m_fck"\r
+#elif defined(SUPPORT_OMAP3630_SGXFCLK_192M)\r
+#define SGX_PARENT_CLOCK "omap_192m_alwon_ck"\r
+#elif defined(SUPPORT_OMAP3630_SGXFCLK_corex2)\r
+#define SGX_PARENT_CLOCK "corex2_fck"\r
+#else\r
+#define SGX_PARENT_CLOCK "core_ck"\r
+#endif\r
+\r
+#if !defined(PDUMP) && !defined(NO_HARDWARE)\r
+struct sgx_platform_data {\r
+          void(*set_min_bus_tput)(struct device *dev, u8 agent_id, unsigned long r);\r
+};\r
+\r
+static struct sgx_platform_data pdata = {\r
+\r
+       //.set_min_bus_tput = &omap_pm_set_min_bus_tput,\r
+          .set_min_bus_tput = NULL,\r
+};\r
+\r
+static struct platform_device sgx_dev = {\r
+         .name = "sgx_dev",\r
+         .id = 1,\r
+         .dev.platform_data = &pdata,\r
+};\r
+void set_vdd2_constraint(void)\r
+{\r
+       if(pdata.set_min_bus_tput){\r
+               pdata.set_min_bus_tput(&(sgx_dev.dev), OCP_INITIATOR_AGENT,800000);\r
+       }\r
+}\r
+\r
+void remove_vdd2_constraint(void)\r
+{\r
+       if(pdata.set_min_bus_tput)\r
+               pdata.set_min_bus_tput(&(sgx_dev.dev), OCP_INITIATOR_AGENT, 0);\r
+\r
+}\r
+#endif\r
+#if !defined(PDUMP) && !defined(NO_HARDWARE)\r
+static IMG_BOOL PowerLockWrappedOnCPU(SYS_SPECIFIC_DATA *psSysSpecData)\r
+{\r
+       IMG_INT iCPU;\r
+       IMG_BOOL bLocked = IMG_FALSE;\r
+\r
+       if (!in_interrupt())\r
+       {\r
+               iCPU = get_cpu();\r
+               bLocked = (iCPU == atomic_read(&psSysSpecData->sPowerLockCPU));\r
+\r
+               put_cpu();\r
+       }\r
+\r
+       return bLocked;\r
+}\r
+\r
+static IMG_VOID PowerLockWrap(SYS_SPECIFIC_DATA *psSysSpecData)\r
+{\r
+       IMG_INT iCPU;\r
+\r
+       if (!in_interrupt())\r
+       {\r
+\r
+               iCPU = get_cpu();\r
+\r
+\r
+               PVR_ASSERT(iCPU != -1);\r
+\r
+               PVR_ASSERT(!PowerLockWrappedOnCPU(psSysSpecData));\r
+\r
+               spin_lock(&psSysSpecData->sPowerLock);\r
+\r
+               atomic_set(&psSysSpecData->sPowerLockCPU, iCPU);\r
+       }\r
+}\r
+\r
+static IMG_VOID PowerLockUnwrap(SYS_SPECIFIC_DATA *psSysSpecData)\r
+{\r
+       if (!in_interrupt())\r
+       {\r
+               PVR_ASSERT(PowerLockWrappedOnCPU(psSysSpecData));\r
+\r
+               atomic_set(&psSysSpecData->sPowerLockCPU, -1);\r
+\r
+               spin_unlock(&psSysSpecData->sPowerLock);\r
+\r
+               put_cpu();\r
+       }\r
+}\r
+\r
+PVRSRV_ERROR SysPowerLockWrap(SYS_DATA *psSysData)\r
+{\r
+       SYS_SPECIFIC_DATA *psSysSpecData = (SYS_SPECIFIC_DATA *) psSysData->pvSysSpecificData;\r
+\r
+       PowerLockWrap(psSysSpecData);\r
+\r
+       return PVRSRV_OK;\r
+}\r
+\r
+IMG_VOID SysPowerLockUnwrap(SYS_DATA *psSysData)\r
+{\r
+       SYS_SPECIFIC_DATA *psSysSpecData = (SYS_SPECIFIC_DATA *) psSysData->pvSysSpecificData;\r
+\r
+       PowerLockUnwrap(psSysSpecData);\r
+}\r
+#else\r
+static IMG_BOOL PowerLockWrappedOnCPU(SYS_SPECIFIC_DATA unref__ *psSysSpecData)\r
+{\r
+       return IMG_FALSE;\r
+}\r
+\r
+static IMG_VOID PowerLockWrap(SYS_SPECIFIC_DATA unref__ *psSysSpecData)\r
+{\r
+}\r
+\r
+static IMG_VOID PowerLockUnwrap(SYS_SPECIFIC_DATA unref__ *psSysSpecData)\r
+{\r
+}\r
+\r
+PVRSRV_ERROR SysPowerLockWrap(SYS_DATA unref__ *psSysData)\r
+{\r
+       return PVRSRV_OK;\r
+}\r
+\r
+IMG_VOID SysPowerLockUnwrap(SYS_DATA unref__ *psSysData)\r
+{\r
+}\r
+#endif\r
+\r
+IMG_BOOL WrapSystemPowerChange(SYS_SPECIFIC_DATA *psSysSpecData)\r
+{\r
+       IMG_BOOL bPowerLock = PowerLockWrappedOnCPU(psSysSpecData);\r
+\r
+       if (bPowerLock)\r
+       {\r
+               PowerLockUnwrap(psSysSpecData);\r
+       }\r
+\r
+       return bPowerLock;\r
+}\r
+\r
+IMG_VOID UnwrapSystemPowerChange(SYS_SPECIFIC_DATA *psSysSpecData)\r
+{\r
+       PowerLockWrap(psSysSpecData);\r
+}\r
+\r
+static inline IMG_UINT32 scale_by_rate(IMG_UINT32 val, IMG_UINT32 rate1, IMG_UINT32 rate2)\r
+{\r
+       if (rate1 >= rate2)\r
+       {\r
+               return val * (rate1 / rate2);\r
+       }\r
+\r
+       return val / (rate2 / rate1);\r
+}\r
+\r
+static inline IMG_UINT32 scale_prop_to_SGX_clock(IMG_UINT32 val, IMG_UINT32 rate)\r
+{\r
+       return scale_by_rate(val, rate, SYS_SGX_CLOCK_SPEED);\r
+}\r
+\r
+static inline IMG_UINT32 scale_inv_prop_to_SGX_clock(IMG_UINT32 val, IMG_UINT32 rate)\r
+{\r
+       return scale_by_rate(val, SYS_SGX_CLOCK_SPEED, rate);\r
+}\r
+\r
+IMG_VOID SysGetSGXTimingInformation(SGX_TIMING_INFORMATION *psTimingInfo)\r
+{\r
+       IMG_UINT32 rate;\r
+\r
+#if defined(NO_HARDWARE)\r
+       rate = SYS_SGX_CLOCK_SPEED;\r
+#else\r
+       PVR_ASSERT(atomic_read(&gpsSysSpecificData->sSGXClocksEnabled) != 0);\r
+\r
+       rate = clk_get_rate(gpsSysSpecificData->psSGX_FCK);\r
+       PVR_ASSERT(rate != 0);\r
+#endif\r
+       psTimingInfo->ui32CoreClockSpeed = rate;\r
+       psTimingInfo->ui32HWRecoveryFreq = scale_prop_to_SGX_clock(SYS_SGX_HWRECOVERY_TIMEOUT_FREQ, rate);\r
+       psTimingInfo->ui32uKernelFreq = scale_prop_to_SGX_clock(SYS_SGX_PDS_TIMER_FREQ, rate);\r
+       psTimingInfo->ui32ActivePowManLatencyms = SYS_SGX_ACTIVE_POWER_LATENCY_MS;\r
+}\r
+\r
+#if defined(CONSTRAINT_NOTIFICATIONS)\r
+#if !defined(SGX_DYNAMIC_TIMING_INFO)\r
+#error "SGX_DYNAMIC_TIMING_INFO must be defined for this platform"\r
+#endif\r
+\r
+#if !defined(PDUMP) && !defined(NO_HARDWARE)\r
+static inline IMG_BOOL ConstraintNotificationsEnabled(SYS_SPECIFIC_DATA *psSysSpecData)\r
+{\r
+       return (atomic_read(&psSysSpecData->sSGXClocksEnabled) != 0) && psSysSpecData->bSGXInitComplete && psSysSpecData->bConstraintNotificationsEnabled;\r
+\r
+}\r
+\r
+static IMG_BOOL NotifyLockedOnCPU(SYS_SPECIFIC_DATA *psSysSpecData)\r
+{\r
+       IMG_INT iCPU = get_cpu();\r
+       IMG_BOOL bLocked = (iCPU == atomic_read(&psSysSpecData->sNotifyLockCPU));\r
+\r
+       put_cpu();\r
+\r
+       return bLocked;\r
+}\r
+\r
+static IMG_VOID NotifyLock(SYS_SPECIFIC_DATA *psSysSpecData)\r
+{\r
+       IMG_INT iCPU;\r
+\r
+       BUG_ON(in_interrupt());\r
+\r
+\r
+       iCPU = get_cpu();\r
+\r
+\r
+       PVR_ASSERT(iCPU != -1);\r
+\r
+       PVR_ASSERT(!NotifyLockedOnCPU(psSysSpecData));\r
+\r
+       spin_lock(&psSysSpecData->sNotifyLock);\r
+\r
+       atomic_set(&psSysSpecData->sNotifyLockCPU, iCPU);\r
+\r
+}\r
+\r
+static IMG_VOID NotifyUnlock(SYS_SPECIFIC_DATA *psSysSpecData)\r
+{\r
+       PVR_ASSERT(NotifyLockedOnCPU(psSysSpecData));\r
+\r
+       atomic_set(&psSysSpecData->sNotifyLockCPU, -1);\r
+\r
+       spin_unlock(&psSysSpecData->sNotifyLock);\r
+\r
+       put_cpu();\r
+}\r
+\r
+static IMG_INT VDD2PostFunc(struct notifier_block *n, IMG_UINT32 event, IMG_VOID *ptr)\r
+{\r
+       PVR_UNREFERENCED_PARAMETER(n);\r
+       PVR_UNREFERENCED_PARAMETER(event);\r
+       PVR_UNREFERENCED_PARAMETER(ptr);\r
+\r
+       if (in_interrupt())\r
+       {\r
+               PVR_DPF((PVR_DBG_ERROR, "%s Called in interrupt context.  Ignoring.", __FUNCTION__));\r
+               return 0;\r
+       }\r
+\r
+\r
+       if (!NotifyLockedOnCPU(gpsSysSpecificData))\r
+       {\r
+               return 0;\r
+       }\r
+\r
+#if defined(DEBUG)\r
+       if (ConstraintNotificationsEnabled(gpsSysSpecificData))\r
+       {\r
+               IMG_UINT32 rate;\r
+\r
+               rate = clk_get_rate(gpsSysSpecificData->psSGX_FCK);\r
+\r
+               PVR_ASSERT(rate != 0);\r
+\r
+               PVR_DPF((PVR_DBG_MESSAGE, "%s: SGX clock rate: %dMHz", __FUNCTION__, HZ_TO_MHZ(rate)));\r
+       }\r
+#endif\r
+       if (gpsSysSpecificData->bCallVDD2PostFunc)\r
+       {\r
+               PVRSRVDevicePostClockSpeedChange(gpsSysSpecificData->psSGXDevNode->sDevId.ui32DeviceIndex, IMG_TRUE, IMG_NULL);\r
+\r
+               gpsSysSpecificData->bCallVDD2PostFunc = IMG_FALSE;\r
+       }\r
+       else\r
+       {\r
+               if (ConstraintNotificationsEnabled(gpsSysSpecificData))\r
+               {\r
+                       PVR_TRACE(("%s: Not calling PVR clock speed notification functions", __FUNCTION__));\r
+               }\r
+       }\r
+\r
+       NotifyUnlock(gpsSysSpecificData);\r
+\r
+       return 0;\r
+}\r
+\r
+static IMG_INT VDD2PreFunc(struct notifier_block *n, IMG_UINT32 event, IMG_VOID *ptr)\r
+{\r
+       PVR_UNREFERENCED_PARAMETER(n);\r
+       PVR_UNREFERENCED_PARAMETER(event);\r
+       PVR_UNREFERENCED_PARAMETER(ptr);\r
+\r
+       if (in_interrupt())\r
+       {\r
+               PVR_DPF((PVR_DBG_WARNING, "%s Called in interrupt context.  Ignoring.", __FUNCTION__));\r
+               return 0;\r
+       }\r
+\r
+       if (PowerLockWrappedOnCPU(gpsSysSpecificData))\r
+       {\r
+               PVR_DPF((PVR_DBG_WARNING, "%s Called from within a power transition.  Ignoring.", __FUNCTION__));\r
+               return 0;\r
+       }\r
+\r
+       NotifyLock(gpsSysSpecificData);\r
+\r
+       PVR_ASSERT(!gpsSysSpecificData->bCallVDD2PostFunc);\r
+\r
+       if (ConstraintNotificationsEnabled(gpsSysSpecificData))\r
+       {\r
+               PVRSRV_ERROR eError;\r
+\r
+               eError = PVRSRVDevicePreClockSpeedChange(gpsSysSpecificData->psSGXDevNode->sDevId.ui32DeviceIndex, IMG_TRUE, IMG_NULL);\r
+\r
+               gpsSysSpecificData->bCallVDD2PostFunc = (eError == PVRSRV_OK);\r
+\r
+       }\r
+\r
+       return 0;\r
+}\r
+static IMG_VOID RegisterConstraintNotifications(IMG_VOID)\r
+{\r
+       PVR_TRACE(("Registering constraint notifications"));\r
+\r
+       PVR_ASSERT(!gpsSysSpecificData->bConstraintNotificationsEnabled);\r
+\r
+\r
+       NotifyLock(gpsSysSpecificData);\r
+       gpsSysSpecificData->bConstraintNotificationsEnabled = IMG_TRUE;\r
+       NotifyUnlock(gpsSysSpecificData);\r
+\r
+       PVR_TRACE(("VDD2 constraint notifications registered"));\r
+}\r
+\r
+static IMG_VOID UnRegisterConstraintNotifications(IMG_VOID)\r
+{\r
+       PVR_TRACE(("Unregistering constraint notifications"));\r
+\r
+\r
+       NotifyLock(gpsSysSpecificData);\r
+       gpsSysSpecificData->bConstraintNotificationsEnabled = IMG_FALSE;\r
+       NotifyUnlock(gpsSysSpecificData);\r
+\r
+}\r
+#else\r
+static IMG_VOID RegisterConstraintNotifications(IMG_VOID)\r
+{\r
+}\r
+\r
+static IMG_VOID UnRegisterConstraintNotifications(IMG_VOID)\r
+{\r
+}\r
+#endif\r
+#endif\r
+\r
+PVRSRV_ERROR EnableSGXClocks(SYS_DATA *psSysData)\r
+{\r
+#if !defined(NO_HARDWARE)\r
+       SYS_SPECIFIC_DATA *psSysSpecData = (SYS_SPECIFIC_DATA *) psSysData->pvSysSpecificData;\r
+       long lNewRate;\r
+       IMG_INT res;\r
+\r
+\r
+       if (atomic_read(&psSysSpecData->sSGXClocksEnabled) != 0)\r
+       {\r
+               return PVRSRV_OK;\r
+       }\r
+\r
+       PVR_DPF((PVR_DBG_MESSAGE, "EnableSGXClocks: Enabling SGX Clocks"));\r
+\r
+       res = clk_enable(psSysSpecData->psSGX_FCK);\r
+       if (res < 0)\r
+       {\r
+               PVR_DPF((PVR_DBG_ERROR, "EnableSGXClocks: Couldn't enable SGX functional clock (%d)", res));\r
+               return PVRSRV_ERROR_GENERIC;\r
+       }\r
+\r
+#if 0 \r
+       lNewRate = clk_round_rate(psSysSpecData->psSGX_FCK, SYS_SGX_CLOCK_SPEED + ONE_MHZ);\r
+        PVR_DPF((PVR_DBG_MESSAGE, "New SGXClocks: CPU Clock is %dMhz", HZ_TO_MHZ(lNewRate)));\r
+       //PVR_DPF((PVR_DBG_WARNING, "EnableSGXClocks: New SGX Func Clk = (%d)", lNewRate));\r
+       if (lNewRate <= 0)\r
+       {\r
+               PVR_DPF((PVR_DBG_ERROR, "EnableSGXClocks: Couldn't round SGX functional clock rate"));\r
+               return PVRSRV_ERROR_GENERIC;\r
+       }\r
+\r
+       res = clk_set_rate(psSysSpecData->psSGX_FCK, lNewRate);\r
+       if (res < 0)\r
+       {\r
+               PVR_DPF((PVR_DBG_ERROR, "EnableSGXClocks: Couldn't set SGX function clock rate (%d)", res));\r
+               return PVRSRV_ERROR_GENERIC;\r
+       }\r
+#endif\r
+#if defined(DEBUG)\r
+       {\r
+\r
+               IMG_UINT32 rate = clk_get_rate(psSysSpecData->psSGX_FCK);\r
+               PVR_DPF((PVR_DBG_MESSAGE, "EnableSGXClocks: SGX Functional Clock is %dMhz", HZ_TO_MHZ(rate)));\r
+       }\r
+#endif\r
+\r
+       set_vdd2_constraint();\r
+\r
+       lNewRate  = clk_get_rate(psSysSpecData->psSGX_FCK);\r
+       atomic_set(&psSysSpecData->sSGXClocksEnabled, 1);\r
+       PVR_DPF((PVR_DBG_ERROR, "EnableSGXClocks: Final SGX Func Clk = (%d)", lNewRate));\r
+#else\r
+       PVR_UNREFERENCED_PARAMETER(psSysData);\r
+#endif\r
+       return PVRSRV_OK;\r
+}\r
+\r
+\r
+IMG_VOID DisableSGXClocks(SYS_DATA *psSysData)\r
+{\r
+#if !defined(NO_HARDWARE)\r
+       SYS_SPECIFIC_DATA *psSysSpecData = (SYS_SPECIFIC_DATA *) psSysData->pvSysSpecificData;\r
+\r
+       if (atomic_read(&psSysSpecData->sSGXClocksEnabled) == 0)\r
+       {\r
+               return;\r
+       }\r
+\r
+       PVR_DPF((PVR_DBG_MESSAGE, "DisableSGXClocks: Disabling SGX Clocks"));\r
+\r
+       if (psSysSpecData->psSGX_FCK)\r
+       {\r
+               clk_disable(psSysSpecData->psSGX_FCK);\r
+       }\r
+\r
+       remove_vdd2_constraint();\r
+\r
+       atomic_set(&psSysSpecData->sSGXClocksEnabled, 0);\r
+\r
+#else\r
+       PVR_UNREFERENCED_PARAMETER(psSysData);\r
+#endif\r
+}\r
+\r
+PVRSRV_ERROR EnableSystemClocks(SYS_DATA *psSysData)\r
+{\r
+       SYS_SPECIFIC_DATA *psSysSpecData = (SYS_SPECIFIC_DATA *) psSysData->pvSysSpecificData;\r
+       struct clk *psCLK;\r
+       IMG_INT res;\r
+       PVRSRV_ERROR eError;\r
+       IMG_BOOL bPowerLock;\r
+\r
+#if defined(DEBUG) || defined(TIMING)\r
+       IMG_INT rate;\r
+       struct clk *sys_ck;\r
+       IMG_CPU_PHYADDR     TimerRegPhysBase;\r
+       IMG_HANDLE hTimerEnable;\r
+       IMG_UINT32 *pui32TimerEnable;\r
+\r
+#endif\r
+\r
+       PVR_TRACE(("EnableSystemClocks: Enabling System Clocks"));\r
+\r
+       if (!psSysSpecData->bSysClocksOneTimeInit)\r
+       {\r
+               bPowerLock = IMG_FALSE;\r
+\r
+               spin_lock_init(&psSysSpecData->sPowerLock);\r
+               atomic_set(&psSysSpecData->sPowerLockCPU, -1);\r
+               spin_lock_init(&psSysSpecData->sNotifyLock);\r
+               atomic_set(&psSysSpecData->sNotifyLockCPU, -1);\r
+\r
+               atomic_set(&psSysSpecData->sSGXClocksEnabled, 0);\r
+\r
+                psCLK = clk_get(NULL, "sgx_ck");\r
+               if (IS_ERR(psCLK))\r
+               {\r
+                       PVR_DPF((PVR_DBG_ERROR, "EnableSsystemClocks: Couldn't get SGX Functional Clock"));\r
+                       goto ExitError;\r
+               }\r
+               psSysSpecData->psSGX_FCK = psCLK;\r
+\r
+               psSysSpecData->bSysClocksOneTimeInit = IMG_TRUE;\r
+       }\r
+       else\r
+       {\r
+\r
+               bPowerLock = PowerLockWrappedOnCPU(psSysSpecData);\r
+               if (bPowerLock)\r
+               {\r
+                       PowerLockUnwrap(psSysSpecData);\r
+               }\r
+       }\r
+\r
+#if defined(CONSTRAINT_NOTIFICATIONS)\r
+\r
+       RegisterConstraintNotifications();\r
+#endif\r
+\r
+#if defined(DEBUG) || defined(TIMING)\r
+\r
+       psCLK = clk_get(NULL, "gpt7_fck");\r
+       if (IS_ERR(psCLK))\r
+       {\r
+               PVR_DPF((PVR_DBG_ERROR, "EnableSystemClocks: Couldn't get GPTIMER11 functional clock"));\r
+               goto ExitUnRegisterConstraintNotifications;\r
+       }\r
+       psSysSpecData->psGPT11_FCK = psCLK;\r
+\r
+       psCLK = clk_get(NULL, "gpt7_ick");\r
+       if (IS_ERR(psCLK))\r
+       {\r
+               PVR_DPF((PVR_DBG_ERROR, "EnableSystemClocks: Couldn't get GPTIMER11 interface clock"));\r
+               goto ExitUnRegisterConstraintNotifications;\r
+       }\r
+       psSysSpecData->psGPT11_ICK = psCLK;\r
+\r
+       rate = clk_get_rate(psSysSpecData->psGPT11_FCK);\r
+       PVR_TRACE(("GPTIMER11 clock is %dMHz", HZ_TO_MHZ(rate)));\r
+\r
+       res = clk_enable(psSysSpecData->psGPT11_FCK);\r
+       if (res < 0)\r
+       {\r
+               PVR_DPF((PVR_DBG_ERROR, "EnableSystemClocks: Couldn't enable GPTIMER11 functional clock (%d)", res));\r
+               goto ExitUnRegisterConstraintNotifications;\r
+       }\r
+\r
+       res = clk_enable(psSysSpecData->psGPT11_ICK);\r
+       if (res < 0)\r
+       {\r
+               PVR_DPF((PVR_DBG_ERROR, "EnableSystemClocks: Couldn't enable GPTIMER11 interface clock (%d)", res));\r
+               goto ExitDisableGPT11FCK;\r
+       }\r
+\r
+\r
+       TimerRegPhysBase.uiAddr = SYS_OMAP3430_GP11TIMER_TSICR_SYS_PHYS_BASE;\r
+       pui32TimerEnable = OSMapPhysToLin(TimerRegPhysBase,\r
+                  4,\r
+                  PVRSRV_HAP_KERNEL_ONLY|PVRSRV_HAP_UNCACHED,\r
+                  &hTimerEnable);\r
+\r
+       if (pui32TimerEnable == IMG_NULL)\r
+       {\r
+               PVR_DPF((PVR_DBG_ERROR, "EnableSystemClocks: OSMapPhysToLin failed"));\r
+               goto ExitDisableGPT11ICK;\r
+       }\r
+\r
+       rate = *pui32TimerEnable;\r
+       if(!(rate & 4))\r
+       {\r
+               PVR_TRACE(("Setting GPTIMER11 mode to posted (currently is non-posted)"));\r
+\r
+\r
+               *pui32TimerEnable = rate | 4;\r
+       }\r
+\r
+       OSUnMapPhysToLin(pui32TimerEnable,\r
+                   4,\r
+                   PVRSRV_HAP_KERNEL_ONLY|PVRSRV_HAP_UNCACHED,\r
+                   hTimerEnable);\r
+\r
+\r
+       TimerRegPhysBase.uiAddr = SYS_OMAP3430_GP11TIMER_ENABLE_SYS_PHYS_BASE;\r
+       pui32TimerEnable = OSMapPhysToLin(TimerRegPhysBase,\r
+                  4,\r
+                  PVRSRV_HAP_KERNEL_ONLY|PVRSRV_HAP_UNCACHED,\r
+                  &hTimerEnable);\r
+\r
+       if (pui32TimerEnable == IMG_NULL)\r
+       {\r
+               PVR_DPF((PVR_DBG_ERROR, "EnableSystemClocks: OSMapPhysToLin failed"));\r
+               goto ExitDisableGPT11ICK;\r
+       }\r
+\r
+\r
+       *pui32TimerEnable = 3;\r
+\r
+       OSUnMapPhysToLin(pui32TimerEnable,\r
+                   4,\r
+                   PVRSRV_HAP_KERNEL_ONLY|PVRSRV_HAP_UNCACHED,\r
+                   hTimerEnable);\r
+\r
+#endif\r
+\r
+       eError = PVRSRV_OK;\r
+       goto Exit;\r
+\r
+#if defined(DEBUG) || defined(TIMING)\r
+ExitDisableGPT11ICK:\r
+       clk_disable(psSysSpecData->psGPT11_ICK);\r
+ExitDisableGPT11FCK:\r
+       clk_disable(psSysSpecData->psGPT11_FCK);\r
+ExitUnRegisterConstraintNotifications:\r
+#endif\r
+#if defined(CONSTRAINT_NOTIFICATIONS)\r
+       UnRegisterConstraintNotifications();\r
+\r
+#endif\r
+ExitError:\r
+       eError = PVRSRV_ERROR_GENERIC;\r
+Exit:\r
+       if (bPowerLock)\r
+       {\r
+               PowerLockWrap(psSysSpecData);\r
+       }\r
+\r
+#if !defined(SUPPORT_ACTIVE_POWER_MANAGEMENT)\r
+       if (eError == PVRSRV_OK)\r
+       {\r
+\r
+               eError = EnableSGXClocks(psSysData);\r
+       }\r
+#endif\r
+       return eError;\r
+}\r
+\r
+IMG_VOID DisableSystemClocks(SYS_DATA *psSysData)\r
+{\r
+       SYS_SPECIFIC_DATA *psSysSpecData = (SYS_SPECIFIC_DATA *) psSysData->pvSysSpecificData;\r
+       IMG_BOOL bPowerLock;\r
+#if defined(DEBUG) || defined(TIMING)\r
+       IMG_CPU_PHYADDR TimerRegPhysBase;\r
+       IMG_HANDLE hTimerDisable;\r
+       IMG_UINT32 *pui32TimerDisable;\r
+#endif\r
+\r
+       PVR_TRACE(("DisableSystemClocks: Disabling System Clocks"));\r
+\r
+       DisableSGXClocks(psSysData);\r
+\r
+       bPowerLock = PowerLockWrappedOnCPU(psSysSpecData);\r
+       if (bPowerLock)\r
+       {\r
+\r
+               PowerLockUnwrap(psSysSpecData);\r
+       }\r
+\r
+#if defined(CONSTRAINT_NOTIFICATIONS)\r
+       UnRegisterConstraintNotifications();\r
+#endif\r
+\r
+#if defined(DEBUG) || defined(TIMING)\r
+\r
+       TimerRegPhysBase.uiAddr = SYS_OMAP3430_GP11TIMER_ENABLE_SYS_PHYS_BASE;\r
+       pui32TimerDisable = OSMapPhysToLin(TimerRegPhysBase,\r
+                               4,\r
+                               PVRSRV_HAP_KERNEL_ONLY|PVRSRV_HAP_UNCACHED,\r
+                               &hTimerDisable);\r
+\r
+       if (pui32TimerDisable == IMG_NULL)\r
+       {\r
+               PVR_DPF((PVR_DBG_ERROR, "DisableSystemClocks: OSMapPhysToLin failed"));\r
+       }\r
+       else\r
+       {\r
+               *pui32TimerDisable = 0;\r
+\r
+               OSUnMapPhysToLin(pui32TimerDisable,\r
+                               4,\r
+                               PVRSRV_HAP_KERNEL_ONLY|PVRSRV_HAP_UNCACHED,\r
+                               hTimerDisable);\r
+       }\r
+\r
+       clk_disable(psSysSpecData->psGPT11_ICK);\r
+\r
+       clk_disable(psSysSpecData->psGPT11_FCK);\r
+\r
+#endif\r
+       if (bPowerLock)\r
+       {\r
+               PowerLockWrap(psSysSpecData);\r
+       }\r
+}\r
diff --git a/tools/intern/debug/client/linuxsrv.h b/tools/intern/debug/client/linuxsrv.h
new file mode 100644 (file)
index 0000000..adfcd75
--- /dev/null
@@ -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. <gpl-support@imgtec.com>
+ * 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 (file)
index 0000000..f8f3bdb
--- /dev/null
@@ -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. <gpl-support@imgtec.com>
+ * Home Park Estate, Kings Langley, Herts, WD4 8LZ, UK 
+ *
+ ******************************************************************************/
+
+
+#ifdef LINUX
+#include <linux/string.h>
+#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 (file)
index 0000000..cdd9312
--- /dev/null
@@ -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. <gpl-support@imgtec.com>
+ * 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 (file)
index 0000000..7b588b5
--- /dev/null
@@ -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. <gpl-support@imgtec.com>
+ * 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 (file)
index 0000000..734de26
--- /dev/null
@@ -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. <gpl-support@imgtec.com>
+ * Home Park Estate, Kings Langley, Herts, WD4 8LZ, UK 
+ *
+ ******************************************************************************/
+
+
+#if !defined(LINUX)
+#include <ntddk.h>
+#include <windef.h>
+#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 (file)
index 0000000..499d64e
--- /dev/null
@@ -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. <gpl-support@imgtec.com>
+ * 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 (file)
index 0000000..8ef809f
--- /dev/null
@@ -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. <gpl-support@imgtec.com>
+ * Home Park Estate, Kings Langley, Herts, WD4 8LZ, UK 
+ *
+ ******************************************************************************/
+
+
+
+#ifdef LINUX
+#include <asm/uaccess.h>
+#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 (file)
index 0000000..061be9a
--- /dev/null
@@ -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. <gpl-support@imgtec.com>
+ * 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 (file)
index 0000000..dc2f035
--- /dev/null
@@ -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. <gpl-support@imgtec.com>
+ * Home Park Estate, Kings Langley, Herts, WD4 8LZ, UK 
+ *
+ ******************************************************************************/
+
+#include <linux/version.h>
+#include <linux/errno.h>
+#include <linux/module.h>
+#include <linux/fs.h>
+#include <linux/kernel.h>
+#include <linux/mm.h>
+#include <linux/string.h>
+#include <asm/page.h>
+#include <linux/vmalloc.h>
+#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,15))
+#include <linux/mutex.h>
+#else
+#include <asm/semaphore.h>
+#endif
+#include <linux/hardirq.h>
+
+#if defined(SUPPORT_DBGDRV_EVENT_OBJECTS)
+#include <linux/sched.h>
+#include <linux/wait.h>
+#include <linux/jiffies.h>
+#include <linux/delay.h>
+#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<ui32Size;i++)
+    {
+        dst[i]=src[i];
+    }
+#else
+    memcpy(pvDst, pvSrc, ui32Size);
+#endif
+}
+
+IMG_UINT32 HostReadRegistryDWORDFromString(char *pcKey, char *pcValueName, IMG_UINT32 *pui32Data)
+{
+    
+       return 0;
+}
+
+IMG_VOID * HostPageablePageAlloc(IMG_UINT32 ui32Pages)
+{
+    return (void*)vmalloc(ui32Pages * PAGE_SIZE);
+}
+
+IMG_VOID HostPageablePageFree(IMG_VOID * pvBase)
+{
+    vfree(pvBase);
+}
+
+IMG_VOID * HostNonPageablePageAlloc(IMG_UINT32 ui32Pages)
+{
+    return (void*)vmalloc(ui32Pages * PAGE_SIZE);
+}
+
+IMG_VOID HostNonPageablePageFree(IMG_VOID * pvBase)
+{
+    vfree(pvBase);
+}
+
+IMG_VOID * HostMapKrnBufIntoUser(IMG_VOID * pvKrnAddr, IMG_UINT32 ui32Size, IMG_VOID **ppvMdl)
+{
+    
+       return IMG_NULL;
+}
+
+IMG_VOID HostUnMapKrnBufFromUser(IMG_VOID * pvUserAddr, IMG_VOID * pvMdl, IMG_VOID * pvProcess)
+{
+    
+}
+
+IMG_VOID HostCreateRegDeclStreams(IMG_VOID)
+{
+    
+}
+
+IMG_VOID * HostCreateMutex(IMG_VOID)
+{
+       struct semaphore *psSem;
+
+       psSem = kmalloc(sizeof(*psSem), GFP_KERNEL);
+       if (psSem)
+       {
+               init_MUTEX(psSem);
+       }
+
+       return psSem;
+}
+
+IMG_VOID HostAquireMutex(IMG_VOID * pvMutex)
+{
+       BUG_ON(in_interrupt());
+
+#if defined(PVR_DEBUG_DBGDRV_DETECT_HOST_MUTEX_COLLISIONS)
+       if (down_trylock((struct semaphore *)pvMutex))
+       {
+               printk(KERN_INFO "HostAquireMutex: Waiting for mutex\n");
+               down((struct semaphore *)pvMutex);
+       }
+#else
+       down((struct semaphore *)pvMutex);
+#endif
+}
+
+IMG_VOID HostReleaseMutex(IMG_VOID * pvMutex)
+{
+       up((struct semaphore *)pvMutex);
+}
+
+IMG_VOID HostDestroyMutex(IMG_VOID * pvMutex)
+{
+       if (pvMutex)
+       {
+               kfree(pvMutex);
+       }
+}
+
+#if defined(SUPPORT_DBGDRV_EVENT_OBJECTS)
+
+#define        EVENT_WAIT_TIMEOUT_MS   500
+#define        EVENT_WAIT_TIMEOUT_JIFFIES      (EVENT_WAIT_TIMEOUT_MS * HZ / 1000)
+
+static int iStreamData;
+static wait_queue_head_t sStreamDataEvent;
+
+IMG_INT32 HostCreateEventObjects(IMG_VOID)
+{
+       init_waitqueue_head(&sStreamDataEvent);
+
+       return 0;
+}
+
+IMG_VOID HostWaitForEvent(DBG_EVENT eEvent)
+{
+       switch(eEvent)
+       {
+               case DBG_EVENT_STREAM_DATA:
+                       
+                       wait_event_interruptible_timeout(sStreamDataEvent, iStreamData != 0, EVENT_WAIT_TIMEOUT_JIFFIES);
+                       iStreamData = 0;
+                       break;
+               default:
+                       
+                       msleep_interruptible(EVENT_WAIT_TIMEOUT_MS);
+                       break;
+       }
+}
+
+IMG_VOID HostSignalEvent(DBG_EVENT eEvent)
+{
+       switch(eEvent)
+       {
+               case DBG_EVENT_STREAM_DATA:
+                       iStreamData = 1;
+                       wake_up_interruptible(&sStreamDataEvent);
+                       break;
+               default:
+                       break;
+       }
+}
+
+IMG_VOID HostDestroyEventObjects(IMG_VOID)
+{
+}
+#endif 
diff --git a/tools/intern/debug/dbgdriv/linux/kbuild/Makefile b/tools/intern/debug/dbgdriv/linux/kbuild/Makefile
new file mode 100644 (file)
index 0000000..d61a64e
--- /dev/null
@@ -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. <gpl-support@imgtec.com>
+# 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 (file)
index 0000000..09f9ab3
--- /dev/null
@@ -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. <gpl-support@imgtec.com>
+ * Home Park Estate, Kings Langley, Herts, WD4 8LZ, UK 
+ *
+ ******************************************************************************/
+
+#include <linux/errno.h>
+#include <linux/module.h>
+#include <linux/fs.h>
+#include <linux/kernel.h>
+#include <linux/kdev_t.h>
+#include <linux/pci.h>
+#include <linux/list.h>
+#include <linux/init.h>
+#include <linux/vmalloc.h>
+#include <asm/uaccess.h>
+
+#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. <gpl-support@imgtec.com>");
+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);
+